추가 조사를 해본 결과, unattended-upgrades가 Discourse 도커 컨테이너에 설치되어 있지만 실행되지 않고 있음을 알 수 있었습니다.
우선, 명확하게 설치되어 있는 것을 확인할 수 있습니다.
root@osestaging1-discourse-ose:/var/www/discourse# dpkg -l | grep -i unatt
ii unattended-upgrades 1.11.2 all automatic installation of security upgrades
root@osestaging1-discourse-ose:/var/www/discourse#
관련 Debian 위키 문서에 따라 unattended-upgrades 패키지의 구성을 더 자세히 살펴보면
기본 구성은 합리적인 것으로 보입니다.
root@osestaging1-discourse-ose:/var/www/discourse# grep -ir 'origin=' /etc/apt/apt.conf.d/50unattended-upgrades
// "origin=Debian,codename=${distro_codename}-updates";
// "origin=Debian,codename=${distro_codename}-proposed-updates";
"origin=Debian,codename=${distro_codename},label=Debian";
"origin=Debian,codename=${distro_codename},label=Debian-Security";
root@osestaging1-discourse-ose:/var/www/discourse# cat /etc/apt/apt.conf.d/20auto-upgrades
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
root@osestaging1-discourse-ose:/var/www/discourse#
그러나 로그를 확인해 보면 마지막 항목이 1개월 전 것이었습니다.
root@osestaging1-discourse-ose:/var/www/discourse# tail -f /var/log/unattended-upgrades/unattended-upgrades*.log
==> /var/log/unattended-upgrades/unattended-upgrades-dpkg.log <==
Log started: 2019-11-17 12:34:54
(Reading database ... 44559 files and directories currently installed.)
Removing freetype2-doc (2.9.1-3+deb10u1) ...
Log ended: 2019-11-17 12:34:54
Log started: 2019-11-17 12:34:56
(Reading database ... 44389 files and directories currently installed.)
Removing libjs-jquery (3.3.1~dfsg-3) ...
Log ended: 2019-11-17 12:34:57
==> /var/log/unattended-upgrades/unattended-upgrades.log <==
2019-11-26 16:37:47,549 INFO Initial blacklist :
2019-11-26 16:37:47,550 INFO Initial whitelist:
2019-11-26 16:37:47,551 INFO Starting unattended upgrades script
2019-11-26 16:37:47,552 INFO Allowed origins are: origin=Debian,codename=buster,label=Debian, origin=Debian,codename=buster,label=Debian-Security
2019-11-26 16:37:50,811 INFO Checking if system is running on battery is skipped. Please install powermgmt-base package to check power status and skip installing updates when the system is running on battery.
2019-11-26 16:37:50,814 INFO Initial blacklist :
2019-11-26 16:37:50,815 INFO Initial whitelist:
2019-11-26 16:37:50,815 INFO Starting unattended upgrades script
2019-11-26 16:37:50,815 INFO Allowed origins are: origin=Debian,codename=buster,label=Debian, origin=Debian,codename=buster,label=Debian-Security
2019-11-26 16:37:53,119 INFO No packages found that can be upgraded unattended and no pending auto-removals
^C
root@osestaging1-discourse-ose:/var/www/discourse#
…그런데 unattended-upgrades에 대해 정의된 기본 systemd 타이머는 하루에 최소 한 번 실행되도록 설정되어 있습니다.
root@osestaging1-discourse-ose:/var/www/discourse# cat /lib/systemd/system/apt-daily.timer
[Unit]
Description=Daily apt download activities
[Timer]
OnCalendar=*-*-* 6,18:00
RandomizedDelaySec=12h
Persistent=true
[Install]
WantedBy=timers.target
root@osestaging1-discourse-ose:/var/www/discourse# cat /etc/systemd/system/apt-daily.timer.d/override.conf
cat: /etc/systemd/system/apt-daily.timer.d/override.conf: No such file or directory
root@osestaging1-discourse-ose:/var/www/discourse# cat /lib/systemd/system/apt-daily-upgrade.timer
[Unit]
Description=Daily apt upgrade and clean activities
After=apt-daily.timer
[Timer]
OnCalendar=*-*-* 6:00
RandomizedDelaySec=60m
Persistent=true
[Install]
WantedBy=timers.target
root@osestaging1-discourse-ose:/var/www/discourse# cat /etc/systemd/system/apt-daily-upgrade.timer.d/override.conf
cat: /etc/systemd/system/apt-daily-upgrade.timer.d/override.conf: No such file or directory
root@osestaging1-discourse-ose:/var/www/discourse#
하지만, 실제로는 해당 타이머들이 비활성화되어 있습니다.
root@osestaging1-discourse-ose:/var/www/discourse# sudo systemctl status apt-daily.timer
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down
root@osestaging1-discourse-ose:/var/www/discourse# sudo systemctl status apt-daily-upgrade.timer
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down
root@osestaging1-discourse-ose:/var/www/discourse#
이것은 unattended-upgrades를 수동으로 실행하여 추가로 확인되었습니다. 이 실행을 통해 두 개의 git 관련 패키지에 대한 업데이트가 필요했던 것으로 나타났습니다.
root@osestaging1-discourse-ose:/var/www/discourse# sudo unattended-upgrade -d
...
Checking: git ([<Origin component:'main' archive:'stable' origin:'Debian' label:'Debian-Security' site:'security.debian.org' isTrusted:True>])
Checking: git-man ([<Origin component:'main' archive:'stable' origin:'Debian' label:'Debian-Security' site:'security.debian.org' isTrusted:True>])
pkgs that look like they should be upgraded: git
git-man
...
All upgrades installed
InstCount=0 DelCount=0 BrokenCount=0
Extracting content from /var/log/unattended-upgrades/unattended-upgrades-dpkg.log since 2019-12-24 17:32:55
root@osestaging1-discourse-ose:/var/www/discourse#
위 unattended-upgrades 실행 중에 업데이트된 git 버전은 git (1:2.20.1-2+deb10u1)이었습니다. 이 테스트를 오늘(2019-12-24) 수행했지만, 해당 보안 업데이트는 이미 두 주 전(2019-12-10부터)에 Debian Buster(Discourse 도커 이미지가 구축된 운영체제)에서 사용 가능했습니다!
실제로 이것은 여러 취약점을 수정하는 상당히 심각한 업데이트이며, 여기에는 원격 코드 실행(RCE) 벡터 2개가 포함됩니다. 자세한 정보는 Debian 보안 공지 4581-1에서 확인할 수 있습니다.
그러나 git는 제가 우연히 발견한 예시에 불과합니다. Discourse 도커 컨테이너가 (기본적으로) 실제로 운영체제에 보안 관련 패치를 적용하지 않는다면 이는 매우 우려스러운 상황입니다.
이것은 버그인가요? 아니면 Discourse 팀의 의도적인 결정이었나요? 아니면 Discourse 도커 컨테이너에서 unattended-upgrades를 활성화하는 기능 요청이 있는 경우를 제외하고는 이것이 그냥 기본 설정인가요?