2026年5月28日

2026年5月28日

SSHの2段階認証をGoogle Authenticatorで設定する方法|公開鍵とワンタイムコード

SSH のログインに、スマートフォンの認証アプリ(Google Authenticator、Microsoft Authenticator など)が 30 秒ごとに表示する 6 桁のコード(TOTP)を加えると、秘密鍵やパスワードが漏れても、それだけではログインできなくなります。

サーバー側で使うのは、Google が公開している PAM モジュール pam_google_authenticator.so です。アプリはサーバーに入れるものではありません。流れは次のとおりです。

  1. サーバーに PAM モジュールを入れる
  2. ログインするユーザーごとに google-authenticator コマンドで秘密鍵を作り、アプリに登録する
  3. /etc/pam.d/sshd と sshd_config を設定して、SSH の認証にコードの入力を加える

この記事では「公開鍵認証に成功したうえで、さらにコードを入力する」構成を作ります。Debian 13(OpenSSH 10.0、libpam-google-authenticator 20191231)で、正しいコードでログインでき、誤ったコードと鍵なしでは拒否されることを確認しました。AlmaLinux 9 ではパッケージと設定ファイルの構成を確認しています(2026年11月時点)。

始める前に

  • 今つないでいる SSH の接続は、最後の確認が終わるまで閉じないでください。 設定を誤ると新しくログインできなくなります。VPS の管理画面にあるコンソール(ブラウザーから操作できる画面)の使い方も確認しておきます。
  • 公開鍵認証でログインできる状態にしておきます。まだの場合は SSHの公開鍵認証を設定する方法 を先に済ませます。
  • TOTP はサーバーの時計がずれていると合いません。時刻が同期されているか確認します。
timedatectl
# System clock synchronized: yes になっていれば同期されている

1. PAM モジュールを入れる

# Debian / Ubuntu
sudo apt update
sudo apt install libpam-google-authenticator

# AlmaLinux / Rocky Linux / RHEL 9(EPEL のパッケージ)
sudo dnf install epel-release
sudo dnf install google-authenticator

パッケージ名に注意してください。Debian/Ubuntu では libpam-google-authenticator、RHEL 系では EPEL の google-authenticator です。どちらにも、秘密鍵を作る google-authenticator コマンドと PAM モジュールが入ります。

2. ユーザーごとに秘密鍵を作る

2 段階認証を使うユーザー自身で実行します(sudo を付けない)。root で実行すると root 用の設定ができます。

google-authenticator

対話形式で質問が出ます。時間ベース(TOTP)にするかに y と答えると、端末に QR コードと秘密鍵(英大文字と数字の文字列)が表示されます。

  1. 認証アプリで QR コードを読み取る(読み取れない場合は秘密鍵を手で入力する)
  2. Enter code from app (-1 to skip): に、アプリに表示されたコードを入力する
  3. 表示された緊急用コード(8 桁、既定で 5 個)を、サーバーの外の安全な場所に控える
  4. 続く質問(設定ファイルの更新、コードの再利用の禁止、許容する時刻のずれ、試行回数の制限)に答える

質問に答える代わりに、オプションでまとめて指定することもできます。

google-authenticator -t -d -f -r 3 -R 30 -w 3
オプション 意味
-t 時間ベース(TOTP)にする
-d 同じコードの再利用を禁止する
-f 確認せずに ~/.google_authenticator に書き込む
-r 3 -R 30 30 秒あたり 3 回までに試行を制限する
-w 3 前後 1 つずつのコードまで受け付ける(時計のずれの許容)

この指定でも、QR コードの表示とアプリのコードの確認(Enter code from app)は行われます。

設定は ~/.google_authenticator に保存されます。1 行目が秘密鍵、" で始まる行が設定、残りの 8 桁の行が緊急用コードです。このファイルが漏れるとコードを作れてしまうので、権限(-r--------、本人だけが読める)を変えないでください。

3. PAM の設定(/etc/pam.d/sshd)

設定ファイルを編集する前に、元のファイルを控えておきます。

sudo cp /etc/pam.d/sshd /etc/pam.d/sshd.bak
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak

/etc/pam.d/sshd の末尾に次の 1 行を加えます。

auth required pam_google_authenticator.so

公開鍵とコードの組み合わせにする場合は、パスワードの入力を求める行をコメントにします。コメントにしないと、コードに加えて Linux のパスワードも聞かれます。

# Debian / Ubuntu の場合
#@include common-auth

# AlmaLinux / RHEL 系の場合
#auth       substack     password-auth

まだ設定していないユーザーの扱い

~/.google_authenticator が無いユーザーは、この設定ではログインできなくなります(確認環境でも、ファイルの無いユーザーは鍵が正しくても拒否されました)。全員の設定が終わるまでの移行期間は、公式の README にある nullok を付けると、ファイルが無いユーザーはコードなしで通せます。

auth required pam_google_authenticator.so nullok

全員の設定が済んだら nullok を外します。

4. sshd の設定

/etc/ssh/sshd_config.d/ に新しいファイルを作ります。sshd は同じ設定項目が複数あると最初に読んだ値を使うため、既存のファイルより先に読まれる名前(数字の小さい名前)にします。

sudo nano /etc/ssh/sshd_config.d/01-2fa.conf
KbdInteractiveAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
  • KbdInteractiveAuthentication yes:PAM がコードの入力を求められるようにする。古い設定名 ChallengeResponseAuthentication は、これの別名で非推奨
  • AuthenticationMethods publickey,keyboard-interactive:公開鍵認証に成功し、さらにキーボード入力(ここではコード)の認証にも成功したときだけログインを許す
  • UsePAM yes が必要です。Debian・Ubuntu・AlmaLinux の標準の設定ではすでに有効です

AlmaLinux 9 では /etc/ssh/sshd_config.d/50-redhat.conf に ChallengeResponseAuthentication no があります。ファイル名を 60-2fa.conf にすると、こちらが後から読まれて無視され、確認環境では sshd -T(設定の確認)で次のエラーが出ました。

Disabled method "keyboard-interactive" in AuthenticationMethods list "publickey,keyboard-interactive"
AuthenticationMethods cannot be satisfied by enabled authentication methods

設定を確かめてから sshd を再起動します。

sudo sshd -t
sudo sshd -T | grep -E "^(usepam|kbdinteractiveauthentication|authenticationmethods)"
usepam yes
kbdinteractiveauthentication yes
authenticationmethods publickey,keyboard-interactive
# Debian / Ubuntu
sudo systemctl restart ssh
# AlmaLinux / RHEL 系
sudo systemctl restart sshd

5. 別の端末からログインを確かめる

今の接続を開いたまま、手元のパソコンで新しい端末を開いてログインします。

ssh user@サーバーのアドレス

公開鍵認証のあとに次の表示が出て、アプリのコードを入れるとログインできれば成功です。

(user@203.0.113.10) Verification code:

確認環境での結果は次のとおりでした。

試したこと 結果
正しい鍵 + 正しいコード ログインできた
正しい鍵 + 誤ったコード Verification code: が再表示され、ログインできなかった
鍵を使わない(-o PubkeyAuthentication=no) Permission denied (publickey). で拒否された
~/.google_authenticator の無いユーザー(nullok なし) Permission denied (keyboard-interactive). で拒否された

うまくいかないときは、ログを見ます。Debian/Ubuntu では /var/log/auth.log または journalctl -u ssh、RHEL 系では /var/log/secure または journalctl -u sshd に、pam_google_authenticator の記録が残ります。

sshd(pam_google_authenticator)[1166]: Invalid verification code for user

確認が終わるまでは、最初の接続を閉じないでください。ログインできない場合は、最初の接続から /etc/pam.d/sshd.bak と sshd_config.bak を戻し、01-2fa.conf を削除して sshd を再起動します。

スマートフォンをなくしたとき

  • 緊急用コード:Verification code: に 8 桁の緊急用コードを入れるとログインできます。各コードは 1 回だけ使えます。
  • 再設定:ログインしたら、本人が google-authenticator を実行し直すと新しい秘密鍵と緊急用コードが作られ、古いアプリの登録は使えなくなります。
  • 誰もログインできない場合:VPS の管理画面のコンソールからログインし、/etc/pam.d/sshd の pam_google_authenticator.so の行をコメントにします。

複数のスマートフォンに登録しておきたい場合は、最初に QR コードを表示したときにそれぞれのアプリで読み取ります。

注意点

  • SFTP や rsync などで鍵だけを使って自動でログインしている処理も、コードを求められて失敗します。自動処理に使うユーザーを分け、Match User で AuthenticationMethods publickey を指定するなどの対応が必要です。
  • 同じ秘密鍵の情報(~/.google_authenticator)をバックアップする場合、そのバックアップも鍵と同じ扱いで保護します。
  • 公開鍵認証を使うなら、パスワードでのログインも止めておくと安全性が上がります。手順は SSHのパスワード認証を無効化する方法 で説明しています。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲