はじめに
Proxmox VEのホストOSに対してSSH接続 + TOTP(Google Authenticator)による多要素認証を導入しようとした際、想定外の挙動に遭遇しました。
具体的には、
- SSH パスワードと TOTP が同時に認識されているように見える
- 「パスワード → OTP」という順序にしたいのに1回の入力で通ってしまう
という現象です。
本記事では、
- 何が起きていたのか
- なぜその挙動になるのか
- どう設計すれば意図通りになるのか
をPAMの内部ロジック視点で整理します。
本記事は筆者がPAM/OpenSSH/TOTP(pam_google_authenticator)について学習・検証している途中の内容を整理したものです。
そのため、記載内容に誤りが含まれている場合があります。
もし誤りなどがありましたら、コメント等でご指摘いただけると助かります。
前提構成
- Proxmox VE(Debian系)
- OpenSSH(UsePAMを利用)
- pam_google_authenticatorによるTOTP
- SSH接続時にパスワード + OTPを要求したい
やりたかったこと(設計意図)
理想の認証フローは以下です。
- SSHクライアントがパスワードを入力
- Proxmox ホストOS側でUNIXパスワードを検証
- その後にOTPを別プロンプトで要求
- 両方成功したらログイン許可
Password → OTP → Login
実際に起きた問題
設定後、SSH接続すると以下のような挙動になりました。
- パスワード入力時にOTPも同時に認識されているように見える
- 1回の入力でログインできてしまう
- ログを見るとPAMは成功扱い
一見すると設定ミスに見えますが、実はこれはPAMの仕様を正しく理解していないと普通に起きる挙動でした。
そもそもPAMとは何か
PAM(Pluggable Authentication Modules)とは、
Linux における認証・アカウント制御・セッション制御を共通化する仕組み
です。
重要なポイントは次の2点です。
- SSHやsudoなどのアプリケーションは**「認証をPAMに委託するだけ」**
- 実際の検証ロジックはpam_unix/pam_google_authenticatorなどのモジュールが担当
UsePAM yesの意味
/etc/ssh/sshd_configに以下を設定すると、
UsePAM yes
sshdは、
- 認証の可否判断
- 追加認証(OTPなど)
- アカウント・セッション管理
をPAMに完全に委譲します。
このとき、sshdは/etc/pam.d/sshdの定義を呼び出します。
PAMは「上から順に」実行される
/etc/pam.d/sshdのauth行は上から順に評価されます。
一部例外あり
例:
auth required pam_unix.so
auth required pam_google_authenticator.so
意味は非常に単純です。
- UNIXパスワードが正しいこと
- OTPが正しいこと
- 両方成功して初めてログイン許可
この直列モデルがPAMの基本です。
なぜ「同時に認識される」ように見えたのか
原因としては、password認証だけで多要素を完結させようとしたが考えられます。
- SSHクライアントは「パスワードは 1 回入力するもの」と想定
- PAM側は「OTPも追加で聞きたい」
このズレにより、
- 同じ入力が再利用される
- プロンプトが分離されない
という事象が起きたと推測できます。
正しい設計(今回のゴール)
sshd_config
PasswordAuthentication no
KbdInteractiveAuthentication yes
AuthenticationMethods keyboard-interactive:pam
UsePAM yes
/etc/pam.d/sshd
@include common-auth
auth required pam_google_authenticator.so
@include common-account
@include common-session
この構成にすると、
- PAMによるUNIXパスワード検証
- OTPを別プロンプトで要求
- 両方成功でログイン
という意図通りの流れになります。
学び・まとめ
今回の躓きから得られた学びは以下です。
-
UsePAM yesは認証ロジックをPAMに丸投げする設定 - PAMはスタック型(上から順)
- OTP が混ざる問題はPAMの入力受け渡し仕様を知らないと起きる
- 「パスワード → OTP」はPAMの順序設計で安全に実現できる