Rocky Linux 9でFail2Banを使用してSSHを保護する方法
イントロダクション
SSHは、クラウドサーバーに接続するための事実上の方法です。耐久性があり、新たな暗号化基準の開発によって新しいSSHキーを生成することができるため、核となるプロトコルの安全性が保たれます。ただし、どんなプロトコルやソフトウェアスタックも完全に万全ではありませんし、SSHがインターネット全体に広く展開されていることは、攻撃者がアクセスを試みる予測可能な攻撃経路または攻撃ベクトルを意味します。
ネットワークに公開されているどのサービスも、このような方法で潜在的な攻撃対象となり得ます。広く使われるサーバー上で実行されるSSHサービスのログを確認すると、ユーザーやボットによる繰り返された、システマチックなログイン試行が頻繁に見られることがあります。パスワード認証の代わりにSSHキーを利用するなど、SSHサービスの最適化を行えば、これらの攻撃がほとんど成功しない可能性をほぼゼロに近づけることができますが、それにも関わらず、いくぶんかの持続的なリスクは依然として存在します。
大規模な生産展開では、この責任を完全に受け入れられない場合、通常、WireGuardなどのVPNをSSHサービスの前に設置します。これにより、外部インターネットからデフォルトのSSHポート22に直接接続することは、追加のソフトウェア抽象化やゲートウェイなしでは不可能になります。これらのVPNソリューションは広く信頼されていますが、複雑さを増し、一部の自動化や他の小さなソフトウェアフックが破損する可能性があります。
完全なVPNセットアップに取り組む前またはそれに加えて、Fail2banと呼ばれるツールを導入することができます。Fail2banは、一定数の失敗したログイン試行後に特定のIPを禁止するためにファイアウォールの設定を自動的に変更するルールを作成し、ブルートフォース攻撃を大幅に緩和することができます。これにより、あなたのサーバーはあなたの介入なしでこれらのアクセス試行に対して自己強化されます。
このガイドでは、Rocky Linux 9サーバーにFail2banをインストールして使用する方法について説明します。
前提条件
このガイドを完成させるために、以下のものが必要です。
- A Rocky Linux 9 server and a non-root user with sudo privileges. You can learn more about how to set up a user with these privileges in our Initial Server Setup with Rocky Linux 9 guide. You should also have firewalld running on the server, which is covered in our initial server setup guide.
- Optionally, a second server that you can connect to your first server from, which you will use to test getting deliberately banned.
ステップ1 – Fail2banのインストール
Fail2banはRockyのデフォルトのソフトウェアリポジトリでは利用できません。ただし、Red HatやRocky Linuxで一般的に使用されるサードパーティパッケージ用のEPEL(Enhanced Packages for Enterprise Linux)リポジトリで利用できます。すでにEPELをシステムパッケージソースに追加していない場合は、dnfを使用してリポジトリを追加することができます。他のパッケージをインストールするのと同様です。
- sudo dnf install epel-release -y
新しいソフトウェアをインストールする際に、dnfパッケージマネージャーはデフォルトのパッケージソースに加えてEPELもチェックします。Fail2banをインストールしてください。
- sudo dnf install fail2ban -y
インストール後、Fail2banは自動的にバックグラウンドサービスを設定します。ただし、デフォルトでは無効になっています。デフォルトの設定の一部が望ましくない効果を引き起こす可能性があるためです。systemctlコマンドを使用して、これを確認できます。
- systemctl status fail2ban.service
○ fail2ban.service – Fail2Ban Service Loaded: loaded (/lib/systemd/system/fail2ban.service; disabled; vendor preset: disabled Active: inactive (dead) Docs: man:fail2ban(1)
すぐにFail2banを有効にすることもできますが、最初に機能のいくつかを確認します。
ステップ2 – Fail2banの設定を行います。
fail2banサービスは、その設定ファイルを/etc/fail2banディレクトリに保存しています。デフォルトのファイルであるjail.confがあります。そのディレクトリに移動し、head -20コマンドを使ってそのファイルの最初の20行を表示してください。
- cd /etc/fail2ban
- head -20 jail.conf
# # WARNING: heavily refactored in 0.9.0 release. Please review and # customize settings for your setup. # # Changes: in most of the cases you should not modify this # file, but provide customizations in jail.local file, # or separate .conf files under jail.d/ directory, e.g.: # # HOW TO ACTIVATE JAILS: # # YOU SHOULD NOT MODIFY THIS FILE. # # It will probably be overwritten or improved in a distribution update. # # Provide customizations in a jail.local file or a jail.d/customisation.local. # For example to change the default bantime for all jails and to enable the # ssh-iptables jail the following (uncommented) would appear in the .local file. # See man 5 jail.conf for details. # # [DEFAULT]
次に示すように、このファイルの最初のいくつかの行はコメントアウトされています。#文字で始まることを示しており、これらは設定ではなくドキュメンテーションとして読まれる必要があることを示しています。また、これらのコメントは、このファイルを直接変更しないように指示しています。代わりに、2つのオプションがあります:jail.d/ディレクトリ内の複数のファイルにFail2banの個別のプロファイルを作成するか、jail.localファイルにすべてのローカル設定を作成して収集するかです。Fail2ban自体がアップデートされるたびにjail.confファイルが定期的に更新され、オーバーライドされていないデフォルト設定のソースとして使用されます。
このチュートリアルでは、jail.localを作成します。これは、jail.confをコピーすることによって行うことができます。
- sudo cp jail.conf jail.local
今から設定の変更を始めることができます。お好きなテキストエディターでファイルを開いてください。
- sudo vi jail.local
ファイルをスクロールしている間に、このチュートリアルでは更新する必要のあるいくつかのオプションを確認します。ファイルの上部付近にある[DEFAULT]セクションの設定は、Fail2banでサポートされているすべてのサービスに適用されます。ファイルの他の場所には[sshd]や他のサービス用のヘッダーがあり、デフォルト設定の上に適用されるサービス固有の設定が含まれています。
「/etc/fail2ban/jail.local」
[DEFAULT]
. . .
bantime = 10m
. . .
bantime(禁止時間)パラメータは、クライアントが正しく認証できなかった場合の禁止期間を設定します。この期間は秒単位で計測されます。デフォルトでは、10分に設定されています。
[DEFAULT]
. . .
findtime = 10m
maxretry = 5
. . .
次の2つのパラメータは、findtimeとmaxretryです。これらは、クライアントが禁止すべき不正利用者とみなされる条件を確立するために連携して機能します。
以下は、日本語での表現例です:
デフォルトの設定では、fail2banサービスはクライアントが10分間に5回のログイン試行に失敗した場合に、そのクライアントを禁止します。maxretry変数は、findtimeで定義される一定の時間枠内で、クライアントが認証を試みる回数を設定します。
[DEFAULT]
. . .
destemail = root@localhost
sender = root@<fq-hostname>
mta = sendmail
. . .
Fail2banがアクションを起こした際にメール通知を受け取る必要がある場合は、destemail、sendername、およびmtaの設定を評価する必要があります。destemailパラメータは禁止メッセージを受け取るべきメールアドレスを設定します。sendernameはメールの「送信元」フィールドの値を設定します。mtaパラメータはメールを送信するために使用されるメールサービスを設定します。デフォルトではsendmailが使用されますが、Postfixや他のメールソリューションを使用することもできます。
「/etc/fail2ban/jail.local」
[DEFAULT]
. . .
action = %(action_)s
. . .
このパラメータは、Fail2banが禁止措置を実施する際のアクションを設定します。値「action_」は、このパラメータのすぐ前にあるファイルで定義されています。デフォルトのアクションは、禁止期間が経過するまで問題のホストからのトラフィックを拒否するために、ファイアウォールの設定を更新することです。
上記の$(action_)を置き換えることができるデフォルトで提供されている他のアクション_スクリプトがあります。
…
# ban & send an e-mail with whois report to the destemail.
action_mw = %(action_)s
%(mta)s-whois[sender="%(sender)s", dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"]
# ban & send an e-mail with whois report and relevant log lines
# to the destemail.
action_mwl = %(action_)s
%(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"]
# See the IMPORTANT note in action.d/xarf-login-attack for when to use this action
#
# ban & send a xarf e-mail to abuse contact of IP address and include relevant log lines
# to the destemail.
action_xarf = %(action_)s
xarf-login-attack[service=%(__name__)s, sender="%(sender)s", logpath="%(logpath)s", port="%(port)s"]
# ban IP on CloudFlare & send an e-mail with whois report and relevant log lines
# to the destemail.
action_cf_mwl = cloudflare[cfuser="%(cfemail)s", cftoken="%(cfapikey)s"]
%(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"]
…
例えば、action_mwはアクションを実行し、メールを送信します。action_mwlはアクションを実行し、メールを送信し、ログを含めます。そして、action_cf_mwlはこれらすべてを実行し、加えてあなたのアカウントに関連するCloudflare APIにも違反者を禁止するためのアップデートを送信します。
個別の監獄設定
次は個々のサービスに関連する設定ファイルの部分です。これらは[sshd]のようなセクションヘッダで指定されます。
各セクションは、その他の設定と共にヘッダーの下に enabled = true の行を追加することで個別に有効化する必要があります。
[jail_to_enable]
. . .
enabled = true
. . .
このチュートリアルでは、SSHのジェイルを有効にします。それは各ジェイルの設定のトップにあります。それ以外の場合はデフォルトのパラメータが機能しますが、[sshd]ヘッダーの下にenabled = trueという設定行を追加する必要があります。
「/etc/fail2ban/jail.local」
#
# JAILS
#
#
# SSH servers
#
[sshd]
# To use more aggressive sshd modes set filter parameter "mode" in jail.local:
# normal (default), ddos, extra or aggressive (combines all).
# See "tests/files/logs/sshd" or "filter.d/sshd.conf" for usage example and details.
#mode = normal
enabled = true
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
ここで設定されている他の設定には、ログ内の行が認証失敗を示すかどうかを決定するために使用されるフィルタや、特定のサービスのログが配置されている場所をfail2banに伝えるログパスなどがあります。
フィルター値は実際には、/etc/fail2ban/filter.dディレクトリにあるファイルへの参照で、.conf拡張子を除いたものです。これらのファイルには、行が認証失敗の試みかどうかを判定するための正規表現(テキスト解析の共通略語)が含まれています。このガイドでは、これらのファイルを詳しく説明しませんが、それらはかなり複雑で、事前に設定された設定は適切な行にマッチします。
ただし、そのディレクトリを調べることで利用可能なフィルターの種類を確認することができます。
- ls /etc/fail2ban/filter.d
あなたが使用しているサービスに関連するように見えるファイルがあれば、テキストエディタで開いてみるべきです。ほとんどのファイルにはコメントがしっかりと付いており、少なくともスクリプトがどのような状態を防ぐために設計されているかは分かるはずです。これらのフィルターのほとんどは、jail.confファイルに適切な(無効化された)セクションがあり、必要に応じてjail.localファイルで有効にすることができます。
例えば、Nginxを使用してウェブサイトを提供していると想像してください。そして、サイトのパスワード保護された部分にログイン試行が集中していることに気付きます。この状況を確認するために、fail2banにnginx-http-auth.confファイルを使用し、/var/log/nginx/error.logファイルをチェックするように指示することができます。
実際には、/etc/fail2ban/jail.conf ファイルの [nginx-http-auth] というセクションで既に設定がされています。単に enabled パラメータを追加する必要があります。
「/etc/fail2ban/jail.local」
. . .
[nginx-http-auth]
enabled = true
. . .
編集が終了したら、ファイルを保存して閉じてください。もしviを使用している場合は、:xを使って保存して終了してください。この時点でFail2banサービスを有効化することができます。最初に、systemctl enableコマンドを実行してください。
- sudo systemctl enable fail2ban
そのあと、最初の起動はsystemctl startコマンドを使って手動で開始してください。
- sudo systemctl start fail2ban
「systemctl status」で動作を確認することができます。
- sudo systemctl status fail2ban
● fail2ban.service – Fail2Ban Service Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; vendor preset: disabled Active: active (running) since Wed 2022-09-14 20:48:40 UTC; 2s ago Docs: man:fail2ban(1) Main PID: 39396 (fail2ban-server) Tasks: 5 (limit: 1119) Memory: 12.9M CPU: 278ms CGroup: /system.slice/fail2ban.service └─39396 /usr/bin/python3.6 -s /usr/bin/fail2ban-server -xf start Sep 14 20:48:40 rocky9-tester systemd[1]: Starting Fail2Ban Service… Sep 14 20:48:40 rocky9-tester systemd[1]: Started Fail2Ban Service. Sep 14 20:48:41 rocky9-tester fail2ban-server[39396]: Server ready
次のステップでは、Fail2banの実際の動作を示します。
ステップ3 — 禁止ポリシーのテスト(オプション)
将来的にFail2banサーバーにログインする必要がない別のサーバーから、そのルールをテストするためには、2番目のサーバーを禁止することで試すことができます。2番目のサーバーにログインした後、Fail2banサーバーにSSH接続を試みてください。存在しない名前を使用して接続を試してみることもできます。
- ssh blah@your_server
パスワードのプロンプトにランダムな文字列を入力してください。数回繰り返してください。ある時点で、受け取っているエラーは「許可が拒否されました」から「接続が拒否されました」に変わるはずです。これは、第2のサーバーがFail2banサーバーから禁止されたことを示しています。
Fail2banサーバー上で、fail2ban-clientの出力を確認することで、新しいルールを確認することができます。fail2ban-clientはFail2banが実行時の設定を確認するために提供されている追加のコマンドです。
- sudo fail2ban-client status
Status |- Number of jail: 1 `- Jail list: sshd
もし、fail2ban-client status sshd を実行すれば、SSH から禁止された IP のリストを確認することができます。
- sudo fail2ban-client status sshd
Status for the jail: sshd |- Filter | |- Currently failed: 2 | |- Total failed: 7 | `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd `- Actions |- Currently banned: 1 |- Total banned: 1 `- Banned IP list: 134.209.165.184
「Banned IPリストの内容は、あなたのセカンドサーバーのIPアドレスを反映するべきです。」
結論
現在、サービスに対していくつかの禁止ポリシーを設定することができるようになりました。Fail2banは、認証を使用するあらゆる種類のサービスを保護するための有用な方法です。Fail2banの動作についてもっと詳しく知りたい場合は、Fail2banのルールとファイルの仕組みに関する当社のチュートリアルを参照してください。
他のサービスを保護するためにfail2banを使用する方法の情報については、「How To Protect an Nginx Server with Fail2Ban」を読んでください。