Ubuntu 22.04 Nginx ModSecurity WAF 設定

Ubuntu 22.04 Nginx ModSecurity WAF Configuration

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 模式

偵測並阻擋惡意請求。適合正式環境:

1
SecRuleEngine 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>"

參考資料

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy