fail2ban を導入してお行儀の悪い奴を効率的に排除する

スポンサーリンク

はじめに

 筆者の運用しているメールサーバー (MTA) ではメール送信時に認証を必要としているが、MTA に対して適当なユーザー名とパスワードで何度も繰り返すことでアカウントを盗むか若しくはその他の目的で宜しくない試みが行われて居る。
 これは何も特別筆者のサーバーがどうのと言う訳では無くて、そこに MTA があればどこからか奴等はやってくるという感じである。
 そういった不正なアクセスを短期に行っていると目立つ物は手動にてファイアーウォールでブロックしてきた。
 流石に手動とか運用上面倒臭い事この上無いし非効率だ。

 そんなこんなで特定のアクセスを規定時間内に規定回数行ったら自動でファイアーウォールで対象の IP アドレスをブロックしてくれる fail2ban の導入と相成った。

fail2ban のインストール

 サーバー OS は CentOS 7 なので yum で一発だが epel にあるのでリポジトリを追加しておく必要がある。

yum install epel-release
yum install --enablerepo=epel fail2ban fail2ban-systemd

 とすると依存関係も含め次のパッケージがインストールされる。

インストール中:
 fail2ban                           noarch                 0.9.7-1.el7
 fail2ban-systemd                   noarch                 0.9.7-1.el7
依存性関連でのインストールをします:
 fail2ban-firewalld                 noarch                 0.9.7-1.el7
 fail2ban-sendmail                  noarch                 0.9.7-1.el7
 fail2ban-server                    noarch                 0.9.7-1.el7
 systemd-python                     x86_64                 219-57.el7_5.3

初期設定

 筆者環境では firewalld を使用せず iptables を使用しているので、デフォルトで firewalld が使われるようになっている箇所を無効化しておく。

# iptables を使うので firewalld に関する設定内容を全てコメントアウトしておく
sed -i -e 's/^\([^#].*\)/#\1/;' /etc/fail2ban/jail.d/00-firewalld.conf

 fail2ban で BAN された IP からのアクセスは iptables で REJECT される。これでは相手に REJECT されたという結果が残ってしまうので DROP するように変更しておく。
 既存設定ファイル名の拡張子を .local とする事で .conf の内容をオーバーライド出来るのでこれ上手いこと利用しておく。

# BAN した IP はデフォルトでは REJECT なので DROP にしておく
cat << EOF > /etc/fail2ban/action.d/iptables-common.local
[Init]
blocktype = DROP
EOF

 最後に fail2ban 本体の設定を行っておく。
 以下内容を /etc/fail2ban/jail.local として新規作成する。
 メインは MTA 側の認証に関することなので postfix-sasl のフィルタを有効にしているが、MDA 側の dovecot のフィルタも念のため有効化している。

[DEFAULT]
destemail = hoge@example.com        # 通知先の E-Mail アドレス
sender    = hostmaster@example.com  # 送信元の E-Mail アドレス

ignoreip = 127.0.0.1/8 192.168.1.0/24 10.0.0.0/8
findtime = 3600                 # findtime [sec] 以内に
maxretry = 4                    # maxretry の回数検知されたら
bantime  = 86400                # bantime [sec] の間だけ BAN を行う
backend  = systemd
usedns   = yes

[postfix-sasl]
enabled = true
port    = smtp,465,submission,imap3,imaps,pop3,pop3s
logpath = /var/log/maillog
action  = %(action_)s

[dovecot]
enabled = true
port    = pop3,pop3s,imap,imaps,submission,465,sieve
logpath = /var/log/dovecot.log
action  = %(action_)s

 上記設定では「不正なアクセスと定義するフィルター」に 3,600 秒 (1 時間) 以内で 4 回引っかかったら 86,400 秒間 (1 日)、アクセスしてきた IP アドレスからのパケットを iptables で DROP するという動作にしている。

 フィルターの設定は次の通りで例として postfix-sasl の物で説明。

  • [postfix-sasl]
    /etc/fail2ban/filter.d/postfix-sasl.conf のフィルターを使用する。この場合 Postfix で使用している SASL 認証に関するフィルタ。
  • port
    listen しているポートを指定しておく。imaps, pop3, pop3s などは MDA 側の認証にも関わる為。
  • logpath
    監視するログファイルを指定する。fail2ban 自体で変数 %(postfix_log)s とログまでのパスが定義されているが、物によっては正しくないパスがあったので、絶対パスで明示する事とした。
  • action
    BAN を適用する際のアクションを指定出来る。
    %(action_)s にすると BAN 処理のみ
    %(action_mw)s にすると該当 IP アドレスと whois の結果を添えて E-Mail にて通知 & BAN
    %(action_mwl)s にすると該当 IP アドレスと whois 情報に加えて該当ログも添えて E-Mail 通知 & BAN

fail2ban の起動

 継続して使用するのでシステム起動時に自動起動するようにしてから起動を行った。

systemctl enable fail2ban.service
systemctl start fail2ban.service

fail2ban の状態確認

 fail2ban-client コマンドにフィルタ名を与えると、該当するフィルタに関する情報が得られる。
 次の実行結果は postfix-sasl フィルタで実際に BAN された IP も出ていたが伏せずにそのままとしてみた。

fail2ban-client status postfix-sasl
Status for the jail: postfix-sasl
|- Filter
|  |- Currently failed: 23
|  |- Total failed:     70
|  `- Journal matches:  _SYSTEMD_UNIT=postfix.service
`- Actions
   |- Currently banned: 4
   |- Total banned:     4
   `- Banned IP list:   185.234.217.94 185.234.219.22 193.169.252.52 80.82.70.189

その他

 筆者の場合、iptables の内容はシェルスクリプトで管理しているが同様な場合スクリプト内で iptables を restart する場面で同時に fail2ban もrestart しておかないと BAN する為の chain が見えなくなってエラーを吐くから要注意。
 要は fail2ban の動作中に iptables の内容を更新して再起動かけると fail2ban の chain がクリアされちゃうのが問題になるという事で。

おわりに

 fail2ban は各サーバーのログを読みつつ自身の DB に情報を貯める動作をするので若干負荷の高い挙動を示す事もあるそうだが、なにより自動制御で不正なアクセスをブロックできるので、「ログを眺めるのも怠くなってきた」とか「手動とかそもそもどうかと思う」場合には fail2ban を上手く活用してみると良いだろう。

導入後の様子

 fail2ban の導入直後はパラメータ調整をしたりで若干きつめの設定に変えてみた。だいたい人の MTA に向かって認証を要するアクセスをしてくるようなホストはどうでも良いだろうというのが理由。

 そしてその後の様子は監視ツールである Munin にグラフ化させているので伸びを見て楽しむ。

 導入後は右上がりに BAN されていくホストが増え、bantime が過ぎた当たりで unban されて解除。急降下したあとは BAN されてもしつこく自動化されたような不正アクセスが続き BAN されるホストが少しずつ増えていく感じに。
 しつこいホストに関しては recidive というフィルターを有効化し、fail2ban のログから BAN された IP を取得。別途定義したよりキツい bantime の間だけ BAN されるという仕組みにしてある感じに。

[recidive]
enabled = true
logpath = /var/log/fail2ban.log
action  = %(action_mw)s
bantime = 2419200
findtime = 604800
maxretry = 2

 1 週間以内に 2 度の BAN で 4 週間ほど BAN するという感じで。引っかかったホストは Whois 情報を付けてメール通知するような action とした。

 肝心な fail2ban 導入による効果は Logwatch でレポートされる Postfix SASL の認証失敗回数を見ると面白い。

 導入前

     7768   SASL authentication failed 
      219   Miscellaneous warnings

 導入後の本日 2018/11/01 のレポート

       40   SASL authentication failed 
      108   Miscellaneous warnings  

 効果てきめん。

スポンサーリンク