RSS듀오랩스

커널 패치는 왜 재부팅해야 적용될까? Livepatch 와 자동 재부팅

새로 만든 서버를 점검하다가 이걸 봤습니다.

설치됨:  linux-image-...-29,  libc6
실행 중: ...-28
/var/run/reboot-required  존재

자동 보안 업데이트는 켜져 있었고, 대기 중인 패치는 0건이었습니다. 겉보기에는 완벽했습니다. 그런데 실제로 돌고 있는 커널은 패치 전 버전이었습니다.

설치와 적용은 다릅니다

unattended-upgrades 는 이름 그대로 무인 업그레이드를 해 줍니다. 다만 커널에 대해서는 하는 일이 정확히 이겁니다.

새 커널 패키지를 내려받아 디스크에 설치한다.   ← 여기까지

실행 중인 커널은 메모리에 올라가 있습니다. 디스크의 파일을 바꿔도 이미 돌고 있는 커널이 교체되지는 않습니다. 재부팅해서 새 커널로 부팅해야 비로소 적용됩니다.

그래서 이런 상태가 만들어집니다.

보이는 것 실제
자동 업데이트 enabled 맞습니다
대기 패치 0건 맞습니다. 설치가 끝났으니까요
그래서 패치됐다 아닙니다

apt 는 자기 할 일을 다 했다고 보고합니다. 거짓말이 아닙니다. 다만 우리가 알고 싶은 것("이 서버가 취약한가")과 다른 질문에 답하고 있습니다.

저는 이 상태를 몇 달씩 방치한 서버를 여럿 봤습니다. 대부분 악의도 태만도 아니고, 아무도 재부팅할 이유를 못 찾아서입니다. 잘 돌고 있는 서버를 굳이 껐다 켜는 건 심리적으로 어렵습니다.

확인하는 방법

두 줄이면 됩니다.

uname -r                        # 지금 돌고 있는 커널
ls /var/run/reboot-required     # 이 파일이 있으면 재부팅 대기 중

/var/run/reboot-required 는 재부팅이 필요한 패키지가 설치될 때 만들어집니다. 어떤 패키지 때문인지도 볼 수 있습니다.

cat /var/run/reboot-required.pkgs

제 경우 linux-image, linux-base, libc6 가 들어 있었습니다.

그래서 자동 재부팅을 켰습니다

unattended-upgrades 설정에 두 줄입니다.

Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "04:30";

패치 설치 후 재부팅이 필요하면 지정한 시각에 알아서 재부팅합니다.

이걸 켤 수 있느냐는 그 서버가 상태를 들고 있느냐에 달렸습니다. 제 경우는 프록시와 터널 수신만 하는 서버라 재부팅해도 잃을 게 없었습니다. 켜기 전에 실제로 재부팅해서 확인했습니다.

SSH 복구        20초
서비스          systemd 가 전부 다시 띄움
바깥에서 온 연결 자동 재접속

설정에 Restart=always 를 적어 두는 것과 실제로 복구되는 것은 다릅니다. 한 번은 눌러 봐야 압니다.

여기서 실수를 했습니다

04:30 이라고 적어 놓고 새벽에 재부팅될 거라고 생각했습니다. 아니었습니다.

Automatic-Reboot-Time 은 서버의 로컬 시간 기준입니다. 클라우드 인스턴스는 대개 UTC 로 옵니다. 확인해 보니 제 서버도 UTC 였습니다.

Time zone: Etc/UTC

그러면 05:30 은 한국 시간 오후 2시 30분입니다. 트래픽이 가장 많은 시간에 재부팅하도록 걸어 놓은 겁니다. 다행히 다음 재부팅 전에 발견했습니다.

고치는 건 한 줄입니다.

timedatectl set-timezone Asia/Seoul

시간대를 맞춰 두면 설정 파일의 숫자가 의도한 대로 읽힙니다. 로그 타임스탬프도 같이 읽기 편해지고요.

클라우드 서버에 시각이 들어가는 설정을 넣을 때는 시간대부터 확인하시길 권합니다. cron, 백업 스케줄, 로그 회전도 같은 함정이 있습니다.

재부팅을 안 하는 방법도 있습니다

Canonical 의 Livepatch 는 재부팅 없이 커널 보안 패치를 적용합니다. 실행 중인 커널의 코드를 메모리에서 바꿔치기하는 방식입니다.

Ubuntu Pro 에 포함되고, 개인 사용은 5대까지 무료입니다(공식 커뮤니티 멤버는 50대). 등록하면 이렇게 켭니다.

sudo pro attach <>
sudo pro enable livepatch

솔깃하지만, 조건을 읽어 보니 생각보다 좁았습니다.

첫째, 커널 CVE 중에서도 high·critical 만 다룹니다. 문서에 따르면 낮은 등급의 보안 수정, 일반 버그 수정, 성능 개선은 포함되지 않습니다.

둘째, 커널만입니다. 제 서버가 대기 중이던 libc6 는 커널이 아닙니다. Livepatch 를 켰어도 그건 그대로 남습니다.

셋째, 결국 재부팅해야 하는 경우가 있습니다. ABI 가 바뀌거나 구조가 크게 달라지면 실행 중에 안전하게 못 바꿉니다. 그런 문제가 나오면 Livepatch 클라이언트가 kernel-upgrade-required 상태를 보고하고, 그 이전 커널은 더 이상 livepatch 되지 않습니다.

Canonical 자신도 이렇게 적어 두었습니다.

모든 재부팅을 피하려 하면 보안 패치 적용이 불완전해지고 취약한 패치 전략으로 이어진다

그래서 뭘 골랐나

저는 자동 재부팅으로 갔습니다. 이유는 단순합니다.

자동 재부팅 Livepatch
커버 범위 커널·유저스페이스 전부 커널 high·critical CVE
다운타임 새벽 20초 없음 (다만 가끔 재부팅 필요)
필요한 것 설정 두 줄 Ubuntu Pro 등록, 도구 하나 추가

제 서버는 20초 단절이 문제가 되지 않는 성격입니다. 그러면 커버 범위가 넓고 관리할 것이 적은 쪽이 낫습니다.

반대 상황이라면 답도 반대입니다. 세션을 오래 물고 있는 서버, 재시작에 시간이 걸리는 데이터베이스, 새벽에도 트래픽이 끊기면 안 되는 서비스라면 Livepatch 의 값어치가 큽니다. 그때도 자동 재부팅을 완전히 끄지는 말고 주기를 길게 잡는 편이 낫습니다. 언젠가는 새 커널로 갈아타야 하니까요.

정리하면 확인할 것 셋

서버를 하나 새로 세우셨다면 이것부터 보시길 권합니다.

uname -r                          # 돌고 있는 커널
cat /var/run/reboot-required.pkgs # 대기 중인 것
timedatectl                       # 시간대. 시각 설정을 넣기 전에

자동 업데이트가 켜져 있다고 안심하고 있었는데, 재보니 옛 커널로 돌고 있었습니다. 설치와 적용은 다르고, 그 차이는 재부팅 한 번입니다.

마지막 수정:

공유하실 때는 출처(Duolabs)와 원문 주소를 표시해 주세요.