LinuxでWebサーバーへの不正アクセスをFail2banで防ぐ方法

LinuxでWebサーバーへの不正アクセスをFail2banで防ぐ方法

インターネットに公開しているWebサーバーのセキュリティ対策の一つとして「不正アクセス対策」があります。

対策方法には、WAFやIPS機能を備えたネットワーク機器で対策したり、サーバーにセキュリティ対策ソフトを導入する方法などがありますが、ここでは、Linux上のWebサーバーへの不正アクセスを、Fail2banで防ぐ方法を紹介します。

Fail2banとは

Fail2banは、SSHサーバーやWebサーバーなどのネットワーク経由のサービスを提供するソフトウェアのログを監視して、不正なアクセスや過剰なアクセスを行っているIPアドレスをファイアウォールに登録して、自動的に遮断(BAN)してくれるセキュリティ対策ツールです。

Fail2banのインストール

まずは、以下のコマンドを順に実行してFail2banをインストールします。

「jwhois」は、アクセスを遮断したIPアドレスの詳細を調べる時に利用するソフトウェアです。

# yum install epel-release
# yum install --enablerepo=epel fail2ban fail2ban-systemd gamin-python
# yum install jwhois

Fail2banの設定

次に、フィルター設定ファイルとジェイル設定ファイルを作成します。

フィルター設定

フィルター設定では、監視するログのパターンを定義します。

fail2banには、よく利用されているアプリケーション向けのフィルターがデフォルトで用意されていますが、フィルター定義を自分で作成することもできます。

ここでは、監視するログのパターンとして、閲覧が禁止されているページへのアクセスや、不正なリクエストのログを定義します。

# vi /etc/fail2ban/filter.d/myfilter.conf

[Definition]
failregex = ^<HOST>.*\"(GET|POST).*\" (403|444) .*$
            ^<HOST>.*\" 400 .*$
ignoreregex =

フィルターの設定が完了したら、監視するログに対して作成したフィルターが機能しているかを、以下のコマンドで確認します。

コマンドの実行結果で「Match lines」に、監視したいログが抽出されていればOKです。

# fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/myfilter.conf  --print-all-matched

ジェイル設定

ジェイル設定では、フィルター設定で定義したパターンに一致するアクセスがあった場合の動作を定義します。

# vi /etc/fail2ban/jail.d/wordpress_jail.conf

[DEFAULT]
bantime  = 21600
findtime  = 3600
maxretry = 3
banaction = firewallcmd-ipset
backend = gamin
action = %(action_mwl)s
ignoreip = 127.0.0.1/8 192.168.1.0/24

[recidive]
enabled = true
banaction = firewallcmd-allports
bantime = 604800
findtime = 86400
maxretry = 2

[nginx]
enabled = true
port = http,https
filter = myfilter
logpath = /var/log/nginx/*access.log

上の定義内容は、次のとおりです。(時間の指定は「秒」で指定しています。)

「DEFAULT」セクションの設定

  • 1時間(findtime)に3回(maxretry)を超えてフィルターにマッチするアクセスを試みたIPアドレスを、6時間(bantime)BAN
  • BANする方法は、firewalldにipsetを使ってルール登録(banaction)
  • ログの監視方法(backend)は「gamin」を使用 ※ログローテーション等のタイミングで監視対象ログを追尾できなくなる場合を考慮し、gaminとしました。
  • 通知内容は「BANしたIPアドレス」「IPアドレスのWHOIS情報」「そのときに記録されたログ」(action)※既定の通知先はroot宛メールです。
  • 自分自身と、192.168.1.0/24のネットワークからのアクセスは監視の対象外(ignoreip)

「recidive」セクションの設定

  • この設定を有効化(enabled)
  • 1日に2回(maxretry)を超えてBANされたIPアドレスを、1週間(bantime)BANする設定 ※bantimeに「-1」を設定すると永久BANできます。
  • BANする方法は、firewalldを使ってすべてのポートを遮断するルールを登録(banaction)

「nginx」セクションの設定

  • この設定を有効化(enabled)
  • 使用ポートとしてHTTPとHTTPSを指定
  • フィルター「myfilter」を使用(filter)して、「/var/log/nginx/」ディレクトにあるファイル名の末尾が「access.log」のログファイルを監視(logpath)

recidiveを利用するときの追加設定

fail2banには、何回もBANされている悪質なIPアドレスに対して、長期間BANする設定[recidive]を定義でき、上の設定でも定義していますが、recidiveを利用するには、以下を追加設定する必要があります。

# vi /etc/fail2ban/fail2ban.local

[Definition]
loglevel = INFO ←DEBUG以外である必要があります。
dbpurgeage = 648000 ←少なくとも[recidive]セクションで定義しているbantimeの時間+0.5日分(43200秒)を指定します。

Fail2banの起動と自動起動設定

以下のコマンドを順に実行して、Fail2banを自動起動設定して、Fail2banを起動します。

# systemctl enable fail2ban
# systemctl start fail2ban
# systemctl status fail2ban

なお、環境にもよると思いますが、あらかじめログファイルを生成しておかないと、サービスを起動できないケースがあります。

そのような時は、以下のコマンドでからのログファイルを作成しておいてから、サービスを起動しましょう。

# touch  /var/log/fail2ban.log

Fail2banの動作確認

試しに、Webサーバー上の存在しないページや、閲覧が禁止されているページへアクセスを繰り返すと、設定どおり4回目でBANされていることがわかります。

# tail -f /var/log/fail2ban.log 

2018-03-20 19:40:13,162 fail2ban.filter         [237169]: INFO    [nginx] Found XXX.XXX.XXX.198
2018-03-20 19:40:18,169 fail2ban.filter         [237169]: INFO    [nginx] Found XXX.XXX.XXX.198
2018-03-20 19:40:19,171 fail2ban.filter         [237169]: INFO    [nginx] Found XXX.XXX.XXX.198
2018-03-20 19:40:20,002 fail2ban.actions        [237169]: NOTICE  [nginx] Ban XXX.XXX.XXX.198

アクセスが遮断(BAN)されているIPアドレスを確認するときは、以下のコマンドを実行します。

# fail2ban-client status <jail名>

アクセスが遮断(BAN)されているIPアドレスを解除するときは、以下のコマンドを実行します。

# fail2ban-client set <jail名> unbanip ***.****.***.***

あとがき

Fail2banは、Webサーバーだけでなくsshなどのネットワークサービスでも、IPアドレスベースでの不正アクセス対策に有効なツールです。ご活用あれ。