تم إعداد هذا. الجزء الأكثر تعقيدًا هو أنه—حتى لو كنت جذر (root)—ستظل تحصل على أخطاء “مرفوضة من حيث الإذن” عند محاولة عرض أو تعديل قواعد iptables داخل حاوية Discourse الافتراضية في Docker.
root@24a1f9f4c038:/# iptables -L
# تحذير: جداول iptables-legacy موجودة، استخدم iptables-legacy لرؤيتها
iptables: مرفوضة من حيث الإذن (يجب أن تكون root).
root@24a1f9f4c038:/#
السبب في ذلك هو أن سكريبت launcher الخاص بـ Discourse، الذي يُغلف أوامر Docker، يقوم بتشغيل حاوية Docker الخاصة بـ Discourse دون خاصية “NET_ADMIN” بشكل افتراضي.
أكثر الطرق متانة لإضافة خاصية NET_ADMIN إلى حاوية Docker الخاصة بـ Discourse هي تحديث ملف yaml الخاص بالحاوية لتشمل الوسيطة اللازمة لأمر docker run ... /sbin/boot عبر سلسلة yaml docker_args:
docker_args: "--cap-add NET_ADMIN"
على سبيل المثال:
[root@osestaging1 discourse]# head -n15 containers/app.yml
## هذا قالب حاوية Docker منفرد لـ Discourse متكامل
##
## بعد إجراء تغييرات على هذا الملف، يجب عليك إعادة البناء
## /var/discourse/launcher rebuild app
##
## كن *حذرًا جدًا* عند التعديل!
## ملفات YAML حساسة للغاية للأخطاء في المسافات البيضاء أو المحاذاة!
## قم بزيارة http://www.yamllint.com/ للتحقق من صحة هذا الملف عند الحاجة
docker_args: "--cap-add NET_ADMIN"
templates:
- "templates/postgres.template.yml"
- "templates/redis.template.yml"
- "templates/web.template.yml"
[root@osestaging1 discourse]#
سيتم إضافة هذه إلى أمر docker run ... /sbin/boot الذي تنفذه launcher عبر متغير $user_args:
[root@osestaging1 discourse]# grep -A2 -E '^\s*\$docker_path run' launcher
$docker_path run --shm-size=512m $links $attach_on_run $restart_policy "${env[@]}" "${labels[@]}" -h "$hostname" \
-e DOCKER_HOST_IP="$docker_ip" --name $config -t "${ports[@]}" $volumes $mac_address $user_args \
$run_image $boot_command
[root@osestaging1 discourse]#
نظرًا لأن إجراء تغييرات مُدمجة في صورة Docker الخاصة بـ Discourse بعد docker pull وقبل docker run ... /sbin/boot معقد للغاية، فقد قررت تثبيت وتكوين iptables عبر سكريبت بسيط يتم تنفيذه بواسطة runit عند تشغيل الحاوية.
الأمر التالي سينشئ ملف yaml القالب الضروري الذي سيُنشئ سكريبت runit في عملية ./launcher rebuild app التالية
cat << EOF > /var/discourse/templates/iptables.template.yml
run:
- file:
path: /etc/runit/1.d/01-iptables
chmod: "+x"
contents: |
#!/bin/bash
################################################################################
# الملف: /etc/runit/1.d/01-iptables
# الإصدار: 0.2
# الغرض: تثبيت وتأمين iptables
# المؤلف: Michael Altfield <michael@opensourceecology.org>
# تم الإنشاء: 2019-11-26
# تم التحديث: 2019-12-17
################################################################################
sudo apt-get update
sudo apt-get install -y iptables
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A INPUT -s 127.0.0.1/32 -j DROP
sudo iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A INPUT -j DROP
sudo iptables -A OUTPUT -s 127.0.0.1/32 -d 127.0.0.1/32 -j ACCEPT
sudo iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A OUTPUT -m owner --uid-owner 0 -j ACCEPT
sudo iptables -A OUTPUT -m owner --uid-owner 100 -j ACCEPT
sudo iptables -A OUTPUT -j DROP
sudo ip6tables -A INPUT -i lo -j ACCEPT
sudo ip6tables -A INPUT -s ::1/128 -j DROP
sudo ip6tables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo ip6tables -A INPUT -j DROP
sudo ip6tables -A OUTPUT -s ::1/128 -d ::1/128 -j ACCEPT
sudo ip6tables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo ip6tables -A OUTPUT -m owner --uid-owner 0 -j ACCEPT
sudo ip6tables -A OUTPUT -m owner --uid-owner 100 -j ACCEPT
sudo ip6tables -A OUTPUT -j DROP
EOF
لاحظ أن هذا إعداد أساسي جدًا لـ iptables. مع ملف web.socketed.template.yml (الذي أستخدمه)، لا تحتاج حاوية Docker تقنيًا إلى أي وصول إلى الإنترنت، حيث أن خادم nginx العكسي على مضيف Docker يتواصل مع خادم nginx الخاص بـ Discourse داخل حاوية Docker عبر منفذ نطاق يونكس. السبب الرئيسي الذي يسمح لي بالوصول إلى الإنترنت هو السماح لنظام التشغيل الأساسي للحاوية بتحديث نفسه بإصلاحات أمنية حرجة عبر unattended-upgrades. ومن هنا فتح الوصول للمستخدم 100، وهو مستخدم apt.
أخيرًا، أضف ملف templates/iptables.template.yml أعلاه إلى ملف app.yaml الخاص بحاويتك.
[root@osestaging1 discourse]# head -n15 /var/discourse/containers/discourse_ose.yml
## هذا قالب حاوية Docker منفرد لـ Discourse متكامل
##
## بعد إجراء تغييرات على هذا الملف، يجب عليك إعادة البناء
## /var/discourse/launcher rebuild app
##
## كن *حذرًا جدًا* عند التعديل!
## ملفات YAML حساسة للغاية للأخطاء في المسافات البيضاء أو المحاذاة!
## قم بزيارة http://www.yamllint.com/ للتحقق من صحة هذا الملف عند الحاجة
docker_args: "--cap-add NET_ADMIN"
templates:
- "templates/iptables.template.yml"
- "templates/postgres.template.yml"
- "templates/redis.template.yml"
[root@osestaging1 discourse]#
الآن يجب أن تتمكن من
./launcher rebuild app
وبعد الانتظار حوالي 10 دقائق، ستكون حاوية Docker الخاصة بـ Discourse قد أصبحت iptables تعمل بكامل طاقتها 