Linux PAMセキュリティハードニング実践ガイド:MFA・ロックアウト・脆弱性対策まで徹底解説

Linux PAMのセキュリティを実践的に強化する完全ガイド。最新CVE脆弱性への対策、pam_faillockによるブルートフォース防御、FIDO2/TOTPの多要素認証統合、CIS準拠のパスワードポリシー、pam_accessによるアクセス制御、監査スクリプトまでを現場目線で徹底解説します。

はじめに:なぜ今PAMセキュリティが重要なのか

Linux PAM(Pluggable Authentication Modules)は、Linuxシステムにおける認証の根幹を担うフレームワークです。SSH、sudo、su、ログインコンソール――要するに、ユーザーが「自分は誰か」を証明するあらゆる場面でPAMが裏方として動いています。裏を返せば、PAMの設定をミスすると、システム全体のセキュリティが一気に崩れるということです。

2025年には、PAMに関する重大な脆弱性が複数発見されました。CVE-2025-8941ではpam_namespaceモジュールのレースコンディションを悪用したローカル権限昇格が可能となり、CVSSスコア7.8の高深刻度と評価されています。さらに厄介なのがCVE-2025-6018とCVE-2025-6019の連鎖攻撃で、通常のローカルユーザーがallow_activeステータスを取得し、udisksデーモンを経由してroot権限を奪取できることが実証されました。正直なところ、この連鎖攻撃のPoCを初めて読んだときはかなり背筋が冷たくなりました。

こうした事例を見ると、PAMの設定を適切に行い、多層防御を実装することの重要性を改めて痛感します。本記事では、PAMのアーキテクチャの基礎から、最新の脅威への対策、多要素認証(MFA)の統合、CISベンチマーク準拠のパスワードポリシー設定まで、実践的に解説していきます。現場で実際に使える内容を目指しましたので、ぜひ手を動かしながら読んでみてください。

PAMアーキテクチャの基礎理解

PAMの4つのモジュールタイプ

PAMは認証プロセスを4つの独立したタイプ(スタック)に分類しています。ここをしっかり理解しておかないと、後の設定で「なぜこの順番なのか」が分からなくなるので、少し退屈かもしれませんがお付き合いください。

  • auth(認証):ユーザーの身元を確認します。パスワード検証、多要素認証トークンの検証などがここに含まれます
  • account(アカウント):アカウントの有効性を確認します。アカウントの有効期限、時間帯による制限、ログイン失敗回数によるロックアウトなどを制御します
  • password(パスワード):パスワードの変更処理を管理します。パスワードの複雑性要件、履歴チェックなどがここで適用されます
  • session(セッション):認証の前後に実行されるセッション設定を管理します。ログ記録、環境変数の設定、リソース制限の適用などが含まれます

制御フラグの理解

各PAMモジュールには制御フラグが設定され、そのモジュールの成功/失敗がスタック全体の結果にどう影響するかを決定します。ここが一番混乱しやすいポイントなので、特にrequiredとrequisiteの違いは頭に入れておいてください。

  • required:モジュールが失敗すると最終的に認証は失敗しますが、スタック内の残りのモジュールは引き続き実行されます。これは「失敗してもすぐには止めない」という動作で、攻撃者に対して認証のどの段階で失敗したかを悟らせにくくする意味があります
  • requisite:モジュールが失敗すると即座に認証が失敗し、以降のモジュールは実行されません
  • sufficient:モジュールが成功すると、それ以前のrequiredモジュールがすべて成功していれば即座に認証成功となります
  • optional:モジュールの成功/失敗は、他にrequiredやsufficientなモジュールがない場合にのみ影響します
  • include / substack:他のPAM設定ファイルの内容を読み込みます

設定ファイルの構造

PAMの設定ファイルは /etc/pam.d/ ディレクトリに、サービスごとに配置されています。例えば、SSHは /etc/pam.d/sshd、sudoは /etc/pam.d/sudo という具合です。慣れてくると「あのサービスの認証どうなってたっけ」と思ったら反射的にこのディレクトリを開くようになります。

# /etc/pam.d/sshd の基本構造例
# タイプ    制御フラグ    モジュール            オプション
auth        required      pam_sepermit.so
auth        substack      password-auth
auth        include       postlogin
account     required      pam_nologin.so
account     include       password-auth
password    include       password-auth
session     required      pam_selinux.so close
session     required      pam_loginuid.so
session     required      pam_selinux.so open env_params
session     optional      pam_keyinit.so force revoke
session     include       password-auth
session     include       postlogin

最新のPAM脆弱性と対策

CVE-2025-8941:pam_namespaceのレースコンディション

CVE-2025-8941は、pam_namespaceモジュールに存在するレースコンディションの脆弱性です。攻撃者はシンボリックリンクの操作とタイミング攻撃を組み合わせることで、ディレクトリ作成プロセスを乗っ取り、root権限への昇格を実現できます。レースコンディション系の脆弱性は再現が難しいことも多いですが、だからといって放置していい理由にはなりません。

影響を受ける環境:pam_namespaceモジュールを使用してユーザーセッションの名前空間を分離しているシステム全般

対策手順:

  1. システムのPAMパッケージを最新バージョンにアップデートする
  2. pam_namespaceが不要な場合は設定から無効化する(そもそも使っていないなら無効にしておくのが鉄則です)
  3. ホストベースの侵入検知システム(HIDS)でシンボリックリンクの異常な作成・操作を監視する
# PAMパッケージのアップデート(RHEL/CentOS/AlmaLinux/Rocky Linux)
sudo dnf update pam --security

# Ubuntu/Debian
sudo apt update && sudo apt upgrade libpam-modules libpam-runtime

# 現在のPAMバージョンを確認
rpm -q pam 2>/dev/null || dpkg -l libpam-modules 2>/dev/null

CVE-2025-6018 / CVE-2025-6019:連鎖的権限昇格

この2つの脆弱性は連鎖的に悪用されるのが厄介なところです。CVE-2025-6018によりローカルユーザーがallow_activeステータスを取得し、CVE-2025-6019ではそのステータスを利用してudisksデーモン経由でroot権限を奪取します。SUSE Linux Enterprise 15およびopenSUSE Leap 15が影響を受けます。

対策:

  • ディストリビューションのセキュリティアップデートを即時適用する(「後でやろう」は禁物です)
  • udisksデーモンのPolKit設定を見直し、不要な権限を制限する
  • PAM設定でallow_activeの付与条件を厳格化する

pam_faillock:アカウントロックアウトの設定

ブルートフォース攻撃からシステムを防御するために、ログイン失敗回数に基づくアカウントロックアウトの設定は必須です。従来のpam_tally2は非推奨になっていますので、まだ使っている方はこの機会にpam_faillockへ移行しましょう。

基本設定

/etc/security/faillock.conf で一元的に設定できます。個人的には、PAMファイルにオプションを直接書くよりこちらの方が管理しやすくて好みです。

# /etc/security/faillock.conf
# ロックアウトまでの失敗回数
deny = 5

# ロックアウト解除までの秒数(1800秒 = 30分)
unlock_time = 1800

# 失敗回数がリセットされるまでの秒数
fail_interval = 900

# root アカウントにもロックアウトを適用するか
even_deny_root = true

# root のロックアウト時間(通常ユーザーより長く設定)
root_unlock_time = 3600

# 監査ログに記録する
audit = true

# ロックアウト情報の保存先
dir = /var/run/faillock

PAM設定ファイルへの統合

/etc/pam.d/system-auth および /etc/pam.d/password-auth に以下の行を追加します。

# /etc/pam.d/system-auth(RHEL系)
auth        required      pam_faillock.so preauth silent audit deny=5 unlock_time=1800
auth        sufficient    pam_unix.so try_first_pass nullok
auth        required      pam_faillock.so authfail audit deny=5 unlock_time=1800
auth        required      pam_deny.so

account     required      pam_faillock.so
account     required      pam_unix.so

重要:pam_faillock.soのpreauth行はpam_unix.soのに、authfail行はpam_unix.soのに配置する必要があります。この順序を間違えると正しく動作しません。何度か現場で順序ミスによるトラブルを見てきたので、ここは慎重に確認してください。

ロックアウト状態の管理

# 特定ユーザーのロックアウト状態を確認
faillock --user username

# ロックアウトされたユーザーのリセット
faillock --user username --reset

# 全ユーザーのロックアウト状態を一覧表示
faillock

CISベンチマーク準拠の推奨設定

CIS(Center for Internet Security)ベンチマークでは、以下のパラメータが推奨されています。監査対応が求められる環境では、このあたりを押さえておくと話が早いです。

  • deny = 35:3回から5回の失敗でロックアウト
  • unlock_time = 900以上:最低15分のロックアウト時間
  • even_deny_root = true:rootアカウントにもロックアウトを適用

pam_pwquality:パスワードポリシーの強化

弱いパスワードは依然としてLinuxシステムへの侵入経路の上位に位置しています。「うちはSSHキー認証だから大丈夫」と思っていても、sudoやsuではパスワードを使うケースが多いですよね。pam_pwqualityモジュールを使用して、組織のセキュリティポリシーに準拠したパスワード要件をきちんと強制しておきましょう。

設定ファイル

# /etc/security/pwquality.conf

# パスワードの最小文字数
minlen = 14

# 前のパスワードと異なる必要がある最小文字数
difok = 4

# 数字の最小要求数(負の値は最小必須数を意味する)
dcredit = -1

# 大文字の最小要求数
ucredit = -1

# 小文字の最小要求数
lcredit = -1

# 特殊文字の最小要求数
ocredit = -1

# 同一文字の連続を許可する最大回数
maxrepeat = 3

# 同一文字クラスの連続を許可する最大回数
maxclassrepeat = 4

# 辞書ファイルによるチェックを有効化
dictcheck = 1

# ユーザー名がパスワードに含まれていないことをチェック
usercheck = 1

# パスワードの複雑さチェック:最低限必要な文字クラス数
minclass = 3

# パスワード変更のリトライ回数
retry = 3

# rootユーザーにもポリシーを強制
enforce_for_root

PAMへの統合

# /etc/pam.d/system-auth のpasswordセクション
password    requisite     pam_pwquality.so retry=3 local_users_only
password    sufficient    pam_unix.so sha512 shadow try_first_pass use_authtok remember=12
password    required      pam_deny.so

remember=12 は過去12回分のパスワード履歴を保持し、再利用を防止します。ハッシュ化されたパスワード履歴は /etc/security/opasswd に保存されます。地味ですが、パスワード使い回しの抑止にはかなり効きます。

パスワードポリシーの検証

# pwquality の設定を検証するテスト
echo "weakpass" | pwscore
# 出力例: パスワード品質チェック失敗: パスワードは辞書チェックに失敗しました

echo "C0mpl3x!P@ssw0rd#2026" | pwscore
# 出力例: 82(100点満点のスコア)

# 現在の設定値を確認
pwmake 128
# 128ビットエントロピーのパスワードを生成

多要素認証(MFA)の統合

Google Authenticator(TOTP)の設定

時間ベースのワンタイムパスワード(TOTP)は、追加の認証要素として広く使用されています。導入のハードルも比較的低いので、まだMFAを入れていない環境であれば、まずここから始めるのがおすすめです。

# インストール(RHEL/CentOS/AlmaLinux)
sudo dnf install google-authenticator -y

# インストール(Ubuntu/Debian)
sudo apt install libpam-google-authenticator -y

# ユーザーごとの初期設定
google-authenticator \
  --time-based \
  --disallow-reuse \
  --rate-limit=3 \
  --rate-time=30 \
  --window-size=3 \
  --force

上記コマンドを実行すると、QRコードが端末に表示されます。Google AuthenticatorやAuthyなどの認証アプリでスキャンし、緊急用のバックアップコードを安全な場所に保管してください。バックアップコードの保管、本当に大事です。スマホを落としたときに泣くことになります。

SSHでのTOTP認証の有効化

# /etc/pam.d/sshd に追加
auth    required    pam_google_authenticator.so nullok secret=${HOME}/.google_authenticator

# nullok オプションにより、MFA未設定のユーザーも一時的にログイン可能
# セキュリティを強化する場合は nullok を削除し、全ユーザーにMFA設定を強制する
# /etc/ssh/sshd_config の設定
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive

# SSHを再起動
sudo systemctl restart sshd

注意:AuthenticationMethods publickey,keyboard-interactive は、SSHキー認証TOTP認証の両方を要求するため、真の多要素認証が実現されます。カンマ区切りが「かつ(AND)」、スペース区切りが「または(OR)」という仕様なので、ここを間違えないようにしてください。

FIDO2/U2Fハードウェアキーの統合

YubiKeyなどのFIDO2対応ハードウェアセキュリティキーは、フィッシング耐性を持つ最も強固な認証要素です。予算が許すなら、特に本番サーバーへのアクセスにはこちらを検討してほしいところです。pam_u2fモジュールを使用してLinuxに統合できます。

# インストール(RHEL/CentOS/AlmaLinux)
sudo dnf install pam-u2f -y

# インストール(Ubuntu/Debian)
sudo apt install libpam-u2f -y

# ユーザーのセキュリティキーを登録
mkdir -p ~/.config/Yubico
pamu2fcfg > ~/.config/Yubico/u2f_keys

# 追加のセキュリティキーを登録(バックアップ用)
pamu2fcfg -n >> ~/.config/Yubico/u2f_keys

PAM設定でのFIDO2統合

# /etc/pam.d/sudo にFIDO2認証を追加
auth    required    pam_u2f.so cue origin=pam://hostname appid=pam://hostname

# cue オプションはユーザーにキータッチを促すメッセージを表示する

TOTPとFIDO2のフォールバック構成

FIDO2キーを持っていない場合にTOTPにフォールバックする柔軟な設定も可能です。実運用では、全員がハードウェアキーを持っているとは限らないので、こういった構成が現実的でしょう。

# /etc/pam.d/sshd - FIDO2優先、TOTPフォールバック構成
auth    [success=1 default=ignore]    pam_u2f.so cue
auth    required                       pam_google_authenticator.so

# 解説:
# pam_u2f.so が成功した場合、次の1行(pam_google_authenticator.so)をスキップ
# pam_u2f.so が失敗した場合、pam_google_authenticator.so によるTOTP認証を要求

pam_limitsによるリソース制限

認証成功後のセッションにおいて、ユーザーのリソース使用量を制限することもセキュリティ上重要です。典型的なのはフォークボム攻撃の防止ですね。:(){ :|:& };: を一度でも食らったことがある方なら、この設定の大切さは身に染みているはずです。

# /etc/security/limits.conf

# 全ユーザーのプロセス数を制限(フォークボム対策)
*               hard    nproc           256
*               soft    nproc           128

# 全ユーザーのオープンファイル数を制限
*               hard    nofile          65536
*               soft    nofile          32768

# コアダンプを無効化(機密情報の漏洩防止)
*               hard    core            0

# 特定グループに対する例外設定
@developers     hard    nproc           1024
@developers     soft    nproc           512

# root ユーザーのプロセス数制限
root            hard    nproc           unlimited

PAMでのlimits設定の有効化

# /etc/pam.d/system-auth のsessionセクション
session     required      pam_limits.so

pam_timeによる時間帯アクセス制御

特定のサービスへのアクセスを時間帯で制限するというのも、意外と見落とされがちですが有効な手段です。深夜に本番サーバーへSSHしてくるアカウントがあったら、それ自体が不審ですよね。

# /etc/security/time.conf

# SSH経由のログインを平日の業務時間帯(8:00-20:00)に制限
sshd;*;*;Wk0800-2000

# root ユーザーのコンソールログインを常時許可
login;tty*;root;Al0000-2400

# 特定ユーザーのsudoを業務時間に制限
sudo;*;developer1|developer2;Wk0900-1800

# 書式: サービス;TTY;ユーザー;時間帯
# Al = 全日、Wk = 平日、Wd = 週末
# Mo Tu We Th Fr Sa Su = 各曜日

PAMでの時間制限の有効化

# /etc/pam.d/sshd に追加
account    required    pam_time.so

セキュリティ監査とログ管理

PAM認証ログの監視

設定を入れたら終わり、ではありません。PAMの認証イベントはシステムログに記録されるので、これをちゃんと見ておく必要があります。何か問題が起きたとき、ログがなければ原因究明もできません。

# 認証ログの確認(RHEL系)
sudo journalctl -u sshd --since "1 hour ago" | grep -i "pam\|auth\|failed"

# 認証ログの確認(Debian/Ubuntu)
sudo tail -f /var/log/auth.log | grep -i "pam\|authentication"

# ロックアウトされたアカウントの一覧
sudo faillock --dir /var/run/faillock

# PAM関連のauditdルール設定
sudo auditctl -w /etc/pam.d/ -p wa -k pam_config_changes
sudo auditctl -w /etc/security/ -p wa -k security_config_changes

auditdとの連携

PAMの設定ファイル変更を監査するauditdルールを永続的に設定します。誰かが(悪意の有無にかかわらず)PAMの設定をいじったら、すぐに分かるようにしておくのが理想です。

# /etc/audit/rules.d/pam-audit.rules

# PAM設定ファイルの変更を監査
-w /etc/pam.d/ -p wa -k pam_modification
-w /etc/security/faillock.conf -p wa -k faillock_config
-w /etc/security/pwquality.conf -p wa -k pwquality_config
-w /etc/security/limits.conf -p wa -k limits_config
-w /etc/security/time.conf -p wa -k time_config
-w /etc/security/access.conf -p wa -k access_config

# PAM共有ライブラリの変更を監査
-w /lib64/security/ -p wa -k pam_modules
-w /lib/x86_64-linux-gnu/security/ -p wa -k pam_modules
# auditdルールを再読み込み
sudo augenrules --load

# PAM関連の監査ログを検索
sudo ausearch -k pam_modification -ts recent
sudo ausearch -k pam_config_changes -ts today

pam_accessによるアクセス制御リスト

pam_accessモジュールを使用すると、ユーザー、グループ、ネットワークに基づいたきめ細かいアクセス制御が可能です。ファイアウォールとは別のレイヤーで制御できるので、多層防御の一環として非常に有用です。

# /etc/security/access.conf

# rootのSSHログインを特定IPからのみ許可
+ : root : 10.0.1.0/24
+ : root : 192.168.100.50

# 管理者グループは全アクセス許可
+ : @sysadmins : ALL

# 開発者グループはローカルネットワークからのみ許可
+ : @developers : 10.0.0.0/8

# その他のユーザーはすべて拒否
- : ALL : ALL
# /etc/pam.d/sshd に追加
account    required    pam_access.so accessfile=/etc/security/access.conf

実践的なPAMハードニングチェックリスト

ここまで色々と解説してきましたが、結局のところ「自分の環境は大丈夫なのか」を確認する手段がないと不安ですよね。以下に、本番環境のLinuxサーバーに対して使えるPAMセキュリティ監査スクリプトを用意しました。

自動化スクリプト:PAMセキュリティ監査

#!/bin/bash
# pam_security_audit.sh - PAMセキュリティ設定の監査スクリプト
# 使用法: sudo bash pam_security_audit.sh

set -euo pipefail

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

PASS=0
FAIL=0
WARN=0

check_pass() { echo -e "${GREEN}[PASS]${NC} $1"; ((PASS++)); }
check_fail() { echo -e "${RED}[FAIL]${NC} $1"; ((FAIL++)); }
check_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; ((WARN++)); }

echo "========================================="
echo "  PAM セキュリティ監査レポート"
echo "  実行日時: $(date '+%Y-%m-%d %H:%M:%S')"
echo "  ホスト名: $(hostname)"
echo "========================================="
echo ""

# 1. pam_faillock の設定確認
echo "--- アカウントロックアウト設定 ---"
if grep -rq "pam_faillock" /etc/pam.d/ 2>/dev/null; then
    check_pass "pam_faillock が PAM設定に含まれています"
else
    check_fail "pam_faillock が設定されていません(ブルートフォース攻撃のリスク)"
fi

if [ -f /etc/security/faillock.conf ]; then
    DENY=$(grep "^deny" /etc/security/faillock.conf 2>/dev/null | awk '= {print $3}')
    if [ -n "$DENY" ] && [ "$DENY" -le 5 ]; then
        check_pass "ロックアウト閾値: ${DENY}回(推奨: 5回以下)"
    else
        check_warn "ロックアウト閾値が未設定または高すぎます"
    fi
fi

# 2. pam_pwquality の設定確認
echo ""
echo "--- パスワードポリシー設定 ---"
if [ -f /etc/security/pwquality.conf ]; then
    MINLEN=$(grep "^minlen" /etc/security/pwquality.conf 2>/dev/null | awk '= {print $3}')
    if [ -n "$MINLEN" ] && [ "$MINLEN" -ge 12 ]; then
        check_pass "最小パスワード長: ${MINLEN}文字(推奨: 12文字以上)"
    else
        check_fail "最小パスワード長が不十分です(現在: ${MINLEN:-未設定})"
    fi
else
    check_fail "/etc/security/pwquality.conf が存在しません"
fi

# 3. パスワードハッシュアルゴリズムの確認
echo ""
echo "--- パスワードハッシュ設定 ---"
if grep -q "sha512\|yescrypt" /etc/pam.d/system-auth 2>/dev/null || \
   grep -q "sha512\|yescrypt" /etc/pam.d/common-password 2>/dev/null; then
    check_pass "強力なハッシュアルゴリズム(SHA-512/yescrypt)が使用されています"
else
    check_fail "弱いハッシュアルゴリズムが使用されている可能性があります"
fi

# 4. pam_limits の確認
echo ""
echo "--- リソース制限設定 ---"
if grep -rq "pam_limits" /etc/pam.d/ 2>/dev/null; then
    check_pass "pam_limits がセッション設定に含まれています"
else
    check_warn "pam_limits が設定されていません"
fi

# 5. MFA設定の確認
echo ""
echo "--- 多要素認証設定 ---"
if grep -rq "pam_google_authenticator\|pam_u2f\|pam_duo" /etc/pam.d/ 2>/dev/null; then
    check_pass "多要素認証モジュールが設定されています"
else
    check_warn "多要素認証が設定されていません"
fi

# 6. 不要なPAMモジュールの確認
echo ""
echo "--- 不要モジュール確認 ---"
if grep -rq "pam_tally2" /etc/pam.d/ 2>/dev/null; then
    check_warn "非推奨の pam_tally2 が使用されています(pam_faillock への移行を推奨)"
fi

# 7. PAM設定ファイルのパーミッション確認
echo ""
echo "--- ファイルパーミッション ---"
BAD_PERMS=0
for f in /etc/pam.d/*; do
    PERM=$(stat -c '%a' "$f" 2>/dev/null)
    if [ "$PERM" != "644" ] && [ "$PERM" != "640" ]; then
        check_fail "不適切なパーミッション: $f ($PERM)"
        ((BAD_PERMS++))
    fi
done
if [ "$BAD_PERMS" -eq 0 ]; then
    check_pass "全PAM設定ファイルのパーミッションが適切です"
fi

# 結果サマリー
echo ""
echo "========================================="
echo "  監査結果サマリー"
echo "========================================="
echo -e "  ${GREEN}合格: ${PASS}${NC}"
echo -e "  ${RED}不合格: ${FAIL}${NC}"
echo -e "  ${YELLOW}警告: ${WARN}${NC}"
echo ""
if [ "$FAIL" -gt 0 ]; then
    echo -e "${RED}セキュリティ上の問題が検出されました。上記の指摘事項を修正してください。${NC}"
    exit 1
else
    echo -e "${GREEN}重大なセキュリティ問題は検出されませんでした。${NC}"
    exit 0
fi

本番環境向けの統合設定例

さて、ここまでの内容を踏まえて、これまでの全要素を統合した本番環境に適用可能なPAM設定の完全な例を示します。そのままコピペするのではなく、自分の環境に合わせて必要な部分を取捨選択してください。

system-auth(RHEL系統合設定)

# /etc/pam.d/system-auth - セキュリティ強化版
# ============================================

# --- 認証(auth)セクション ---
# アカウントロックアウトの事前チェック
auth        required      pam_env.so
auth        required      pam_faillock.so preauth silent audit deny=5 unlock_time=1800 even_deny_root root_unlock_time=3600
auth        sufficient    pam_unix.so try_first_pass nullok
auth        required      pam_faillock.so authfail audit deny=5 unlock_time=1800 even_deny_root root_unlock_time=3600
auth        required      pam_deny.so

# --- アカウント(account)セクション ---
account     required      pam_faillock.so
account     required      pam_access.so
account     required      pam_unix.so

# --- パスワード(password)セクション ---
password    requisite     pam_pwquality.so retry=3 local_users_only
password    sufficient    pam_unix.so sha512 shadow try_first_pass use_authtok remember=12 rounds=65536
password    required      pam_deny.so

# --- セッション(session)セクション ---
session     optional      pam_keyinit.so revoke
session     required      pam_limits.so
session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session     required      pam_unix.so

sshd(SSH用MFA統合設定)

# /etc/pam.d/sshd - MFA対応セキュリティ強化版
# ============================================

# --- 認証(auth)セクション ---
auth        required      pam_sepermit.so
auth        required      pam_faillock.so preauth silent audit deny=3 unlock_time=1800
auth        substack      password-auth
auth        required      pam_faillock.so authfail audit deny=3 unlock_time=1800

# FIDO2 優先、TOTP フォールバック
auth        [success=1 default=ignore]    pam_u2f.so cue
auth        required                       pam_google_authenticator.so

# --- アカウント(account)セクション ---
account     required      pam_nologin.so
account     required      pam_access.so
account     required      pam_time.so
account     include       password-auth

# --- パスワード(password)セクション ---
password    include       password-auth

# --- セッション(session)セクション ---
session     required      pam_selinux.so close
session     required      pam_loginuid.so
session     required      pam_selinux.so open env_params
session     required      pam_limits.so
session     optional      pam_keyinit.so force revoke
session     include       password-auth
session     include       postlogin

トラブルシューティングと復旧手順

PAMの設定変更は、誤るとシステムにログインできなくなります。これは脅しではなく、実際にやらかした経験がある人は少なくないはずです。以下の安全策を必ず実施してください。

設定変更前の安全策

  1. 既存セッションを維持する:PAM設定を変更する際は、必ず既存のrootセッション(SSHまたはコンソール)を開いたままにしてください。新しい設定で別ターミナルからログインをテストし、問題がなければ既存セッションを閉じます。これは本当に基本中の基本ですが、何度強調しても足りません
  2. バックアップを作成する:変更前に設定ファイルのバックアップを取得します
  3. シングルユーザーモードへのアクセス手段を確保する:物理コンソールやIPMI/iLOなどのアウトオブバンド管理へのアクセスを確保してください。クラウド環境ならシリアルコンソールが使えるかも確認しておきましょう
# PAM設定のバックアップ
sudo cp -a /etc/pam.d/ /etc/pam.d.backup.$(date +%Y%m%d)
sudo cp -a /etc/security/ /etc/security.backup.$(date +%Y%m%d)

# 変更後のテスト(別のターミナルで実施)
ssh testuser@localhost

# 問題発生時の復旧
sudo cp -a /etc/pam.d.backup.20260208/* /etc/pam.d/
sudo cp -a /etc/security.backup.20260208/* /etc/security/

よくある問題と解決方法

  • 全ユーザーがログインできない:シングルユーザーモードで起動し、/etc/pam.d/ のバックアップから復元する
  • MFA設定後にログインできないnullok オプションを追加するか、コンソールからMFA設定を一時的に無効化する
  • pam_faillock でrootがロックアウトされた:シングルユーザーモードまたはレスキューモードで起動し、faillock --user root --reset を実行する
  • パスワード変更時にpam_pwqualityが厳しすぎる/etc/security/pwquality.conf のパラメータを段階的に調整する。いきなり厳しくしすぎると、ユーザーからの問い合わせが殺到するので注意です

まとめ:PAMセキュリティの多層防御戦略

Linux PAMのセキュリティ強化は、銀の弾丸のような単一の設定で解決するものではありません。複数のモジュールを組み合わせた多層防御アプローチで初めて実効性のあるものになります。本記事で解説した主要な対策を振り返っておきましょう。

  1. パッチ管理:CVE-2025-8941やCVE-2025-6018/6019などの脆弱性に対応するため、PAMパッケージを常に最新に保つ
  2. アカウントロックアウト:pam_faillockを使用してブルートフォース攻撃を防御し、rootアカウントにもロックアウトを適用する
  3. パスワードポリシー:pam_pwqualityで14文字以上、多文字クラス、辞書チェックなどの強力なポリシーを強制する
  4. 多要素認証:FIDO2ハードウェアキーやTOTPを導入し、パスワード単体への依存を排除する
  5. アクセス制御:pam_accessとpam_timeを組み合わせ、IPアドレスと時間帯に基づくアクセス制限を実装する
  6. リソース制限:pam_limitsでフォークボムやリソース枯渇攻撃を防止する
  7. 監査とログ:auditdとの連携により、PAM設定の変更をリアルタイムで検知する
  8. 安全な運用:設定変更前のバックアップと、テスト用セッションの維持を徹底する

これらの対策を体系的に導入することで、Linuxシステムの認証基盤をかなり堅牢なものにできます。ただし、PAMの設定は一度行えば終わりというものではありません。新たな脆弱性は日々発見されますし、組織のセキュリティ要件も変わっていきます。定期的な見直しと改善を怠らないこと――結局のところ、それが一番大事なのかもしれません。

著者について Editorial Team

Our team of expert writers and editors.