WAFとしてNaxsiを使う場合の設定について。
Naxsiのインストールについては、以下。
ここでは、具体的にNaxsiをどう設定するかについて、ドキュメントに従って具体的に作業した内容を記す。
(ドキュメント)https://github.com/nbs-system/naxsi/wiki
1.ホワイトリスト設定
基本ルールでブロックされるページについて、表示できるようにホワイトリスト設定をする。
(ホワイトリスト)https://github.com/nbs-system/naxsi/wiki/whitelists-bnf
(MatchZones)https://github.com/nbs-system/naxsi/wiki/matchzones-bnf
ログからブロックされたルール条件を確認して、それに対するホワイトリストを設定すればいい。
(Naxsiログ)https://github.com/nbs-system/naxsi/wiki/naxsilogs
ツールで自動にも作成できるが、それほどないのであれば、サンプルを見ながら簡単にできる。
https://github.com/nbs-system/naxsi/wiki/whitelists-examples
具体的な対応方法は、以下のように行う。
1)ログのエラー確認
エラーログを見ると、例えば、Chromeからのアクセスの場合にfavicon.icoの取得でエラーが出ていることがわかる。
2022/02/23 14:46:11 [error] 1654#1654: *181 NAXSI_FMT: ip=x.x.x.x&server=xxx.net&uri=/favicon.ico&vers=1.3&total_processed=144&total_blocked=92&config=block&cscore0=$LIBINJECTION_SQL&score0=8&cscore1=$SQL&score1=16&zone0=HEADERS&id0=17&var_name0=sec-ch-ua&zone1=HEADERS&id1=1005&var_name1=cookie, client: x.x.x.x, server: xxx.net, request: "GET /favicon.ico HTTP/1.1", host: "xxx.net", referrer: "https://xxx.net/favicon.ico"
上記メッセージは、以下の2つのルールでブロックされていることを示している。
【ルールID:17、変数:sec-ch-ua】
zone0=HEADERS&id0=17&var_name0=sec-ch-ua
【ルールID:1005、変数:cookie】
zone1=HEADERS&id1=1005&var_name1=cookie
2)ホワイトリスト追加
上記2ルールに対して、以下の設定を追加する。
BasicRule wl:17 "mz:$URL:/favicon.ico|$HEADERS_VAR:sec-ch-ua";
BasicRule wl:1005 "mz:$URL:/favicon.ico|$HEADERS_VAR:cookie";
以下サンプルも参考に。
https://github.com/nbs-system/naxsi/wiki/whitelists-examples
3)動作確認
設定を確認して、以下で再読み込みを行う。
nginx -t
systemctl reload nginx
これで再度表示できるか確認する。別のエラーになったら、正常に表示できるまで1)から3)の手順を繰り返す。
favicon.ico以外の読み込みも同じ問題があるので、URLの条件を外した。また他のルール1010,1011への対応も必要となったので、以下のような設定となった。
BasicRule wl:17 "mz:$HEADERS_VAR:sec-ch-ua";
BasicRule wl:1005,1010,1011 "mz:$HEADERS_VAR:cookie";
2.Fail2ban連携
Fail2banと連携することで、Naxsiで連続でエラーになったIPを除外できる。
https://github.com/nbs-system/naxsi/wiki/integration-fail2ban
設定は簡単に(2,3分で)できる。
2.1 設定
1)/etc/fail2ban/filter.d/nginx-naxsi.confを追加
以下の内容で、/etc/fail2ban/filter.d/nginx-naxsi.confを作成
[INCLUDES]
before = common.conf
[Definition]
failregex = NAXSI_FMT: ip=<HOST>&server=.*&uri=.*&learning=0
NAXSI_FMT: ip=<HOST>.*&config=block
ignoreregex = NAXSI_FMT: ip=<HOST>.*&config=learning
2)/etc/fail2ban/jail.localに定義を追加
ドキュメントではjail.confを修正となっているが、jail.localに定義する方が良いので、こちらに定義を追加。
[nginx-naxsi]
enabled = true
port = http,https
filter = nginx-naxsi
logpath = /var/log/nginx/*error.log # ※Naxsiのエラーログを指定
maxretry = 6
3)定義の読み込み
systemctl reload fail2ban
2.2 動作確認
連続でエラーを起こして、BANされることを確認する。
/var/log/fail2ban.logで確認できる。また、以下コマンドでも確認できる。
fail2ban-client status nginx-naxsi
Banned IP listに、自分のIPアドレスが追加されていることが確認できる。
実際のIP制限は、banactionのデフォルトではiptablesになってるため、CentOS Stream9では効かないので次の手順で設定する。
2.3 IP制限の種類変更
CentOS Stream9では、iptablesではなくてfirewalldを利用しているので、実際にBANを有効にするには、/etc/fail2ban/jail.localに以下定義を追加して、firewalldでIP制限をかけるように変更する。
[DEFAULT]
banaction = firewallcmd-ipset
banaction_allports = firewallcmd-allports
:
BANされた場合に、この設定が効いているのは、以下コマンドで確認できる。
# firewall-cmd --direct --get-all-rules
ipv4 filter INPUT_direct 0 -p tcp -m multiport --dports http,https -m set --match-set f2b-nginx-naxsi src -j REJECT --reject-with icmp-port-unreachable
f2b-nginx-naxsiというIPセットに問題のIPアドレスが設定される。
# ipset list f2b-nginx-naxsi
Name: f2b-nginx-naxsi
Type: hash:ip
Revision: 5
Header: family inet hashsize 1024 maxelem 65536 timeout 0 bucketsize 12 initval 0x29e6ce30
Size in memory: 280
References: 1
Number of entries: 1
Members:
X.X.X.X timeout 0 ※問題のIPアドレス
ブロックIPを解除するには以下。
fail2ban-client set nginx-naxsi unbanip X.X.X.X
2.4 メール通知
BANした場合に、メール通知する設定は以下。
destemail = jibun@xxxx.com # メールの通知先(自分)
sender = fail2ban@xxxx.com # メールの送信元
action = %(action_mwl)s # BANが発動した時のアクション
Whois情報もつけてくれるので、whoisをインストール。
dnf install whois