VPSなどサーバを外部に公開していると、様々な攻撃を受ける可能性があります。例えば、パスワードを総当りで入力してSSHログインしようとするブルートフォース攻撃などが代表的です。 以前、公開した公開鍵認証でSSH接続する方法に変更していれば秘密鍵を盗まれない限り、サーバにSSH接続することができませんが、攻撃をただただ受けるのは嫌なのでfail2banをインストールして対策しましょう。
fail2banのバージョンは0.8.11-2.el6 です。 0.8.11 より古いバージョンは脆弱性があるとのことなので、古いバージョンをインストールしている人はアップデートしてください。
fail2banのインストール
epelパッケージをインストール
$ sudo rpm -Uvh http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
すでにインストールしている場合は次に進みます。
yumでfail2banをインストール
$ sudo yum install --enablerepo=epel fail2ban
起動
$ sudo service fail2ban start
Starting fail2ban:
Message from syslogd@ip-10-0-0-6 at Apr 23 12:54:28 ...
ソ<30>fail2ban.filter : INFO Added logfile = /var/log/secure
Message from syslogd@ip-10-0-0-6 at Apr 23 12:54:28 ...
ソ<30>fail2ban.filter : INFO Set maxRetry = 5
Message from syslogd@ip-10-0-0-6 at Apr 23 12:54:28 ...
ソ<30>fail2ban.filter : INFO Set findtime = 600
[ OK ]
起動確認
$ sudo service fail2ban status
fail2ban-server (pid 2171) を実行中...
Status
|- Number of jail: 1
`- Jail list: ssh-iptables
初期設定ではSSHの設定のみが有効になっています。
自動起動設定
$ sudo chkconfig --add fail2ban
$ sudo chkconfig fail2ban on
$ chkconfig --list fail2ban
fail2ban 0:off 1:off 2:on 3:on 4:on 5:on 6:off
設定
ログディレクトリを変更
ログがデフォルトではsyslogに保存されるので/var/log/fail2ban/ 以下に保存するように変更します。
$ sudo mkdir /var/log/fail2ban
$ vim /etc/fail2ban/fail2ban.conf
## /etc/fail2ban/fail2ban.conf
# logtarget = SYSLOG # コメントアウト
logtarget = /var/log/fail2ban/fail2ban.log # 追加
SSH-iptablesの設定
# /etc/fail2ban/jail.conf
[ssh-iptables]
# trueにするとフィルタが有効になる
enabled = true
# フィルタ名
filter = sshd
# BANしたときのアクション
# sendmail-whois はBANしたIPアドレスのWhois情報をメールで送信(PostfixなどMTAがインストールしていることが前提)
# dest ・・・ 送信先メールアドレス
# sender ・・・ 送信元メールアドレス
action = iptables[name=SSH, port=ssh, protocol=tcp]
sendmail-whois[name=SSH, dest=foofoo@gamil.com, sender=fail2ban@bar.com, sendername="Fail2Ban"]
# 監視するログ名
logpath = /var/log/secure
# BANした後、再び接続できるようになるまでの時間(秒)
# 3600秒 = 1時間
bantime = 3600
# 許容する接続回数
# 3回以上不正に接続するとBANされる
maxretry = 3
再起動
$ sudo service restart
logrotateの設定
/var/log/fail2ban/fail2ban.log にログが残されると、ファイルサイズが肥大するので定期的にログをローテートするようにします。
# /etc/logrotate.d/fail2ban
/var/log/fail2ban/fail2ban.log {
missingok
notifempty
weekly
rotate 5
compress
dateext
create 0644 root root
postrotate
/usr/bin/fail2ban-client set logtarget /var/log/fail2ban/fail2ban.log 2> /dev/null || true
endscript
}
仕組み
例として先ほどのssh-iptablesの設定を見てみます。
[ssh-iptables]
enabled = true
filter = sshd
action = iptables[name=SSH, port=ssh, protocol=tcp]
sendmail-whois[name=SSH, dest=foofoo@gamil.com, sender=fail2ban@bar.com, sendername="Fail2Ban"]
logpath = /var/log/secure
ssh-iptablesを構成するファイルは以下の通りです。
/etc/fail2ban
├── action.d
│ ├── iptables.conf
├── fail2ban.conf
├── filter.d
│ ├── sendmail-whois.conf
│ ├── sshd.conf
├── jail.conf
filterの値がfilter.d/xxxx.conf を指定しています。 actionの値がaction.d/xxxx.conf を指定しています(actionは複数指定が可能)。 logpathで指定されたログを監視して攻撃された形跡があった場合、そのIPアドレスをBANします。
攻撃されたかの判定は/etc/fail2ban/filter.d/sshd.conf で指定しています。
# /etc/fail2ban/filter.d/sshd.conf
...
failregex = ^%(__prefix_line)s(?:error: PAM: )?[aA]uthentication (?:failure|error) for .* from <HOST>( via \S+)?\s*$
^%(__prefix_line)s(?:error: PAM: )?User not known to the underlying authentication module for .* from <HOST>\s*$
^%(__prefix_line)sFailed \S+ for .*? from <HOST>(?: port \d*)?(?: ssh\d*)?(: (ruser .*|(\S+ ID \S+ \(serial \d+\) CA )?\S+ %(__md5hex)s(, client user ".*", client host ".*")?))?\s*$
^%(__prefix_line)sROOT LOGIN REFUSED.* FROM <HOST>\s*$
^%(__prefix_line)s[iI](?:llegal|nvalid) user .* from <HOST>\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because not listed in AllowUsers\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because listed in DenyUsers\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because not in any group\s*$
^%(__prefix_line)srefused connect from \S+ \(<HOST>\)\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because a group is listed in DenyGroups\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because none of user's groups are listed in AllowGroups\s*$
...
failregex で指定された正規表現にマッチしたログが/var/log/secureに書き込まれたらそのIPアドレスをBANします。
IPアドレスをiptableに登録することでBANされます。
$ sudo iptables -L
...
Chain fail2ban-SSH (1 references)
target prot opt source destination
REJECT all -- xxx.xxx.xxx anywhere reject-with icmp-port-unreachable
REJECT all -- xxx.com anywhere reject-with icmp-port-unreachable
REJECT all -- xxx.com anywhere reject-with icmp-port-unreachable
RETURN all -- anywhere anywhere
また、BANしたときに、以下のようなメールが飛びます。
Subject:[Fail2Ban] SSH: banned xxx.xxx.xxx.xxx from bar_host
Body:
----
Hi,
The IP xxx.xxx.xxx.xxx has just been banned by Fail2Ban after
3 attempts against SSH.
Here are more information about xxx.xxx.xxx.xxx:
<IPアドレスのWhois情報>
最後に
fail2banをインストールし、SSH不正攻撃を防ぐことができました。 fail2banはSSHだけでなく、Basic認証などの攻撃も防ぐことができるのでとても便利なツールです。 その辺りを今後紹介したいと思います。