FreeBSD Brute Force Attack Counter Tool (No. 1) の続きです。
ハッシュリファレンスを多用しています。理解している前提で書いているので予めご了承ください。
処理概要
- 毎分 /var/log/auth.log (sshd), /var/log/poplog (popd) に出力した Failed password の行から IP アドレスを抽出し、
- 所定の場所 ($item->{target0}, $item->{target1}) に記録、
- 一定回数 $item->{mistime} を超えた場合は
- ipfw add 00101 deny ip from [ipaddr] to any で遮断し
- 一定時間 $item->{expire} を経過後解放。
所定の場所に出力されるサンプルは以下の通りです。実際の出力から 1, 2 オクテットのみプライベート IP アドレスに変更していますが、ニュアンスは伝わるでしょう。
last_line 2267195 2012/10/02 19:20:04 10.10.59.71 7 - 2012/10/02 19:20:04 10.10.75.90 8 - 2012/10/02 19:20:04 10.10.246.33 2 - 2012/10/02 19:20:04 10.10.121.198 2 - 2012/10/02 19:22:02 10.10.75.90 9 - 2012/10/02 19:44:01 10.10.75.90 10 add 2012/10/02 20:14:01 10.10.75.90 0 expire 2012/10/02 20:28:01 10.10.75.90 1 - 2012/10/02 20:30:01 10.10.207.240 1 - 2012/10/02 20:34:01 10.10.75.90 2 - 2012/10/02 20:43:02 10.10.75.90 3 - 2012/10/02 20:56:01 10.10.75.90 4 - 2012/10/02 21:02:01 10.10.75.90 5 - 2012/10/02 21:04:01 10.10.75.90 6 - 2012/10/02 21:10:01 10.10.75.90 7 - 2012/10/02 22:40:01 10.10.139.161 2 - 2012/10/02 23:15:03 10.10.248.211 972 add 2012/10/02 23:24:02 10.10.98.192 1 - 2012/10/02 23:27:02 10.10.207.240 3 - 2012/10/02 23:29:01 10.10.207.240 4 - 2012/10/02 23:30:02 10.10.207.240 6 - 2012/10/02 23:46:02 10.10.248.211 0 expire
10.10.75.90 は正規のユーザが "おっかしいな。。" と言いながら何度か試している可能性はありますが、10.10.248.211 のケースが総当たり攻撃の典型です。
popd 改修
今回は FreeBSD の ports に収録されている /usr/ports/mail/popd/ を、 sshd 同様 poplog に Failed password の行が出力する様に修正する点がポイントです。
これにより、大半のサブルーチンは兼用することが出来ます。今回は引数なしで実行すれば sshd (/var/log/auth.log) を、-p 付きで実行する場合は popd (/var/log/poplog) を監査する様にしました。
実際 bfcheck.pl 側を sshd だけでなく popd に対応させる修正は、$item の target0, target1 や dir0, dir1 とログファイルや監査結果の出力先ディレクトリの分岐と、71 – 81 行目の分岐でほぼ終了です。
popd 側の修正はまだ完全とは言えない可能性があるので、ポイントのみ。
- popd.c の終端の switch 文で、case FALSE, case QUIT の場合に syslog(facility, “Failed password for null from %s”, inet_ntoa(addr.sin_addr)); の様に追記。IPv6 に対応する場合は case TRUE の分岐を参考に。
- 必須ではないが、authenticate.c の終端 case PASS: で if (counter == 4) の 4 を sshd_config の MaxAuthTries と揃えて変更。
これで、sshd の場合と同じ条件で認証し、失敗時の出力も 340 行目の様になり、sshd か popd のみの違いとなります。
当初は ipfw でなく /etc/hosts.allow で
当初は /etc/hosts.allow に deny で追加・解放していましたが、この場合では懲りずに通信を続ける場合は負荷を避けることが出来ないことが分かりました。
ipfw と違いルール番号を気にしなくて良いので、手軽に始めたことがきっかけですが、Refused … と出ていても通信を止めないクライアントが結構多いのです。
そのため、ipfw で遮断する方針に切り替えました。効果はてきめんです。
ルール番号と登録ポリシーや、ipfw でなく pf に変更等応用は効くと思いますが、cron で実行する場合には工夫も必要です。
cron からはラッパースクリプトで直列起動
当初 crontab -e で
*/1 * * * * /home/tools/bfcheck.pl 2>/dev/null
*/1 * * * * /home/tools/bfcheck.pl -p 2>/dev/null
の様に登録しましたが、ipfw のルール変更で実に不思議な動きをしました。正常に消す場合と、消すはずの IP アドレスが消えずに増え続ける場合があるのです。
同じルール番号を用いていたので、sshd と popd の場合でルール番号を分けることでも対処は可能でしょうが、今回は bfcheck.sh を以下の内容で用意し、crontab -e では単に
*/1 * * * * /home/tools/bfcheck.sh 2>/dev/null
とだけ呼ぶ様にしました。
#!/bin/sh /home/tools/bfcheck.pl 2>/dev/null /home/tools/bfcheck.pl -p 2>/dev/null
まだ運用開始してい間もないので、経過観察は続けてみます。そのうち、ftpd や sendmail 向けの機能拡張も必要となる気はしています。
- FreeBSD Disk Array Check Tool
- FreeBSD File System Check Tool
- FreeBSD Brute Force Attack Counter Tool (No. 1)
- FreeBSD Brute Force Attack Counter Tool (No. 2)
- FreeBSD ACPI Thermal Check Tool