いい加減ブルートフォースアタックが secure ログを圧迫してきたので対策しようとして google 先生にお伺いを立てたら、大変なことになった。
- maxlogins.pl → Perl 入れてないよ orz。Matsup's blog: FreeBSD:sshサーバーに対する辞書攻撃の防御
- おお、これはすばらしい。シェルスクリプトだったらどのマシンでも動くやん → Firewall はルータ任せでした orz。Altair☆'s 三日坊主 blog:SSHへの辞書攻撃回避スクリプト - livedoor Blog(ブログ)
- syslog.conf 書いてパイプ経由でスクリプト動かせばええやん。ぎゃー、動かん。スクリプトいつの間にか上書きされる。 → linux では、名前付きパイプでした orz。http://www.horse-water.mydns.jp/tips/tips_L00009.html
と、書いたスクリプトはパイプ扱いされてを上書きされるわ、入れたパッケージ確認するわ、Perl入れようか悩んで結局ごった煮状態で作ってみた。
ということで
非常に限定された環境向けで、ほとんど人の物まねやけれど、
- Perl入れてない。Perl じゃなくて、シェルスクリプトで書くよ。Perl 入れるのはまた今度。
- 名前付きパイプ使うよ。syslog-ng とか入れるのは、また今度。
- スクリプトがいい。hosts.allow 使うので iptables 入れるのはまた今度。
な人向け。Perl 入れてないなんてあり得ないとか、この際だし syslog-ng 入れようかとか、iptables なんで使わないのとかな人は、もっと良いのがありますので、参考程度にどうそ。
- syslog.conf で、名前付きパイプを使って処理する。一度やってみたかったので。syslogでも、アプリ毎のログとれるようになったりするかなと。あと、fork する処理、開眼した。pipe, fork, dup2, exec*、納得。
- sshd は hosts ファイル読んでくれる。inetd 経由じゃないのに格好いいナイスガイ。許可するホストの一覧とか外部においておくときとかも、保守性あがるよね。
ということで勉強がてら書いてみた。
スクリプト本体
#!/bin/sh # usage : script_name pid_file pipe_file host_file & n='[0-9]\{1,3\}' ip="$n\.$n\.$n\.$n" echo $$ > $1 while read log; do echo ${log} | \ sed -ne '/sshd\[.*\]: /!d /Did not receive identification string from /bx /Invalid user .* from /bx /User .* from '$ip' not allowed /!b :x s/.*[^0-9]\+\('$ip'\).*/\1/ p' >> $3 done < $2
ほとんど Altair☆'s 三日坊主 blog:SSHへの辞書攻撃回避スクリプト - livedoor Blog(ブログ) で書かれているスクリプトと同じです。違いは tail の出力ではなく、名前付きパイプからログを取得しているところと、攻撃してきたホストをファイルに書き出している部分。ssh のバージョン違いで、出力ログが若干変わってることに対応したぐらい。速攻で監獄行きです。
ほとんどコピペですな orz。sed で条件分岐ってコマンド初めて使いますた。お勉強になりました。
設置する
まずは名前付きパイプの作成
# mkfifo /var/log/auth.pipe
で syslog.conf を編集。名前付きパイプに出力を送るように設定をする。
auth.* |/var/log/auth.pipe
で rc.syslogd に追加。スクリプト名とか、pid ファイルとか、ホスト一覧とかはまあ適当に。
/usr/local/sbin/jail_ssh /var/run/jail_ssh.pid /var/log/auth.pipe /var/log/jail.hosts &
hosts.allow を編集。ホスト一覧ファイルをみて、アクセス拒否するような設定を書く。sshd は、hosts ファイルみてアクセス制限してくれる。
sshd : /var/log/jail.hosts : deny sshd : all : allow
sshd:all:allow のところは適切に。上から順番に処理されていくので allow が下ってことだけ。
パイプファイルが閉じられるとスクリプトも終了してしまうので、logrotate 使ってるなら、syslogd が再起動されるタイミングで、再度スクリプトを起動させる一文を追加。
うまく動作していると、こんな感じにピンポンダッシュを防げる
Cct 4 08:32:10 www sshd[13471]: Did not receive identification string from 219.216.128.109 Oct 4 08:38:32 www sshd[13476]: refused connect from 219.216.128.109 (219.216.128.109) Oct 4 12:29:09 www sshd[13533]: Did not receive identification string from 219.117.245.84 Oct 4 12:35:33 www sshd[13537]: refused connect from 219.117.245.84 (219.117.245.84)
終わりに
昔の環境でも動くかな。jail.hosts たまってくると少し楽しい。でも、よく考えたら遅くなるかも。設定がいろんなところにあって、ちょっといやかも。