fail2ban
centos8
24
どのような問題がありますか?

この記事は最終更新日から1年以上が経過しています。

投稿日

更新日

fail2banの使い方

1 fail2banとは?

不正アクセスからサーバを守るツールです。
具体的には、ログファイルに記録される内容を監視して、何度も認証に失敗しているログや、
連続アクセスしているログを見つけると、ファイアーウォールを自動的に調整して、
接続元からの不正アクセスを禁止にします。
たとえば、sshのログイン失敗すると、/var/log/secureに以下のログが記録されます。
fail2banは、このログを監視してsshログインに何度も失敗している接続元をアクセス禁止にします。

/var/log/secureの抜粋
Jan 31 20:58:45 server unix_chkpwd[127841]: password check failed for user (root)
Jan 31 20:58:45 server sshd[127839]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.2.105  user=root
Jan 31 20:58:47 server sshd[127839]: Failed password for root from 192.168.2.105 port 55770 ssh2

2 環境

VMware Workstation 15 Player上の仮想マシン(2台)を使いました。
2台とも仮想マシンの版数は以下のとりです。

CentOSの版数
[root@server ~]# cat /etc/redhat-release
CentOS Linux release 8.3.2011
カーネル版数
[root@server ~]# uname -r
4.18.0-240.el8.x86_64

検証環境は以下のとおりです。
サーバで、fail2banを実行します。
クライアントでは、サーバに対してsshログインやcurlコマンドを実行します。

環境
              192.168.2.0/24
client --------------------------- server
    .120                        .115

3 インストール方法

3.1 fail2banのインストール

fail2banはepelリポジトリにあるので、まず、epel-releaseパッケージをインストールします。

epel-releaseのインストール
[root@server ~]# dnf -y install epel-release

次に、fail2banパッケージをインストールします。

fail2banのインストール
[root@server ~]# dnf -y install fail2ban

インストールしたfail2banの版数を確認します。

版数の確認
[root@server ~]# fail2ban-server --version
Fail2Ban v0.11.2
[root@server ~]# fail2ban-client --version
Fail2Ban v0.11.2
[root@server ~]# fail2ban-regex --version
fail2ban-regex 0.11.2
[root@server ~]# fail2ban-python --version
Python 3.6.8

3.2 Apacheのインストール

サーバにApacheをインストールします。

インストール
[root@server ~]# dnf -y install httpd

4 機能概要

4.1 fail2ban-server/fail2ban-client概要

fail2banパッケージをインストールすると、
依存関係のあるfail2ban-serverパッケージがインストールされます。
fail2ban-serverパッケージには、以下のコマンドがはいっています。

コマンド 概要
fail2ban-server システムに常駐して,ログファイルの監視や攻撃を受けた際の処理を行う
fail2ban-client fail2ban-serverの起動・停止や各種設定をおこなう。

4.2 設定ファイル

fail2banには、4つの設定ファイルがあります。

設定ファイル名 概要 備考
fail2ban.conf ログの格納場所やログレベルを指定する
filter.d/*.conf 正規表現を使ってアクセス違反を定義する
action.d/*.conf アクセス違反が発生したときの動作を定義する
jail.conf どの程度(時間、回数)アクセスがあったらブロックするかを定義する。 ただし、このファイルは編集しない(後述)

5 サーバの起動、停止方法

fail2ban-clientコマンドを使って、サーバの起動、停止をします。
なお、systemctlコマンドでも、サーバの起動、停止ができます。

サーバの起動方法
[root@server ~]# fail2ban-client start
Server ready

サーバを起動すると、以下のプロセスが生成されます。
・fail2ban-server:親プロセス
・f2b/observer:fail2ban-serverが生成するスレッド。
なお、psコマンドの使い方はpsコマンドの使い方を参照ください。

プロセスの状態
[root@server ~]# ps -LC fail2ban-server -o comm,pid,ppid
COMMAND             PID    PPID
fail2ban-server  125652       1
f2b/observer     125652       1
f2b/observer     125652       1
サーバの状態確認
[root@server ~]# fail2ban-client status
Status
|- Number of jail:      0
`- Jail list:
サーバの停止方法
[root@server ~]# fail2ban-client stop
Shutdown successful

6 設定ファイルのカスタマイズ方法

jail.confのmanを確認すると、以下の説明があります。
設定のカスタマイズはjail.confではなく、jail.localを新規作成して、そこに記述するようです。

jail.confのmanより抜粋
       *.conf  files  are  distributed  by  Fail2Ban.   It  is  recommended  that *.conf files should remain
       unchanged to ease upgrades.  If needed, customizations should be  provided  in  *.local  files.   For
       example,  if  you  would  like to enable the [ssh-iptables-ipset] jail specified in jail.conf, create
       jail.local containing

       jail.local
              [ssh-iptables-ipset]

              enabled = true

       In .local files specify only the settings you would like to change and the rest of the  configuration
       will then come from the corresponding .conf file which is parsed first.

7 実行例その1

10秒間で2回、sshログインに失敗すると、サーバに600秒間アクセス禁止にする、
という設定をしてみます。
アクセス禁止とは、ファイアーウォールでsshパケットをREJECTする、という意味です。

7.1 設定内容

jail.localを新たに作成します。設定内容は次のとおりです。
・アクセス禁止時間(bantime):600秒
・監視時間(findtime):10秒
・リトライ回数(maxRetry):1回

設定ファイル編集
[root@server ~]# vi /etc/fail2ban/jail.local
[root@server ~]# cat /etc/fail2ban/jail.local
[sshd]
enabled = true
bantime  = 600
findtime  = 10
maxretry = 1

上記jail.localに監視対象のログファイル(logpath)が設定されていませんが、
下記理由により設定不要です。
まず、jail.confのsshdの定義を確認します。logpathが以下のように定義されています。
下記抜粋には、コメント行は省略しています。

jail.confの抜粋
[sshd]
enabled = true
port    = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s

さらに、sshd_logは以下のように定義されています。

paths-common.confの抜粋
sshd_log = %(syslog_authpriv)s

さらに、syslog_authprivは、/var/log/secureと定義されています。
以上より、sshについては、jail.confで監視対象のログファイルが定義されているので、
jail.localに監視対象のログファイルを定義することは不要となります。

paths-fedora.confの抜粋
syslog_authpriv = /var/log/secure

次に、fail2banを起動します。

fail2banの起動
[root@server ~]# fail2ban-client start
Server ready

fail2banの状態を確認します。
まだアクセス禁止(Banned IP list)になっているIPアドレスはありません。

fail2banの状態確認
[root@server ~]# fail2ban-client status sshd
Status for the jail: sshd
|- Filter
|  |- Currently failed: 0
|  |- Total failed:     0
|  `- Journal matches:  _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
   |- Currently banned: 0
   |- Total banned:     0
   `- Banned IP list:

7.2 実行結果

クライアントからサーバにsshログインを実行します。
このとき、故意にsshログインパスワードを間違えてみます。

sshログイン失敗(1回目)
[root@client ~]# ssh 192.168.2.115
root@192.168.2.115's password:
Permission denied, please try again.
sshログイン失敗(2回目)
root@192.168.2.115's password:
Permission denied, please try again.
sshログイン失敗(3回目)
root@192.168.2.115's password:
Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
sshログイン失敗(4回目)
[root@client ~]# ssh 192.168.2.115
ssh: connect to host 192.168.2.115 port 22: Connection refused

fail2banの状態を確認します。
192.168.2.120からのアクセスが禁止されたことがわかります。

fail2banの状態確認
[root@server ~]# fail2ban-client status sshd
Status for the jail: sshd
|- Filter
|  |- Currently failed: 0
|  |- Total failed:     3
|  `- Journal matches:  _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
   |- Currently banned: 1
   |- Total banned:     1
   `- Banned IP list:   192.168.2.120

ファイアーウォールを確認すると、192.168.2.120から22番ポートへの
アクセス拒否(REJECT)が設定されていることがわかります。

ファイアーウォールの確認
[root@server ~]# nft list ruleset|grep -A2 filter_IN_public_deny
                jump filter_IN_public_deny
                jump filter_IN_public_allow
                jump filter_IN_public_post
--
        chain filter_IN_public_deny {
                ip saddr 192.168.2.120 tcp dport 22 ct state { new, untracked } reject
        }

クライアント(192.168.2.120)からサーバへのアクセスを許可します。

アクセス許可
[root@server ~]# fail2ban-client set sshd unbanip 192.168.2.120
1

fail2banの状態を確認します。
クライアント(192.168.2.120)からのアクセスが許可されたことがわかります。

状態確認
[root@server ~]# fail2ban-client status sshd
Status for the jail: sshd
|- Filter
|  |- Currently failed: 1
|  |- Total failed:     3
|  `- Journal matches:  _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
   |- Currently banned: 0
   |- Total banned:     1
   `- Banned IP list:

8 実行例その2

HTTP GETやHTTP HEADを連続して送信するアクセス元をアクセス禁止にしてみます。

8.1 設定

設定内容は以下のとおりです。
・監視ポート番号(port):80,443
・フィルタ(filter):http-get-dos.conf
・監視するファイル(logpath):/var/log/httpd/access_log
・アクセス禁止時間(bantime):600秒
・監視時間(findtime):10秒
・リトライ回数(maxRetry):2回

設定内容
[root@server ~]# vi /etc/fail2ban/jail.local
[root@server ~]# cat /etc/fail2ban/jail.local
[http-get-dos]
enabled = true
port = http,https
filter = http-get-dos
logpath   = /var/log/httpd/access_log
bantime = 600
findtime = 10
maxRetry = 2

フィルタの設定内容は次のとおりです。
/var/log/httpd/access_logに次の正規表現に合致するログが出力されたら、
接続元からのアクセス拒否します。
・HOST:行頭がホスト名、またはIPアドレス(IPv4,IPv6)
・GET|HEAD:HTTPメソッドがGETまたHEAD

フィルタの設定内容
[root@server ~]# cat /etc/fail2ban/filter.d/http-get-dos.conf
[Definition]
failregex = ^<HOST> -.*"(GET|HEAD).*
ignoreregex =

fail2banを起動します。

起動
[root@server ~]# fail2ban-client start
Server ready

fail2banの状態を確認します。

状態の確認
[root@server ~]# fail2ban-client status
Status
|- Number of jail:      1
`- Jail list:   http-get-dos

http-get-dosフィルタの詳細情報を確認してみます。

詳細の確認
[root@server ~]# fail2ban-client status http-get-dos
Status for the jail: http-get-dos
|- Filter
|  |- Currently failed: 0
|  |- Total failed:     0
|  `- File list:        /var/log/httpd/access_log
`- Actions
   |- Currently banned: 0
   |- Total banned:     0
   `- Banned IP list:

8.2 動作確認(IPv4)

ここでは、curlコマンドを使って、GETメソッドをサーバに送信してみます。
なお、HEADメソッドは、curlの-Iオプションを使って送信できます。
どちらのメソッドを使っても、アクセスが禁止されることが確認できます。

HTTPアクセス1回目
[root@client ~]# date;curl http://192.168.2.115
2021年  2月  4日 木曜日 21:55:45 JST
Hello
HTTPアクセス2回目(リトライ1回目)
[root@client ~]# date;curl http://192.168.2.115
2021年  2月  4日 木曜日 21:55:46 JST
Hello

HTTPアクセスを実行する。この時点でリトライが2回目なので、
アクセス元はアクセス禁止になっています。

HTTPアクセス3回目(リトライ2回目)
[root@client ~]# date;curl http://192.168.2.115
2021年  2月  4日 木曜日 21:55:46 JST
Hello

クライアントからのHTTPメッセージがファイアーウォールで拒否されている
ことがわかります。

HTTPアクセス4回目
[root@client ~]# date;curl http://192.168.2.115
2021年  2月  4日 木曜日 21:55:47 JST
curl: (7) Failed to connect to 192.168.2.115 port 80: 接続を拒否されました

10秒間でHTTPアクセスが2回あったもで、接続元をアクセス禁止にしたことがわかります。

[root@server ~]# fail2ban-client status http-get-dos
Status for the jail: http-get-dos
|- Filter
|  |- Currently failed: 1
|  |- Total failed:     8
|  `- File list:        /var/log/httpd/access_log
`- Actions
   |- Currently banned: 1
   |- Total banned:     2
   `- Banned IP list:   192.168.2.120
ファイアーウォールの確認
[root@server ~]# nft list ruleset|grep -A2 filter_IN_public_deny
                jump filter_IN_public_deny
                jump filter_IN_public_allow
                jump filter_IN_public_post
--
        chain filter_IN_public_deny {
                ip saddr 192.168.2.120 tcp dport 80 ct state { new, untracked } reject
                ip saddr 192.168.2.120 tcp dport 443 ct state { new, untracked } reject

クライアントからのアクセス禁止を解除します。

解除
[root@server ~]# fail2ban-client set http-get-dos unbanip 192.168.2.120
1

fail2banの状態を確認します。
クライアントからのアクセス禁止が解除されたことがわかります。

fail2banの状態確認
[root@server ~]# fail2ban-client status http-get-dos
Status for the jail: http-get-dos
|- Filter
|  |- Currently failed: 1
|  |- Total failed:     8
|  `- File list:        /var/log/httpd/access_log
`- Actions
   |- Currently banned: 0
   |- Total banned:     2
   `- Banned IP list:
ファイアウォールの確認
[root@server ~]# nft list ruleset|grep -A2 filter_IN_public_deny
                jump filter_IN_public_deny
                jump filter_IN_public_allow
                jump filter_IN_public_post
--
        chain filter_IN_public_deny {
        }

[root@server ~]#

8.3 動作確認(IPv6)

fail2banの設定内容は8.1と同じで、8.2と同様のことをIPv6環境で実施してみました。
図中の上がIPv6グローバルアドレス、下がIPv6リンクローカルアドレスです。

検証環境
client ---------------------------------------------------------------- server
240b:11:4462:b10:447:4605:e709:cb6d/64          240b:11:4462:b10:752e:3fc4:6e2c:14ab/64
fe80::d10b:8c2a:7fb4:d35/64                     fe80::6aaa:cac4:d1b2:6f6f/64

IPv6環境では、HEADメソッドをサーバに送信してみます。
curlコマンドの使い方は、curlコマンドの使い方を参照ください。

HEADメソッドによるアクセス
[root@client ~]# curl -I -g http://[240b:11:4462:b10:752e:3fc4:6e2c:14ab]
curl: (7) Failed to connect to 240b:11:4462:b10:752e:3fc4:6e2c:14ab port 80: 接続を拒否されました

ログファイルの左端は、クライアントのIPv6グルーバルアドレスです。
また、curlに-Iオプションを指定しているので、サーバにはHEADメソッドで
アクセスしていることがわかります。

access_logの確認
[root@server ~]# tail -f /var/log/httpd/access_log
240b:11:4462:b10:447:4605:e709:cb6d - - [08/Feb/2021:20:41:41 +0900] "HEAD / HTTP/1.1" 200 - "-" "curl/7.61.1"
240b:11:4462:b10:447:4605:e709:cb6d - - [08/Feb/2021:20:41:42 +0900] "HEAD / HTTP/1.1" 200 - "-" "curl/7.61.1"
240b:11:4462:b10:447:4605:e709:cb6d - - [08/Feb/2021:20:41:42 +0900] "HEAD / HTTP/1.1" 200 - "-" "curl/7.61.1"

fail2banの状態を確認します。
クライアントからのIPv6グローバルアドレスによるアクセスが禁止されていることがわかります。

fail2banの状態確認
[root@server ~]# fail2ban-client status http-get-dos
Status for the jail: http-get-dos
|- Filter
|  |- Currently failed: 1
|  |- Total failed:     3
|  `- File list:        /var/log/httpd/access_log
`- Actions
   |- Currently banned: 1
   |- Total banned:     1
   `- Banned IP list:   240b:11:4462:b10:447:4605:e709:cb6d
ファイアウォールの確認
[root@server ~]# nft list ruleset|grep -A2 filter_IN_public_deny
                jump filter_IN_public_deny
                jump filter_IN_public_allow
                jump filter_IN_public_post
--
        chain filter_IN_public_deny {
                ip6 saddr 240b:11:4462:b10:447:4605:e709:cb6d tcp dport 80 ct state { new, untracked } reject
                ip6 saddr 240b:11:4462:b10:447:4605:e709:cb6d tcp dport 443 ct state { new, untracked } reject

クライアントからのIPv6グルーバルアドレスによるアクセス禁止を解除します。

アクセス禁止の解除
[root@server fail2ban]# fail2ban-client set http-get-dos unbanip 240b:11:4462:b10:447:4605:e709:cb6d
1

fail2banの状態を確認します。
クライアントからのアクセス禁止が解除されていることがわかります。

fail2banの状態確認
[root@server fail2ban]# fail2ban-client status http-get-dos
Status for the jail: http-get-dos
|- Filter
|  |- Currently failed: 1
|  |- Total failed:     3
|  `- File list:        /var/log/httpd/access_log
`- Actions
   |- Currently banned: 0
   |- Total banned:     1
   `- Banned IP list:

Z 参考情報

Fail2ban

CentOS 7でfail2banを用いてApacheへのDDoSなどのアタックを検知・対象のIPアドレスをブロックする
Linux:fail2banで防ぐ「DoS/DDoS攻撃」対策
Protect Apache From Brute Force And DDoS Attacks Using Fail2ban
fail2ban
Fail2Ban Jails Management
How to Install and Use Fail2ban on RHEL 8 / CentOS 8
GNU bash の脆弱性 ~ shellshock 問題~ について

第96回 サイトの防御とFail2ban[その2]
Fail2banで不正なアクセスをブロック(BAN)してサーバを守る
DoS攻撃/DDoS攻撃からサーバーを守る方法(fail2banのススメ)
CentOS 7でFail2Banを使用してSSHを保護する
Configure Apache With Fail2Ban on Ubuntu 18.04
まんがでわかるLinux シス管系女子3 (日経BPパソコンベストムック)
fail2banの設定について

ユーザー登録して、Qiitaをもっと便利に使ってみませんか。
  1. あなたにマッチした記事をお届けします
    ユーザーやタグをフォローすることで、あなたが興味を持つ技術分野の情報をまとめてキャッチアップできます
  2. 便利な情報をあとで効率的に読み返せます
    気に入った記事を「ストック」することで、あとからすぐに検索できます
hana_shin
写真は淡路島SAから明石海峡大橋を撮影したものです.

コメント

この記事にコメントはありません。
あなたもコメントしてみませんか :)
ユーザー登録
すでにアカウントを持っている方はログイン
記事投稿イベント開催中
データに関する記事を書こう!
~
新人プログラマ応援 - みんなで新人を育てよう!
~
24
どのような問題がありますか?
ユーザー登録して、Qiitaをもっと便利に使ってみませんか

この機能を利用するにはログインする必要があります。ログインするとさらに下記の機能が使えます。

  1. ユーザーやタグのフォロー機能であなたにマッチした記事をお届け
  2. ストック機能で便利な情報を後から効率的に読み返せる
ユーザー登録ログイン
ストックするカテゴリー