Linux OSにおける3層のログイン防御メカニズム
SSHポートを公開しているサーバーは、ボットネットから毎日5,000〜20,000回ものパスワード試行攻撃に晒される可能性があります。さらにSSHだけでなく、ターミナルでのsudo/suコマンド、SFTPサービス、物理コンソールからのログインなど、サーバーには多数のエントリーポイントが存在します。この脅威を阻止するため、システムエンジニアは通常、次の3つのアプローチを採用します。
- 方法1:各デーモンでの個別設定(アプリケーションレベル):
sshd_config(MaxAuthTries 3など)やvsftpd.confのパラメータを直接編集します。手軽に実装できますが、設定が分散し、内部アクセス経路を見落とすリスクがあります。 - 方法2:Fail2banによるログ監視:Fail2banは
/var/log/auth.logを解析し、特定IPの認証失敗回数が閾値を超えると、iptablesやnftablesにそのIPを遮断するルールを自動追加します。 - 方法3:コア認証層での直接制御(PAM – Pluggable Authentication Modules):PAMはLinuxの認証を一元管理する中核コンポーネントです。SSH経由の認証、
suによるユーザー切り替え、sudoでのコマンド実行など、あらゆるアプリケーションは同一のルールセットに基づいてPAMに認証処理を委譲します。
実務における比較:Fail2banがPAMに及ばないシナリオとは?
各ソリューションは攻撃チェーンの異なる段階に対応しています。
1. サービスごとの分散設定
- メリット:迅速かつシンプル。使い慣れた設定ファイルの1〜2行を変更してデーモンをリロードするだけで完了します。
- デメリット:セキュリティホールを見落としがちです。SSHで失敗回数を3回に制限しても、Webminなどの管理画面、FTPポート、あるいはローカルマシン上の
suコマンド経由で無制限にブルートフォース攻撃を受けるリスクが残ります。
2. ソフトウェアファイアウォール(Fail2ban)
- メリット:外部からの不要なネットワークパケットを確実に遮断できます。サーバーのCPUリソースがSSHハンドシェイク処理に浪費されるのを防ぎます。
- デメリット:分散型ブルートフォース攻撃(Distributed Brute-force)に対して無力です。攻撃者が1,000台のローテーションプロキシを使用し、各IPから1回ずつ試行して切り替える場合、Fail2banの検知閾値に達することはありません。また、攻撃者がすでに内部シェルを取得し、
suコマンドでrootパスワードを総当たりしている場合にはまったく効果がありません。
3. PAMによる一元管理
- メリット:リクエスト元のIPやプロトコルを問わず、ユーザーアカウントそのものを直接ロックします。「5回失敗したら15分間アカウントをロック」「12文字以上のパスワードを強制」「ユーザー名と同じ文字列を禁止」など、厳格なポリシーを一括適用できます。
- リスク:PAMの編集は極めて慎重に行う必要があります。空白1つの誤りやモジュールの順序ミスによって、管理者自身がシステムから締め出される恐れがあります。
多層防御(Defense-in-Depth)戦略
どちらか一方を選ぶ必要はありません。本番環境(プロダクション)における標準的なベストプラクティスは、両者を併用することです。外部ネットワーク層にFail2ban(およびバックエンドのnftables)を配置して自動スキャントラフィックの95%をフィルタリングし、内部ではPAMをアカウント保護の最終防衛ラインとして機能させます。さらに、不正アクセスの追跡にはauditdによるログ監視、プロセスの保護にはSELinuxやAppArmorによるアクセス制御を組み合わせることで、強固な防御体制を構築できます。
PAMの詳細設定手順:pam_faillock と pam_pwquality
以下のコマンドを実行する前に、rootセッションが有効なSSHウィンドウをあらかじめ2つ開いておいてください。3つ目のターミナルから正常にログインできることを確認するまで、これら2つのセッションは絶対に閉じないでください。
ステップ1:必要なモジュールのインストール
Ubuntu 20.04/22.04およびRHEL/CentOS 8以降では、非推奨(deprecated)となった従来のpam_tally2モジュールに代わり、pam_faillockが完全に採用されています。
Ubuntu/Debianの場合:
sudo apt update
sudo apt install -y libpam-modules libpam-pwquality
RHEL/Rocky Linux/AlmaLinuxの場合:
sudo dnf install -y pam pam-devel libpwquality
ステップ2:pam_faillock によるアカウント自動ロックの設定
現在最も推奨される安全な管理方法は、設定ファイル /etc/security/faillock.conf で一括管理することです。
sudo nano /etc/security/faillock.conf
コメントアウトを解除し、以下の標準値を設定します。
# ロックされるまでの最大試行失敗回数
deny = 5
# 失敗カウントをリセットするまでの間隔(秒)
fail_interval = 900
# アカウントのロック時間:900秒(15分)
unlock_time = 900
# ユーザーの存在有無の漏洩を防ぐため、拒絶理由を詳細に通知しない
silent
次に、システムの認証スタックでfaillockを有効化します。
Ubuntu/Debianの場合は、/etc/pam.d/common-auth を開きます。
sudo nano /etc/pam.d/common-auth
pam_unix.so の検証行を挟むように pam_faillock.so を定義します。
auth required pam_faillock.so preauth
auth [success=1 default=ignore] pam_unix.so nullok
auth [default=die] pam_faillock.so authfail
auth sufficient pam_faillock.so authsucc
あわせて /etc/pam.d/common-account を開き、ファイルの先頭に以下の行を追加します。
account required pam_faillock.so
RHEL/Rocky Linuxにおける注意点:PAMファイルを手動で直接編集しないでください。設定の上書きを防ぐため、
sudo authselect enable-feature with-faillockを実行してからauthselect apply-changesを適用してください。
ステップ3:pam_pwquality によるパスワード複雑性の強化
/etc/security/pwquality.conf を開いてパスワードポリシーを設定します。
sudo nano /etc/security/pwquality.conf
各パラメータを次のように設定・更新します。
# 最小文字数
minlen = 12
# 数字を最低1文字必須
dcredit = -1
# 小文字を最低1文字必須
lcredit = -1
# 大文字を最低1文字必須
ucredit = -1
# 特殊文字(記号)を最低1文字必須
ocredit = -1
# ユーザー名を含むパスワードを禁止
usercheck = 1
# 3文字を超える同一文字の連続を禁止
maxrepeat = 3
負の値(例:-1)は「必須条件」を意味します。これは、ユーザーがパスワードを設定する際の加点(ウェイト)として機能する正の値とは挙動が異なります。
ステップ4:faillockコマンドによるログ確認とアカウントロック解除
パスワードの入力ミスが5回を超えると、アカウントは自動的にロック状態になります。root権限で状況を確認します。
# 失敗したリクエストの日時と送信元IPの詳細を確認
sudo faillock --user deploy_user
ターミナル上の出力例:
deploy_user:
When Type Source Valid
2026-03-15 09:12:01 RHOST 192.168.1.50 V
2026-03-15 09:12:08 RHOST 192.168.1.50 V
2026-03-15 09:12:15 RHOST 192.168.1.50 V
2026-03-15 09:12:22 RHOST 192.168.1.50 V
2026-03-15 09:12:30 RHOST 192.168.1.50 V
15分の解除待機時間を待たずに緊急でロックを解除する場合:
sudo faillock --user deploy_user --reset
ステップ5:動作確認テスト
現在のrootターミナルは開いたまま保持してください。テスト用に新しいターミナルウィンドウを開き、以下を実行します。
ssh deploy_user@<ip_server>を実行し、意図的にパスワードを連続5回間違えて入力します。- 6回目に正しいパスワードを入力しても、システムによってアクセスが拒否されます(Permission denied)。
- rootターミナルに戻り、
sudo faillock --user deploy_userを実行してロック状態を確認します。 sudo faillock --user deploy_user --resetを実行します。これでユーザーは即座に再ログインできるようになります。

