هل يستخدم حاوية Discourse تحديثات غير مراقبة؟

هل يستخدم حاوية Docker الخاصة بـ Discourse unattended-upgrades لتحديث حزم نظام التشغيل في الحاوية المدعومة بـ Debian؟

لاحظت أن دليل INSTALL-cloud.md يوصي بتثبيت unattended-upgrades على جهاز المضيف الذي يشغّل Docker، مما أثار فضولي بشأن حالة حزم نظام التشغيل داخل حاوية Docker. بحثت في مستودعي discourse و discourse_docker على GitHub، لكن المرجع الوحيد الذي عثرت عليه لـ unattended-upgrades كان نفس وثيقة التثبيت:

لكن ماذا عن حاوية Docker الخاصة بـ Discourse؟ هل هي تستخدم unattended-upgrades؟

بعد بحث أعمق، يبدو أن unattended-upgrades مثبتة ولكنها ليست قيد التشغيل في حاوية Discourse Docker.

أولاً، من الواضح أنها مثبتة

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# 

عند فحص إعدادات حزمة unattended-upgrades وفقًا لمقال ويكي Debian ذي الصلة، يتضح ما يلي:

يبدو الإعداد الافتراضي معقولاً

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# 

لكن فحص السجلات يُظهر أن آخر إدخال كان قبل شهر واحد

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# 

…على الرغم من أن مؤقتات systemd الافتراضية المحددة لـ unattended-upgrades مضبوطة للتشغيل مرة واحدة على الأقل يوميًا

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# 

كان إصدار git الذي تم تحديثه في عملية unattended-upgrades أعلاه هو git (1:2.20.1-2+deb10u1). قمت بتشغيل هذا الاختبار اليوم (2019-12-24)، لكن التحديث الأمني كان متاحًا لـ Debian Buster (نظام التشغيل الذي تم بناء صورة Discourse Docker عليه) منذ أسبوعين (منذ 2019-12-10)!

هذا في الواقع تحديث خطير جدًا يُصلح عدة ثغرات أمنية، بما في ذلك طريقتان لتنفيذ الأكواد عن بُعد (Remote Code Execution). تتوفر المزيد من المعلومات في نصيحة الأمان Debian 4581-1

لكن git مجرد مثال عثرت عليه بالصدفة. من المقلق للغاية إذا كانت حاوية Discourse Docker لا تطبق فعليًا (افتراضيًا) التصحيحات الأمنية على نظام التشغيل الخاص بها.

هل هذا خطأ؟ أم أن هذا قرار متعمد من فريق Discourse؟ أم أن هذا هو الوضع الافتراضي في انتظار طلب ميزة لتمكين unattended-upgrades على حاوية Discourse Docker؟

أعتقد أنه تم إيقافه عمدًا لأنه قد يتسبب في حدوث خلل ما، ويتم تحديث الصورة نفسها عند اكتشاف مشكلة أمنية خطيرة.

يمكنك تمكينه إذا أردت، فقط أدخل الحاوية.

في الواقع، لقد أدركت للتو أن صورة Docker الخاصة بـ Discourse مُعدّة لاستخدام runit. هل تم تثبيت systemd أصلاً في حاوية Docker الخاصة بـ Discourse؟

أعتقد أن عدم تثبيت systemd هو ما يُسبب تعطل unattended-upgrades.

يبدو ذلك صحيحًا. هناك أشخاص لا يحبون systemd حقًا. لذا يمكنك إما أن تثق في أن الحاوية الأساسية يتم تحديثها بانتظام من قبل فريق كبير من المحترفين يعتمدون عليها، أو يمكنك القيام بذلك بطريقة أخرى بنفسك وتتمنى ألا تكسر أي شيء.

لا، لا تستخدمها، ولا نخطط لجعلها تستخدمها. التوصية هي الحفاظ على تحديث نظام التشغيل المضيف الخاص بك بأحدث التحديثات الأمنية.

وهو ما يحدث بالفعل، وللتوضيح.

معلومة جانبية، قمت بإصلاح تثبيت unattended-upgrades المعطّل (الذي لا يعمل فعليًا بدون systemd في حاوية Discourse Docker) عن طريق تشغيله عبر مهمة مجدولة (cron job).

لقد أنشأت ملف قالب YAML التالي في مجلد /var/discourse/templates/ الخاص بي لإنشاء مهمة الجدولة المطلوبة (لاحظ أنه يحتوي أيضًا على أمر لـ إصلاح خلل في cron موجود في صورة Discourse Docker المعتمدة على Debian):

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

لتفعيل ملف القالب أعلاه، يجب عليك إضافته إلى قائمة templates في ملف yaml الخاص بتطبيقك. على سبيل المثال،

[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]# 

يبدو أنه مفعّل في صورة Docker جديدة لـ Discourse (تعمل بنظام Debian 10). يتم تشغيله عبر runit → cron → /etc/cron.daily/apt-compat → /usr/lib/apt/apt.systemd.daily

كما كان يعمل على صورة Docker قائمة على Ubuntu 16 عمرها سنة واحدة (مبنية على discourse/base:2.0.20190321-0122)، وأنا متأكد تمامًا من أنها كانت تعمل دون أي تخصيص.

لم يتم تثبيت systemd، لذا فهو لا يعمل فعليًا أبدًا.