2010年3月24日水曜日

fail2banでブルートフォース対策

以前のものでiptablesのipt_recentをつかって、2行のコマンドでsshのアタックを防ごうという記事があるのだけど、とあるサーバで適用できなかったので別手段を。
 
 


(ほぼ)共同で借りているVPSレンサバがあるんだが、OpenVZかVirtuozzoかのコンテナらしくてiptablesのモジュールが自由にできないのがある。
そこではipt_recentをつかうとエラーになってしまい、前述の簡単ブルートフォース対策が使えないのだ。
 
 


仕方ないので fail2ban を使うことに。
pythonで動く、アクセス制限操作用のプログラムだ。
ちなみに導入先はCentOS5.4。
 
 

fail2banのインストール


開発元のサイトから最新のStableを落とそう、記事の時点では0.8.4だった。
http://www.fail2ban.org/wiki/index.php/Main_Page
 

RPM があるみたいだけど、ここはtarボールで。簡単だから。
 

展開したらPythonのスクリプトを流そう、Python2.3以上がいるらしいが、
まあ問題ないだろう。
# python ./setup.py install
 
なんとこれだけで終わりだ、便利になったもんだ。

 
 

"/etc/fail2ban/" に設定が一式、"/usr/share/fail2ban"にpythonのスクリプトが入る。


  1. fail2ban.conf:基本の設定

  2. jail.conf:サービス別設定


これだけ覚えてりゃなんとかなる、今回は jail.conf しかいじらない。
 
 


fail2banの動作パターン


ログを30秒ごとに監視する⇒パターンマッチしたらアクション(iptables設定追加など)
一定時間経過⇒適用済みのアクションを解除
 
という感じだ。
 
 

色々細かい設定やテストが出来るが基本はこのパターン。シンプルで他に影響が出ない。
導入の敷居としては低いんじゃないかな。
 

※当然iptablesを動かして無いと効果がない。
 
 

sshの制限(設定)


じゃあ導入のきっかけ、sshの制限をしよう
 
 

jail.confにもともと書いてある設定をちょっといじる。太字は大事なとこで、他も適当に書き換えよう。
 

[ssh-iptables]
enabled = true
filter = sshd
action = iptables[name=SSH, port=ssh, protocol=tcp]
# sendmail-whois[name=SSH, dest=hogehoge@example.com, sender=fail2ban@mail.com]
logpath = /var/log/secure
maxretry = 5

 


有効にして、メール通知やログパスの設定を環境に合わせる。
通知はコメントアウトしているが、動作確認などでは便利なので安定動作を確認するまで使ったほうがいい。
 
 

sshの制限(デーモン稼働)


fail2banの軌道方法だけど、スクリプトが用意してある。
デーモンモードとなり、制御端末は切り離されるのでログアウトしても心配いらない。
# /usr/bin/fail2ban-client start
 

設定を変更した場合などは、
# /usr/bin/fail2ban-client reload
 
 

自動起動についてだけど、init.d/に置くスクリプトはとくに用意してないみたいだったので、inittabに書いちゃったな。
これについてはきっちり試してないのだが多分大丈夫だろう。
 
 


fail2banの様子


とりあえず同一のIPから600秒以内に5回ログインミスったらbanするように(さっきの設定)した。
デフォルトではbanして600秒たったら元に戻る。
 

"/var/log/fail2ban.log" にbanの様子が記録されるので見てみよう。

# tail /var/log/fail2ban.log
2010-03-23 18:20:55,628 fail2ban.actions: WARNING [ssh-iptables] Ban 211.142.19.251
2010-03-23 18:30:55,810 fail2ban.actions: WARNING [ssh-iptables] Unban 211.142.19.251
2010-03-23 21:35:14,533 fail2ban.actions: WARNING [ssh-iptables] Ban 211.142.19.251
2010-03-23 21:45:14,707 fail2ban.actions: WARNING [ssh-iptables] Unban 211.142.19.251
2010-03-23 22:33:37,424 fail2ban.actions: WARNING [ssh-iptables] Ban 211.157.108.132
2010-03-23 22:43:37,616 fail2ban.actions: WARNING [ssh-iptables] Unban 211.157.108.132
2010-03-24 00:00:34,088 fail2ban.actions: WARNING [ssh-iptables] Ban 64.3.96.221
2010-03-24 00:10:34,310 fail2ban.actions: WARNING [ssh-iptables] Unban 64.3.96.221
2010-03-24 00:53:33,939 fail2ban.actions: WARNING [ssh-iptables] Ban 211.142.19.251
2010-03-24 01:03:34,114 fail2ban.actions: WARNING [ssh-iptables] Unban 211.142.19.251


おお、引っかかってるね。Banして、10分後にUnban、10分もすりゃたいがい攻撃は終わってる。
こいつらほっといたら万単位で試行しやがる、まったく。
 
 


ついでにログを何秒間隔で掘っているのか気になったのでstraceして測ってみた。
# strace -p 26424
Process 26424 attached - interrupt to quit
poll([{fd=3, events=POLLIN|POLLPRI|POLLERR|POLLHUP|POLLNVAL}], 1, 30000) = 0 (Timeout)
poll([{fd=3, events=POLLIN|POLLPRI|POLLERR|POLLHUP|POLLNVAL}], 1, 30000) = 0 (Timeout)
poll([{fd=3, events=POLLIN|POLLPRI|POLLERR|POLLHUP|POLLNVAL}], 1, 30000) = 0 (Timeout)


30秒間隔見てるね、まー十分だろう。
 
 


他にも各種サービス用の設定がプリセットされていた、使いやすいツールの一つとして覚えておこう。