Le conteneur Discourse utilise-t-il unattended-upgrades ?

Le conteneur Docker de Discourse utilise-t-il unattended-upgrades pour maintenir à jour les paquets du système d’exploitation de son conteneur Docker basé sur Debian ?

J’ai remarqué que le guide INSTALL-cloud.md recommande d’installer unattended-upgrades sur la machine hôte Docker, ce qui m’a fait me demander quel était l’état des paquets du système d’exploitation à l’intérieur du conteneur Docker. J’ai recherché à la fois dans les dépôts discourse et discourse_docker sur GitHub, mais la seule référence à unattended-upgrades que j’ai trouvée était le même document d’installation :

Mais qu’en est-il du conteneur Docker de Discourse ? Est-ce que lui utilise unattended-upgrades ?

1 « J'aime »

After further digging, it appears that unattended-upgrades is installed but not running on the Discourse docker container.

First, it’s clearly installed

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# 

Further inspecting of the unattended-upgrades package’s config per the relevant Debian wiki article shows

The default config looks sane

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# 

But checking the logs show the last entry was 1 month ago

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# 

…Even though the default systemd timers defined for unattended-upgrades are set to run at least once per day

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# 

But, indeed, those timers are disabled.

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# 

This is further confirmed by manually running unattended-upgrades, which just happened to require an update to two git-related packages

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# 

The git version that was updated in the above unattended-upgrades run was git (1:2.20.1-2+deb10u1). I ran this test today (2019-12-24), but the security upgrade had been available to Debian Buster (the OS on which the Discourse docker image is built) for two weeks (since 2019-12-10)!

This is actually a pretty serious upgrade that fixes several vulnerabilities, including two vectors for Remote Code Execution. More info is available at the Debian Security Advisory 4581-1

But git is just an example I happened to stumble on. It’s extremely concerning if the Discourse docker container doesn’t (by default) actually apply security-related patches to its OS.

Is this a bug? Or was this an intentional decision by the Discourse team? Or is this just the default in-lieu of a feature request to enable unattended-upgrades on the Discourse docker container?

My guess is that it’s off on purpose as it might break something, and the image itself is updated when a serious security issue is found.

You can enable it if you want, just enter the container.

1 « J'aime »

Actually, I just realized that Discourse’s docker image is setup to use runit. Is systemd even installed on the Discourse docker container?

My guess is not having systemd installed is what’s breaking unattended-upgrades.

Sounds right. Some people really don’t like systemd. So you can either trust that the base container gets updated regularly by people running a large team of professionals that depends on it, or you can do it some other way yourself and hope that you don’t break anything.

No it doesn’t and we don’t plan to make it use. The recommendation is to keep your host OS updated with the latest security patches.

6 « J'aime »

Which, for the record, it is.

5 « J'aime »

FYI, j’ai réparé l’installation cassée de unattended-upgrades (qui ne fonctionne pas sans systemd dans le conteneur Docker de Discourse) en le déclenchant via une tâche cron.

J’ai créé le fichier modèle YAML suivant dans mon répertoire /var/discourse/templates/ pour créer la tâche cron nécessaire (notez qu’il contient également une commande pour corriger un bug avec cron présent dans l’image Docker de Discourse basée sur Debian) :

cat << EOF > /var/discourse/templates/unattended-upgrades.template.yml
run:
  - file:
     path: /etc/cron.d/unattended-upgrades
     contents: |+
        ################################################################################
        # Fichier:    /etc/cron.d/unattended-upgrades
        # Version: 0.2
        # Objectif: exécuter unattended-upgrades à la place de systemd. Pour plus d'infos voir
        #           * https://wiki.opensourceecology.org/wiki/Discourse
        #           * https://meta.discourse.org/t/does-discourse-container-use-unattended-upgrades/136296/3
        # Auteur:  Michael Altfield <michael@opensourceecology.org>
        # Créé: 2020-03-23
        # Mis à jour: 2020-04-23
        ################################################################################
        20 04 * * * root /usr/bin/nice /usr/bin/unattended-upgrades --debug
        

  - exec: /bin/echo -e "\n" >> /etc/cron.d/unattended-upgrades
  # corriger le bug cron de Docker 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

Pour activer le fichier modèle ci-dessus, vous devez l’ajouter à votre liste de templates dans le fichier YAML de votre application. Par exemple,

[root@osestaging1 discourse]# head -n20 /var/discourse/containers/app.yml
## ceci est le modèle de conteneur Docker Discourse tout-en-un, autonome
##
## Après avoir apporté des modifications à ce fichier, vous DEVEZ reconstruire
## /var/discourse/launcher rebuild app
##
## SOYEZ *TRÈS* PRUDENT EN ÉDITANT !
## LES FICHIERS YAML SONT EXTRÊMEMENT SENSIBLES AUX ERREURS D'ESPACEMENT OU D'ALIGNEMENT !
## visitez http://www.yamllint.com/ pour valider ce fichier si nécessaire

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"
## Décommentez ces deux lignes si vous souhaitez ajouter Lets Encrypt (https)
  #- "templates/web.ssl.template.yml"
  #- "templates/web.letsencrypt.ssl.template.yml"
[root@osestaging1 discourse]# 

Il semble que cela soit activé sur une image Docker Discourse fraîchement installée (exécutant Debian 10). Elle est lancée via runit → cron → /etc/cron.daily/apt-compat → /usr/lib/apt/apt.systemd.daily

Cela fonctionnait également sur une image Docker basée sur Ubuntu 16 vieille d’un an (basée sur discourse/base:2.0.20190321-0122), et je suis presque certain qu’aucune personnalisation n’avait été effectuée.

1 « J'aime »

systemd n’étant pas installé, il ne s’exécute jamais réellement.

1 « J'aime »