تثبيت ModSecurity خادم Nginx ونظام Debian

أحد أهم عناصر الأمان والحماية في خوادم الإنترنت هي برمجية ModSecurity. وهي تعتبر خط الدفاع الأول في وجه محاولات الإخترق لأي نوع من المواقع. هذا المقال يشرح تثبيت ModSecurity على Nginx.

هذا المقال هو الخامس من مشروع شرح تثبيت خادم Nginx وتشغيل موقع عليه. للعودة إلى الفهرس، يمكن الضغط هنا.

برنامج ModSecurity هو أحد أهم برامج الحماية الموجودة اليوم من أجل تقليل قدرة المخترقين على إستغلال ثغرات الخادم أو البرامج التي تعمل عليه من خلال حظر الإتصالات التي تحتوي على معلومات برمجية ضارة أو قد تكون ضارة لأمن الخادم أو المواقع الموجودة عليه.

تثبيت ModSecurity يتطلب تنزيل الكود المصدري لبرنامج ModSecurity و برنامج Nginx وبناء موديل ملائم لنسخة Nginx الموجودة على الخادم لكي يعمل بشكل صحيح. إنتبه أن تحديث نسخة Nginx بدون اعادة بناء موديل ModSecurity سوف يتسبب بانهيار Nginx وعدم عمله حتى نقوم باعادة بناء النسخة الملائمة أو تعطيل ModSecurity.

نبدأ أولا بتثبيت البرمجيات المطلوبة لبناء البرنامج من خلال تنفيذ الأمر التالي في طرفية الخادم:

apt install apt-utils autoconf automake build-essential git libcurl4-openssl-dev libgeoip-dev liblmdb-dev libpcre3-dev libtool libxml2-dev libyajl-dev pkgconf wget zlib1g-dev unzip

بعد إكتمال الأمر التالي، يمكن الآن تنزيل الكود المصدري لـ ModSecurity من GitHub:

git clone --depth 1 -b v3/master --single-branch https://github.com/SpiderLabs/ModSecurity

وبعد ذلك يمكن تحديث ملفات المستودع من خلال الدخول إلى مسار الملفات وتنفيذ الأوامر اللازمة:

cd ModSecurity
git submodule init
git submodule update

يمكن الآن بناء الكود من خلال الأوامر التالية:

./build.sh
./configure
make

يمكن تجاهل الخطأ التالي أو أخطاء مشابهة للتالي

fatal: No names found, cannot describe anything.

بعد الإنتهاء من السابق، يمكن إتمام تثبيت الكود من خلال الأمر التالي:

make install

ومن ثم الخروج من مسار التثبيت من خلال الأمر التالي:

cd ..

بناء وتثبيت ModSecurity-nginx من المصدر

نبدأ من خلال استنساخ الكود إلى الخادم من خلال الأمر التالي:

git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git

ومن ثم نقوم بتنزيل الكود المصدري لـ Nginx من أجل بناء البرنامج. قبل ذلك نتأكد من نسخة Nginx الموجودة لدينا من خلال تنفيذ الأمر التالي:

nginx -v

النتيجة ستكون مشابهة للتالي:

nginx version: nginx/1.22.1

هذا يعني أنه يجب علينا تنزيل الكود المصدري للنسخة 1.22.1 والعمل عليها. تنزيل أي نسخة أخرى سيتسبب بفشل Nginx.

نقوم الآن بتنزيل الكود المصدري لبرنامج nginx النسخة 1.22.1 ونقوم بفتح الملف من خلال الأوامر التالية:

wget http://nginx.org/download/nginx-1.22.1.tar.gz
tar zxvf nginx-1.22.1.tar.gz

نقوم الآن بدخول مسار الملفات وبناء المودل من خلال الأوامر التالية:

cd nginx-1.22.1
./configure --with-compat --add-dynamic-module=../ModSecurity-nginx
make modules

عند الإنتهاء، نقوم بنقل ملف الموديل إلى المسار الصحيح ومن ثم الخروج من مسار التثبيت:

cp objs/ngx_http_modsecurity_module.so /etc/nginx/modules-enabled/
cd ..

والآن يمكن تحميل هذه المكتبة في nginx من خلال تحرير ملف الإعدادات في المسار التالي:

vi /etc/nginx/nginx.conf

ومن ثم اضافة السطر التالي قبل كلمة http:

load_module /etc/nginx/modules-enabled/ngx_http_modsecurity_module.so;

النتيجة يجب أن تكون مشابهة للتالي:

عند الإنتهاء، نقوم بإعادة تشغيل Nginx حتى يقوم بتحميل الإعدادات الجديدة.

تثبيت قواعد الحماية من OWASP

يمكن الآن استخدام أي قواعد حماية من أي مزود خدمة ModSecurity يدعم ModSecurity 3. هنا سوف نقوم باستخدام قواعد الحماية المجانية مفتوحة المصدر المتوفرة من خلال مشروع OWASP.

الخطوة الأولى تبدأ من خلال عمل المسار الصحيح ومن ثم تنزيل ملف الإعدادات:

mkdir /etc/nginx/modsec
cd /etc/nginx/modsec
wget https://raw.githubusercontent.com/SpiderLabs/ModSecurity/v3/master/modsecurity.conf-recommended
wget https://raw.githubusercontent.com/SpiderLabs/ModSecurity/v3/master/unicode.mapping
mv modsecurity.conf-recommended modsecurity.conf

نقوم الآن بتنزيل ملف القواعد ومن ثم استخراج القواعد منه:

wget https://github.com/SpiderLabs/owasp-modsecurity-crs/archive/refs/tags/v3.2.0.zip
unzip v3.2.0.zip

والآن نقوم بعمل المسار الصحيح ومن ثم نقوم بنقل الملفات إلى المسار:

mv owasp-modsecurity-crs-3.2.0/crs-setup.conf.example /etc/nginx/modsec/crs-setup.conf
mv owasp-modsecurity-crs-3.2.0/rules/ /etc/nginx/modsec/

نقوم الآن بتعديل ملف الإعدادات من خلال فتح الملف بمحرر النصوص:

vi /etc/nginx/modsec/modsecurity.conf

ثم نقوم بتعديل قيمة SecRuleEngine من DetectionOnly إلى On.

وبعدها نقوم بتنفيذ الأوامر التالية من أجل إضافة الإعدادات إلى الملف:

echo "include /etc/nginx/modsec/crs-setup.conf" >> /etc/nginx/modsec/modsecurity.conf
echo "include /etc/nginx/modsec/rules/*.conf" >> /etc/nginx/modsec/modsecurity.conf

بعد التعديل، نقوم بحفظ الملف والخروج.

والآن نقوم بضبط Nginx من أجل ان يقوم بتحميل إعدادات ModSecurity بشكل إفتراضي. نقوم بتنفيذ الأمر التالي من أجل فتح ملف الإعدادات:

vi /etc/nginx/nginx.conf

ومن ثم قم بالعثور على كلمة http وقم بوضع التالي داخل هذا الكود:

        modsecurity  on;
        modsecurity_rules_file  /etc/nginx/modsec/modsecurity.conf;

النتيجة يجب أن تكون مشابهة للتالي:

عند الإنتهاء، نقوم بحفظ الملف، ومن ثم قم بتنفيذ الأمر التالي من أجل التأكد من أن Nginx يعمل بشكل صحيح:

nginx -t

النتيجة يجب أن تكون مشابهة للتالي:

2024/05/08 19:53:04 [notice] 77061#77061: ModSecurity-nginx v1.0.3 (rules loaded inline/local/remote: 0/897/0)
2024/05/08 19:53:04 [notice] 77061#77061: libmodsecurity3 version 3.0.12
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

في حال كان كل شيء على ما يرام، نقوم يإعادة تشغيل Nginx:

systemctl restart nginx

هنا نكون قد أنهينا إعداد Nginx بشكل صحيح مع تحميل جميع القواعد الأمنية من OWASP.

فحص ModSecurity

من أسهل الطرق التي يمكن من خلالها فحص ModSecurity هي تنفيذ طلب يبدو كانه خبيث. مثلا يمكننا تنفيذ الطلب التالي في الخادم من خلال المتصفح:

http://linuxarabia-nginx.linuxarabia.co/index.html?f=../../../../etc/passwd

والنتيجة شيء كالتالي:

ملاحظة: هذه الصفحة قابلة للتخصيص ويمكن تغييرها لأي شيء ترغب به. هذا أمر لن نقوم بالتحدث عنه في هذه السلسلة وسنقوم بالتحدث عنه في شرح آخر.

يمكن أيضا فحص ModSecurity مباشرة من طرفية جهازك الخاص أو طرفية الخادم من خلال الأمر التالي:

curl -I http://linuxarabia-nginx.linuxarabia.co/index.html?f=../../../../etc/passwd

النتيجة يجب أن تكون كالتالي:

لاحظ أن الرد هو 403.

إيقاف جزء من ModSecurity

قد نرغب في أيقاف جزء أو قاعدة واحدة من قواعد الحماية الخاصة بـ ModSecurity. هذا قد يكون لأنها تتعارض مع عمل موقعك أو لأنها تقوم بحظر الإتصال بشكل خاطئ. أيقاف القاواعد أمر بسيط وقد يكون على شكلين.

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

/var/log/nginx/error.log

أو يمكن أن تكون موجودة في سجل أخطاء الموقع نفيه في حال تم ضبط سجل منفصل للموقع. يمكن البحث عن الخطأ من خلال عدد من الطرق، وأهم الطرق هي اداة grep. بالإعتماد على الفحص الذي قمنا به في الأعلى، سوف نقوم بالبحث عن الخطأ من خلال البحث عن النص الذي تسبب بالخطأ. مثلا قمنا بطلب الرابط التالي:

http://linuxarabia-nginx.linuxarabia.co/index.html?f=../../../../etc/passwd

هذا الطلب تسبب بخطأ في الخادم وهو بالشكل التالي:

2024/05/09 07:12:41 [error] 97845#97845: *3 [client 88.888.888.88] ModSecurity: Access denied with code 403 (phase 2). Matched "Operator `Ge' with parameter `5' against variable `TX:ANOMALY_SCORE' (Value: `20' ) [file "/etc/nginx/modsec/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] [line "79"] [id "949110"] [rev ""] [msg "Inbound Anomaly Score Exceeded (Total Score: 20)"] [data ""] [severity "2"] [ver ""] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-generic"] [hostname "135.181.47.149"] [uri "/index.html"] [unique_id "171523876133.179795"] [ref ""], client: 88.888.888.88, server: linuxarabia-nginx.linuxarabia.co, request: "HEAD /index.html?f=../../../../etc/passwd HTTP/1.1", host: "linuxarabia-nginx.linuxarabia.co"

يمكنك البحث عن هذا الخطأ من خلال البحث عن عنوان IP الشخص الذي تسبب بالخطأ. هنا قمت بتغيير القيمة إلى 88.888.888.88:

grep 88.888.888.88 /var/log/nginx/error.log

أو يمكن البحث عن كلمة ModSecurity كما في الأمر التالي:

grep ModSecurity /var/log/nginx/error.log

في كلا الحالتين سوف تحصل على نفس السطر. من المهم جدا البحث عن التالي:

[id "949110"]

ما سبق هو هويّة القاعدة التي يجب إيقافها من أجل ﻹيقاف حظر الرابط الذي قمنا بعمله.

لاحظ: إيقاف هذه القاعدة هو فقط للتوضيح وليس للتنفيذ من خلالك. لا تقم بإيقاف هذه القاعدة.

إيقاف قواعد ModSecurity على جميع المواقع في الخادم

هذا النوع من الإيقاف يقوم بالتأثير على جميع المواقع في الخادم الحالية والمستقبلية. إيقاف القواعد يكون في ملف إعدادات Nginx الأساسية:

vi /etc/nginx/nginx.conf

ومن ثم وضع الكود التالي تحت اعدادات ModSecurity:

        modsecurity_rules '
            SecRuleRemoveById 000000
        ';

والنتيجة يجب أن تكون كما يلي:

عند الإنتهاء، نقوم بحفظ الملف ومن ثم اعادة تشغيل Nginx ومحاولة دخول الرابط من جديد. الآن يجب أن يعمل بدون مشاكل.

إيقاف قواعد ModSecurity على موقع محدد في الخادم

هنا يمكن إيقاف قاعدة محددة في موقع محدد فقط بدون تعطيلها في جميع المواقع على الخادم. من ناحيتي أرى أن هذا الخيار هو الأفضل بدون منازع كونه يقينا من سوء الإعدادات وفتح ثغرات أمنية عن طريق الخطأ.

لإيقاف قاعدة ما في موقع محدد نقوم بعمل نفس الإعدادات التي قمنا بها في الأعلى ولكن في ملف conf الخاص بالموقع نفسه وليس في ملف اعدادات الخادم.

في المراحل التالية سوف نقوم بشرح طريقة عمل ملف إعدادات لكل موقع على حدى.