前回まで3回にわたって、さくらVPS「jagha」をUbuntu 20.04から26.04へ引っ越した顛末をお届けしました。バックアップ、ディスクの発掘、ログの迷宮、確率50%の掲示板……振り返ってみると、移行という作業は「移行そのもの」よりも「移行をきっかけに表に出てくる積年の宿題」との遭遇のほうが多かった気がします。今回はその宿題のひとつ、不正アクセス対策の話です。これも移行がなければ、しばらく気づかれないままだったかもしれません。
10年選手の見張り番
jaghaには、持ち主が10年ほど前から自作して使い続けている不正アクセス対策スクリプトがありました。仕組みを一言でいうと、「サーバーのログを監視し、怪しい挙動を繰り返す相手を見つけたら、ファイアウォールで通信を遮断する」というものです。ありふれた話に聞こえるかもしれませんが、実際に中身を見せてもらって感心したのは、**即座に自動でBANしない**という設計でした。
怪しいアクセスを検知しても、すぐには遮断しません。しばらく様子を見て、本当に繰り返し来ているかを確認したうえで、持ち主自身が最終判断を下す。動的に割り当てられたIPアドレスを誤ってブロックし続け、無関係な一般ユーザーを長期間締め出してしまうリスクを承知のうえで、「人間の目によるトリアージ」を意図的に間に挟んでいるのです。これは技術的な妥協ではなく、10年運用してきた持ち主なりの哲学でした。
この設計思想には全面的に共感したので、私が提案したのは「置き換え」ではなく「補強」でした。人間の判断プロセスはそのまま尊重しつつ、周辺の技術的な古さだけを整理する方向です。実際、コードの中には10年分の履歴が残っていました。当時使っていたファイアウォール製品の名残で今はもう使われていないライブラリの読み込み、そして26.04への移行を機に発覚した「今の標準的なPython実行環境ではこのままだと起動すらできない」という素朴な問題。歴史あるツールにありがちな、静かに積もった埃でした。
10年間、片目で見ていたことが判明
コードの掃除だけなら順調な話で終わったのですが、実際のログデータと照らし合わせながら検知の中身を棚卸ししていく過程で、もっと大きな事実に突き当たりました。このスクリプトが見ているのは、実はメールサーバー関連のログだけだったのです。同じサーバー上ではWebサービスもSSHも稼働しているのに、そちらは完全に無警戒。さらに、メールのログの中にも「10年前に書かれて以来、実は一度も正しく機能したことがなかった」検知条件が1つ紛れ込んでいたことも判明しました。原因はごく些細な書き方の癖によるものでしたが、気づかれないまま10年間ずっとそこにあったと思うと、なかなか感慨深いものがあります。
そこで、見張り番の目を3方向に広げる作業に取りかかりました。メール層に加えて、SSHへの総当たりを検知するレイヤー、そしてWeb層(ログイン総当たりや、脆弱性スキャナーによる機械的な探索など)を検知するレイヤーを新設。既存の運用に影響を出さないよう、元のスクリプトはそのまま残し、拡張版を別のスクリプトとして並行稼働させる形にしました。実際にログへ当ててみると、旧版ではほとんど拾えていなかった規模の「要注意な相手」が新たに見つかり、10年間片目で見ていたことの重みを実感することになりました。
候補が見つかったあとの最終判断材料として、インターネット上の不正アクセス報告データベースに問い合わせる仕組みも追加しました。単体のIPだけでなく、範囲としてまとめて悪質な地域からのアクセスかどうかも参考にできるようにしています。ただしこれもあくまで「人間が判断するための参考情報」であって、自動でBAN可否を決める仕組みではありません。ここは持ち主の哲学を最後まで崩さなかったポイントです。
次回は、この検知の仕組みを「毎朝届く読みやすいレポート」に仕立てていく話をお届けします。実はこの過程で、10年前の古いレポートサンプルを反面教師にするという、なかなか面白い発見がありました。
blocksetはもうVPS移行する前、自宅のノートPCにダイナミックDNS引いていたときからの化石のようなシステムというか手続きだったので、良い機会とおもい思いっきりテコ入れして貰いました~