1 fail2banとは?
不正アクセスからサーバを守るツールです。
具体的には、ログファイルに記録される内容を監視して、何度も認証に失敗しているログや、
連続アクセスしているログを見つけると、ファイアーウォールを自動的に調整して、
接続元からの不正アクセスを禁止にします。
たとえば、sshのログイン失敗すると、/var/log/secure
に以下のログが記録されます。
fail2banは、このログを監視してsshログインに何度も失敗している接続元をアクセス禁止にします。
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台とも仮想マシンの版数は以下のとりです。
[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パッケージをインストールします。
[root@server ~]# dnf -y install epel-release
次に、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
を新規作成して、そこに記述するようです。
*.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
が以下のように定義されています。
下記抜粋には、コメント行は省略しています。
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
さらに、sshd_log
は以下のように定義されています。
sshd_log = %(syslog_authpriv)s
さらに、syslog_authpriv
は、/var/log/secure
と定義されています。
以上より、sshについては、jail.conf
で監視対象のログファイルが定義されているので、
jail.local
に監視対象のログファイルを定義することは不要となります。
syslog_authpriv = /var/log/secure
次に、fail2banを起動します。
[root@server ~]# fail2ban-client start
Server ready
fail2banの状態を確認します。
まだアクセス禁止(Banned IP list
)になっているIPアドレスはありません。
[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ログインパスワードを間違えてみます。
[root@client ~]# ssh 192.168.2.115
root@192.168.2.115's password:
Permission denied, please try again.
root@192.168.2.115's password:
Permission denied, please try again.
root@192.168.2.115's password:
Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
[root@client ~]# ssh 192.168.2.115
ssh: connect to host 192.168.2.115 port 22: Connection refused
fail2banの状態を確認します。
192.168.2.120
からのアクセスが禁止されたことがわかります。
[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
オプションを使って送信できます。
どちらのメソッドを使っても、アクセスが禁止されることが確認できます。
[root@client ~]# date;curl http://192.168.2.115
2021年 2月 4日 木曜日 21:55:45 JST
Hello
[root@client ~]# date;curl http://192.168.2.115
2021年 2月 4日 木曜日 21:55:46 JST
Hello
HTTPアクセスを実行する。この時点でリトライが2回目なので、
アクセス元はアクセス禁止になっています。
[root@client ~]# date;curl http://192.168.2.115
2021年 2月 4日 木曜日 21:55:46 JST
Hello
クライアントからのHTTPメッセージがファイアーウォールで拒否されている
ことがわかります。
[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の状態を確認します。
クライアントからのアクセス禁止が解除されたことがわかります。
[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コマンドの使い方を参照ください。
[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メソッドで
アクセスしていることがわかります。
[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グローバルアドレスによるアクセスが禁止されていることがわかります。
[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の状態を確認します。
クライアントからのアクセス禁止が解除されていることがわかります。
[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 参考情報
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の設定について
コメント