はじめに
インフラ運用において、アクセスログはクラッカーが何かしてきた痕跡であり、宝の山です。今回は、当ブログが稼働するNginxサーバーの直近のアクセスログ(約4時間分)をGemini APIに食わせて分析させてみました。
AIから提示されたレポートは期待を上回るほどではありませんが、まあまあでした。自サーバーの現状把握から、次に打つべき具体的な対策までは出てきました。
今回は、その分析結果のサマリーと、レポートを基にOS・Nginx・WordPressの各レイヤーで実際に適用した具体的な防御設定・コマンドを詳しく解説します。
1. ログ分析から見えたブログのアクセス傾向
約4時間分のログを分析したところ、アクセスは大きく分けて「検索クローラー」「一般ユーザー」「不審なスキャン」に分類されました。
クローラーとユーザーの動向
正常系アクセスでは、ClaudeBotやBingbot、ChatGPT-UserといったAI・検索エンジンのクローラーが活発にコンテンツを巡回していました。
注目すべきはアクセスが集中している記事の傾向です。当ブログで公開しているPython関連の技術記事(Reflex、FastAPI + SQLAlchemy、mock-patchなど)や、相続手続き、GLP-1、白内障手術といったライフスタイル・健康系の記事が、AI Botやスクレイパー(Scrapyなど)の情報収集ターゲットになっているようです。
セキュリティ上の評価
現状、Nginxは脆弱性スキャンや攻撃試行に対して 400 Bad Request、403 Forbidden、404 Not Found を適切に返しており、「第一線の防御機構として十分に機能している(概ね健康)」との評価を得ました。しかし、バックグラウンドでは暗号通貨マイニングソフトの狙い撃ちや、PHP RCE(遠隔コード実行)を狙った高危険度のスキャンが常時届いているため、対策はしておこうと考えました。を強化する必要があります。
2. 【実践編】レイヤー別・即時セキュリティ対策
Geminiのアドバイスを元に、サーバーの防御力を引き上げるための具体的な設定を行いました。まずは「攻撃パケットを止められるところで止める」を意識してます。
レイヤー1:ネットワーク / OSレイヤー(Firewalldによる特定IPの拒否)
最もリソースを消費しない確実な防御は、Webサーバー(Nginx)にリクエストが届く前にパケットを破棄することです。ログ上で明確に「高危険度」と評価された4つのIPアドレスを、OSのファイアウォール(firewalld)レベルで即座に遮断(reject)しました。
実行したコマンド
$ sudo firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='45.227.254.152' reject"
$ sudo firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='45.227.254.155' reject"
$ sudo firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='195.170.172.128' reject"
$ sudo firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='220.197.14.60' reject"
$ sudo firewall-cmd --reload設定の解説
- –permanent: サーバーが再起動しても設定が保持されるようにします。
- reject: 対象IPからの通信に対して、拒否通知(ICMPポート到達不能)を返して即座に通信を断ち切ります(より隠蔽性を高めたい場合は drop でも可)。
最後のリロード(–reload)を実行した時点で、ログに出現していたこれら4つのホストはWebサーバーに一切アクセスできなくなります。
レイヤー2:Nginxレイヤー(スキャン・不正リクエストの直接遮断)
ファイアウォールをすり抜けてくる、不特定多数からの「既知の脆弱性スキャン」や「オープンプロキシとして悪用しようとするテスト」をNginxの設定で弾きます。
(a) 機密ファイル・スキャンパスの正規表現ブロック
.env や .git などの環境設定・リポジトリファイル、およびJava(Tomcat)などの管理画面を狙った機械的なアクセスをアプリケーション(PHPなど)に渡さずにNginxで一括拒否します。
“`
site.conf等の の server ブロック内に記述
# site.conf等の の server ブロック内に記述
server {
listen 443 ssl;
server_name example.com; # 自身の正規ドメイン
# 1. 隠しファイルやディレクトリへのアクセスを拒否
# well-known(SSL証明書の更新等で使用)以外、ドットから始まるパスをすべて弾く
location ~ /\.(?!well-known).* {
deny all;
access_log off; # ログを肥大化させないためにオフ
log_not_found off; # エラーログへの記録もオフ
}
# 2. 既知のスキャンパス(Tomcat管理画面、phpMyAdminなど)をまとめて拒否
location ~* /(manager/text/list|phpmyadmin|pma|muieblackcat) {
deny all;
access_log off;
log_not_found off;
}
}レイヤー3:Fail2banの導入
ここまでの手動ブロックで直近の脅威は去りましたが、インターネット上のスキャンは24時間365日形を変えてやってきます。手動でのIP登録には限界があるため、ログをリアルタイムに監視して自動でIPを一定期間バンする仕組み(Fail2ban)を導入しました。
Fail2banによる自動運用の設定 Ubuntu/Debian系であれば sudo apt install fail2ban で導入後、以下のような設定ファイルを配備します。
# /etc/fail2ban/jail.local
[nginx-botsearch]
enabled = true
port = http,https
filter = nginx-botsearch
logpath = /var/log/nginx/access.log
maxretry = 3 # 3回不審なスキャンパスにアクセスしたら弾く
bantime = 86400 # 24時間(86400秒)ファイアウォールで自動ブロックこれにより、Nginxが 4xx エラーを返すような悪意ある探索行動を検知すると、Fail2banが自動的に iptables や firewalld と連携して攻撃者の通信を遮断してくれるようになり、運用の手間が大幅に削減されます。
4. まとめ
サーバーセキュリティにおいて最も重要なのは、「現状のログ(事実)に基づき、対策を打つこと」、そして「OS・ミドルウェア・アプリケーションの各層でそれぞれ防御を固める多層防御の視点」です。
今後もログを分析することで、どのような対策が必要か検討していこうと考えています。