AWS Amazonlinux 2023 nginx に fail2ban を使ってみた。
さて頼まれごとでAWSを使っているわけですが、調べれば調べるほどAmazonlinux 2023は2からの乗換えにもあまりおススメ出来ません。っつまり新規に作るなら結構イケてるんじゃないかと思い、(それがドツボにはまるわけですが)webサーバー案件で使ってみました。
- ユーザー設定
- php設定
- nginx設定
- Let’sEncryptの設定
- fail2ban設定
- 仮想ルーターで世界の皆さんこんにちは
- ログの監視
- filterのカスタマイズ
となります。
今回はfail2banがうまく機能しなかったのでそこを重点に説明します。
fail2banの実際の制限方法に昔はiptablesでしたがfirewalldを使っています。
今後さらに変わる可能性もありますのでこの記事が古くなるかもしれませんね。
そこらへんは自分で確認してください。
fail2banの前にやれること。
nginxのセキュリティ設定ですね。出来るだけ新しい技術を使ってあげてください。
SSL周りはnginxのバージョンが低くてHTTP3がサポートされていませんでした。
nginx.confの注意点
/etc/nginx/nginx.conf
ssl_certificate /etc/letsencrypt/live/www.ddd.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.ddd.com/privkey.pem;
ssl_session_cache shared:SSL:15m;
ssl_session_timeout 10m;
# ssl_ciphers PROFILE=SYSTEM;
ssl_prefer_server_ciphers on;
# add_header Alt-Svc 'h3=":443"; ma=86400';
ssl_protocols TLSv1.2 TLSv1.3;
# ssl_ciphers HIGH:!aNULL:!MD5;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-CCM:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-CCM:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_SHA256';
#ssl_ciphers ECDHE+AESGCM:DHE+AESGCM:HIGH:!aNULL:!MD5;
ssl_buffer_size 8k;
HTTP2は使えるので圧縮転送はします。
#gzip
gzip on;
gzip_types text/plain
text/xml
text/css
application/xml
application/xhtml+xml
application/rss+xml
application/atom_xml
application/javascript
application/x-javascript
application/x-httpd-php
application/x-font-ttf
font/opentype
font/x-woff
font/x-woff2
application/vnd.ms-fontobject
image/svg+xml;
# video/mp4;
gzip_proxied any;
gzip_min_length 1000;
gzip_buffers 8 32k;
gzip_comp_level 5;
gzip_static on;
gzip_vary on;
クロスサイトスクリプティング関係はいい加減だとダメです。
一番重要なのはコメント行のContent-Security-Policyです。
ここを何行かに分けて設定するのが一番いいです。今回はほぼリンクが無いのでパス。
add_header X-Cache $upstream_cache_status;
add_header X-Frame-Options "DENY";
add_header X-Content-Type-Options "nosniff";
add_header X-XSS-Protection "1; mode=block";
# add_header Content-Security-Policy "default-src 'self'";
robots.txtも無視して検索してくるので直リンク防止もしておきましょう。この拡張子は実際の攻撃されたログから抽出しました。もちろん.pyは動かすなら外しておいてもいいですよ。
location ~* \.(jpg|jpeg|png|gif|bak|old|dat|core|env|mp4|zip|gz|tar|tgz|json|txt|conf|config|HEAD|yaml|yml|ini|bash_history|log|error_log|ftpconfig|git|htaccess|idea|sh|local|credentials|msmtprc|mysql_history|php_history|production|remote|s3cfg|authorized_keys|id_rsa|pub|svn|key|jenkinsFile|xml|phpinfo|dockerfunc|DS_Store|sql|py)$ {
valid_referers none blocked www.ddd.com *.ddd.com;
if ($invalid_referer) {
return 403;
}
}
ではnginx -tしてsystemctl restart nginxする。
つぎにrobots.txtを設置します。
コンテンツのRootにrobots.txtを置く
User-agent: Googlebot
Disallow: /*.mp4$
Disallow: /*.png$
Disallow: /*.json$
Disallow: /*.txt$
Disallow: /*.sql$
User-agent: bingbot
Disallow: /*.mp4$
Disallow: /*.png$
Disallow: /*.json$
Disallow: /*.txt$
Disallow: /*.sql$
User-agent: Applebot
Disallow: /*.mp4$
Disallow: /*.png$
Disallow: /*.json$
Disallow: /*.txt$
Disallow: /*.sql$
User-agent: DuckDuckBot
Disallow: /*.mp4$
Disallow: /*.png$
Disallow: /*.json$
Disallow: /*.txt$
Disallow: /*.sql$
User-agent: *
Disallow: /
#御覧の通り4つ以外のクローラーには死んでもらう。
つぎにfail2banの設定
jail.confの設定
まず自分のIPがBANされちゃうと困るので空白区切りで好きなだけ登録しておきましょう。
そしてデフォルトの牢屋行きの基準値も書いておきましょう。
ハッキングしにくるクローラーは[nginx-botsearch]になりますのでこれをenableにします。
ignoreip = 127.0.0.1/8 ::1 <BANされたくないIP>
bantime = 1d
findtime = 60m
maxretry = 3
[nginx-botsearch]
enabled = true
さて牢屋行きはいますか?
# fail2ban-client status nginx-botsearch
Status for the jail: nginx-botsearch
|- Filter
| |- Currently failed: 0
| |- Total failed: 0
| `- File list: /var/log/nginx/error.log
`- Actions
|- Currently banned: 0
|- Total banned: 0
`- Banned IP list:
はい、nginxのログフォーマットと全くマッチしていません。
nginx-botsearch.confの変更と試験
技術者の中でも難易度の高い正規表現を治します。ファイルの場所は/etc/fail2ban/filter.d/nginx-botsearch.confです。実際の/var/log/nginx/error.logの先頭は日付と時間ですのでマッチするわけがありませんね。
#failregex = ^<HOST> \- \S+ \[\] \"(GET|POST|HEAD) \/<block> \S+\" 404 .+$
# ^ \[error\] \d+#\d+: \*\d+ (\S+ )?\"\S+\" (failed|is not found) \(2\: No such file or directory\), client\: <HOST>\, server\: \S*\, request: \"(GET|POST|HEAD) \/<block> \S+\"\, .*?$
failregex = \(2: No such file or directory\), client: <HOST>
いいじゃんこれでw
確認用のコマンドがあります。
# fail2ban-regex /var/log/nginx/error.log /etc/fail2ban/filter.d/nginx-botsearch.conf
どんどん牢屋に入れられます。実に清々しいですね。
fail2ban関連でよく使うコマンド
filterの試験
# fail2ban-regex /var/log/nginx/error.log /etc/fail2ban/filter.d/nginx-botsearch.conf
特定IPアドレスをBANする。
# fail2ban-client set nginx-botsearch banip 157.173.197.163
すべての BAN の解除
# fail2ban-client unban --all
特定の IP アドレスの BAN の解除
# fail2ban-client set nginx-botsearch unbanip 157.173.197.163
firewalld側での永久BAN
# firewall-cmd --permanent --zone=public --add-rich-rule="rule family='ipv4' source address='141.98.11.83' DROP"
firewalldの解放中ポート確認
# firewall-cmd --list-ports --zone=public
firewalldでBAN中の確認
# firewall-cmd --list-rich-rules --zone=public
ん。ほとんどログが増えませんw
いんですよそれで。
コメント
コメントを投稿