Verwendet der Discourse-Container unattended-upgrades?

Verwendet der Discourse-Docker-Container unattended-upgrades, um die OS-Pakete seines Debian-basierten Docker-Containers aktuell zu halten?

Ich habe festgestellt, dass der INSTALL-cloud.md-Leitfaden empfiehlt, unattended-upgrades auf der Docker-Host-Maschine zu installieren, was mich dazu brachte, mich über den Zustand der OS-Pakete innerhalb des Docker-Containers zu fragen. Ich habe sowohl die discourse- als auch die discourse_docker-Repositories auf GitHub durchsucht, aber der einzige Hinweis auf unattended-upgrades, den ich finden konnte, war dieselbe Installationsdokumentation:

Aber was ist mit dem Discourse-Docker-Container? Verwendet er unattended-upgrades?

Nach weiterer Recherche scheint es, dass unattended-upgrades im Discourse-Docker-Container installiert, aber nicht ausgeführt wird.

Zunächst ist es eindeutig installiert:

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# 

Eine weitere Überprüfung der Konfiguration des unattended-upgrades-Pakets gemäß dem entsprechenden Debian-Wiki-Artikel ergibt:

Die Standardkonfiguration sieht vernünftig aus:

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# 

Ein Blick in die Logs zeigt jedoch, dass der letzte Eintrag vor einem Monat war:

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# 

…Obwohl die standardmäßig definierten systemd-Timer für unattended-upgrades so eingestellt sind, dass sie mindestens einmal täglich ausgeführt werden:

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# 

Tatsächlich sind diese Timer jedoch deaktiviert.

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# 

Dies wird weiter bestätigt, indem unattended-upgrades manuell ausgeführt wird, was zufällig ein Update für zwei git-bezogene Pakete erforderte:

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# 

Die git-Version, die im obigen unattended-upgrades-Lauf aktualisiert wurde, war git (1:2.20.1-2+deb10u1). Ich habe diesen Test heute (2019-12-24) durchgeführt, aber das Sicherheitsupdate war für Debian Buster (das Betriebssystem, auf dem das Discourse-Docker-Image basiert) bereits seit zwei Wochen verfügbar (seit 2019-12-10)!

Dies ist tatsächlich ein ziemlich ernstes Update, das mehrere Schwachstellen behebt, darunter zwei Vektoren für Remote Code Execution. Weitere Informationen finden Sie im Debian-Sicherheitsbericht 4581-1:

Aber git ist nur ein Beispiel, auf das ich zufällig gestoßen bin. Es ist äußerst besorgniserregend, wenn der Discourse-Docker-Container (standardmäßig) keine sicherheitsrelevanten Patches auf sein Betriebssystem anwendet.

Ist dies ein Fehler? Oder war dies eine bewusste Entscheidung des Discourse-Teams? Oder ist dies einfach der Standardfall, bis eine Feature-Anfrage gestellt wird, um unattended-upgrades im Discourse-Docker-Container zu aktivieren?

Meine Vermutung ist, dass es absichtlich deaktiviert ist, da es etwas beschädigen könnte, und das Bild selbst wird aktualisiert, wenn ein schwerwiegendes Sicherheitsproblem festgestellt wird.

Sie können es aktivieren, wenn Sie möchten, indem Sie einfach den Container betreten.

Eigentlich ist mir gerade aufgefallen, dass das Docker-Image von Discourse für die Verwendung von runit eingerichtet ist. Ist systemd überhaupt im Discourse-Docker-Container installiert?

Meine Vermutung ist, dass das Fehlen von systemd die Ursache dafür ist, dass unattended-upgrades nicht funktioniert.

Klingt vernünftig. Manche Leute mögen systemd wirklich nicht. Du kannst also entweder darauf vertrauen, dass das Basis-Container-Image regelmäßig von einem großen Team von Fachleuten aktualisiert wird, die darauf angewiesen sind, oder du machst es auf eine andere Art selbst und hoffst, dass du nichts kaputt machst.

Nein, das tut er nicht, und wir haben nicht vor, dies einzurichten. Die Empfehlung lautet, Ihr Host-Betriebssystem mit den neuesten Sicherheitspatches aktuell zu halten.

Was, für alle Fälle, auch der Fall ist.

FYI: Ich habe die defekte Installation von unattended-upgrades behoben (die ohne systemd im Discourse-Docker-Container nicht tatsächlich ausgeführt wird), indem ich sie über einen Cron-Job zur Ausführung angestoßen habe.

Ich habe folgende YAML-Vorlagendatei in meinem Verzeichnis /var/discourse/templates/ erstellt, um den erforderlichen Cron-Job einzurichten (beachten Sie, dass sie auch einen Befehl enthält, um einen Fehler mit Cron zu beheben, der im Debian-basierten Discourse-Docker-Image enthalten ist):

cat << EOF > /var/discourse/templates/unattended-upgrades.template.yml
run:
  - file:
     path: /etc/cron.d/unattended-upgrades
     contents: |+
        ################################################################################
        # File:    /etc/cron.d/unattended-upgrades
        # Version: 0.2
        # Purpose: run unattended-upgrades in lieu of systemd. For more info see
        #           * https://wiki.opensourceecology.org/wiki/Discourse
        #           * https://meta.discourse.org/t/does-discourse-container-use-unattended-upgrades/136296/3
        # Author:  Michael Altfield <michael@opensourceecology.org>
        # Created: 2020-03-23
        # Updated: 2020-04-23
        ################################################################################
        20 04 * * * root /usr/bin/nice /usr/bin/unattended-upgrades --debug
        

  - exec: /bin/echo -e "\n" >> /etc/cron.d/unattended-upgrades
  # fix the Docker cron bug https://stackoverflow.com/questions/43323754/cannot-make-remove-an-entry-for-the-specified-session-cron
  - exec: /bin/sed --in-place=.\`date "+%Y%m%d_%H%M%S"\` 's%^\([^#]*\)\(session\s\+required\s\+pam_loginuid\.so\)$%\1#\2%' /etc/pam.d/cron
EOF

Um die oben genannte Vorlagendatei zu aktivieren, müssen Sie sie in Ihre Liste der templates in der YAML-Datei Ihrer Anwendung aufnehmen. Zum Beispiel:

[root@osestaging1 discourse]# head -n20 /var/discourse/containers/app.yml
## this is the all-in-one, standalone Discourse Docker container template
##
## After making changes to this file, you MUST rebuild
## /var/discourse/launcher rebuild app
##
## BE *VERY* CAREFUL WHEN EDITING!
## YAML FILES ARE SUPER SUPER SENSITIVE TO MISTAKES IN WHITESPACE OR ALIGNMENT!
## visit http://www.yamllint.com/ to validate this file as needed

templates:
  - "templates/unattended-upgrades.template.yml"
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
#  - "templates/web.socketed.template.yml"
  - "templates/web.modsecurity.template.yml"
  - "templates/web.ratelimited.template.yml"
## Uncomment these two lines if you wish to add Lets Encrypt (https)
  #- "templates/web.ssl.template.yml"
  #- "templates/web.letsencrypt.ssl.template.yml"
[root@osestaging1 discourse]# 

Es scheint, dass dies in einem frischen Discourse-Docker-Image (mit Debian 10) aktiviert ist. Es wird über runit → cron → /etc/cron.daily/apt-compat → /usr/lib/apt/apt.systemd.daily gestartet.

Es lief auch auf einem ein Jahr alten Docker-Image auf Basis von Ubuntu 16 (basierend auf discourse/base:2.0.20190321-0122), und ich bin mir ziemlich sicher, dass ohne jegliche Anpassungen.

systemd ist nicht installiert, daher wird es nie tatsächlich ausgeführt.