Rocky LinuxとAlmaLinuxに Fail2ban をインストール 完全ガイド

Linux

<景品表示法に基づく表記> 本サイトのコンテンツには、商品プロモーションが含まれている場合があります。

インターネット上に公開するサーバーは、従来のファイアウォールやIDS/IPSでは防ぐことができない攻撃に対しても対策するのが当たり前になってきました。

動的フィルターとして動作するFail2Banのインストール手順を解説します。

  • Fail2Banって何?
  • IDS/IPSの代わりを探している
  • 動的ファイアウォールを構築したい

私は Rocky Linux を利用しています。「Rocky Linux (ロッキーリナックス)」と「AlmaLinux(アルマリナックス)」という Linux ディストリビューションは CentOS Linux の後継として RHEL(Red Hat Enterprise Linux)の完全クローンです。

Fail2Banってなに?

Fail2Banとは

Fail2Banとはログを監視し、不審なアクセスを検出すると通信を遮断(BAN)します。指定時間が経過したらブロックを自動的に解除(UNBAN)を実行してくれる便利なツールです。

fail2banは、サーバーのログファイルを監視し、不正なアクセスを自動的にブロックすることで、セキュリティを向上させるツールです。自動化されたブロックや拡張性の高さ、監視と通知機能、オープンソースの無料利用など、多くのメリットがあります。

Fail2Ban自体に遮断する機能はありません。iptablesやfirewalldと連携して遮断と解除を自動で実施します。

  • Fail2Banはログの分析と解析を実施する
  • Fail2Ban自体が通信遮断を行わない
  • 通信遮断はiptablesやFirewalldが行う

つまり、Fail2banはログを解析し不正アクセスを見つけたら、iptablesやfirewalldに命令を送り通信許可リストを自動的に更新します。通信の遮断・解除はデファクトスタンダートのiptablesやfirewalldに実施されるので、安定性がピカイチです。

Fail2Banがログを監査 > しきい値を検出 > ブロック(iptablesやfirewalldで遮断) > 指定時間経過でブロック解除

Fai2Banが再検知した場合、より厳しい条件で付加するルールを作成することもできます。

Fail2Banが提供している定義

Fail2Banは非常に多くの定義を最初から提供してくれます。不正アタックがよく行われる各種プロトコル(HTTP,HTTPS,SMTP,POP,IMAP,SSH,FTP,DNSなど)は標準でサポートしています。

雑感としてはログが出力でくるものは「何でも使える」って感じでしょうか。

3proxy.conf
apache-auth.conf
apache-badbots.conf
apache-botsearch.conf
apache-common.conf
apache-fakegooglebot.conf
apache-modsecurity.conf
apache-nohome.conf
apache-noscript.conf
apache-overflows.conf
apache-pass.conf
apache-shellshock.conf
assp.conf
asterisk.conf
bitwarden.conf
botsearch-common.conf
centreon.conf
common.conf
counter-strike.conf
courier-auth.conf
courier-smtp.conf
cyrus-imap.conf
directadmin.conf
domino-smtp.conf
dovecot.conf
dropbear.conf
drupal-auth.conf
ejabberd-auth.conf
exim-common.conf
exim-spam.conf
exim.conf
freeswitch.conf
froxlor-auth.conf
gitlab.conf
grafana.conf
groupoffice.conf
gssftpd.conf
guacamole.conf
haproxy-http-auth.conf
horde.conf
kerio.conf
lighttpd-auth.conf
mongodb-auth.conf
monit.conf
murmur.conf
mysqld-auth.conf
nagios.conf
named-refused.conf
nginx-botsearch.conf
nginx-http-auth.conf
nginx-limit-req.conf
nsd.conf
openhab.conf
openwebmail.conf
oracleims.conf
pam-generic.conf
perdition.conf
php-url-fopen.conf
phpmyadmin-syslog.conf
portsentry.conf
postfix.conf
proftpd.conf
pure-ftpd.conf
qmail.conf
recidive.conf
roundcube-auth.conf
screensharingd.conf
selinux-common.conf
selinux-ssh.conf
sendmail-auth.conf
sendmail-reject.conf
sieve.conf
slapd.conf
softethervpn.conf
sogo-auth.conf
solid-pop3d.conf
squid.conf
squirrelmail.conf
sshd.conf
stunnel.conf
suhosin.conf
tine20.conf
traefik-auth.conf
uwimap-auth.conf
vsftpd.conf
webmin-auth.conf
wuftpd.conf
xinetd-fail.conf
znc-adminlog.conf
zoneminder.conf

実際に利用できる定義は少ないのかもしれません。しかし、多くの定義が提供されているので、参考にしながらカスタマイズし自分に最適な定義を作ることが可能です。

Fail2Ban のインストール

Firewalldの設定

Fail2Ban自体は通信遮断を行わず、実際に遮断を行うのはiptablesやfirewalldです。Rocky Linux は firewalld がインストールされているのでサービスを起動させます。合わせてOSが起動した時に自動起動するように設定を行います。

# systemctl start firewalld
# systemctl enable firewalld

firewalld のデフォルト設定ではSSHしか通信許可されていません。

firewalld の動作状況を確認します。

# firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens160
  sources:
  services: dhcpv6-client ssh
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

必要に応じて対象プロトコルを追加してください。

Fail2Banのインストール

fail2ban は標準リポジトリでは提供されておらず、EPELリポジトリにて提供されています。はじめにEPELリポジトリを登録します。

# dnf install epel-release

EPELリポジトリを取り込んだら、fail2ban をインストールします。

# dnf install fail2ban

fail2ban のインストールが完了したらサービスの起動と自動起動の設定を行います。初期設定ではブロックする動作はありません。気にせず fail2ban 起動させてください。

# systemctl start fail2ban
# systemctl enable fail2ban

fail2ban のログが出力され状況を確認することができます。ログには遮断したプロトコルやIPなどが出力されるので、ログを追うことで経緯を調査できます。

/var/log/fail2ban.log

fail2ban.server   [48544]: INFO    --------------------------------------------------
fail2ban.server   [48544]: INFO    Starting Fail2ban v0.11.2
fail2ban.observer [48544]: INFO    Observer start...
fail2ban.database [48544]: INFO    Connected to fail2ban persistent database '/var/lib/fail2ban/fail2ban.sqlite3'

Fail2Ban 設定の作法について

fail2ban 設定の考え方

fail2ban の設定はちょっとクセがあります。

  • 設定ファイルを変更しない
  • 新規ファイル(.local)で設定変更を行う
  • セクション毎に設定を行う
  • パラメーター名が重複している
  • フィルターは個別ファイルにする

理屈さえ理解すれば簡単なので、お作法と理解して設定を行いましょう。

設定ファイルを変更しない(fail2ban.conf jail.conf)

バージョンアップを行うと、各種設定ファイルを上書きしてしまうようです。設定ファイルを新規作成してパラメーターを制御します。

/etc/fail2ban/fail2ban.local
/etc/fail2ban/jail.local

fail2ban は jail.local に記述されたパラメーターを jail.conf に上書きして動作します。よって変更が必要な部分だけ記入すれば動作します。

後から見ると、変更したい部分だけ設定が記載されているのでわかりやすいです。

セクション毎に設定を行う

[]で囲ったセクション(JAILルール名)に続いて、設定を記述するとセクションの設定になります。

[DEFAULT]
 bantime = 1h
・・・
[sshd]
 enabled = true
・・・
[apache-auth]
 port     = http,https
・・・

パラメーター名(port,logpath など)が重複しているので、別のセクションを変更してしまう時があるので気おつけてください。

フィルターは個別の設定ファイル

最近はプログラムはfail2banに限らず、設定を1つのファイルに詰め込まず、まとまり毎にファイルを作成するようになっています。

/etc/fail2ban/jail.d

/etc/fail2ban/jail.d の配下に設定ファイルを作成してください。

Fail2Ban の設定

fail2banの基本的な設定(fail2ban.local)

/etc/fail2ban/fail2ban.local (fail2ban.conf) は、ログ出力の場所や、ログレベルといった fail2ban 本体の設定を記述します。

[DEFAULT]
loglevel = INFO
logtarget = /var/log/fail2ban.log
syslogsocket = auto
socket = /var/run/fail2ban/fail2ban.sock
pidfile = /var/run/fail2ban/fail2ban.pid
dbfile = /var/lib/fail2ban/fail2ban.sqlite3
dbpurgeage = 1d
dbmaxmatches = 10

カスタマイズの必要性が無ければ、デフォルトのままで構いません。ログの出力先を変更した際は logrotate などのログローテーションにも修正を行ってください。

フィルターの基本的な共通設定(jail.local)

/etc/fail2ban/jail.local (jail.conf) はフィルターで検出したときの振る舞いを制御する設定ファイルです。

jail.local は共通設定になり、個別で動作を変えたい場合は個別のJAIL設定を記述して制御を行います。よって、個別のJAIL設定がなければ jail.local の設定がデフォルト値として反映します。

個別のJAIL設定(/etc/fail2ban/jail.d/)

/etc/fail2ban/jail.d/ に個別設定を記述します。jail.local と異なった設定で動作を変更することができます。

各パラメーターの説明

通信遮断の条件や動作について代表的なものを記載します。

例外設定 : ignoreip

通信遮断しないホストを「IPアドレス」「CIDR」形式で記述します。

[DEFAULT]
# "ignoreip" can be a list of IP addresses, CIDR masks or DNS hosts. Fail2ban
# will not ban a host which matches an address in this list. Several addresses
# can be defined using space (and/or comma) separator.

# 例外として除外IP
ignoreip = 127.0.0.1/8 192.168.0.0/16 172.18.1.1

例外として除外IPと認識されるとログに表示されます。

/var/log/fail2ban.log

fail2ban.filter : INFO    [apache-sqlinject] Ignore xxx.xxx.xxx.xxx by ip

セクションの有効・無効 : enabled

[]で囲ったセクション(JAILルール名)の有効・無効を制御します。

設定を有効にする場合は「1」または「true」、無効にする場合は「0」または「false」を指定します。

[sshd]
# 有効化
enabled = true

制御するポート : port

遮断するポートを制御します。「ニーモニック表示」か「ポート番号」で指定します。

# ニーモックの場合
port = http,https
# ポート番号の場合
port = 80,443

遮断に利用するフィルターとログファイル: filter logpath

ログから遮断情報を抽出するためのフィルターを指定します。指定するフィルターは /etc/fail2ban/filter.d/ に保存します。

# フィルター
filter = apache-sqlinject
# ログファイル
logpath = /var/log/httpd/access.log

遮断時間や監視の設定 : bantime findtime maxretry

フィルターで検出されたとき、挙動を制御する設定項目です。

[DEFAULT]
# "bantime" is the number of seconds that a host is banned.
# 遮断時間
bantime = 10m

# A host is banned if it has generated "maxretry" during the last "findtime"
# 監視時間
findtime = 10m

# "maxretry" is the number of failures before a host get banned.
# リトライ回数
maxretry = 5

メール通知の設定 : action

fail2ban が検知した時の通知に関する設定で3種類が提供されています。初期設定はログに出力されるだけでメール通知はありません。

[DEFAULT]
# 遮断した時のアクション
#「%(action_)s」:遮断のみ(デフォルト)
#「%(action_mw)s」:遮断してWhois情報を付加してメール通知
#「%(action_mwl)s」:遮断してWhois情報とログ情報を付加してメール通知
action = %(action_mwl)s

再検知した場合の設定 : recidive

fail2ban がトラフィックを検知し遮断しても、同じように通信が来る場合のための設定を行うことができます。

デフォルトでは無効化されているので有効化する必要があります。

[recidive]
# 有効化
enabled = true
# 遮断時間
bantime = 1w
# 監視時間
findtime = 1d

1日5回 fail2ban が遮断(BAN)すると、遮断期間を1週間に伸ばす動作になります。

設定が有効化されると、ログに出力されるようになります。

/var/log/fail2ban.log

fail2ban.jail [12804]: INFO Creating new jail 'recidive'
fail2ban.jail [12804]: INFO Jail 'recidive' uses poller {} ← recidiveの設定が有効化
fail2ban.jail [12804]: INFO Initiated 'polling' backend
fail2ban.filter [12804]: INFO maxRetry: 5
fail2ban.filter [12804]: INFO encoding: UTF-8
fail2ban.filter [12804]: INFO findtime: 86400 ← 1週間
fail2ban.actions [12804]: INFO banTime: 604800 ← 1日
fail2ban.filter [12804]: INFO Added logfile: '/var/log/fail2ban.log' (pos = 7423, hash = bcae681f5638050c4a7cf4c7553181d6)

フィルターの実例設定

SQLインジェクション対策のFail2Ban構成

今回は Fail2Ban をSQLインジェクション対策を目的に簡易WAFとして構築します。

SQLインジェクション対策は、プログラムコードの中にエスケープ処理、サニタイジングを組み込むのは当然なのですが、どうしても「抜け」が発生したり、動作しなかったりすることが出てします。

不正対策は多段で防御することで安全性を向上させます。SQLインジェクションを試みるトラフィックは、通信自体をDropしてしまいます。トラフィックが流れてこないことは最強の不正対策です。

関連記事 Fail2BanでSQLインジェクション対策(WAF)

fail2ban-regex コマンド(テストツール)

fail2ban フィルター動作テスト

フィルターが想定通りに動作するか、ログファイルと、作成したフィルターを利用して動作テストを行うことができます。

# fail2ban-regex [ログファイル] [フィルターファイル]
# fail2ban-regex /var/log/httpd/access.log /etc/fail2ban/filter.d/apache-sqlinject.conf

Running tests
=============

Use   failregex filter file : apache-sqlinject, basedir: /etc/fail2ban
Use         log file : /var/log/httpd/access.log
Use         encoding : UTF-8


Results
=======

Failregex: 5 total
|-  #) [# of hits] regular expression
|   1) [5] ^ -.*(union.*select|UNION.*SELECT|select.*from|delete.*from|update.*set|insert.*into|replace.*(value|set)|and(\+|%20)ascii%28substring|and(\+|%20)Length|union(\+|%20)all(\+|%20)select|and(\+|%20)1%3C1|and(\+|%20)1%3D1|and(\+|%20)1%3E1|and(\+|%20)%27.%27%3D%27|%2F\*%21[0-9]+((\+|%20)[0-9]*)?\*%2F)[^"]*HTTP[^"]*
`-

Ignoreregex: 0 total

Date template hits:
|- [# of hits] date format
|  [108236] Day(?P<_sep>[-/])MON(?P=_sep)ExYear[ :]?24hour:Minute:Second(?:\.Microseconds)?(?: Zone offset)?
`-

Lines: 108236 lines, 0 ignored, 5 matched, 108231 missed ← 5件のログがマッチ
[processed in 34.43 sec]

動作テストとしてSQLインジェクションと認識するアクセスをブラウザから実施しました。その時のApacheのログをfail2ban-regexコマンドに読み込ませて解析したところ、想定通りSQLインジェクションとして認識しました。

fail2ban-client コマンド

fail2ban-client コマンドが出来ること

fail2ban-client コマンドは、稼働中Fail2Banのステータスを確認したり、手動で遮断・解除したりと色々できます。色々なことができるのでよく利用するコマンドを解説します。

もっと詳細を知りたい場合はヘプルを参照してください。

# fail2ban-client -h

 

動作中 JAIL ルール一覧

稼働中Fail2BanのJAILルールを確認したい場合には引数に [status] を与えます。

# fail2ban-client status
# fail2ban-client status 
Status
|- Number of jail: 1
`- Jail list: apache-sqlinject, sshd

JAILルールの apache-sqlinject, sshd が動作していることが確認できます。

動作中 JAIL ルールの個別ステータス

個別のJAILルールの状態について、もっと詳細を知りたい場合は、対象をしていすると詳細を確認することができます

# fail2ban-client status [JAILルール名]
# 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:

 

手動による遮断と解除

手動による遮断ブロック(BAN)

手動で通信遮断する際には fail2ban-client コマンドを利用してBANします。

# fail2ban-client set [JAILルール名] banip [IPアドレス]
# fail2ban-client set sshd xxx.xxx.xxx.xxx 

手動でBANしたあとは、fail2ban-client status [JAILルール名] で状態を確認してください。

手動によるブロック解除(UNBAN)

JAILルールの個別解除

手動で通信遮断を解除する際には fail2ban-client コマンドを利用してUNBANします。

# fail2ban-client set [JAILルール名] unbanip [IPアドレス]
# fail2ban-client set sshd unbanip xxx.xxx.xxx.xxx

手動でBANしたあとは、fail2ban-client status [JAILルール名] で状態を確認してください。

JAILルールの一括解除

手動で通信遮断を解除する際には fail2ban-client コマンドを利用してUNBANします。

# fail2ban-client unban --all

手動でBANしたあとは、fail2ban-client status [JAILルール名] で状態を確認してください。

あとがき

fail2banは、IPアドレスをブロックするためのセキュリティソフトです。主にSSHやFTP、Webサーバーなどのログイン認証の保護に使用されます。

fail2banは、ログファイルを監視し、定義された規則に基づいて、IPアドレスが一定回数のログイン失敗をした場合に、そのIPアドレスを自動的にブロックすることができます。規則はユーザーが定義することができ、ログファイルの種類やログインの失敗回数、ブロック時間などを指定することができます。

ログファイルを利用してブロックさせることができるので、利用用途は無限大に広がります。