ESC

Start typing to search across invoices, services, domains, tickets, and more...

Search... Ctrl+K
Linuxサーバー

Fail2ban のインストールと設定:SSH ブルートフォースと Nginx への攻撃を防ぐ(Debian・Ubuntu・Rocky)

6 ステップ 12 分で読めます 4 回閲覧 0
目次

グローバル IP を持つサーバーには、数分以内にボットによる SSH パスワードの総当たりが始まり、Web サイトも管理画面のスキャンや大量リクエストにさらされます。Fail2ban はログを監視し、短時間に失敗を繰り返したりリクエストが多すぎたりする IP をファイアウォールで自動的に遮断します。この記事では Debian/Ubuntu と Rocky Linux/AlmaLinux への Fail2ban のインストール、jail.local の作成、SSH ブルートフォース対策の sshd ジェイル、nginx-limit-req・nginx-http-auth による Web サイト保護、ufw/firewalld との連携、BAN 解除とホワイトリストを解説します。

作業前に自分のグローバル IP をホワイトリスト(ステップ2の ignoreip)に追加し、SSH セッションを 1 つ開いたままにして、テスト中に自分を締め出さないようにしてください。

ステップ1:Fail2ban をインストール

Debian/Ubuntu では標準リポジトリからインストールし、systemd ジャーナルから SSH ログを読めるよう python3-systemd も入れます(Debian 12 以降は既定で /var/log/auth.log が作成されません)。Rocky/AlmaLinux では EPEL から入れ、fail2ban-firewalld パッケージで firewalld 経由の BAN が有効になります。

# Debian / Ubuntu
apt update
apt install -y fail2ban python3-systemd

# Rocky Linux / AlmaLinux (EPEL)
dnf install -y epel-release
dnf install -y fail2ban fail2ban-firewalld

systemctl enable --now fail2ban
fail2ban-client version

ステップ2:jail.local を作成し sshd ジェイルを有効化

jail.conf はアップデートで上書きされるため編集せず、変更はすべて jail.local に書きます。以下の設定では 10 分間に 3 回失敗すると 1 時間 BAN し、繰り返す IP は最大 1 週間まで BAN 時間が延びます。SSH ポートを変更している場合(「SSH ポートとパスワードの変更」の記事を参照)は port を実際の番号にしてください。そうしないと実際のポートが保護されません。

# Never edit jail.conf (it is overwritten on upgrade); use jail.local
cat > /etc/fail2ban/jail.local <<'EOF'
[DEFAULT]
# Your own IPs are never banned (office/home IP, monitoring, other servers)
ignoreip = 127.0.0.1/8 ::1 198.51.100.20 203.0.113.0/24
bantime  = 1h
findtime = 10m
maxretry = 5
# Repeat offenders get longer bans, up to one week
bantime.increment = true
bantime.maxtime   = 1w

[sshd]
enabled  = true
# use your custom port if you changed it, e.g. port = 2222
port     = ssh
backend  = systemd
maxretry = 3
EOF

fail2ban-client -t            # test the configuration
systemctl restart fail2ban
fail2ban-client status
fail2ban-client status sshd

ステップ3:ufw・firewalld に合わせて banaction を設定

banaction は Fail2ban がどの方法で遮断するかを決めます。Ubuntu/Debian で ufw を使っているなら ufw、Rocky/AlmaLinux では fail2ban-firewalld により firewalld のリッチルールが自動で選ばれます。どちらも使っていない場合は nftables-multiport です。1 つだけ選んで jail.local の [DEFAULT] に書き、Fail2ban を再起動します(ファイアウォールの基本は「Linux ファイアウォール」の記事を参照)。

# Debian / Ubuntu with ufw - add to [DEFAULT] in /etc/fail2ban/jail.local
banaction = ufw

# Rocky / AlmaLinux with firewalld - set automatically by fail2ban-firewalld
# (/etc/fail2ban/jail.d/00-firewalld.conf), or explicitly:
banaction = firewallcmd-rich-rules

# Plain nftables without ufw/firewalld
banaction = nftables-multiport

# Check that bans really reach the firewall
ufw status numbered | head
firewall-cmd --list-rich-rules
nft list ruleset | grep -A5 f2b

ステップ4:Nginx でレート制限と認証を設定

nginx-limit-req ジェイルは Nginx の limit_req モジュールに依存します。制限を超えると Nginx が error.log に「limiting requests」を記録し、Fail2ban がそれを見て BAN します。nginx-http-auth は Basic 認証の失敗を監視するので、管理ディレクトリの保護に向いています。正常な訪問者を巻き込まないよう、レートはサイトのアクセス状況に合わせて調整してください。

# /etc/nginx/nginx.conf, inside http { }
limit_req_zone $binary_remote_addr zone=perip:10m rate=10r/s;

# inside the server { } or location { } you want to protect
limit_req zone=perip burst=20 nodelay;

# protected area with basic auth (optional)
location /admin/ {
    auth_basic           "Restricted";
    auth_basic_user_file /etc/nginx/.htpasswd;
}

nginx -t && systemctl reload nginx

ステップ5:nginx-limit-req と nginx-http-auth ジェイルを有効化

Nginx 用のジェイルは jail.d に別ファイルとして作ると管理しやすくなります。有効にする前に fail2ban-regex でフィルターが実際のログに一致するか確認しましょう。aaPanel などのパネルではログの場所が異なるので、logpath を実際のパスに合わせます。

cat > /etc/fail2ban/jail.d/nginx.local <<'EOF'
[nginx-http-auth]
enabled  = true
port     = http,https
logpath  = /var/log/nginx/error.log

[nginx-limit-req]
enabled  = true
port     = http,https
logpath  = /var/log/nginx/error.log
findtime = 1m
maxretry = 10
bantime  = 2h
EOF

# Check that the filter matches lines in your log
fail2ban-regex /var/log/nginx/error.log /etc/fail2ban/filter.d/nginx-limit-req.conf

fail2ban-client reload
fail2ban-client status nginx-limit-req
CDN を利用している場合、Nginx のログには CDN ノードの IP が記録され、それを BAN すると多くの正規ユーザーがアクセスできなくなります。先に real_ip で訪問者の実 IP を復元する(「Nginx リバースプロキシ」の記事を参照)か、CDN 側でレート制限を行ってください。

ステップ6:BAN の解除とホワイトリスト登録

誤って BAN した場合は、ジェイル単位または全体で解除できます。addignoreip は Fail2ban の再起動までしか有効でないため、恒久的なホワイトリストは jail.local の ignoreip に追加して reload します。自分が BAN されて SSH できない場合は、別の回線(スマートフォンのテザリングなど)から接続するか、クライアントエリアのコンソール(提供されている場合)を使うか、チケットでご連絡ください。

fail2ban-client status sshd                      # list banned IPs
fail2ban-client set sshd unbanip 198.51.100.20   # unban from one jail
fail2ban-client unban 198.51.100.20              # unban from all jails
fail2ban-client unban --all                      # clear every ban

fail2ban-client set sshd addignoreip 198.51.100.20   # whitelist until restart
# Permanent whitelist: add the IP to "ignoreip" in jail.local, then
fail2ban-client reload

tail -f /var/log/fail2ban.log                    # watch bans live

よくある質問

ログファイルが見つからず Fail2ban が起動しない

auth.log が作られない Debian 12 以降でよく起こります。sshd セクションに backend = systemd を設定し、python3-systemd をインストールしてください。fail2ban-client -t で具体的なエラーを確認できます。

BAN されているのに相手がまだ接続できる

多くは banaction が使用中のファイアウォールと合っていないか、port が実際の SSH ポートと異なっています。ステップ3のコマンドでルールが作られているか確認してください。

Fail2ban があれば鍵認証は不要ですか?

いいえ。Fail2ban は総当たりの速度を落とすだけです。パスワードログインを無効にして SSH キーを使うことが根本対策で、両方を併用するのが最も効果的です。

上記の手順で解決しない場合は、サポートチケットを送信して IMIDC の 24 時間 365 日対応テクニカルサポートへご連絡ください。サーバー IP、OS バージョン、実行したコマンド、エラー全文を添えていただくと、より迅速に調査できます。

この回答はお役に立ちましたか?

関連チュートリアル