この記事は自分用のメモで、技術的に新しい話は含んでいません。ごくたまにしかやらない設定は、書き残しておかないとすぐ記憶から消えてしまうので・・・。
2か月ほど前にささやかなWebサービスを公開しましたが、DNSに登録されるや否や、サービス利用の数百倍、数千倍の、脆弱性スキャンと思われるアクセスが来ました。
といってもサーバの能力からみたら全く問題ない範囲ですし、サーバにはクレデンシャル的なものは一切置いていないので、万一侵入されてもサーバを落とせば基本的には解決するはずです。
しかしながら、ひどいときには1日10万回を超えるアクセスがあり、さすがに鬱陶しくなってきたのでfail2banを導入しました。
fail2banはログファイルを監視し、同一のIPアドレスから、指定したパターン(主にはアクセス先のURL)のログが複数回連続したときに、当該IPアドレスからのアクセスをブロックするツールです。Ubuntuではaptでインストールできます。
指定するURLパターンは正規表現で指定できますが、2か月分のアクセスログの統計を取り、頻度の高いものを指定しました。頻度の高かったURLを以下に示します。(数字は2か月間でもっともアクセスが多かった1日の中での出現頻度)
13100 /admin
12315 /api
11785 /config
9097 /core
4267 /:8181
4196 /:8443
4188 /:8008
4182 /:8888
4177 /:10000
4174 /:9000
4161 /:5601
4161 /:5000
4155 /:8880
4139 /:8000
4122 /:8080
818 /backup
344 /app
276 /src
218 /public
203 /services
これらのURLパターンに限らず、ステータス404が短時間に連続した場合もbanすることにしました。
あと、特定のサーバの脆弱性を狙っているのか、HTTPリクエストではなくバイナリデータを突っ込んでくるアクセスもあり、これも問答無用でbanしました。
fail2banのフィルタ設定の例を以下に載せます。
[Definition]
failregex = ^ \- \S+ \[\] \"(GET|POST).*(\/admin\/|\/api|\/config|\/core|\.env|\.git).* HTTP\/.*\".*$
^ \- \S+ \[\] \"\\x.*\".*$
^ \- \S+ \[\] \"(GET|POST).*\/[^ ]* HTTP\/.*\" 404 .*$
ignoreregex =
Ubuntu 24.04のfail2banでは、このようなフィルタしたいURLパターンを/etc/fail2ban/filter.d/
の下に置き、引っかかったアクセス元のIPアドレスへの対処方法(banする閾値、アクセス禁止する期間等)を/etc/fail2ban/jail.d/
に置きます。
jailの設定では、以下のようにnginxのアクセスログを読みに行かせています。
[nginx-exploit-scanner]
enabled = true
backend = polling
filter = nginx-exploit-scanner
port = http,https
logpath = /var/log/nginx/access.log
maxretry = 10
findtime = 600
bantime = 172800
このとき、jailの設定ではbackend(監視対象)にpollingを指定する必要があります。Ubuntuではデフォルトのbackend設定がsystemdになっており、この設定を変えないとログファイルを読みに行ってくれません。(ここでちょっと嵌りました)
ちなみに今回、設定ファイルをChatGPTに書いてもらおうとしたら、どうもうまくいきませんでした。ChatGPTのコード生成は、正規表現をうまく書けてないことがたまにあります。
なお、fail2ban用のfilter定義に書かれた正規表現のテストは
$ fail2ban-regex [ログファイル] [フィルタ定義ファイルまたは正規表現]
で行うことができます。
コメント