انجیناکس؛ شب ۳۷: OWASP CRS از DetectionOnly تا مسدودسازی
فهرست نوشته
OWASP CRS مجموعهای از قواعد عمومی تشخیص حمله است. ابتدا ثابت میکنیم موتور درخواست را میبیند، سپس قواعد CRS و مسیر عبور ترافیک سالم را بررسی میکنیم.
این جلسه بخشی از دورهٔ انجیناکس در ۵۰ شب است. قرارداد آزمایشگاه، مسیرها و روال اعمال تغییر در راهنمای دوره آمده است.
محیط: connector سازگار شب ۳۵ یا ۳۶، server app.nginx.test و backend سالم؛ کلاینت آزمایشگاهی ۲۰. همهٔ payloadها فقط روی این VM اجرا میشوند.
config کمینه و probe مستقل#
sudo install -d -o root -g root -m 755 /etc/nginx/modsec
sudo install -d -o root -g "$NGINX_USER" -m 750 /var/log/nginx/modsec
sudo install -o "$NGINX_USER" -g "$NGINX_USER" -m 640 /dev/null /var/log/nginx/modsec/audit.log
فایل /etc/nginx/modsec/main.conf در آغاز:
SecRuleEngine DetectionOnly
SecRequestBodyAccess On
SecRequestBodyLimit 16777216
SecRequestBodyNoFilesLimit 1048576
SecRequestBodyLimitAction Reject
SecResponseBodyAccess Off
SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus "^(?:5|4(?!04))"
SecAuditLogType Serial
SecAuditLog /var/log/nginx/modsec/audit.log
SecAuditLogParts AHZ
SecRule ARGS:lab_probe "@streq block" "id:100500,phase:2,deny,status:403,log,auditlog,msg:'Nginx lab probe'"
در server app اضافه کن:
modsecurity on;
modsecurity_rules_file /etc/nginx/modsec/main.conf;
پس از nginx -t و reload، درخواست سالم و /?lab_probe=block را بفرست. در DetectionOnly، probe باید همچنان پاسخ برنامه را بدهد، ولی rule با شناسهٔ 100500 در log ثبت شود. سپس روی clone SecRuleEngine را On کن: همان probe باید 403 و درخواست عادی پاسخ سالم بدهد. از return 200 فوری برای endpoint آزمون WAF استفاده نکن؛ endpoint به backend واقعی برود. رخداد و وضعیت HTTP را با هم ثبت کن.
افزودن CRS نسخهٔ مشخص#
پیش از اضافه کردن CRS دوباره DetectionOnly کن. release پشتیبانیشده را از پروژهٔ رسمی بگیر؛ نمونهٔ این دوره CRS v4.25.0 LTS است، با بررسی امضا و advisory پیش از استفاده. artifact تأییدشده را در /etc/nginx/modsec/crs قرار بده و crs-setup.conf.example را به crs-setup.conf کپی کن. owner ریشه و قواعد غیرقابل نوشتن برای worker باشند.
برای CRS، تنظیمات پایهٔ modsecurity.conf-recommended از همان نسخهٔ موتور را هم استفاده کن: پردازشگر body، خطاهای parse و limitها را کامل میکند. مسیر unicode.mapping همان release را درست کن. فایل پایه نباید شامل CRS باشد و تنظیم SecRuleEngine و auditهایش را با policy بالا یکدست کن؛ directiveهای همنام را کور دوباره اضافه نکن.
ترتیب نهایی main.conf را به این صورت بازسازی کن؛ probe سفارشی و overrideهای audit/engine را در انتهای فایل پایهٔ خودت نگه دار:
Include /etc/nginx/modsec/base.conf
Include /etc/nginx/modsec/crs/crs-setup.conf
Include /etc/nginx/modsec/exclusions-before.conf
Include /etc/nginx/modsec/crs/rules/*.conf
Include /etc/nginx/modsec/exclusions-after.conf
دو فایل exclusions در ابتدا خالی ولی موجود باشند. paranoia level میزان حساسیت و anomaly threshold آستانهٔ تصمیم را تعیین میکند؛ از baseline release شروع کن. upload، login، REST و متن فارسی سالم را در DetectionOnly بررسی کن، سپس با نمونههای کنترلشدهٔ SQL injection و XSS از مجموعهٔ رسمی تست CRS، تشخیص و blocking را آزمایش کن. payload، rule ID و status واقعی را ثبت کن؛ وقوع هر 403 به معنی دخالت CRS نیست.
بازگشت: از On به DetectionOnly برگردان یا اتصال WAF همان server را خاموش کن، validate/reload و درخواست سالم را بررسی کن. AHZ عمداً header/body خام را کم میکند، ولی پیام rule همچنان میتواند مقدار حساس داشته باشد؛ log را عمومی نکن و rotation را با دسترسی worker تنظیم کن.
منبع: مرجع ModSecurity v3 ، CRS 4.25 LTS ، امنیت و releaseهای CRS .