OWASP CRS नियम-समूह के साथ ModSecurity दस मिनट में चालू होता है और तीन दिन बाद बंद कर दिया जाता है — जब एडमिन क्षेत्र में लेख सहेजे जाना बंद हो जाते हैं, फ़ाइल अपलोड टूट जाता है, और ग्राहक ऑर्डर नहीं दे पाता क्योंकि उसके पते में एपॉस्ट्रॉफ़ी थी। निष्कर्ष अपने-आप बनता है कि «WAF काम में बाधा है», और वह ग़लत है: उन रुकावटों में से लगभग सारी तीन-चार सटीक छूटों से ठीक हो जाती हैं, और पूरी कारीगरी उन्हें सही ढंग से ढूँढ़ने में है।

अवरोधन तुरंत चालू न करें

पहला हफ़्ता सिर्फ़ निगरानी का है। /etc/modsecurity/modsecurity.conf में:

SecRuleEngine DetectionOnly

इस मोड में WAF वह सब लॉग करता है जिसे रोकता, और कुछ नहीं रोकता। असली ट्रैफ़िक का एक हफ़्ता — एडमिन क्षेत्र में अपने काम, तस्वीरों के अपलोड और ऑर्डर देने समेत — काल्पनिक नहीं, बल्कि सच्चे झूठे नतीजों की सूची देता है। उस सूची से निपटने के बाद ही On पर जाना समझदारी है।

CRS कैसे काम करता है: एक नियम नहीं, योग

आगे की हर बात की कुंजी यही है। CRS किसी अनुरोध को शायद ही कभी एक नियम से रोकता है। चलने वाला हर नियम अनुरोध में असामान्यता के अंक जोड़ता है, और रुकावट तब होती है जब कुल सीमा पार कर जाए। इसीलिए लॉग में एक नहीं, कई पंक्तियाँ दिखती हैं, और उनमें आख़िरी पहचानकर्ता 949110 वाला नियम होता है — वही जो कुल जोड़ता है।

व्यावहारिक परिणाम: छूट उस नियम के लिए देनी चाहिए जिसने अंक जोड़े, 949110 के लिए नहीं। योग करने वाला नियम बंद किया, तो पूरा समूह बंद हो जाता है, और WAF कॉन्फ़िग फ़ाइल की एक पंक्ति भर रह जाता है।

दूसरा परिणाम है paranoia स्तर। डिफ़ॉल्ट रूप से वह एक है, और यही सही विकल्प है। स्तर 2 और 3 ऐसे नियम जोड़ते हैं जो सामान्य साइटों पर डिज़ाइन से ही झूठे नतीजे देते हैं, और उन्हें तभी चालू करना चाहिए जब पहला स्तर पूरी तरह ट्यून हो चुका हो।

दोषी नियम ढूँढ़ें

जो चाहिए वह सब audit लॉग (/var/log/modsec_audit.log) में और वेब सर्वर के त्रुटि लॉग में है। रुकावट के समय से खोजें:

sudo grep -o 'id "[0-9]*"' /var/log/modsec_audit.log | sort | uniq -c | sort -rn | head

यह चले हुए नियमों की आवृत्ति सूची है। फिर किसी ख़ास पहचानकर्ता के लिए देखें कि उसे किस चीज़ ने चलाया:

sudo grep -A5 'id "942100"' /var/log/modsec_audit.log | head -40

तीन चीज़ें चाहिए: नियम का पहचानकर्ता, पैरामीटर का नाम (ARGS:content, ARGS:comment) और अनुरोध का रास्ता। छूट इन्हीं से बनती है।

सामान्य संदिग्ध

सूची साइट-दर-साइट दोहराती है:

  • 942100 — SQL injection। लंबी सामग्री वाले पाठ क्षेत्रों पर चलता है: लेख का मुख्य भाग, उत्पाद का विवरण, टिप्पणी। साधारण गद्य के भीतर उद्धरण चिह्न, कोष्ठक और select जैसे शब्द पहचानकर्ता को संदिग्ध लगते हैं;
  • 941100 और 941xxx परिवार — XSS। ये दृश्य संपादक के साथ आते हैं: किसी क्षेत्र में HTML टैग होना ही उसके काम करने का पूरा मतलब है;
  • 920420 — अस्वीकृत Content-Type। API और फ़ाइल अपलोड तोड़ता है: अनुमत प्रकारों का डिफ़ॉल्ट समूह संकरा है, और पुराने संस्करणों में application/json उसमें था ही नहीं;
  • 913100 — User-Agent से स्कैनर। स्कैनरों के साथ जायज़ औज़ार भी पकड़ता है: उपलब्धता की निगरानी, अपनी स्क्रिप्टों में curl;
  • 200002, 200004 — अनुरोध के मुख्य भाग को पढ़ने की त्रुटियाँ। ये आमतौर पर हमला नहीं, बल्कि मुख्य भाग के आकार की सीमा पार होना बताती हैं, यानी बड़ी फ़ाइल का अपलोड।

छूट देने के तीन तरीक़े

भोंडेपन के बढ़ते क्रम में। ये सब आपकी अपनी फ़ाइल में जाते हैं (जैसे /etc/modsecurity/crs/REQUEST-900-EXCLUSION-RULES.conf), न कि ख़ुद CRS की फ़ाइलों में: नियम-समूह अपडेट होता है और आपके बदलाव उसके साथ ग़ायब हो जाएँगे।

एक नियम के नीचे से एक पैरामीटर हटाना। सबसे सटीक विकल्प, और वही जिसका लक्ष्य रखना चाहिए:

SecRuleUpdateTargetById 942100 "!ARGS:content"

नियम को सिर्फ़ एक रास्ते पर बंद करना। तब ठीक है जब कोई ख़ास पन्ना शोर मचाता हो — संपादक, आयात, समीक्षा का फ़ॉर्म:

SecRule REQUEST_URI "@beginsWith /admin/post" \
    "id:1001,phase:1,pass,nolog,ctl:ruleRemoveById=942100"

नियम को पूरी तरह बंद करना। आख़िरी उपाय और लगभग हमेशा इस बात का संकेत कि कारण मिला ही नहीं:

SecRuleRemoveById 942100

पहले और तीसरे का फ़र्क़ बड़ा है। पहले मामले में एक क्षेत्र — लेख का मुख्य भाग — एक नियम से SQL injection के लिए जाँचा जाना बंद होता है; दूसरे और तीसरे में पूरी साइट जाँची जानी बंद हो जाती है। मेहनत का फ़र्क़ लगभग पाँच मिनट का है।

बदलावों के बाद कॉन्फ़िगरेशन जाँचें और नरमी से दोबारा लोड करें:

sudo apachectl configtest && sudo systemctl reload apache2
sudo nginx -t && sudo systemctl reload nginx

वह क्रम जो एक हफ़्ता बचाता है

  1. DetectionOnly में एक हफ़्ता, साइट, एडमिन क्षेत्र और अपलोड समेत सामान्य काम के साथ।
  2. audit लॉग से नियमों की आवृत्ति सूची। ऊपर से नीचे चलें — पहले तीन-चार ही नब्बे प्रतिशत शोर के लिए ज़िम्मेदार हैं।
  3. हर एक के लिए: समझें कि कौन सा पैरामीटर और किस पन्ने पर। छूट पैरामीटर से दें, नियम से नहीं।
  4. और अब जाकर SecRuleEngine On
  5. महीने में एक बार रुकावटों में झाँकें: साइट बदली है, तो नए झूठे नतीजे आए हैं।

आख़िरी बिंदु पर ही आमतौर पर सब बिखरता है: audit लॉग गीगाबाइटों का पाठ है और उसे हाथ से कोई नहीं पढ़ेगा। इकट्ठे पैनल का मतलब यही है कि चले हुए नियमों की सूची, रोके गए अनुरोध और सक्रिय नियम-समूह आपके सामने हों, grep से निकाले न जाएँ। यह कैसा लगता है, नीचे डेमो पेज पर।