تمكنت بنجاح من الاحتفاظ بتغييرات إعدادات nginx ModSecurity عبر عمليات تشغيل launcher rebuild app على النحو التالي:
أولاً، قمنا بتحديث النسخة المحلية من install-nginx التي أتت من مستودع discourse_docker وتم استنساخها إلى /var/discourse/.
cd /var/discourse/image/base
cp install-nginx install-nginx.`date "+%Y%m%d_%H%M%S"`.orig
# إضافة كتلة لاستخراج وحدة ModSecurity لـ nginx مباشرة قبل تنزيل مصدر nginx
grep 'ModSecurity' install-nginx || sed -i 's%\(curl.*nginx\.org/download.*\)%# mod_security\napt-get install -y libmodsecurity-dev modsecurity-crs\ncd /tmp\ngit clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git\n\n\1%' install-nginx
# تحديث سطر التكوين ليشمل وحدة ModSecurity المستخرجة أعلاه
sed -i '/ModSecurity/! s%^[^#]*./configure \(.*nginx.*\)%#./configure \1\n./configure \1 --add-module=/tmp/ModSecurity-nginx%' install-nginx
# إضافة سطر إلى قسم التنظيف
grep 'rm -fr /tmp/ModSecurity-nginx' install-nginx || sed -i 's%\(rm -fr.*/tmp/nginx.*\)%rm -fr /tmp/ModSecurity-nginx\n\1%' install-nginx
لاحظ أن ملف Dockerfile المسؤول عن تنفيذ سكريبت install-nginx يتم تنفيذه عند بناء الصورة. ويتم بناء الصورة فقط بواسطة فريق Discourse قبل رفعها إلى docker hub. عند تشغيل أمر Discourse ./launcher rebuild app، يتم تفعيل (إذا كانت هناك تحديثات متاحة) أمر docker pull، الذي يجلب أحدث صورة Docker الخاصة بـ Discourse من docker hub. مرة أخرى، هذا لا يعيد بناء الصورة، ولا ينفذ ملف Dockerfile، ولا ينفذ سكريبت install-nginx الذي تم تعديله أعلاه.
الطريقة الوحيدة (التي أعرفها) لتفعيل تشغيل سكريبت bash المحدّث install-nginx (والذي يتم تنفيذه بواسطة Dockerfile) هي أن يقوم docker ببناء صورة جديدة. على سبيل المثال، هذا يؤدي إلى بناء docker صورة جديدة باسم discourse_modsecurity — والتي سيتم بناؤها باستخدام سكريبت install-nginx المعدّل محليًا:
docker build --tag 'discourse_modsecurity' /var/discourse/image/base/
للأسف، لم أستطع إيجاد طريقة لإخبار launcher باستخدام صورة مخصصة (تحديد run-image يستخدم الصورة المحددة مباشرة، دون تنفيذ القوالب عليها — كما هو مطلوب لتكوين nginx فعليًا [وليس مجرد تثبيته]). لذا قمنا باستبدال متغير image المحدد في سكريبت launcher لاستخدام صورتنا المحلية الجديدة باسم discourse_modsecurity:
# استبدال السطر "image="discourse/base:<version>" بـ 'image="discourse_modsecurity"'
grep 'discourse_modsecurity' launcher || sed --in-place=.`date "+%Y%m%d_%H%M%S"` '/base_image/! s%^\(\s*\)image=\(.*\)$%#\1image=\2\n\1image="discourse_modsecurity"%' /var/discourse/launcher
الآن نضيف ملف قالب جديد لإعداد إعدادات nginx الخاصة بنا لتشمل ملفات/كتل modsecurity الضرورية:
cat << EOF > /var/discourse/templates/web.modsecurity.template.yml
run:
- exec:
cmd:
- sudo apt-get install -y modsecurity-crs
- cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf
- sed -i 's/SecRuleEngine DetectionOnly/SecRuleEngine On/' /etc/modsecurity/modsecurity.conf
- sed -i 's^\(\s*\)[^#]*SecRequestBodyInMemoryLimit\(.*\)^\1#SecRequestBodyInMemoryLimit\2^' /etc/modsecurity/modsecurity.conf
- sed -i '/nginx/! s%^\(\s*\)[^#]*SecAuditLog \(.*\)%#\1SecAuditLog \2\n\1SecAuditLog /var/log/nginx/modsec_audit.log%' /etc/modsecurity/modsecurity.conf
- file:
path: /etc/nginx/conf.d/modsecurity.include
contents: |
################################################################################
# File: modsecurity.include
# Version: 0.1
# Purpose: Defines mod_security rules for the discourse vhost
# This should be included in the server{} blocks nginx vhosts.
# Author: Michael Altfield <michael@opensourceecology.org>
# Created: 2019-11-12
# Updated: 2019-11-12
################################################################################
Include "/etc/modsecurity/modsecurity.conf"
# OWASP Core Rule Set, installed from the 'modsecurity-crs' package in debian
Include /etc/modsecurity/crs/crs-setup.conf
Include /usr/share/modsecurity-crs/rules/*.conf
- replace:
filename: "/etc/nginx/conf.d/discourse.conf"
from: /server.+{/
to: |
server {
modsecurity on;
modsecurity_rules_file /etc/nginx/conf.d/modsecurity.include;
EOF
وأضفنا هذا القالب (templates/web.modsecurity.template.yml) إلى كتلة القوالب في ملف تكوين yaml الخاص بتطبيقنا ليصبح الشكل كالتالي:
[root@osestaging1 discourse]# vim /var/discourse/containers/app.yml
...
[root@osestaging1 discourse]# grep -A 6 'templates:' /var/discourse/containers/app.yml
templates:
- "templates/postgres.template.yml"
- "templates/redis.template.yml"
- "templates/web.template.yml"
- "templates/web.ratelimited.template.yml"
- "templates/web.socketed.template.yml"
- "templates/web.modsecurity.template.yml"
[root@osestaging1 discourse]#
الآن عند إعادة بناء تطبيق Discourse docker، سيتم استخدام صورتك الجديدة discourse_modsecurity باستخدام nginx مع modsecurity، وسيتم تكوين nginx لاستخدام OWASP CRS.
/var/discourse/launcher rebuild app