インターネットに公開したLinuxサーバーのSSHポートには、公開した翌日から世界中のスキャナーが探りを入れてきます。\`/var/log/secure\`や\`journalctl -u sshd\`を確認すると、1時間に数百件もの不正ログイン試行が記録されている — そんな状況は珍しくありません。
パスワードを複雑にするだけでは根本的な対策になりません。認証情報が流出した瞬間に終わりだからです。
この記事では、TOTPベースの二要素認証(2FA)をLinuxサーバーのSSHに設定する完全な手順を解説します。RHEL9系(Rocky Linux 9/AlmaLinux 9含む)とUbuntu 24.04 LTSの両方で動作確認済みです。パスワードが漏えいしても、スマートフォンの認証コードがなければログインできない構成を30分で構築できます。
この記事のポイント
・TOTPは30秒ごとに変わる6桁コードで、パスワード漏えいだけでは不正ログインを防げる構成にできる
・libpam-google-authenticatorとPAMの設定変更だけでSSHに組み込める
・公開鍵認証との組み合わせはAuthenticationMethodsで2段階を明示するのが確実
・ロックアウト対策としてスクラッチコードを設定直後にオフライン保管すること
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
SSHへの不正ログインがなぜ後を絶たないのか
「22番ポートを開けたら翌日には攻撃が来ている」というのは、インターネットに公開したLinuxサーバーを運用していれば誰でも経験することです。実際に`journalctl`で確認すると、こんなログが延々と流れています。# journalctl -u sshd --since "2026-09-22" | grep "Failed password" Sep 22 03:12:41 web01 sshd[3289]: Failed password for root from 103.114.x.x port 51823 ssh2 Sep 22 03:12:44 web01 sshd[3292]: Failed password for root from 103.114.x.x port 51824 ssh2 Sep 22 03:12:47 web01 sshd[3295]: Failed password for admin from 185.220.x.x port 44218 ssh2 Sep 22 03:15:02 web01 sshd[3311]: Failed password for ubuntu from 45.33.x.x port 60012 ssh2 (以下省略: 1時間に200件超)
二要素認証(2FA)が根本的に異なるのは、「知識(パスワード)+所持(スマートフォン)の2要素が揃わないとログインできない」点です。攻撃者がパスワードを知っていても、あなたのスマートフォンを持っていなければ侵入できません。
TOTPの仕組みと今回の設定ゴール
TOTP(Time-based One-Time Password)は、サーバーとスマートフォンで共有したシークレットキーと現在時刻を組み合わせて、30秒ごとに変わる6桁のコードを生成します。RFC 6238で定義された標準規格であり、Google Authenticator・Authy・1Passwordなど多くのアプリが対応しています。今回の設定完了後、SSHログインフローはこうなります。
・SSHクライアントが接続要求を送る
・サーバーがパスワードを要求(または公開鍵認証)
・サーバーがTOTPコード(Verification Code)を要求
・30秒以内に正しい6桁を入力するとログイン成功
動作確認環境:Rocky Linux 9.4 / Ubuntu 24.04 LTS
libpam-google-authenticatorのインストール
1. Rocky Linux 9 / RHEL 9 / AlmaLinux 9の場合
Rocky Linux 9系では`libpam-google-authenticator`はEPELリポジトリに収録されています。EPELが未導入であればまず有効化します。# EPELリポジトリを有効化(既に有効な場合は不要) dnf install epel-release -y # google-authenticatorとQRコード表示用ツールをインストール dnf install google-authenticator qrencode -y # インストール確認 rpm -q google-authenticator google-authenticator-1.10-2.el9.x86_64
2. Ubuntu 24.04 LTSの場合
Ubuntuはaptで直接インストールできます。apt install libpam-google-authenticator -y # インストール確認 dpkg -l libpam-google-authenticator ii libpam-google-authenticator 20210105-2 amd64 Two-step verification
google-authenticatorコマンドでシークレットキーを初期化する
インストール後、TOTPを有効にしたいユーザーとして(rootではなく対象ユーザーで)`google-authenticator`コマンドを実行します。# 対象ユーザーでログインした状態で実行する google-authenticator
1. 対話式設問への回答と実機の出力例
実行すると以下のような対話式設問が続きます。Do you want authentication tokens to be time-based (y/n) y Warning: pasting the following URL into your browser exposes the OTP secret to Google: https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/... (ここにターミナル上でQRコードが表示される) Your new secret key is: ABCDE23456FGHIJ7 Enter code from app (-1 to skip): 836492 Code confirmed Your emergency scratch codes are: 42815709 91637402 58024167 76310582 30947861 Do you want me to update your "/home/sysadm/.google_authenticator" file? (y/n) y Do you want to disallow multiple uses of the same authentication token? (y/n) y By default, a new token is generated every 30 seconds by the mobile app. In order to compensate for possible time-skew between the client and the server, we allow an extra token before and after the current time. Do you want to do so? (y/n) y If the computer that you are logging into isn't hardened against brute-force login attempts, you can enable rate-limiting for the authentication module. Do you want to enable rate-limiting? (y/n) y
・time-based y/n:時刻ベースのTOTPを使うかどうか。「y」で固定です
・disallow multiple uses:同じコードを1回しか使えなくする(リプレイ攻撃防止)。「y」推奨
・time-skew補正:前後1ステップ(前後30秒)の時刻ズレを許容するか。「y」推奨
・rate-limiting:30秒間に3回までの制限を設ける。「y」推奨
2. QRコードをスマートフォンアプリで読み取る
ターミナルに表示されたQRコードを、Google Authenticator(iOS/Android)やAuthyなどのTOTPアプリで読み取ります。アプリに追加されると、30秒ごとに変わる6桁のコードが表示されるようになります。読み取り後、アプリに表示されているコードをコマンドの「Enter code from app」の設問に入力して正しいことを確認してください。
3. スクラッチコードを必ずオフラインで保管する
表示された5つのスクラッチコード(8桁)は、スマートフォンを紛失・初期化した場合に一度だけ使える緊急ログイン用コードです。これを失うとロックアウトから自力で復旧できなくなります。紙に印刷してオフライン保管するか、専用パスワードマネージャーに保存してください。PAMとsshd_configを変更してSSHにTOTPを組み込む
変更作業中は必ず現在のSSHセッションを維持したまま別セッションでテストしてください。設定ミスでロックアウトされた場合にコンソール(VNC/ILO/iDRAC)以外での復旧が不可能になります。1. /etc/pam.d/sshdを編集する
`/etc/pam.d/sshd`の末尾に以下の1行を追加します。# /etc/pam.d/sshd の末尾に追加(既存行は変更しない) auth required pam_google_authenticator.so
# /etc/pam.d/sshd(末尾抜粋・Rocky Linux 9.4) auth substack password-auth auth include postlogin # ...(省略)... # 末尾に追加した行 auth required pam_google_authenticator.so
2. /etc/ssh/sshd_configを変更する
`/etc/ssh/sshd_config`を開き、キーボードインタラクティブ認証を有効にします。ディストリビューションによって設定キー名が異なります。# RHEL9系 / Rocky Linux 9 / Ubuntu 22.04以降 → KbdInteractiveAuthentication を使用 KbdInteractiveAuthentication yes # 古いOS(CentOS 7等)は下記のキー名を使用 # ChallengeResponseAuthentication yes # UsePAMはyesであることを確認(大半のディストリビューションでデフォルトyes) UsePAM yes
3. sshdの再起動と設定反映確認
変更後は必ず構文チェックをしてからsshdを再起動します。# 構文チェック(エラーがなければ何も出力されない) sshd -t && echo "構文OK" 構文OK # sshdを再起動 systemctl restart sshd # 状態確認 systemctl status sshd | grep -E "Active:|Loaded:" Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; preset: enabled) Active: active (running) since Tue 2026-09-23 14:30:12 JST; 3s ago
動作確認と公開鍵認証との組み合わせ設定
1. Verification Codeが要求されることを確認する
別ターミナルから対象ユーザーでSSH接続します。パスワード入力後に「Verification code:」が表示されれば設定成功です。ssh sysadm@192.168.x.x sysadm@192.168.x.x's password: Verification code:
2. 公開鍵認証とTOTPを組み合わせる設定
公開鍵認証を利用している場合、デフォルトでは公開鍵認証が成功した時点でTOTPなしでログインできてしまいます。公開鍵認証にもTOTPを必須にするには、`/etc/ssh/sshd_config`に次の行を追加します。# 公開鍵認証が成功した後にもTOTPコードを要求する AuthenticationMethods publickey,keyboard-interactive
# 公開鍵認証で接続(鍵のパスフレーズなしの場合) ssh -i ~/.ssh/id_ed25519 sysadm@192.168.x.x # 公開鍵認証成功後、TOTPが要求される Authenticated with partial success. Verification code:
トラブルシュート
【問題1】設定後もVerification Codeが要求されずにログインできてしまう
原因:`/etc/pam.d/sshd`への追記ミス、またはsshd_configの`KbdInteractiveAuthentication`が`no`のまま。# PAM設定確認 grep pam_google /etc/pam.d/sshd auth required pam_google_authenticator.so # この行があればOK # sshd設定確認 sshd -T | grep -iE "kbdinteractive|challengeresponse|usepam" kbdinteractiveauthentication yes usepam yes
【問題2】正しいコードを入力しても「Verification code incorrect」になる
原因の多くはサーバーとスマートフォンの時刻ズレです。TOTPは現在時刻に基づいてコードを生成するため、双方の時刻が数十秒以上ずれると認証が失敗します。ntpd 時刻同期設定を参考にサーバーのNTP同期状態を確認してください。# サーバーのNTP同期状態確認 timedatectl Local time: Tue 2026-09-23 14:35:22 JST Universal time: Tue 2026-09-23 05:35:22 UTC RTC time: Tue 2026-09-23 05:35:22 Time zone: Asia/Tokyo (JST, +0900) System clock synchronized: yes ← yes でなければ要確認 NTP service: active
【問題3】スクラッチコードも尽きてロックアウトされた
コンソール(KVM/VNC/ILO/iDRAC)でサーバーに直接ログインし、`~/.google_authenticator`ファイルを削除すればTOTPが無効化されます。SSHでログインできるようになったら、`google-authenticator`コマンドで再設定してください。# コンソールでログイン後にTOTP設定を削除してSSHを一時無効化 rm ~/.google_authenticator # SSHで再ログインできることを確認後、再設定する google-authenticator
本記事のまとめ
| 手順 | コマンド・設定 |
|---|---|
| インストール(RHEL9系) | dnf install epel-release google-authenticator qrencode |
| インストール(Ubuntu) | apt install libpam-google-authenticator |
| TOTPシークレット初期化 | google-authenticator(対象ユーザーで実行) |
| PAM設定追加 | /etc/pam.d/sshd末尾にauth required pam_google_authenticator.so |
| SSHD設定変更 | KbdInteractiveAuthentication yes(sshd_configに追加) |
| 構文確認と再起動 | sshd -t && systemctl restart sshd |
| 公開鍵+TOTP設定 | AuthenticationMethods publickey,keyboard-interactive |
「こういったセキュリティ設定を迷わず正確に判断できるエンジニアになりたい」という方には、Linuxサーバー管理の実践スキルを2日間で体系的に習得できるセミナーをご用意しています。
SSH二要素認証を設定したら、次はサーバー全体のセキュリティ設計を体系的に固めませんか?
TOTPの設定は「攻撃者を門前払いする入口の鍵」です。しかし現場では、ファイアウォール設計・SELinux・監査ログ・侵入後の検知まで多層防御が求められます。
ネット上の断片的な情報をつなぎ合わせるだけでなく、現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。
「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 前のページへ:LinuxサーバーをrealmdでActive Directoryに参加させる方法|sssdで認証統合する実践手順
- この記事の属するカテゴリ:セキュリティへ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます