外出先からSSHで自宅のサーバに接続できる環境にしたい。でもSSHを空けると不正ログインしてこようとしてくる輩がわんさか。まったくインターネットは地獄だぜ!というわけで不正ログインの成功率を思いっきり下げてあげましょう。スティーブ(誰?w)がPerlでいいスクリプトを作ってくれてます。設定した回数ログインに失敗したIPアドレスは、hosts.denyによって設定した時間の間アクセスを拒否されるのです。ざまああああああw 自分の接続元IPアドレスが決まっているならおとなしくファイアウォールなりiptablesなりで絞り込めばいいのですが、それじゃあなんとなくつまらないでしょ。w

まずここのDownloadから、スクリプトをコピってきます。1行目 #!/usr/local/bin/perl -w から DOCUMENTATION の手前までね。1行目のPerlのパスはUbuntuの環境、/usr/bin/perlに直して、/usr/local/bin/あたりにmaxlogins.plという名前ででも放り込んでパーミッション等を設定。

# chown root.root /usr/local/bin/maxlogins.pl
# chmod 750 /usr/local/bin/maxlogins.pl

SSHログイン失敗のログを使って動作する仕組みのこのスクリプト。スクリプトにログを食わせる設定をしていきます。

# vi /etc/rsyslog.d/50-default.conf
  auth,authpriv.*                 /var/log/auth.log
 の行の下に
  auth,authpriv.*                 | /var/log/maxloginpipe 
 と追加して保存

rsyslogではパイプは名前つきパイプとなるので、名前つきパイプを作りそこにログを流し込みます。そしてそれを maxlogins.pl に流し込む maxlogins.sh というスクリプトを作成します。maxlogins.pl の引数 -a 5 -e 24h は、5回ログインに失敗したらそのIPアドレスからのログインは24時間ポートの入り口で門前払い、ということになります。同じIPアドレスで誰か自分以外に規定回ログインに失敗したらどうすんの?という突っ込みは無しでお願いします。(笑)他にも色々オプションがありますのでドキュメントを見て適宜設定しましょう。

# mkfifo /var/log/maxloginpipe
# vi /usr/local/bin/maxlogins.sh

  #!/bin/sh
  while read line ; do
    echo $line | /usr/local/bin/maxlogins.pl -a 5 -24h
  done < /var/log/maxloginpipe

# chmod 750 /usr/local/bin/maxlogins.sh

このmaxlogins.plはデフォルトで /var/log/maxlogins というhosts.denyで使えるファイルを生成するので、/etc/hosts.denyに以下のエントリを追加します。

# vi /etc/hosts.deny
 
  sshd: /var/log/maxlogins

rsyslogの設定変更を有効にし、maxlogins.shをバックグラウンドで実行します。起動スクリプトから実行などはお好みで設定してください。(手抜き)
なお、rsyslogがreloadやrestartされるとmaxlogins.shが落ち、reloadの場合その後にmaxloginsが正常に動かなくなるので、/etc/logrotate.d/rsyslogを以下のように変更します。

# service rsyslog restart
# /usr/local/bin/maxlogins.sh &
# vi /etc/logrotate.d/rsyslog
  postrotateとendscriptの間を以下のように変更する。(2箇所)
  /usr/local/bin/rsyslog.sh

最後にlogrotateから呼び出されるスクリプトを用意します。

# vi /usr/local/bin/rsyslog.sh

  !#/bin/bash
  kill `ps -ef | grep maxlogins | grep -v grep | tr -s " " | cut -d" " -f2`
  restart rsyslog >/dev/null 2>&1 || true
  /usr/local/bin/maxlogins.sh

# chmod 755 /usr/local/bin/rsyslog.sh