PAM Pluggable Authentication Modules
PAM (Pluggable Authentication Modules) 包括的ガイド
目次
- はじめに
- PAM アーキテクチャ
- PAM モジュールタイプ
- PAM 制御フラグ
- /etc/pam.d/ 設定
- 主要な PAM モジュール
- パスワード複雑性要件
- アカウントロックアウトポリシー
- PAM による多要素認証
- 高度な PAM 設定例
- トラブルシューティング
- ベストプラクティス
- 参考文献
1. はじめに
PAM (Pluggable Authentication Modules) は、Linux/Unix システムにおける認証フレームワークである。アプリケーションと認証メカニズムを分離することにより、認証方法を柔軟に設定・変更できる。PAM を理解することは、Linux システムのセキュリティ管理において極めて重要である。
1.1 PAM の歴史と目的
PAM は1995年に Sun Microsystems によって提案された。その主な目的は以下の通りである。
| 目的 | 説明 |
|---|---|
| 認証の標準化 | アプリケーションごとに異なる認証コードを排除 |
| モジュール性 | 認証メカニズムを独立したモジュールとして実装 |
| 柔軟性 | システム管理者が認証ポリシーを容易に変更可能 |
| スタック可能 | 複数の認証モジュールを組み合わせ可能 |
1.2 PAM の全体像
┌─────────────────────────────────────────────────────────┐
│ アプリケーション │
│ (login, sshd, su, sudo, etc.) │
└─────────────┬───────────────────────────────────────────┘
│ PAM API
┌─────────────▼───────────────────────────────────────────┐
│ PAM ライブラリ │
│ (libpam.so) │
└─────────────┬───────────────────────────────────────────┘
│ 設定ファイル参照
┌─────────────▼───────────────────────────────────────────┐
│ /etc/pam.d/ 設定ファイル │
│ (サービスごとの設定ファイル) │
└─────────────┬───────────────────────────────────────────┘
│ モジュール呼び出し
┌─────────────▼───────────────────────────────────────────┐
│ PAM モジュール │
│ (/usr/lib/x86_64-linux-gnu/security/ or │
│ /usr/lib64/security/) │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │pam_unix │ │pam_ldap │ │pam_sssd │ │pam_google│ │
│ │ │ │ │ │ │ │_auth │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────────────────┘
2. PAM アーキテクチャ
2.1 PAM の構成要素
PAM は以下の4つの主要コンポーネントから構成される。
PAM アーキテクチャ
├── PAM 対応アプリケーション
│ └── PAM API を使用して認証を要求
├── PAM ライブラリ (libpam)
│ └── アプリケーションとモジュール間の仲介
├── PAM 設定ファイル (/etc/pam.d/)
│ └── サービスごとの認証ポリシー定義
└── PAM モジュール (/usr/lib/security/)
└── 実際の認証・認可処理を実装
2.2 PAM の処理フロー
ユーザー → アプリケーション → libpam → 設定ファイル読み込み
│
▼
┌─── auth モジュールスタック ───┐
│ pam_faillock.so (preauth) │
│ pam_unix.so │
│ pam_faillock.so (authfail) │
└────────────────────────────────┘
│
┌─── account モジュールスタック ─┐
│ pam_unix.so │
│ pam_access.so │
│ pam_time.so │
└────────────────────────────────┘
│
┌─── password モジュールスタック ┐
│ pam_pwquality.so │
│ pam_unix.so │
└────────────────────────────────┘
│
┌─── session モジュールスタック ─┐
│ pam_limits.so │
│ pam_unix.so │
│ pam_motd.so │
│ pam_mkhomedir.so │
└────────────────────────────────┘
│
▼
結果をアプリケーションに返却
2.3 PAM モジュールの配置場所
# モジュールの配置ディレクトリ確認
# RHEL/CentOS (64bit)
ls /usr/lib64/security/
# 出力例:
# pam_access.so pam_faillock.so pam_limits.so pam_pwquality.so pam_unix.so
# pam_console.so pam_filter.so pam_listfile.so pam_rhosts.so pam_warn.so
# pam_cracklib.so pam_ftp.so pam_localuser.so pam_rootok.so pam_wheel.so
# pam_deny.so pam_group.so pam_loginuid.so pam_securetty.so pam_xauth.so
# pam_echo.so pam_issue.so pam_mkhomedir.so pam_selinux.so
# pam_env.so pam_keyinit.so pam_motd.so pam_shells.so
# pam_exec.so pam_lastlog.so pam_namespace.so pam_succeed_if.so
# pam_faildelay.so pam_ldap.so pam_nologin.so pam_time.so
# Ubuntu/Debian (64bit)
ls /usr/lib/x86_64-linux-gnu/security/
# インストール済みPAMモジュールの確認
dpkg -l | grep libpam # Debian/Ubuntu
rpm -qa | grep pam # RHEL/CentOS
3. PAM モジュールタイプ
3.1 4つのモジュールタイプ
| タイプ | 目的 | 実行タイミング |
|---|---|---|
| auth | ユーザーの本人確認 (認証) | ログイン時、su/sudo 実行時 |
| account | アカウントの有効性チェック (認可) | 認証成功後 |
| password | パスワードの変更処理 | passwd コマンド実行時 |
| session | セッションの設定/解放 | ログイン/ログアウト時 |
3.2 auth タイプ
ユーザーの身元を確認する。通常はパスワードの入力を求め、正しいかどうかを検証する。
# auth タイプの例
# /etc/pam.d/login
auth required pam_securetty.so # root のログイン端末を制限
auth required pam_nologin.so # /etc/nologin チェック
auth required pam_faillock.so preauth # ロックアウト前チェック
auth sufficient pam_unix.so nullok # UNIX パスワード認証
auth required pam_faillock.so authfail # 認証失敗の記録
auth required pam_deny.so # すべて拒否 (フォールバック)
3.3 account タイプ
認証されたユーザーがサービスにアクセスする権限があるかを確認する。
# account タイプの例
account required pam_unix.so # アカウントの有効期限チェック
account required pam_access.so # /etc/security/access.conf による制御
account required pam_time.so # 時間帯によるアクセス制御
account sufficient pam_localuser.so # ローカルユーザーのチェック
account required pam_permit.so # すべて許可
3.4 password タイプ
パスワードの変更に関する処理を制御する。
# password タイプの例
password requisite pam_pwquality.so retry=3 # パスワード品質チェック
password sufficient pam_unix.so sha512 shadow \
use_authtok remember=12 # UNIX パスワード設定
password required pam_deny.so # その他は拒否
3.5 session タイプ
ログインセッションの開始と終了に関する処理を制御する。
# session タイプの例
session required pam_limits.so # リソース制限の適用
session required pam_unix.so # セッション管理
session optional pam_motd.so # MOTD の表示
session optional pam_mkhomedir.so # ホームディレクトリの自動作成
session required pam_loginuid.so # 監査用 loginuid の設定
session optional pam_keyinit.so force revoke # カーネルキーリング
session optional pam_env.so # 環境変数の設定
4. PAM 制御フラグ
4.1 制御フラグ一覧
| フラグ | 成功時 | 失敗時 | 説明 |
|---|---|---|---|
| required | 処理続行 | 処理続行(最終的に失敗) | 必須。失敗しても後続モジュールを実行 |
| requisite | 処理続行 | 即座に失敗を返却 | 必須。失敗時は即座にアプリケーションに戻る |
| sufficient | 即座に成功を返却 | 無視して処理続行 | 成功時は後続モジュールをスキップ |
| optional | 結果を記録 | 結果を記録 | 他に判定がない場合のみ結果が使用される |
| include | - | - | 別の設定ファイルを読み込む |
| substack | - | - | include と似るが、スタックのスコープが限定 |
4.2 制御フラグの動作フロー
required の動作:
モジュール1 (required) → 成功 → モジュール2 (required) → 失敗 → モジュール3 (required) → 成功
結果: 失敗 (モジュール2が失敗したため、最終結果は失敗)
requisite の動作:
モジュール1 (requisite) → 成功 → モジュール2 (requisite) → 失敗 → [即座に失敗を返却]
結果: 失敗 (モジュール2が失敗した時点で即座に失敗)
sufficient の動作:
モジュール1 (sufficient) → 成功 → [即座に成功を返却]
結果: 成功 (前の required が全て成功している場合)
モジュール1 (sufficient) → 失敗 → モジュール2 (required) → 成功
結果: 成功 (sufficient の失敗は無視される)
4.3 高度な制御構文
# 角括弧構文 (より細かい制御)
# [value1=action1 value2=action2 ...]
# 利用可能な値:
# success, open_err, symbol_err, service_err, system_err,
# buf_err, perm_denied, auth_err, cred_insufficient,
# authinfo_unavail, user_unknown, maxtries, new_authtok_reqd,
# acct_expired, session_err, cred_unavail, cred_expired,
# cred_err, no_module_data, conv_err, authtok_err,
# authtok_recover_err, authtok_lock_busy, authtok_disable_aging,
# try_again, ignore, abort, authtok_expired, module_unknown,
# bad_item, conv_again, incomplete, default
# 利用可能なアクション:
# ignore, bad, die, ok, done, N (スキップ数), reset
# 実際の例
auth [success=2 default=ignore] pam_unix.so nullok
auth [success=1 default=ignore] pam_ldap.so use_first_pass
auth requisite pam_deny.so
auth required pam_permit.so
# 上記の動作:
# 1. pam_unix.so が成功 → 2つ先 (pam_permit.so) へジャンプ
# 2. pam_unix.so が失敗 → pam_ldap.so を試行
# 3. pam_ldap.so が成功 → 1つ先 (pam_permit.so) へジャンプ
# 4. pam_ldap.so が失敗 → pam_deny.so で拒否
4.4 制御フラグと角括弧構文の対応
required ≡ [success=ok new_authtok_reqd=ok ignore=ignore default=bad]
requisite ≡ [success=ok new_authtok_reqd=ok ignore=ignore default=die]
sufficient ≡ [success=done new_authtok_reqd=done default=ignore]
optional ≡ [success=ok new_authtok_reqd=ok default=ignore]
5. /etc/pam.d/ 設定
5.1 設定ファイル構造
# /etc/pam.d/ ディレクトリの内容確認
ls -la /etc/pam.d/
# 出力例:
# -rw-r--r-- 1 root root 384 Jan 10 2025 common-account
# -rw-r--r-- 1 root root 581 Jan 10 2025 common-auth
# -rw-r--r-- 1 root root 508 Jan 10 2025 common-password
# -rw-r--r-- 1 root root 622 Jan 10 2025 common-session
# -rw-r--r-- 1 root root 613 Jan 10 2025 common-session-noninteractive
# -rw-r--r-- 1 root root 170 Jan 10 2025 login
# -rw-r--r-- 1 root root 92 Jan 10 2025 other
# -rw-r--r-- 1 root root 143 Jan 10 2025 passwd
# -rw-r--r-- 1 root root 520 Jan 10 2025 sshd
# -rw-r--r-- 1 root root 232 Jan 10 2025 su
# -rw-r--r-- 1 root root 257 Jan 10 2025 sudo
# 設定ファイルのフォーマット:
# type control module-path [module-arguments]
5.2 共通設定ファイル (Ubuntu/Debian)
# /etc/pam.d/common-auth
cat /etc/pam.d/common-auth
# 出力例:
# auth [success=1 default=ignore] pam_unix.so nullok
# auth requisite pam_deny.so
# auth required pam_permit.so
# auth optional pam_cap.so
# /etc/pam.d/common-account
cat /etc/pam.d/common-account
# 出力例:
# account [success=1 new_authtok_reqd=done default=ignore] pam_unix.so
# account requisite pam_deny.so
# account required pam_permit.so
# /etc/pam.d/common-password
cat /etc/pam.d/common-password
# 出力例:
# password requisite pam_pwquality.so retry=3
# password [success=1 default=ignore] pam_unix.so obscure use_authtok \
# try_first_pass sha512 remember=5
# password requisite pam_deny.so
# password required pam_permit.so
# /etc/pam.d/common-session
cat /etc/pam.d/common-session
# 出力例:
# session [default=1] pam_permit.so
# session requisite pam_deny.so
# session required pam_permit.so
# session optional pam_umask.so
# session required pam_unix.so
# session optional pam_systemd.so
5.3 サービス別設定ファイル (RHEL/CentOS)
# /etc/pam.d/system-auth (RHEL/CentOS)
cat /etc/pam.d/system-auth
# auth required pam_env.so
# auth required pam_faildelay.so delay=2000000
# auth required pam_faillock.so preauth silent deny=5 unlock_time=900
# auth sufficient pam_unix.so nullok
# auth [default=die] pam_faillock.so authfail deny=5 unlock_time=900
# auth sufficient pam_faillock.so authsucc deny=5 unlock_time=900
# auth required pam_deny.so
#
# account required pam_unix.so
# account sufficient pam_localuser.so
# account sufficient pam_succeed_if.so uid < 1000 quiet
# account required pam_permit.so
#
# password requisite pam_pwquality.so retry=3
# password sufficient pam_unix.so sha512 shadow nullok use_authtok remember=5
# password required pam_deny.so
#
# 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
# /etc/pam.d/sshd
cat /etc/pam.d/sshd
# auth substack password-auth
# auth include postlogin
# account required pam_sepermit.so
# 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 required pam_namespace.so
# session optional pam_keyinit.so force revoke
# session optional pam_motd.so
# session include password-auth
# session include postlogin
6. 主要な PAM モジュール
6.1 pam_unix - 標準 UNIX 認証
# pam_unix は最も基本的な認証モジュール
# /etc/passwd, /etc/shadow を使用
# 主なオプション:
# nullok - 空パスワードを許可
# shadow - /etc/shadow を使用
# sha512 - SHA-512 ハッシュ
# remember=N - N 個のパスワード履歴を保存
# use_authtok - 前のモジュールが設定したトークンを使用
# try_first_pass - 前のモジュールのパスワードを先に試す
# 設定例
auth sufficient pam_unix.so nullok try_first_pass
account required pam_unix.so
password sufficient pam_unix.so sha512 shadow nullok use_authtok remember=12
session required pam_unix.so
6.2 pam_ldap - LDAP 認証
# LDAP サーバーに対して認証を行う
# インストール
apt install libpam-ldap # Ubuntu/Debian
dnf install nss-pam-ldapd # RHEL/CentOS
# /etc/pam.d/common-auth (LDAP統合)
auth [success=2 default=ignore] pam_unix.so nullok
auth [success=1 default=ignore] pam_ldap.so use_first_pass
auth requisite pam_deny.so
auth required pam_permit.so
# /etc/pam.d/common-account (LDAP統合)
account [success=2 new_authtok_reqd=done default=ignore] pam_unix.so
account [success=1 default=ignore] pam_ldap.so
account requisite pam_deny.so
account required pam_permit.so
# LDAP設定 (/etc/ldap.conf or /etc/pam_ldap.conf)
# uri ldap://ldap.example.com
# base dc=example,dc=com
# ldap_version 3
# pam_password md5
# pam_filter objectclass=posixAccount
# pam_login_attribute uid
# pam_member_attribute memberUid
6.3 pam_sssd - SSSD 認証
# SSSD (System Security Services Daemon) による統合認証
# LDAP, Active Directory, FreeIPA に対応
# インストール
apt install sssd sssd-ldap # Ubuntu/Debian
dnf install sssd sssd-ldap # RHEL/CentOS
# /etc/sssd/sssd.conf
cat > /etc/sssd/sssd.conf << 'EOF'
[sssd]
config_file_version = 2
services = nss, pam
domains = example.com
[domain/example.com]
id_provider = ldap
auth_provider = ldap
ldap_uri = ldaps://ldap.example.com
ldap_search_base = dc=example,dc=com
ldap_id_use_start_tls = True
ldap_tls_cacert = /etc/ssl/certs/ca-certificates.crt
cache_credentials = True
offline_credentials_expiration = 7
[nss]
filter_groups = root
filter_users = root
[pam]
offline_credentials_expiration = 7
offline_failed_login_attempts = 3
offline_failed_login_delay = 5
EOF
chmod 600 /etc/sssd/sssd.conf
# PAM 設定
# /etc/pam.d/common-auth (SSSD統合)
auth [success=2 default=ignore] pam_unix.so nullok
auth [success=1 default=ignore] pam_sss.so use_first_pass
auth requisite pam_deny.so
auth required pam_permit.so
# SSSD の起動
systemctl enable --now sssd
6.4 pam_faillock - アカウントロックアウト
# pam_faillock はログイン失敗のカウントとロックアウトを管理
# (pam_tally2 の後継)
# /etc/security/faillock.conf
cat > /etc/security/faillock.conf << 'EOF'
deny = 5
unlock_time = 900
fail_interval = 900
even_deny_root
root_unlock_time = 60
dir = /var/run/faillock
audit
EOF
# PAM 設定
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
auth requisite pam_deny.so
auth required pam_permit.so
account required pam_faillock.so
# ロックアウト管理コマンド
faillock --user username # 状態確認
faillock --user username --reset # リセット
faillock # 全ユーザー表示
6.5 pam_pwquality - パスワード品質
# パスワードの複雑性を強制する
# /etc/security/pwquality.conf
minlen = 14
minclass = 3
ucredit = -1
lcredit = -1
dcredit = -1
ocredit = -1
difok = 8
maxrepeat = 3
maxclassrepeat = 4
usercheck = 1
dictcheck = 1
enforcecheck = 1
retry = 3
enforce_for_root
# PAM 設定
password requisite pam_pwquality.so retry=3
password sufficient pam_unix.so sha512 shadow use_authtok remember=12
6.6 pam_limits - リソース制限
# ユーザーやグループに対するリソース制限を設定
# /etc/security/limits.conf
# <domain> <type> <item> <value>
#
# domain: ユーザー名, @グループ名, * (全員)
# type: soft (変更可能な制限), hard (上限)
# item: core, data, fsize, memlock, nofile, nproc, stack, cpu, etc.
cat > /etc/security/limits.d/99-hardening.conf << 'EOF'
# コアダンプの無効化
* hard core 0
# ファイルディスクリプタ制限
* soft nofile 4096
* hard nofile 65536
# プロセス数制限
* soft nproc 4096
* hard nproc 16384
# メモリロック制限
* soft memlock 65536
* hard memlock 65536
# 特定グループの制限
@developers soft nofile 8192
@developers hard nofile 131072
# 特定ユーザーの制限
admin soft nproc unlimited
admin hard nproc unlimited
EOF
# 現在の制限確認
ulimit -a
# 出力例:
# core file size (blocks, -c) 0
# data seg size (kbytes, -d) unlimited
# file size (blocks, -f) unlimited
# max locked memory (kbytes, -l) 65536
# max memory size (kbytes, -m) unlimited
# open files (-n) 4096
# pipe size (512 bytes, -p) 8
# stack size (kbytes, -s) 8192
# cpu time (seconds, -t) unlimited
# max user processes (-u) 4096
# virtual memory (kbytes, -v) unlimited
# PAM 設定
session required pam_limits.so
6.7 pam_access - アクセス制御
# ユーザー/グループに対してログイン元に基づくアクセス制御
# /etc/security/access.conf
# フォーマット: permission : users/groups : origins
# permission: + (許可) or - (拒否)
# origins: ホスト名, IPアドレス, ネットワーク, tty, ALL, LOCAL
cat > /etc/security/access.conf << 'EOF'
# root はコンソールからのみログイン可能
+ : root : LOCAL
# 管理者グループは管理ネットワークからのみ
+ : @admins : 10.0.0.0/24
+ : @admins : LOCAL
# 開発者グループは社内ネットワークから
+ : @developers : 192.168.0.0/16
+ : @developers : LOCAL
# その他のユーザーは全て拒否
- : ALL : ALL
EOF
# PAM 設定
account required pam_access.so
6.8 pam_time - 時間帯制御
# 時間帯に基づくアクセス制御
# /etc/security/time.conf
# フォーマット: services;ttys;users;times
# services: サービス名 (login, sshd, etc.)
# ttys: 端末名 (* = all)
# users: ユーザー名/グループ名 (!で否定)
# times: 日時指定
cat > /etc/security/time.conf << 'EOF'
# 月曜〜金曜の9:00〜18:00のみSSHログインを許可
sshd;*;@developers;Wk0900-1800
# root は常に許可
sshd;*;root;Al0000-2400
# 週末はメンテナンスグループのみ
sshd;*;@maintenance;Wd0000-2400
# すべてのサービスについて、一般ユーザーは営業時間のみ
*;*;!root;Wk0800-2000
EOF
# 時間指定の形式:
# Mo Tu We Th Fr Sa Su - 個別の曜日
# Wk - 平日 (月〜金)
# Wd - 週末 (土日)
# Al - すべて
# HHMM-HHMM - 時間範囲
# PAM 設定
account required pam_time.so
6.9 pam_motd - ログインメッセージ
# ログイン時にメッセージを表示
# 静的 MOTD
cat > /etc/motd << 'EOF'
Authorized access only.
All activity is monitored and logged.
EOF
# 動的 MOTD スクリプト
# /etc/update-motd.d/ ディレクトリ内のスクリプトが順番に実行される
cat > /etc/update-motd.d/10-system-info << 'SCRIPT'
#!/bin/bash
echo "========================================"
echo " Hostname: $(hostname)"
echo " Date: $(date)"
echo " Uptime: $(uptime -p)"
echo " Load: $(cat /proc/loadavg | awk '{print $1, $2, $3}')"
echo " Memory: $(free -h | grep Mem | awk '{print $3"/"$2}')"
echo " Disk: $(df -h / | tail -1 | awk '{print $3"/"$2" ("$5")"}')"
echo "========================================"
SCRIPT
chmod +x /etc/update-motd.d/10-system-info
# PAM 設定
session optional pam_motd.so motd=/run/motd.dynamic
session optional pam_motd.so noupdate
6.10 pam_env - 環境変数設定
# ログイン時に環境変数を設定
# /etc/security/pam_env.conf
# フォーマット: VARIABLE [DEFAULT=[value]] [OVERRIDE=[value]]
cat > /etc/security/pam_env.conf << 'EOF'
# 基本環境変数
EDITOR DEFAULT=vim
VISUAL DEFAULT=vim
PAGER DEFAULT=less
# ロケール設定
LANG DEFAULT=en_US.UTF-8
LC_ALL DEFAULT=en_US.UTF-8
# PATH の追加
PATH DEFAULT=${PATH}:/usr/local/bin
# カスタム環境変数
COMPANY_ENV DEFAULT=production
EOF
# /etc/environment (システム全体の環境変数)
cat > /etc/environment << 'EOF'
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
LANG="en_US.UTF-8"
EOF
# PAM 設定
session required pam_env.so readenv=1
session required pam_env.so readenv=1 envfile=/etc/default/locale
6.11 pam_mkhomedir - ホームディレクトリ自動作成
# LDAP/SSSD ユーザーのホームディレクトリを自動作成
# PAM 設定
session required pam_mkhomedir.so skel=/etc/skel umask=0027
# オプション:
# skel=DIR - スケルトンディレクトリ (テンプレート)
# umask=MASK - 作成時の umask
# スケルトンディレクトリの内容確認
ls -la /etc/skel/
# 出力例:
# -rw-r--r-- 1 root root 220 Jan 6 2022 .bash_logout
# -rw-r--r-- 1 root root 3771 Jan 6 2022 .bashrc
# -rw-r--r-- 1 root root 807 Jan 6 2022 .profile
# カスタムスケルトンの作成
mkdir -p /etc/skel/.ssh
chmod 700 /etc/skel/.ssh
cat > /etc/skel/.bashrc << 'EOF'
# Custom bashrc for new users
export EDITOR=vim
alias ll='ls -la'
EOF
6.12 pam_tally2 - ログイン試行カウント (レガシー)
# 注意: pam_tally2 は非推奨。pam_faillock を使用すること。
# RHEL 8+ / Ubuntu 22.04+ では pam_faillock が推奨
# レガシー設定 (参考)
auth required pam_tally2.so deny=5 onerr=fail unlock_time=900 \
even_deny_root root_unlock_time=60
account required pam_tally2.so
# カウンターの確認
pam_tally2 --user=username
# 出力例:
# Login Failures Latest failure From
# username 3 01/15/25 14:30:22 192.168.1.100
# カウンターのリセット
pam_tally2 --user=username --reset
7. パスワード複雑性要件
7.1 pam_pwquality の詳細設定
# /etc/security/pwquality.conf の全パラメータ
cat > /etc/security/pwquality.conf << 'EOF'
# === 文字要件 ===
# 最小パスワード長
minlen = 14
# 最小文字クラス数 (大文字、小文字、数字、記号)
minclass = 3
# 各文字クラスの最小数 (負の値 = 必須数)
ucredit = -1 # 大文字: 最低1文字
lcredit = -1 # 小文字: 最低1文字
dcredit = -1 # 数字: 最低1文字
ocredit = -1 # 記号: 最低1文字
# === 品質チェック ===
# 旧パスワードとの差分文字数
difok = 8
# ユーザー名チェック (パスワードにユーザー名を含まないか)
usercheck = 1
# GECOS フィールドチェック (ユーザーのフルネーム等)
gecoscheck = 1
# 辞書チェック (cracklib辞書)
dictcheck = 1
# === 繰り返し制限 ===
# 連続する同一文字の最大数
maxrepeat = 3
# 連続する同一クラスの最大数
maxclassrepeat = 4
# 回文チェック
palindrome = 1
# === その他 ===
# 不正パスワード入力の再試行回数
retry = 3
# root にもポリシーを強制
enforce_for_root
# 拒否されたパスワードについてのメッセージ
badwords = password company admin root
# ローカルユーザーの辞書ファイル
# dictpath = /usr/share/dict/words
EOF
7.2 パスワード複雑性テスト
# pwscore コマンドでパスワード強度をテスト
echo "MyP@ssw0rd123!" | pwscore
# 出力: 82
echo "password" | pwscore
# 出力: (エラーメッセージ)
# Password quality check failed:
# The password fails the dictionary check - it is based on a dictionary word
# cracklib-check でのテスト
echo "testpassword" | cracklib-check
# 出力: testpassword: it is based on a dictionary word
echo "X9#kL2mN@pQ4" | cracklib-check
# 出力: X9#kL2mN@pQ4: OK
8. アカウントロックアウトポリシー
8.1 包括的なロックアウト設定
# === /etc/security/faillock.conf ===
cat > /etc/security/faillock.conf << 'EOF'
# 5回の失敗でロックアウト
deny = 5
# 15分後に自動アンロック (0=手動のみ)
unlock_time = 900
# 15分以内の失敗をカウント
fail_interval = 900
# root もロックアウト対象
even_deny_root
# root のアンロック時間 (短めに設定)
root_unlock_time = 60
# 監査ログの記録
audit
# サイレントモード (セキュリティ上推奨)
silent
# ロックアウトデータの保存先
dir = /var/run/faillock
EOF
# === PAM 設定 (auth スタック) ===
# /etc/pam.d/system-auth or /etc/pam.d/common-auth
# preauth: 認証前にロックアウト状態をチェック
auth required pam_faillock.so preauth
# 通常の認証
auth [success=1 default=ignore] pam_unix.so nullok
# authfail: 認証失敗時にカウント
auth [default=die] pam_faillock.so authfail
# authsucc: 認証成功時にカウンターリセット
auth sufficient pam_faillock.so authsucc
auth requisite pam_deny.so
auth required pam_permit.so
# === PAM 設定 (account スタック) ===
account required pam_faillock.so
account required pam_unix.so
8.2 ロックアウト管理
# ユーザーのロックアウト情報を表示
faillock --user john
# 出力例:
# john:
# When Type Source Valid
# 2025-01-15 10:00:01 RHOST 192.168.1.100 V
# 2025-01-15 10:00:05 RHOST 192.168.1.100 V
# 2025-01-15 10:00:09 RHOST 192.168.1.100 V
# 2025-01-15 10:00:13 RHOST 192.168.1.100 V
# 2025-01-15 10:00:17 RHOST 192.168.1.100 V
# ロックアウトの解除
faillock --user john --reset
# 全ユーザーのロックアウト状態を確認
faillock
# ロックアウト監視スクリプト
cat > /usr/local/bin/check-lockouts.sh << 'SCRIPT'
#!/bin/bash
LOCKED_USERS=$(faillock 2>/dev/null | grep -B1 "V$" | grep ":" | cut -d: -f1 | sort -u)
if [ -n "$LOCKED_USERS" ]; then
echo "=== Locked Out Users ==="
for user in $LOCKED_USERS; do
COUNT=$(faillock --user "$user" 2>/dev/null | grep "V$" | wc -l)
echo " $user: $COUNT failed attempts"
done
fi
SCRIPT
chmod +x /usr/local/bin/check-lockouts.sh
9. PAM による多要素認証
9.1 Google Authenticator (TOTP)
# Google Authenticator PAM モジュールのインストール
apt install libpam-google-authenticator # Ubuntu/Debian
dnf install google-authenticator # RHEL/CentOS (EPEL必要)
# ユーザーごとの初期設定
google-authenticator
# 対話形式で以下を設定:
# - 時間ベース (TOTP) トークンを使用するか? → y
# - QRコードが表示される (Google Authenticator アプリでスキャン)
# - 緊急バックアップコードが生成される
# - .google_authenticator ファイルの更新を許可? → y
# - 同一トークンの複数使用を禁止? → y
# - 時間ずれの許容? → y (1分程度)
# - レート制限を有効化? → y
# PAM 設定 (/etc/pam.d/sshd)
# SSH鍵認証 + TOTP の二要素認証
auth required pam_google_authenticator.so nullok
# SSH 設定 (/etc/ssh/sshd_config)
# ChallengeResponseAuthentication yes
# AuthenticationMethods publickey,keyboard-interactive
# KbdInteractiveAuthentication yes
# sshd の再起動
systemctl restart sshd
# テスト接続
ssh -o PubkeyAuthentication=yes user@server
# パスワード入力後にワンタイムパスワードが求められる
9.2 YubiKey による認証
# YubiKey PAM モジュールのインストール
apt install libpam-yubico # Ubuntu/Debian
dnf install pam_yubico # RHEL/CentOS
# PAM 設定
auth required pam_yubico.so id=<API_CLIENT_ID> key=<API_SECRET_KEY> \
authfile=/etc/yubikey_mappings
# ユーザーとYubiKeyのマッピング
cat > /etc/yubikey_mappings << 'EOF'
admin:ccccccxxxxx1
john:ccccccxxxxx2:ccccccxxxxx3
EOF
9.3 FIDO2/U2F による認証
# pam-u2f のインストール
apt install libpam-u2f # Ubuntu/Debian
# U2F キーの登録
mkdir -p ~/.config/Yubico
pamu2fcfg > ~/.config/Yubico/u2f_keys
# 追加のキー登録
pamu2fcfg -n >> ~/.config/Yubico/u2f_keys
# PAM 設定
auth required pam_u2f.so authfile=/etc/u2f_mappings cue nouserok
# システム全体のマッピングファイル
# /etc/u2f_mappings
# username:key_handle,public_key,...
10. 高度な PAM 設定例
10.1 LDAP + TOTP の多要素認証
# /etc/pam.d/sshd (LDAP + Google Authenticator)
auth required pam_env.so
auth required pam_faillock.so preauth silent
auth [success=2 default=ignore] pam_unix.so nullok
auth [success=1 default=ignore] pam_sss.so use_first_pass
auth requisite pam_deny.so
auth [default=die] pam_faillock.so authfail
auth sufficient pam_faillock.so authsucc
auth required pam_google_authenticator.so
account required pam_faillock.so
account required pam_unix.so
account sufficient pam_sss.so
account required pam_permit.so
password requisite pam_pwquality.so retry=3
password sufficient pam_unix.so sha512 shadow use_authtok remember=12
password sufficient pam_sss.so use_authtok
password required pam_deny.so
session required pam_limits.so
session required pam_unix.so
session optional pam_sss.so
session optional pam_mkhomedir.so skel=/etc/skel umask=0077
session optional pam_motd.so
10.2 時間帯とネットワークに基づくアクセス制御
# /etc/pam.d/sshd (時間帯 + ネットワーク制限)
auth required pam_env.so
auth required pam_faillock.so preauth
auth sufficient pam_unix.so nullok
auth [default=die] pam_faillock.so authfail
auth sufficient pam_faillock.so authsucc
auth required pam_deny.so
account required pam_faillock.so
account required pam_unix.so
account required pam_access.so # ネットワーク制限
account required pam_time.so # 時間帯制限
# /etc/security/access.conf
+ : @admins : ALL
+ : @developers : 10.0.0.0/8
+ : @operators : 10.0.0.0/8 172.16.0.0/12
- : ALL : ALL
# /etc/security/time.conf
sshd;*;@developers;Wk0800-2000
sshd;*;@admins;Al0000-2400
10.3 グループベースの sudo 設定
# /etc/pam.d/sudo
auth required pam_env.so
auth required pam_faillock.so preauth
auth sufficient pam_unix.so
auth [default=die] pam_faillock.so authfail
auth sufficient pam_faillock.so authsucc
auth required pam_deny.so
# wheel グループのみ sudo を許可
auth required pam_wheel.so use_uid
account required pam_unix.so
account required pam_faillock.so
session required pam_limits.so
session required pam_unix.so
session required pam_env.so
11. トラブルシューティング
11.1 PAM デバッグの有効化
# モジュールレベルのデバッグ
# 各モジュールに debug オプションを追加
auth required pam_unix.so debug
auth required pam_faillock.so preauth debug
# syslog でデバッグメッセージを確認
tail -f /var/log/auth.log # Ubuntu/Debian
tail -f /var/log/secure # RHEL/CentOS
# journalctl での確認
journalctl -f -u sshd
journalctl -f _COMM=sshd
11.2 一般的な問題と解決策
| 問題 | 原因 | 解決策 |
|---|---|---|
| ログインできない | PAM 設定エラー | シングルユーザーモードで /etc/pam.d/ を確認 |
| パスワード変更できない | pwquality 要件未満 | pwscore でテスト、要件を確認 |
| LDAP ユーザーがログインできない | SSSD/LDAP 接続エラー | systemctl status sssd、ログを確認 |
| ロックアウトが解除されない | faillock 設定 | faillock --user USER --reset |
| ホームディレクトリが作成されない | pam_mkhomedir 未設定 | session に pam_mkhomedir.so を追加 |
| MFA が動作しない | SSH 設定の不整合 | AuthenticationMethods を確認 |
| 権限エラー | SELinux | audit2allow で原因を調査 |
11.3 PAM 設定のテスト方法
# pamtester を使用したテスト
apt install pamtester # Ubuntu/Debian
# 認証テスト
pamtester login username authenticate
# パスワード入力を求められる
# アカウントチェック
pamtester login username acct_mgmt
# セッションテスト
pamtester login username open_session
pamtester login username close_session
# 常にバックアップを保持する
cp -a /etc/pam.d /etc/pam.d.backup
# 緊急時の復旧
# 1. シングルユーザーモードで起動
# 2. /etc/pam.d/ をバックアップから復元
# 3. または /etc/pam.d/other を最小設定にする
cat > /etc/pam.d/other << 'EOF'
auth required pam_unix.so
account required pam_unix.so
password required pam_unix.so
session required pam_unix.so
EOF
11.4 PAM 設定の検証スクリプト
#!/bin/bash
# pam-check.sh - PAM設定の健全性チェック
echo "=== PAM Configuration Health Check ==="
# 1. 設定ファイルの構文チェック
echo ""
echo "--- Syntax Check ---"
for f in /etc/pam.d/*; do
while IFS= read -r line; do
# コメントと空行をスキップ
[[ "$line" =~ ^[[:space:]]*# ]] && continue
[[ -z "$line" ]] && continue
# 基本的な構文チェック
if ! echo "$line" | grep -qP '^(auth|account|password|session)\s+(required|requisite|sufficient|optional|include|substack|\[)'; then
echo " WARNING: $f: Invalid line: $line"
fi
done < "$f"
done
echo " Syntax check complete."
# 2. モジュールの存在確認
echo ""
echo "--- Module Existence Check ---"
for f in /etc/pam.d/*; do
grep -oP '/\S+\.so' "$f" 2>/dev/null | while read -r mod; do
if [ ! -f "$mod" ]; then
echo " MISSING: $f references $mod (not found)"
fi
done
done
# 3. セキュリティ設定の確認
echo ""
echo "--- Security Settings Check ---"
# faillock の確認
if grep -rq "pam_faillock" /etc/pam.d/; then
echo " [OK] pam_faillock is configured"
else
echo " [WARN] pam_faillock is NOT configured"
fi
# pwquality の確認
if grep -rq "pam_pwquality" /etc/pam.d/; then
echo " [OK] pam_pwquality is configured"
else
echo " [WARN] pam_pwquality is NOT configured"
fi
# pam_wheel の確認 (sudo)
if grep -q "pam_wheel" /etc/pam.d/su 2>/dev/null; then
echo " [OK] pam_wheel is configured for su"
else
echo " [WARN] pam_wheel is NOT configured for su"
fi
echo ""
echo "=== Check Complete ==="
12. ベストプラクティス
12.1 PAM 設定のベストプラクティス
| 項目 | 推奨事項 | 優先度 |
|---|---|---|
| バックアップ | 変更前に必ず /etc/pam.d/ のバックアップを取得 | 最高 |
| テスト | 設定変更は別セッションを維持したまま実施 | 最高 |
| ロックアウト | pam_faillock で5回以内のロックアウトを設定 | 高 |
| パスワード品質 | pam_pwquality で14文字以上・3クラス以上を要求 | 高 |
| パスワード履歴 | remember=12 で過去12個のパスワード再利用を防止 | 高 |
| アクセス制御 | pam_access でネットワークベースの制限を実装 | 中 |
| リソース制限 | pam_limits で適切なリソース制限を設定 | 中 |
| MFA | Google Authenticator 等で多要素認証を実装 | 高 |
| ログ | デバッグログを必要時に有効化できるよう準備 | 低 |
| 監査 | PAM 設定の定期的な監査を実施 | 中 |
12.2 セキュリティチェックリスト
# PAM セキュリティ監査チェックリスト
# 1. パスワードポリシーの確認
grep -r "pam_pwquality" /etc/pam.d/
cat /etc/security/pwquality.conf
# 2. ロックアウトポリシーの確認
grep -r "pam_faillock" /etc/pam.d/
cat /etc/security/faillock.conf
# 3. パスワード履歴の確認
grep "remember=" /etc/pam.d/* 2>/dev/null
# 4. root ログイン制限の確認
grep "pam_securetty" /etc/pam.d/login 2>/dev/null
grep "pam_wheel" /etc/pam.d/su 2>/dev/null
# 5. アクセス制御の確認
grep "pam_access" /etc/pam.d/* 2>/dev/null
cat /etc/security/access.conf
# 6. null パスワードの確認
grep "nullok" /etc/pam.d/* 2>/dev/null
# 7. パーミッションの確認
ls -la /etc/pam.d/
# すべて root:root 所有、644 であること
12.3 緊急時の復旧手順
# PAM 設定の破損によりログイン不能になった場合
# 方法1: シングルユーザーモード
# GRUB メニューで 'e' を押してカーネルパラメータに 'single' を追加
# バックアップから復元:
cp -a /etc/pam.d.backup/* /etc/pam.d/
# 方法2: Live CD/USB からの復旧
mount /dev/sda1 /mnt
cp -a /mnt/etc/pam.d.backup/* /mnt/etc/pam.d/
umount /mnt
# 方法3: 最小限の PAM 設定に戻す
for service in login sshd su sudo; do
cat > /etc/pam.d/$service << 'EOF'
auth required pam_unix.so
account required pam_unix.so
password required pam_unix.so
session required pam_unix.so
EOF
done
13. 参考文献
- The Linux-PAM System Administrators' Guide - http://www.linux-pam.org/Linux-PAM-html/Linux-PAM_SAG.html
- The Linux-PAM Module Writers' Guide - http://www.linux-pam.org/Linux-PAM-html/Linux-PAM_MWG.html
- The Linux-PAM Application Developers' Guide - http://www.linux-pam.org/Linux-PAM-html/Linux-PAM_ADG.html
- Red Hat - Configuring PAM - https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/configuring_authentication_and_authorization_in_rhel/configuring-pam
- Ubuntu PAM Configuration - https://ubuntu.com/server/docs/security-pam
- pam_faillock(8) man page - https://man7.org/linux/man-pages/man8/pam_faillock.8.html
- pam_pwquality(8) man page - https://man7.org/linux/man-pages/man8/pam_pwquality.8.html
- pam_unix(8) man page - https://man7.org/linux/man-pages/man8/pam_unix.8.html
- SSSD Documentation - https://sssd.io/docs/introduction.html
- Google Authenticator PAM - https://github.com/google/google-authenticator-libpam
- CIS Benchmarks - PAM Section - https://www.cisecurity.org/cis-benchmarks
本ドキュメントは PAM (Pluggable Authentication Modules) について包括的にまとめたものである。PAM 設定の変更は慎重に行い、必ずバックアップを取得してからテストすること。設定ミスはシステムへのログインを不可能にする可能性がある。