サーバーは一度設定され、その後はひとりで生きていきます。一か月後には一部のパッケージが更新を待ち、証明書は期限まで三週間のところまで来ていて、無関係な何かを入れた拍子に SSH の設定に余計な一行が増えており、ログインを見張るはずの jail は誰にも気づかれないまま止まっています。どれも声を上げません。すべてが静かに、真実であることをやめるだけです。
以下は定期的に点検する価値のある十二項目で、コマンド付きです。ひと回りで十五分ほど。順番は、人が入ってくるところから、ひとりでに壊れるところへと進みます。
SSH: 五行
見るべきはファイルではなく、実際に効いている設定です。これは /etc/ssh/sshd_config、sshd_config.d ディレクトリ全体、そしてビルド時の既定値から組み上がります。
sudo sshd -T | grep -iE 'permitrootlogin|passwordauthentication|permitemptypasswords|maxauthtries|x11forwarding'
見たいのは次のとおりです。permitrootlogin no、passwordauthentication no、permitemptypasswords no、maxauthtries は 3〜4、そして x11forwarding no。最初の三つが扉で、最後の二つはその蝶番 — 接続ごとの試行回数の上限と、サーバーには用のないグラフィック転送です。
注意が二つ、どちらも自分を締め出す簡単な方法です。第一に、鍵が使えることを確かめるまで、パスワードログインと root ログインを切らないでください。別のセッションで、いま開いているものを閉じずに確認します。これを root でパスワードログインしたまま読んでいるなら、その二行が締め出すのはまさにあなたです。
第二に、ファイルの順序です。OpenSSH はあるパラメータについて最初に出会った値を採用し、sshd_config.d のファイルはアルファベット順に読まれます。クラウドイメージはそこに 50-cloud-init.conf を置いていることが多く、自分のファイルを 90-hardening.conf のような名前にしていると、そちらに負けます。自分の設定はより小さい番号の下に置きます — 00- か 10-。そして結果はファイルを読むのではなく sshd -T で確かめます。
ファイアウォール: 一つの点検
sudo ufw status verbose
ここで覚えておきたいのは、この出力が示すのは意図であって結果ではない、ということです。ルールは一覧に並んでいながら何も閉じていないことがあります。UFW 自体が無効になっている、ポートを担っているのが Docker の公開したもの(自分のルールを UFW の下の iptables に書きます)である、あるいはトラフィックが別の経路でサーバーに届いている、といった具合です。ですからルール一覧は、実際に外向きで待ち受けているものと突き合わせる価値があります。
sudo ss -tulpn | grep -v '127.0.0.1\|::1'
fail2ban: 二つの点検
サービスが動いているだけでは足りません。SSH 用に機能している jail も要ります。
sudo fail2ban-client status
sudo fail2ban-client status sshd
ここで最も多い厄介事は、黙りこんだ jail です。Debian 12 や新しい Ubuntu では /var/log/auth.log がそもそも存在しないことがあります。rsyslog が入っておらず、記録は journald の中だけで生きているためです。既定の logpath のままの jail はそれでも起動し、有効だと自己申告し、誰ひとり遮断しません。対処は systemd のジャーナルへ向けることです。
printf '[sshd]\nenabled = true\nbackend = systemd\n' | sudo tee /etc/fail2ban/jail.d/sshd-systemd.local
sudo systemctl restart fail2ban
設定を掘らずにこれを見抜く手がかり: fail2ban-client status sshd の「Currently failed」と「Total failed」がゼロのままなのに、ジャーナルには失敗したログインが明らかに並んでいる、という状態です。
更新: 三つの点検
別々に見ます。全体で何個のパッケージが待っているか、そのうちセキュリティ関連は何個か、そしてカーネル更新のあとに再起動を求められていないか。
sudo apt update
apt list --upgradable 2>/dev/null | grep -c -- '-security'
ls /var/run/reboot-required 2>/dev/null && echo '再起動が必要'
三つ目の点検は、自動セキュリティ更新が有効かどうかです。これがないと最初の二つが毎月の儀式になってしまいます。
systemctl status unattended-upgrades --no-pager
cat /etc/apt/apt.conf.d/20auto-upgrades
このファイルは両方の行とも 1 であるべきです。パッケージが入っていなければ sudo apt install unattended-upgrades && sudo dpkg-reconfigure -plow unattended-upgrades。
証明書: 一つの点検
Let's Encrypt の証明書の寿命は九十日で、更新はたいてい自動で回ります — 回らなくなるその日まで。見るべきはレジストラの画面ではなく、サーバーが実際に出しているものです。
echo | openssl s_client -connect localhost:443 -servername example.com 2>/dev/null | openssl x509 -noout -enddate
sudo certbot renew --dry-run
一つ目のコマンドはその名前に対して出されている証明書の終了日を示し、二つ目は本当の期限を待たずに更新が通ることを確かめます。主ドメインだけでなく、サーバーが扱っているすべての名前を見て回る価値があります。忘れられるのはたいてい、あとから足したサブドメインです。
ディスク: 一つの点検
df -h
df -i
コマンドが二つなのは、容量とファイルの登録枠が互いに独立して尽きるからです。多くのサーバーでは後者のほうが先に天井に当たります。PHP のセッションやアプリケーションのキャッシュにある何百万もの小さなファイルが、ギガバイト単位の空きを残したまま IUse% を 100 にしてしまうのです。どちらの場合についても別記事があります。
この一覧の難点
一覧そのものは正しいのですが、ひとつ性質があります。誰かが覚えていることを要求するのです。週に十五分は大した時間ではありません — サーバーが一台のうちは、そしてきっかけがあるうちは。静かな二か月が過ぎると巡回は飛ばされ、jail が止まったことは他人のログから知ることになります。
そこで、この十二の点検をそのまま独立した無料パネルにまとめました — Arcivéo FREE。コマンド一つで入り、あなたのサーバーで動き、こちらへは何も送らず、登録も要りません。収集プログラムが cron から五分おきに走り、同じものをローカルのデータベースに書きます。SSH のログインと拒否された接続、UFW と fail2ban の状態、保留中のセキュリティ更新、証明書の期限、ディスクの空き。履歴は七日分、画面は 34 言語です。価格はゼロで、業務用サーバーでも同じです。ライセンスは自分のマシン(会社のマシンを含む)への導入を認め、再販や他人のサーバー向けのサービスとしての運用は認めていません。
無料版のスタックは控えめです。UFW と fail2ban を導入して有効にし、そこから先は状態を見せます。ModSecurity、Suricata、AIDE などのモジュールは入っておらず、それらは有償版のものです。ただ、毎週の巡回を頭の中に抱えずに済ませるには、これで足ります。同じデータが完全版のパネルでどう見えるかは、下のデモページで。