Linuxサーバー上のサービスを保護するためのFail2Banの仕組み
序章
インターネットに公開されているサービスは、悪意のある第三者からの攻撃を受けやすくなっています。 サービスに認証が必要な場合、不正なユーザーとボットは、異なる資格情報を使用して認証を繰り返し試行することにより、システムに侵入しようとします。
この一般的な例はSSHの場合です。これは、一般的なアカウント名をブルートフォースしようとするボット攻撃の対象になります。 幸い、 fail2ban のようなサービスは、これらの攻撃を軽減するために作成されました。
Fail2banは、ファイアウォールルールを動的に変更して、特定の回数のログインに失敗したアドレスを禁止することで機能します。 以前のガイドでは、 Ubuntu14.04でfail2banを起動して実行する方法について説明しました。
このガイドでは、fail2banが実際にどのように機能するか、およびこの知識を使用してこのサービスの動作を変更または拡張する方法について詳しく説明します。
基本的な考え方
fail2banの背後にある基本的な考え方は、一般的なサービスのログを監視して、認証の失敗のパターンを見つけることです。
fail2banがサービスのログを監視するように構成されている場合、そのサービスに固有に構成されているfilterを調べます。 このフィルターは、複雑な正規表現を使用して、その特定のサービスの認証の失敗を識別するように設計されています。 これらの正規表現パターンをfailregexという変数に定義します。
幸い、fail2banには一般的なサービスのフィルターファイルが含まれています。 サービスのログファイルの行がフィルターのfailregexと一致すると、そのサービスに対して定義されたactionが実行されます。 actionは、管理者の設定に応じて、さまざまなことを実行するように構成できる変数です。
デフォルトのアクションは、iptablesファイアウォールルールを変更することにより、問題のあるホスト/IPアドレスを禁止することです。 このアクションを拡張して、攻撃者のwhoisレポートまたはアクションをトリガーしたログ行を含む電子メールを管理者に送信することもできます。
アクションターゲットを通常のiptables以外のものに変更することもできます。 これは、作成するのと同じくらい複雑または単純にすることができ、さまざまなファイアウォール構成ファイルと通知オプションを使用できます。
デフォルトでは、10分間に3つの認証失敗が検出されたときにアクションが実行され、デフォルトの禁止時間は10分間です。 禁止をトリガーするために必要な認証失敗の数のデフォルトは、デフォルト構成ファイルのSSH部分でオーバーライドされ、禁止が行われる前に6回の失敗を許可します。 これは、管理者が完全に構成できます。
SSHトラフィックにデフォルトのiptablesターゲットを使用する場合、fail2banは、サービスの開始時に新しいチェーンを作成します。 これは、ポート22に向けられたすべてのTCPトラフィックを新しいチェーンに送信する新しいルールをINPUTチェーンに追加します。 新しいチェーンでは、INPUTチェーンに戻る単一のルールを挿入します。
これにより、トラフィックは新しいチェーンにジャンプし、すぐに戻ります。 これは、開始時のトラフィックには影響しません。 ただし、IPが認証失敗のしきい値に達すると、問題のあるIPからのトラフィックをドロップするルールが新しいチェーンの最上位に追加されます。 これにより、実際の禁止が処理されます。 禁止期間が終了すると、iptablesルールが削除されます。 fail2banサービスが終了すると、チェーンと関連するルールは削除されます。
Fail2banサービス設定の調査
Fail2banは、/etc/fail2ban/ディレクトリの下の階層内にあるさまざまなファイルを介して構成されます。
fail2ban.confファイルは、デーモンが情報をログに記録する方法や、デーモンが使用するソケットとpidファイルなどの基本的な操作設定を構成します。 ただし、主な構成は「jail」を定義するファイルで行われます。
デフォルトでは、fail2banにはjail.confファイルが付属しています。 ただし、これはアップデートで上書きされる可能性があるため、ユーザーはこのファイルをjail.localファイルにコピーし、そこで調整することをお勧めします。
すでにjail.localファイルがある場合は、今すぐ開いてフォローしてください。
sudo nano /etc/fail2ban/jail.local
jail.localファイルがまだない場合、または開いたファイルが空白の場合は、jail.confファイルをコピーして、新しいファイルを開きます。
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local sudo nano /etc/fail2ban/jail.local
ここで利用可能なオプションを見て、このファイルがシステム上の他の構成ファイルとどのように相互作用するかを確認します。
デフォルトセクション
ファイルの最初の部分は、fail2banポリシーのデフォルトを定義します。 これらのオプションは、個々のサービスの構成セクションでオーバーライドできます。
コメントを削除すると、デフォルトのセクション全体が次のようになります。
[DEFAULT]
ignoreip = 127.0.0.1/8
bantime = 600
findtime = 600
maxretry = 3
backend = auto
usedns = warn
destemail = root@localhost
sendername = Fail2Ban
banaction = iptables-multiport
mta = sendmail
protocol = tcp
chain = INPUT
action_ = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
action_mw = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
%(mta)s-whois[name=%(__name__)s, dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s", sendername="%(sendername)s"]
action_mwl = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
%(mta)s-whois-lines[name=%(__name__)s, dest="%(destemail)s", logpath=%(logpath)s, chain="%(chain)s", sendername="%(sendername)s"]
action = %(action_)s
これが実際に何を意味するのかを見てみましょう。
- ignoreip :このパラメーターは、禁止システムによって無視されるべきIPアドレスを識別します。 デフォルトでは、これはマシン自体からのトラフィックを無視するように設定されています。これは非常に適切な設定です。
- bantime :このパラメーターは、禁止の長さを秒単位で設定します。 デフォルトは600秒、つまり10分です。
- findtime :このパラメーターは、失敗した認証試行の繰り返しを探すときにfail2banが注意を払うウィンドウを設定します。 デフォルトは600秒(再び10分)に設定されています。これは、ソフトウェアが過去10分間に失敗した試行の数をカウントすることを意味します。
- maxretry :これは、禁止が開始される前に
findtimeウィンドウ内で許容される失敗した試行の数を設定します。 - backend :このエントリは、fail2banがログファイルを監視する方法を指定します。
autoの設定は、fail2banがpyinotify、gamin、そして利用可能なものに基づくポーリングアルゴリズムを試行することを意味します。 - usedns :これは、禁止の実装を支援するために逆引きDNSを使用するかどうかを定義します。 これを「no」に設定すると、ホスト名ではなくIP自体が禁止されます。 「警告」設定は、逆引きDNSを使用してホスト名を検索し、その方法で禁止しようとしますが、レビューのためにアクティビティをログに記録します。
- destemail :これは、アラートをメールで送信するようにアクションを構成した場合に通知メールが送信されるアドレスです。
- sendername :これは、生成された通知メールの[Emailfrom]フィールドで使用されます
- banaction :しきい値に達したときに使用されるアクションを設定します。 実際には、
/etc/fail2ban/action.d/にあるiptables-multiport.confというファイルの名前があります。 これは、IPアドレスを禁止するための実際のiptables操作を処理します。 これについては後で説明します。 - mta :これは通知メールの送信に使用されるメール転送エージェントです。
- protocol :これは、IP禁止が実装されたときにドロップされるトラフィックのタイプです。 これは、新しいiptablesチェーンに送信されるトラフィックのタイプでもあります。
- chain :これは、トラフィックをfail2banファネルに送信するためのジャンプルールで構成されるチェーンです。
残りのパラメーターは、指定できるさまざまなアクションを定義します。 これらは、次のような文字列補間を使用して、上記で定義したパラメータの一部を渡します。
%(var_name)s
上記の行は、var_nameの内容に置き換えられます。 これを使用すると、action変数がデフォルトでaction_定義に設定されていることがわかります(禁止のみ、メールアラートなし)。
これは、禁止を実行するために必要なパラメーター(サービス名、ポート、プロトコル、およびチェーン)のリストを使用してiptables-multiportアクションを呼び出すことによって構成されます。 __name__は、以下のセクションヘッダーで指定されているサービスの名前に置き換えられます。
サービス固有のセクション
デフォルトのセクションの下には、デフォルト設定を上書きするために使用できる特定のサービスのセクションがあります。 これは、通常の値から外れたパラメーターのみを変更するという慣習に従います(設定より規約)。
各セクションヘッダーは次のように指定されます。
[ service_name ]
この行があるセクションはすべて読み取られ、有効になります。
enabled = true
各セクション内で、ログの解析に使用する必要のあるフィルターファイル(ファイル拡張子を除く)やログファイル自体の場所などのパラメーターが構成されます。
これを念頭に置いて、SSHサービスのアクションを指定するセクションは次のようになります。
[SSH] enabled = true port = ssh filter = sshd logpath = /var/log/auth.log maxretry = 6
これにより、このセクションが有効になり、ポートが「ssh」ポート(ポート22)に設定されます。 これは、fail2banに、このセクションの/var/log/auth.logにあるログを調べ、sshd.confというファイルの/etc/fail2ban/filters.dディレクトリで定義されたフィルタリングメカニズムを使用してログを解析するように指示します。
必要な他のすべての情報は、[DEFAULT]セクションで定義されたパラメーターから取得されます。 たとえば、アクションはaction_に設定され、/etc/fail2ban/action.dにあるiptables-multiport.confというファイルを参照するiptables-multiportbanactionを使用して問題のIPアドレスを禁止します。 ]。
ご覧のとおり、[DEFAULT]セクションのアクションは一般的で柔軟でなければなりません。 賢明なデフォルトを提供するパラメーターとともにパラメーター置換を多用すると、必要に応じて定義を簡単にオーバーライドできます。
フィルタファイルの調査
構成で何が起こっているかを理解するには、作業の大部分を実行するフィルターファイルとアクションファイルを理解する必要があります。
フィルタファイルは、fail2banがログファイルで検索する行を決定して、問題のある特性を識別します。 アクションファイルは、サービスの開始時にファイアウォール構造を構築することから、ルールを追加および削除すること、サービスが停止するときにファイアウォール構造を破棄することまで、必要なすべてのアクションを実装します。
上記の構成でSSHサービスが要求したフィルターファイルを見てみましょう。
sudo nano /etc/fail2ban/filter.d/sshd.conf
[INCLUDES]
before = common.conf
[Definition]
_daemon = sshd
failregex = ^%(__prefix_line)s(?:error: PAM: )?[aA]uthentication (?:failure|error) for .* from <HOST>( via \S+)?\s*$
^%(__prefix_line)s(?:error: PAM: )?User not known to the underlying authentication module for .* from <HOST>\s*$
^%(__prefix_line)sFailed \S+ for .*? from <HOST>(?: port \d*)?(?: ssh\d*)?(: (ruser .*|(\S+ ID \S+ \(serial \d+\) CA )?\S+ %(__md5hex)s(, client user ".*", client host ".*")?))?\s*$
^%(__prefix_line)sROOT LOGIN REFUSED.* FROM <HOST>\s*$
^%(__prefix_line)s[iI](?:llegal|nvalid) user .* from <HOST>\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because not listed in AllowUsers\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because listed in DenyUsers\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because not in any group\s*$
^%(__prefix_line)srefused connect from \S+ \(<HOST>\)\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because a group is listed in DenyGroups\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because none of user's groups are listed in AllowGroups\s*$
ignoreregex =
これは非常に複雑に見えます。 それはかなり複雑だからです。 これを少し分解してみましょう。
[INCLUDES]セクションヘッダーは、このファイルの前または後に読み込まれる他のフィルターファイルを指定します。 この例では、common.confファイルが読み込まれ、このファイルの他の行の前に配置されます。 これにより、構成で使用するいくつかのパラメーターが設定されます。
次に、フィルター一致の実際のルールを定義する[Definition]セクションがあります。 まず、_daemonパラメーターを使用して、監視しているデーモンの名前を設定します。
その後、実際のfailregex定義を確認します。これにより、ログファイルで一致する行が見つかったときにトリガーされるパターンが設定されます。 これらは、ユーザーが正しく認証されなかった場合にスローされる可能性のあるさまざまなエラーや失敗に基づいて一致する正規表現です。
%(__prefix_line)sのような行の一部は、ソースしたcommon.confファイルのパラメーター設定の値に置き換えられます。 これは、オペレーティングシステムが標準的な方法を使用するときにログファイルに書き込むさまざまな主要情報を照合するために使用されます。 たとえば、/var/log/auth.logの一部の行は次のようになります。
5月6日18:18:52localhostsshd [3534]: pam_unix(sshd:auth):認証に失敗しました。 logname = uid = 0 euid = 0 tty = ssh ruser = rhost = 101.79.130.213 May 6 18:18:54 localhost sshd [3534]: 101.79.130.213ポート38354 ssh2 May 6 18:18からの無効なユーザーphilのパスワードが失敗しました: 54 localhost sshd [3534]: 101.79.130.213からの切断を受信しました:11:Bye Bye [preauth]
赤で表示されている部分は、オペレーティングシステムがより多くのコンテキストを提供するために挿入する標準パターンです。 その後、iptablesサービスが失敗の試みをログに書き込む方法はかなりあります。
上記の最初の2行に2つの別々の失敗があります(PAM認証エラーとパスワードエラー)。 フィルタで定義された正規表現は、考えられる障害ラインのいずれかに一致するように設計されています。 これらの行を調整する必要はありませんが、自分でフィルターファイルを作成する必要がある場合は、保護しようとしているアプリケーションの不正使用エラーを示すすべてのログエントリをキャッチする必要があることに注意してください。 。
下部に、現在空白のignoreregexパラメーターが表示されます。 これを使用して、特定のシナリオでfail2banの失敗トリガーを無効にする場合に、通常は失敗条件に一致する、より具体的なパターンを除外できます。 これは調整しません。
調べ終わったら、ファイルを保存して閉じます。
アクションファイルの調査
それでは、アクションファイルを見てみましょう。 このファイルは、悪意のあるホストを禁止するための簡単な変更を可能にする構造でファイアウォールを設定し、必要に応じてそれらのホストを追加および削除する役割を果たします。
ご存知のとおり、SSHサービスが呼び出すアクションはiptables-multiportと呼ばれます。 関連するファイルを今すぐ開きます。
sudo nano /etc/fail2ban/action.d/iptables-multiport.conf
コメントを削除すると、このファイルは次のようになります。
[INCLUDES]
before = iptables-blocktype.conf
[Definition]
actionstart = iptables -N fail2ban-<name>
iptables -A fail2ban-<name> -j RETURN
iptables -I <chain> -p <protocol> -m multiport --dports <port> -j fail2ban-<name>
actionstop = iptables -D <chain> -p <protocol> -m multiport --dports <port> -j fail2ban-<name>
actioncheck = iptables -n -L <chain> | grep -a 'fail2ban-<name>[ \t]'
actionban = iptables -I fail2ban-<name> 1 -s <ip> -j <blocktype>
actionunban = iptables -D fail2ban-<name> -s <ip> -j <blocktype>
[Init]
name = default
port = ssh
protocol = tcp
chain = INPUT
このファイルは、iptables-blocktype.confという別のアクションファイルを調達することから始まります。このファイルは、クライアントが禁止されたときに設定される制限を構成するblocktypeパラメーターを定義するだけです。 デフォルトでは、blocktypeはパケットを拒否し、禁止されたクライアントから送信されたpingに、ポートに到達できないという拒否メッセージで応答するように設定されています。 これを以下の禁止規則で使用します。
次に、ルール定義自体について説明します。 アクションはかなり簡単です。 actionstartアクションは、fail2banサービスの開始時にiptablesファイアウォールを設定します。 新しいチェーンを作成し、そのチェーンにルールを追加して呼び出し元のチェーンに戻し、INPUTチェーンの先頭に、正しいプロトコルとポートの宛先に一致するトラフィックを新しいチェーンに渡すルールを挿入します。
これは、jail.localファイルで定義したactionで渡した値を使用して行われます。 nameは各サービスのセクションヘッダーから取得され、chain、protocol、およびportはaction行から取得されますそのファイル内のそれ自体。
これらは、そのファイルのotherの場所に設定されたotherパラメーターを補間することにより、アクションラインに追加されたことを思い出してください。 この時点で、fail2banが構成ファイルのさまざまな部分の間で多くのパラメーターを渡し、変換していることに気付いているかもしれません。
ここで、他のファイルによって設定されたすべてのパラメーターは、山括弧内にパラメーター名を含めることによって参照されます。
< param_name >
コンパニオンのactionstop定義に移動すると、ファイアウォールコマンドがactionstartコマンドの反転を実装していることがわかります。 fail2banサービスを停止するときに、作成したファイアウォール構造を破棄します。
actioncheckと呼ばれる別のアクションは、禁止ルールを追加する前に、適切なチェーンが作成されていることを確認します。
次に、actionbanと呼ばれる実際の禁止ルールについて説明します。 このルールは、作成したチェーンに新しいルールを追加することで機能します。 ルールは、問題のあるクライアントの送信元IPアドレスと一致し(このパラメーターは、maxretry制限に達したときに認証ログから読み込まれます)、ソースしたblocktypeパラメーターで定義されたブロックを設定します。ファイル上部の[INCLUDE]セクションにあります。
actionunbanルールは、このルールを削除するだけです。 これは、禁止時間が経過すると、fail2banによって自動的に実行されます。
最後に、[Init]セクションに移動します。 これは、適切な値をすべて渡さずにアクションファイルが呼び出された場合に備えて、いくつかのデフォルトを提供するだけです。
Fail2banサービスが構成ファイルを処理して禁止を実装する方法
詳細を確認したので、fail2banの開始時に発生するプロセスを見ていきましょう。
初期構成ファイルのロード
まず、メインのfail2ban.confファイルを読み取って、メインプロセスが動作する条件を決定します。 必要に応じてソケット、pid、およびログファイルを作成し、それらの使用を開始します。
次に、fail2banはjail.confファイルを読み取って構成の詳細を確認します。 これに続いて、[X104X]ディレクトリで.confで終わるファイルをアルファベット順に読み取ります。 これらのファイルにある設定を内部構成に追加し、jail.confファイルに記述されている値よりも新しい値を優先します。
次に、jail.localファイルを検索し、このプロセスを繰り返して、新しい値を調整します。 最後に、jail.dディレクトリを再度検索し、.localで終わるアルファベット順のファイルを読み取ります。
このように、fail2banには、プロセスの最終的な動作を操作するために使用できるファイルが多数あることがわかります。 この例では、jail.confファイルとjail.localファイルしかありません。 jail.localファイルでは、jail.confファイルとは異なる値を定義するだけで済みます。
fail2banプロセスには、検出されたすべてのファイルの組み合わせを表す一連のディレクティブがメモリにロードされるようになりました。
各セクションを調べて、enabled = trueディレクティブを検索します。 見つかった場合は、そのセクションで定義されたパラメーターを使用してポリシーを作成し、必要なアクションを決定します。 サービスのセクションにないパラメーターは、[DEFAULT]セクションで定義されたパラメーターを使用します。
アクションファイルを解析して開始アクションを決定する
Fail2banは、actionディレクティブを探して、禁止/禁止解除ポリシーを実装するために呼び出すアクションスクリプトを特定します。 見つからない場合は、上記で決定されたデフォルトのアクションにフォールバックします。
アクションディレクティブは、読み取られるアクションファイルの名前と、それらのファイルに必要なパラメータを渡すキー値ディクショナリで構成されます。 これらの値は、多くの場合、サービスのセクションで構成された設定を参照することにより、パラメーター置換の形式を取ります。 「name」キーには通常、セクションのヘッダーの値に設定される特別な__name__変数の値が渡されます。
次に、Fail2banはこの情報を使用して、action.dディレクトリ内の関連ファイルを検索します。 最初に.confで終わる関連アクションファイルを探し、次にaction.dディレクトリにある付随する.localファイルに含まれる設定でそこで見つかった情報を修正します。
これらのファイルを解析して、今実行する必要のあるアクションを決定します。 actionstart値を読み取り、環境をセットアップするために実行する必要のあるアクションを確認します。 これには、将来の禁止ルールに対応するためのファイアウォール構造の作成が含まれることがよくあります。
このファイルで定義されているアクションは、actionディレクティブから渡されたパラメーターを使用します。 これらの値を使用して、適切なルールを動的に作成します。 特定の変数が設定されていない場合は、アクションファイルに設定されているデフォルト値を調べて空白を埋めることができます。
フィルタファイルを解析してフィルタリングルールを決定する
jail.*ファイルのサービスのパラメーターには、ログファイルの場所と、ファイルのチェックに使用する必要のあるポーリングメカニズムも含まれます(これはbackendパラメーターで定義されます)。 。 また、ログの行が障害を表すかどうかを判断するために使用する必要があるフィルターも含まれています。
Fail2banは、filter.dディレクトリを調べて、.confで終わる一致するフィルタファイルを見つけます。 このファイルを読み取って、問題のある行を照合するために使用できるパターンを定義します。 次に、.localで終わる一致するフィルターファイルを検索して、デフォルトのパラメーターのいずれかが上書きされていないかどうかを確認します。
サービスのログファイルを読み取るときに、これらのファイルで定義されている正規表現を使用します。 filter.dファイルで定義されている各failregex行を、サービスのログファイルに書き込まれるすべての新しい行に対して試行します。
正規表現が一致を返す場合、ignoreregexで定義された正規表現に対して行をチェックします。 これも一致する場合、fail2banはそれを無視します。 行がfailregexの式と一致するが、がignoreregexの式と一致しない場合、行と関連するクライアントの内部カウンターがインクリメントされます。イベントのタイムスタンプが作成されます。
jail.*ファイルのfindtimeパラメーターによって設定された時間枠に達すると(イベントのタイムスタンプによって決定されるように)、内部カウンターが再びデクリメントされ、イベントは関連性があるとは見なされなくなります。禁止ポリシー。
時間の経過とともに追加の認証失敗がログに記録される場合、試行するたびにカウンターが増加します。 設定された時間枠内にカウンタがmaxretryパラメータで設定された値に達すると、fail2banは、action.d/で定義されているサービスのactioncheckアクションを呼び出して禁止を開始します。サービスのファイル。 これは、actionstartアクションが必要な構造を設定したかどうかを判別するためのものです。 次に、actionbanアクションを呼び出して、問題のあるクライアントを禁止します。 このイベントのタイムスタンプも設定します。
bantimeパラメーターで指定された時間が経過すると、fail2banはactionunbanアクションを呼び出してクライアントの禁止を解除します。
fail2banサービスが停止すると、actionstopアクションを呼び出して作成したファイアウォールルールを破棄しようとします。 これにより、通常、fail2banルールを含むチェーンが削除され、トラフィックがそのチェーンにジャンプする原因となったルールがINPUTチェーンから削除されます。
結論
うまくいけば、これまでに、fail2banがどのように動作するかについてかなり深く理解しているはずです。 難しい設定のほとんどがあなたのために処理されているので、サービス自体はほとんどのユーザーにとって信じられないほど簡単です。
ただし、標準構成から逸脱する場合は、fail2banの動作を予測可能な方法で操作するために、fail2banがどのように機能するかを知っておくと役立ちます。
fail2banで他のサービスを保護する方法については、次のリンクを参照してください。