[linux] sshをiptablesで制限する(without hitcount)
会社のほうで VPS(Virtual Private Server) を契約していて、毎回リモートコンソールで接続するのは面倒なので、やっぱりSSHで接続することになる
んで、調べてみると(というか iptables ssh で検索すると)
「sshへの総当り攻撃をiptablesの2行で防ぐ方法」とか「iptables の ipt_recent で ssh の brute force attack 対策 」いろいろでてくる
んで、たいてい提唱しているルールはこんな感じ
-A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 3 --rttl --name SSH -j DROP
過去60秒の間に、SSHへの接続を3回試してきたらDROPする
なんとなく分かるけど、こちとらSSHのプロンプトすら見せたくないので、こういうふうにした
-A INPUT -p tcp -m tcp --dport 22222 -m recent --set --name check --rsource -j DROP -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --rcheck --seconds 3 --name check --rsource -j ACCEPT
SSHへの接続をしてきた時に、過去3秒の間に22222ポートへのTCP接続があれば、そのIPアドレスからのSSHへの接続を許可する
実際に接続するときには3秒以内に 22222ポートへTCP接続して、22ポートへSSH接続しないとダメなので
$ ssh dummy; ssh target
とし、dummyへの接続は config(~/.ssh/config)で
Host dummy Port 22222 ConnectTimeout 1
1秒たったら接続を遮断して、すぐに target にSSH接続するようにしている
ちなみにこれはTCP接続にしているけど、別にICMPでもUDPでも他のTCPでも何でもいいし、もっと短くできるなら1秒にしちゃってもいい
もちろん、多くの文献にあるように接続回数が多い場合に遮断するのもわかるけど、sshdにセキュリティホールが見つかるかもしれないので、やっぱり使いたくない