ModSecurity 概述
ModSecurity 是一款開源的 Web 應用程式防火牆(WAF),能夠即時監控、記錄和過濾 HTTP 流量。它可以防護多種常見的網路攻擊,包括 SQL 注入、跨站腳本攻擊(XSS)、目錄遍歷等。
主要功能
- 即時監控:監控所有進出的 HTTP 請求與回應
- 攻擊偵測:使用規則集識別惡意流量
- 虛擬修補:在不修改應用程式的情況下修補漏洞
- 完整日誌:記錄詳細的安全事件供後續分析
安裝 ModSecurity 模組
在 Ubuntu 22.04 上安裝 Nginx 的 ModSecurity 模組:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| # 更新系統套件
sudo apt update && sudo apt upgrade -y
# 安裝相依套件
sudo apt install -y apt-utils autoconf automake build-essential \
git libcurl4-openssl-dev libgeoip-dev liblmdb-dev \
libpcre++-dev libtool libxml2-dev libyajl-dev \
pkgconf wget zlib1g-dev
# 下載並編譯 ModSecurity
cd /opt
sudo git clone --depth 1 -b v3/master --single-branch https://github.com/SpiderLabs/ModSecurity
cd ModSecurity
sudo git submodule init
sudo git submodule update
sudo ./build.sh
sudo ./configure
sudo make
sudo make install
|
編譯 Nginx ModSecurity Connector
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # 下載 Nginx ModSecurity Connector
cd /opt
sudo git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git
# 查看目前 Nginx 版本
nginx -v
# 下載對應版本的 Nginx 原始碼(以 1.18.0 為例)
sudo wget http://nginx.org/download/nginx-1.18.0.tar.gz
sudo tar zxvf nginx-1.18.0.tar.gz
cd nginx-1.18.0
# 編譯動態模組
sudo ./configure --with-compat --add-dynamic-module=/opt/ModSecurity-nginx
sudo make modules
# 複製模組到 Nginx 目錄
sudo cp objs/ngx_http_modsecurity_module.so /usr/share/nginx/modules/
|
基本設定
載入 ModSecurity 模組
編輯 /etc/nginx/nginx.conf:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # 在 events 區塊之前載入模組
load_module modules/ngx_http_modsecurity_module.so;
user www-data;
worker_processes auto;
pid /run/nginx.pid;
events {
worker_connections 768;
}
http {
# 啟用 ModSecurity
modsecurity on;
modsecurity_rules_file /etc/nginx/modsec/main.conf;
# 其他設定...
}
|
建立 ModSecurity 設定目錄
1
2
3
| sudo mkdir -p /etc/nginx/modsec
sudo cp /opt/ModSecurity/modsecurity.conf-recommended /etc/nginx/modsec/modsecurity.conf
sudo cp /opt/ModSecurity/unicode.mapping /etc/nginx/modsec/
|
建立主設定檔
建立 /etc/nginx/modsec/main.conf:
1
2
3
| Include /etc/nginx/modsec/modsecurity.conf
Include /etc/nginx/modsec/crs/crs-setup.conf
Include /etc/nginx/modsec/crs/rules/*.conf
|
OWASP CRS 規則集
OWASP Core Rule Set(CRS)是一套通用的攻擊偵測規則,能夠有效防護 OWASP Top 10 攻擊類型。
安裝 CRS
1
2
3
4
| cd /etc/nginx/modsec
sudo git clone https://github.com/coreruleset/coreruleset.git crs
cd crs
sudo cp crs-setup.conf.example crs-setup.conf
|
CRS 設定調整
編輯 /etc/nginx/modsec/crs/crs-setup.conf:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # 設定 Paranoia Level(1-4,數字越高越嚴格)
SecAction \
"id:900000,\
phase:1,\
nolog,\
pass,\
t:none,\
setvar:tx.paranoia_level=1"
# 設定異常分數閾值
SecAction \
"id:900110,\
phase:1,\
nolog,\
pass,\
t:none,\
setvar:tx.inbound_anomaly_score_threshold=5,\
setvar:tx.outbound_anomaly_score_threshold=4"
|
規則模式(DetectionOnly vs On)
ModSecurity 提供兩種主要執行模式:
DetectionOnly 模式
僅偵測並記錄,不阻擋請求。適合測試階段使用:
1
2
| # /etc/nginx/modsec/modsecurity.conf
SecRuleEngine DetectionOnly
|
On 模式
偵測並阻擋惡意請求。適合正式環境:
建議先使用 DetectionOnly 模式觀察一段時間,確認沒有誤判後再切換到 On 模式。
自訂規則
建立自訂規則檔
建立 /etc/nginx/modsec/custom-rules.conf:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| # 阻擋特定 User-Agent
SecRule REQUEST_HEADERS:User-Agent "@contains BadBot" \
"id:10001,\
phase:1,\
deny,\
status:403,\
log,\
msg:'Blocked malicious bot'"
# 阻擋特定 IP
SecRule REMOTE_ADDR "@ipMatch 192.168.1.100,10.0.0.0/8" \
"id:10002,\
phase:1,\
deny,\
status:403,\
log,\
msg:'Blocked IP address'"
# 限制請求大小
SecRule REQUEST_BODY_LENGTH "@gt 10485760" \
"id:10003,\
phase:2,\
deny,\
status:413,\
log,\
msg:'Request body too large'"
|
記得在 main.conf 中引入自訂規則:
1
| Include /etc/nginx/modsec/custom-rules.conf
|
白名單設定
排除特定規則
當某些合法請求被誤判時,可以設定白名單:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| # 針對特定 URL 排除規則
SecRule REQUEST_URI "@beginsWith /api/upload" \
"id:10100,\
phase:1,\
pass,\
nolog,\
ctl:ruleRemoveById=942100"
# 針對特定參數排除規則
SecRule ARGS_NAMES "@streq content" \
"id:10101,\
phase:1,\
pass,\
nolog,\
ctl:ruleRemoveTargetById=941100;ARGS:content"
# 完全排除特定路徑
SecRule REQUEST_URI "@beginsWith /health" \
"id:10102,\
phase:1,\
pass,\
nolog,\
ctl:ruleEngine=Off"
|
日誌分析
日誌設定
編輯 /etc/nginx/modsec/modsecurity.conf:
1
2
3
4
5
6
| # 啟用審計日誌
SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus "^(?:5|4(?!04))"
SecAuditLogParts ABIJDEFHZ
SecAuditLogType Serial
SecAuditLog /var/log/nginx/modsec_audit.log
|
日誌分析工具
1
2
3
4
5
6
7
8
| # 查看被阻擋的請求
sudo grep "Access denied" /var/log/nginx/modsec_audit.log | tail -20
# 統計觸發的規則
sudo grep -oP 'id "\K[0-9]+' /var/log/nginx/modsec_audit.log | sort | uniq -c | sort -rn | head -10
# 即時監控
sudo tail -f /var/log/nginx/modsec_audit.log | grep --line-buffered "deny"
|
效能調校
最佳化設定
1
2
3
4
5
6
7
8
9
10
11
| # 限制請求體檢查大小
SecRequestBodyLimit 13107200
SecRequestBodyNoFilesLimit 131072
SecRequestBodyInMemoryLimit 131072
# 限制回應體檢查
SecResponseBodyLimit 524288
SecResponseBodyMimeType text/plain text/html text/xml
# 停用不需要的規則集以提升效能
# 在 crs-setup.conf 中註解不需要的規則
|
Nginx Worker 設定
1
2
3
4
5
6
7
8
| worker_processes auto;
worker_rlimit_nofile 65535;
events {
worker_connections 4096;
use epoll;
multi_accept on;
}
|
驗證設定並重啟
1
2
3
4
5
6
7
8
| # 測試 Nginx 設定
sudo nginx -t
# 重新載入設定
sudo systemctl reload nginx
# 檢查 ModSecurity 是否正常運作
curl -I "http://localhost/?param=<script>alert(1)</script>"
|
參考資料