則真的攔得住攻擊嗎:ModSecurity-nginx 集成測試實戰(zhàn)入門)
你的 SecRule 規(guī)則真的攔得住攻擊嗎ModSecurity-nginx 集成測試實戰(zhàn)入門【免費下載鏈接】ModSecurity-nginxModSecurity v3 Nginx Connector項目地址: https://gitcode.com/gh_mirrors/mo/ModSecurity-nginxModSecurity-nginx 是 ModSecurity v3 在 Nginx 上的連接器負責把 libmodsecurity 接進 Nginx 的請求生命周期。要驗證一組 SecRule 規(guī)則在這個環(huán)境里是否按預(yù)期攔截攻擊靠的是tests/目錄下的集成測試——它們用 Perl 和 Test::Nginx 框架拉起一個真實的 Nginx 進程發(fā)送真實 HTTP 請求再逐條斷言響應(yīng)。讀一遍這套測試比讀十頁文檔更知道規(guī)則應(yīng)該怎么表現(xiàn)。下圖是連接器以插件方式接入 Nginx 的架構(gòu)示意也是這套測試框架最終驗證的對象備齊三樣?xùn)|西測試跑道跑測試之前需要湊齊三樣測試腳本、Test::Nginx 框架、可用的 Nginx 二進制。測試腳本隨倉庫提供全部在tests/目錄Test::Nginxnginx 官方測試套件中的 Perl 模塊cpan Test::Nginx即可安裝自編 Nginx必須編譯了 ModSecurity-nginx 模塊并鏈接 libmodsecurity原版 Nginx 不認識modsecurity指令。第一次接觸的話clone 倉庫拿到測試腳本是關(guān)鍵一步git clone https://gitcode.com/gh_mirrors/mo/ModSecurity-nginx把第一個測試跑起來 測試文件不能孤立運行需要放進 nginx-tests 測試套件目錄——Test::Nginx 模塊和公共配置模板都住在那里。把 ModSecurity 的測試文件復(fù)制過去再用prove指定 Nginx 二進制的路徑來跑cp tests/*.t /path/to/nginx-tests/ cd /path/to/nginx-tests TEST_NGINX_BINARY/path/to/your/nginx prove .TEST_NGINX_BINARY告訴框架該用哪個 Nginx。兩種常見跑法對比跑法命令適用場景單個測試prove modsecurity.t只想確認規(guī)則攔截行為全量回歸prove .改動連接器代碼后提交前拆開一個 .t 文件看它怎么工作每個.t文件結(jié)構(gòu)都一樣讀懂tests/modsecurity.t就算掌握了全部套路。它分四步聲明測試對象my $t Test::Nginx-new()-has(qw/http/);表示本測試依賴 http 模塊寫 Nginx 配置$t-write_file_expand(nginx.conf, ...)生成臨時配置其中%%TEST_GLOBALS%%一類占位符由框架自動填充配置里modsecurity on;加modsecurity_rules兩條指令就開啟了一套規(guī)則準備資源并啟動$t-write_file(/phase1, should be blocked...)寫入測試用的靜態(tài)文件$t-run()啟動 Nginx發(fā)請求、斷言例如like(http_get(/phase2?whatblock403), qr/^HTTP.*403/, block 403 - phase 2);這一行發(fā)一個請求并斷言響應(yīng)以 403 開頭。modsecurity.t用階段 1~4 × 重定向/攔截組合出 21 條斷言驗證規(guī)則在正確的階段生效、不多攔也不少攔。順著套件認識規(guī)則驗證的場景tests/下有 15 個.t文件文件名基本就是功能地圖測試文件驗證的內(nèi)容modsecurity.t核心攔截階段 1~4 的重定向與攔截行為modsecurity-request-body.t/-h2請求體檢查含 HTTP/2 場景modsecurity-response-body.t階段 4 檢查響應(yīng)體modsecurity-proxy.t/-h2反向代理下的規(guī)則行為modsecurity-config-merge.thttp/server/location 多層配置如何合并繼承modsecurity-config-auditlog.t、-debuglog.t審計日志、調(diào)試日志寫到哪里、寫了什么modsecurity-scoring.t絕對計分與迭代計分是否數(shù)得對modsecurity-transaction-id.t各日志中的事務(wù) ID 是否一致modsecurity-limits.t請求體大小等限制是否生效寫你自己的規(guī)則驗證測試 ??掌握上面的套路后加測試就是套模板改斷言。最小骨架長這樣use Test::More; use Test::Nginx; my $t Test::Nginx-new()-has(qw/http/); $t-write_file_expand(nginx.conf, EOF); %%TEST_GLOBALS%% daemon off; events {} http { %%TEST_GLOBALS_HTTP%% server { listen 127.0.0.1:8080; modsecurity on; modsecurity_rules SecRuleEngine On SecRule ARGS streq attack id:100,phase:2,deny,status:403 ; } } EOF $t-run(); $t-plan(2); like(http_get(/?aattack), qr/^HTTP.*403/, 攻擊請求被攔截); like(http_get(/?asafe), qr/200/, 安全請求放行);幾個約定值得注意日志路徑用%%TESTDIR%%占位符如SecAuditLog %%TESTDIR%%/auditlog-root.txt框架保證每個測試目錄互相隔離寫完還能直接讀日志內(nèi)容來斷言$t-plan(N)的數(shù)目必須和斷言條數(shù)一致對不上測試直接失敗需要手工構(gòu)造原始請求時可以像tests/里的 H2 測試那樣用http(EOF)塊發(fā)送裸請求。用轉(zhuǎn)換腳本跑一遍被動回歸除了專用測試項目還提供tests/nginx-tests-cvt.pl這個小轉(zhuǎn)換腳本它把modsecurity on;和一段基礎(chǔ)規(guī)則自動插進 nginx 官方功能測試的server_name行之后讓整個 nginx 功能測試集帶著 ModSecurity 模塊一起跑驗證模塊不會改變 Nginx 本身的行為perl tests/nginx-tests-cvt.pl original.t modified.t改過連接器的 C 代碼后建議把這類被動回歸也跑一輪再提交。測試紅了怎么排查失敗先別慌測試框架會在/tmp/nginx-test-*留下臨時目錄答案多半在里面Nginx 沒起來看error.log常見原因是TEST_NGINX_BINARY指向了沒編譯 modsecurity 模塊的普通 Nginx規(guī)則像沒生效把SecDebugLogLevel 9配上調(diào)試日志路徑再核對日志里有沒有該規(guī)則 id 的命中記錄斷言數(shù)目或結(jié)果不符先核對$t-plan()條數(shù)再確認listen端口模板里是 8080沒和本地進程沖突。當?shù)谝粋€測試變綠之后剩下的事就是照著套件里的模式一條斷言一條斷言地往上加。【免費下載鏈接】ModSecurity-nginxModSecurity v3 Nginx Connector項目地址: https://gitcode.com/gh_mirrors/mo/ModSecurity-nginx創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考