🔐【体験談】SSHポート22番を「ローカルネットワークのみ許可 + drop」にしたら、自分もはじかれた話
■ はじめに
サーバー構築時に避けて通れないのが SSHのセキュリティ対策。
特に 22番ポート
はSSHの既知ポートなので、外部からのスキャン対象になりやすく、攻撃を受けやすいです。
対策として「公開鍵認証を使う」「ポート番号を変更する」などの方法がありますが、
急ぎで構築する際やローカル環境用であれば、とりあえずローカルネットワーク内からだけSSHを許可するという方法が手軽です。
■ ポート番号を変更?それともそのまま使う?
ポート番号を変更することでスキャン対象から外れる効果はあります。
しかし、あとで自分がポート番号を忘れるリスクもあるため、今回は 22番ポートをそのまま使うことにしました。
その代わりとして、ローカルネットワーク(192.168.1.0/24)のみからの接続を許可し、
それ以外からのアクセスはすべて拒否(drop)する構成にしてセキュリティを担保しました。
■ drop ルールは強力…だが落とし穴も
今回設定したFirewalldのルールは以下のとおり:
rule family="ipv4" source address="192.168.1.0/24" port port="22" protocol="tcp" accept
rule family="ipv4" port port="22" protocol="tcp" drop
このように「ローカルだけ許可・それ以外は drop」にすればセキュリティ的には非常に強固です。
しかし実際には…
なぜかローカルネットワーク内からもSSH接続できなくなってしまいました。
■ 原因:drop が勝ってしまうことがある
Firewalldのリッチルールは、記述順に評価されるように見えるのですが、
実際にはdrop
が強く優先されることがあり、accept
より先に評価されてしまうケースが存在します。
つまり、意図としては:「192.168.1.0/24はOK、それ以外は拒否」
だったはずなのに、実際には:「全部drop!」
と判断されてしまう状況に…。
■ 解決策:いったん drop を削除して、許可だけにする
簡単かつ確実な方法は、いったん drop
を削除し、accept
ルールだけを有効にして確認することです。
sudo firewall-cmd --permanent --remove-rich-rule='rule family="ipv4" port port="22" protocol="tcp" drop'
sudo firewall-cmd --reload
これでローカルネットワークからの接続が通るようになりました。
■ drop と reject、どちらを使うべき?
- reject:明示的に拒否応答を返す(IPもアクティブ)
- 管理しやすい・デバッグしやすい(すぐ拒否応答が返る)
- ただし存在がバレる
- drop:完全に黙殺
- セキュリティ的に強力(存在すら隠せる)
- 管理者も混乱しやすくなる(タイムアウトで原因がわかりにくい)
使い分けが大切。私は今後、デバッグ中は reject、本番環境では drop という方針で運用していく予定です。
■ まとめ
firewalld
のリッチルールでdrop
を使うと、接続できない原因の特定が難しくなることがあるdrop
とaccept
の併用は、ルールの評価順に注意- 初期設定では reject を使い、安定してから drop に切り替えるのが安心
🔚 おまけ:今回の教訓
「自分が接続できなくなるセキュリティ設定は、本当に強い」
…けど、それじゃ困る!😂
コメント