本日も乙

ただの自己満足な備忘録。

fail2banをインストールしてサーバへの不正攻撃を防ぐ

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認証などの攻撃も防ぐことができるのでとても便利なツールです。 その辺りを今後紹介したいと思います。

参考URL

fail2ban.org FAIL2BAN で不正アクセス防止 (DOVECOT 編)