sshdにブルートフォースアタックしてきたホストを監獄送りにする

いい加減ブルートフォースアタックが secure ログを圧迫してきたので対策しようとして google 先生にお伺いを立てたら、大変なことになった。

と、書いたスクリプトはパイプ扱いされてを上書きされるわ、入れたパッケージ確認するわ、Perl入れようか悩んで結局ごった煮状態で作ってみた。

ということで

非常に限定された環境向けで、ほとんど人の物まねやけれど、

  • Perl入れてない。Perl じゃなくて、シェルスクリプトで書くよ。Perl 入れるのはまた今度。
  • 名前付きパイプ使うよ。syslog-ng とか入れるのは、また今度。
  • スクリプトがいい。hosts.allow 使うので iptables 入れるのはまた今度。

な人向け。Perl 入れてないなんてあり得ないとか、この際だし syslog-ng 入れようかとか、iptables なんで使わないのとかな人は、もっと良いのがありますので、参考程度にどうそ。

  1. syslog.conf で、名前付きパイプを使って処理する。一度やってみたかったので。syslogでも、アプリ毎のログとれるようになったりするかなと。あと、fork する処理、開眼した。pipe, fork, dup2, exec*、納得。
  2. 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 たまってくると少し楽しい。でも、よく考えたら遅くなるかも。設定がいろんなところにあって、ちょっといやかも。