Fail2banのルールの書き方

ALL
スポンサーリンク

以前紹介した Fail2ban のルールの書き方です。

ルールを定義する際は次のように考えます。

「(a)どのログ」に「(b)どのような内容」が「(c)どのような頻度」で出力されたら攻撃と認識して「(d)指定のコマンド」を実行し、その後「(e)一定時間経過」したら「(f)指定のコマンド」を実行する。

例えば(a)-(f)を以下のようにすると、sshのパスワードミスが10分に3回起こった場合は、攻撃と判断して、接続をブロックし、その後10分経ったら解除する動作になります。

例)
(a) /var/log/auth.log
(b) Failed password for invalid user XXXXX from yy.yy.yy.yy
(c) 10分間に3回
(d) iptables -I INPUT 1 -s yy.yy.yy.yy -j DROP (接続元yy.yy.yy.yyをブロックする)
(e) 600秒
(f) iptables -D INPUT -s yy.yy.yy.yy -j DROP (接続元yy.yy.yy.yyのブロック解除する)

具体的に fail2ban のルールを作成する手順は、次の通りです。
下記の(a)-(f)は、先述の(a)-(f)です。

(1) フィルタ(攻撃と判定するログ内容の正規表現)を書く(b)
(2) アクション(攻撃認識時と、一定時間経過した際に、実行するコマンド)を書く(d)(f)
(3) (1)のフィルタと、(2)のアクションと、(a)(c)(e)を1組のルールとして jail を書く

以降で具体的に説明します。

スポンサーリンク

(1)フィルタを書く

フィルタとは、ログに現れたら攻撃と判定する文字列を記述したものです。
正規表現で記述します。

/etc/fail2ban/filter.d/フィルタ定義名.conf として用意します。
“フィルタ定義名” は任意に決めて良いです。”フィルタ定義名” は後述の jail を記述する際に指定します。

項目

[INCLUDES]
before =
after =

[Definition]
_daemon =
failregex =
ignoreregex =

項目の説明

    • before,after

このフィルタファイルの読み込み前・後に、読み込ませるフィルタファイルを指定します。

    • _daemon

デーモン名を指定します。この値は、before= でよく指定されているフィルタ common.conf 内の、 __prefix_line の定義で使用されています。
__prefix_line はログにおいて、時刻やサーバ名、ログレベル等の、ログ本文より前の部分を表す正規表現として定義されています。
通常、このような部分には sshd や smtpd といったサービス名が出力されていますので、_daemon を指定すると、そのようなサービス名のログだけを対象とすることができます。
例えば secure.log には sshdやdovecot等のログが記録されていますが、その中から sshd のログだけを対象にする場合は、
_daemon=sshd
before=common.conf
と指定します。

    • failregex

ログに現れたら攻撃と判定する文字列を、正規表現で書きます。
マッチングは部分一致で判定されます。
ログには接続元IPアドレスが含まれたりしますが、そのIPアドレス部分は <HOST> と記述します。
この <HOST> がブロック対象のIPアドレスになります。
複数条件がある場合は、改行して記述します。

    • ignoreregex

攻撃と認識させたくない文字列がある場合は、正規表現で指定します。

記述例

[INCLUDES]
before = common.conf
after = 
[Definition]
_daemon = sshd
failregex = ^%(__prefix_line)s(?:error: PAM: )?[aA]uthentication (?:failure|error|failed) for .* from <HOST>( via \S+)?\s*$
            ^%(__prefix_line)srefused connect from \S+ \(<HOST>\)\s*$
ignoreregex = 

記述したフィルタのテスト

次の書式で fail2ban-regex コマンドを実行します。
指定した “ログファイル名” に対して、”フィルタファイル名” で指定したフィルタを適用します。

fail2ban-regex ログファイル名 フィルタファイル名

次のように実行します。

fail2ban-regex /var/log/secure /etc/fail2ban/filter.d/sshd.conf

実行で表示される内容の内、下記のような行で、マッチした行数、マッチしなかった行数がわかります。

Lines: 182 lines, 0 ignored, 25 matched, 157 missed

マッチしなかった行の内容を出力する場合は、次のようにして fail2ban-regex を実行します。

fail2ban-regex /var/log/secure /etc/fail2ban/filter.d/sshd.conf –print-all-missed

マッチした行の内容を出力するには、次のようにします。

fail2ban-regex /var/log/secure /etc/fail2ban/filter.d/sshd.conf –print-all-matched

(2)アクションを書く

アクションとは、攻撃と判定した場合や、一定時間経過した際に、実行するコマンドです。

/etc/fail2ban/action.d/アクション名.conf に記述します。
“アクション名” は任意に決めて良いです。”アクション名” は後述の jail を記述する際に指定します。

項目

[INCLUDES]
before =

[Definition]
actionstart =
actionstop =
actioncheck =
actionban =
actionunban =

[Init]

項目の説明

    • actionstart =

Fail2Ban 開始時に実行させるコマンドを記述します。

    • actionstop =

Fail2Ban 終了時に実行させるコマンドを記述します。

    • actioncheck =

actionban,actionunbanの内容を実行する前に、実行するコマンドを記述します。
アクションを実行する準備が出来ているかの確認する必要がある場合に記述します。

    • actionban =

BANする時に実行されるコマンドを記述します。

    • actionunban =

UNBAN(BAN解除)する時に実行されるコマンドを記述します。

なお、<> でくくった箇所は、後述の jail で指定した値で置き換わります。
例えば、name=SSH, port=ssh, protocol=tcp とjailで指定されていた場合は、 が SSH に、 は ssh に、 は tcp と置き換わります。

記述例

[INCLUDES]
before = iptables-common.conf
[Definition]
actionstart = <iptables> -N f2b-<name>
              <iptables> -A f2b-<name> -j <returntype>
              <iptables> -I <chain> -p <protocol> -m multiport --dports <port> -j f2b-<name>
actionstop = <iptables> -D <chain> -p <protocol> -m multiport --dports <port> -j f2b-<name>
             <iptables> -F f2b-<name>
             <iptables> -X f2b-<name>
actioncheck = <iptables> -n -L <chain> | grep -q 'f2b-<name>[ \t]'
actionban = <iptables> -I f2b-<name> 1 -s <ip> -j <blocktype>
actionunban = <iptables> -D f2b-<name> -s <ip> -j <blocktype>
[Init]

(3)jail を書く

(1)のフィルタと、(2)のアクションを、1つの Fail2ban のルールとして記述します。

/etc/fail2ban/jail.conf や /etc/fail2ban/jail.d/*.conf 内に記述します。

項目

[ルール名]
enabled =
filter =
action =
logpath =
maxretry =
findtime =
bantime =
backend =

項目の説明

    • []

ルール名

    • enabled

true にすると有効になります。

    • logpath

チェック対象のログファイルを指定します。

    • filter

フィルタ定義名を指定します。
logpath で指定したファイルにどのような文字列が現れていたら攻撃と判定するのかを定義したフィルタファイルを指定します。
/etc/fail2ban/filter.d/フィルタ定義名.conf
今回の例では、filter = sshd なので、/etc/fail2ban/filter.d/sshd.conf が参照されます。
フィルタファイルの詳細については、先述の項目を参照してください。

    • action

アクション定義を指定します。
攻撃と判定された場合(フィルタへのマッチ)が一定期間内に一定回数起こった際に、実行するコマンドを指定します。
実行するコマンドは、/etc/fail2ban/action.d/アクション定義.conf に記述します。
今回の例では、/etc/fail2ban/action.d/iptables.conf が参照されます。

    • maxretry

一定時間内に、ここで指定した回数フィルタにマッチすると攻撃と判定し、アクションを実行します。

    • findtime

ここで指定した期間内に、maxretry 回数、filterで定義したフィルタに引っかかると、。秒で指定します。

    • bantime

ブロックする時間(秒)。マイナスの値を指定すると、永久になります。

    • backend

logpath で指定されたログファイルの変更を監視する方法を指定します。
下記が指定できます。
おそらく、ログファイルやシステム毎に適切なものがあるとは思いますが、私は、どれが適切かは良くわかっていません。
auto を指定してください。

      • pyinotify

pyinotify がインストールされている必要があります。インストールされていない場合は、auto が指定されたものとします。

      • gamin

gamin がインストールされている必要があります。インストールされていない場合は、auto が指定されたものとします。

      • polling

外部ライブラリは必要ありません。ポーリング(一定間隔で能動的にチェック)します。

      • systemd

systemd-journald を使用します。

      • auto

pyinotify、gamin、systemd が利用できる場合は使用されます。いずれも不可の場合は、polling が指定されます。

記述例

[ssh-iptables]
enabled  = true
filter   = sshd
action   = iptables[name=SSH, port=ssh, protocol=tcp]
logpath  = /var/log/auth.log
maxretry = 5
findtime = 86400
bantime  = 604800
backend = auto

以上、 Fail2ban のルールの書き方です。

参考

How Fail2Ban Works to Protect Services on a Linux Server | DigitalOcean
jail.conf – configuration for the fail2ban server – Linux Man Page (5)
しつこい攻撃を fail2ban でブロックする パソコン鳥のブログ
CentOS 6.5でfail2banを設定 | Works | URAMIRAIKANUbuntu Manpage: jail.conf – configuration for the fail2ban server
Commands – Fail2ban
fail2banのフィルタ作成【Qpopper, dovecot】|雲の上はいつも青空
What is the purpose of the _daemon directive in fail2ban? – Server Fault
MANUAL 0 8 – Fail2ban

コメント