以下の記事を教えてもらい、比較的簡単に ssh にワンタイムパスワード認証を追加できるようだったので CentOS 8 でも試してみました。 Raspberry Pi の場合と異なり、SELinux による制御を考慮する必要があったので、それを踏まえて設定しました。
- Setting up two-factor authentication on your Raspberry Pi - Raspberry Pi
https://www.raspberrypi.org/blog/setting-up-two-factor-authentication-on-your-raspberry-pi/
設定方針
ID/パスワードに加えて、ワンタイムパスワードを用いた認証となるよう ssh に Google Authenticator PAM module を設定します。 *1
- GitHub - google/google-authenticator-libpam
https://github.com/google/google-authenticator-libpam#google-authenticator-pam-module
Google Authenticator PAM module の設定
Google Authenticator PAM module のインストール
sudo yum install epel-release
sudo yum install google-authenticator
QRコードを表示するための準備 *2
sudo yum install qrencode
ワンタイムパスワードの生成
google-authenticator -t -d -W -R 30 -r 3 -e 10 -f --secret=/home/${USER}/.ssh/.google_authenticator
設定ファイルの保存場所をデフォルトから変更しているのは、SELinux による制御で認証処理に失敗するのを避けるためです。
うまくいくと QR コードが表示されます。
Microsoft Authenticator
Google Authenticator
確認としてワンタイムパスワードの試し打ちを求められます。 QRコードまたは直後に表示されている secret key をワンタイムパスワードアプリに登録し、 正しく登録できているか試し打ちをします。不要な場合は -1 でスキップできます。
Your new secret key is: ABCDEFGHIJKLMNOPQR123456789 Enter code from app (-1 to skip): -1 Code confirmation skipped Your emergency scratch codes are: 12345678 98765432 12345678 98765432 12345678 98765432 12345678 98765432 12345678 98765432 $
最後に表示される緊急ログイン用のコードは忘れずに安全な場所に書き留めておきます。
なお、設定ファイル(今回であれば /home/${USER}/.ssh/.google_authenticator
)にも記録されています。
sshd の設定
- チャレンジレスポンス認証を有効にします。*5
sudo vim /etc/ssh/sshd_config
# 変更 ChallengeResponseAuthentication yes #ChallengeResponseAuthentication no
- 認証に Google Authenticator を利用するように設定します。
sudo vim /etc/pam.d/sshd
# 追記 auth required pam_google_authenticator.so nullok echo_verification_code secret=/home/${USER}/.ssh/.google_authenticator
- 設定を再読み込み
sudo systemctl reload sshd
*6
以上で設定は完了です。
接続テスト
ssh localhost
うまくいくと以下のように接続後のプロンプトが表示されます。確認できたら Ctrl+D でログオフしておきます。
$ ssh localhost Password: Verification code: 123456 Last failed login: Sun May 17 12:34:56 JST 2020 from ::1 on ssh:notty Last login: Sun May 17 01:23:45 2020 from ::1 $
Tera Term の場合は以下のように「キーボードインタラクティブ認証を使う」にチェックを入れて接続します。
付録 A: 認証コードが正しいのにログインできない
他の記事を参考にワンタイムパスワードの設定をした際に、 ワンタイムパスワードのコードが正しいらしいものの、うまく認証されない事象に遭遇しました。
結果的には SELinux の制御によって認証処理の一部が失敗していることが原因でした。 その際の原因調査についてメモを残しておきます。
設定ファイルの確認
まず設定ファイルが正しく更新されているか確認しました。 これについては特に問題ないようでした。
設定ファイルの確認
sudo vim /etc/ssh/sshd_config
sudo vim /etc/pam.d/sshd
sshd に設定を確実に反映するためリスタート
sudo systemctl restart sshd
*7
ログの確認(ログイン関連)
次にログインに関するログを確認して失敗に関するエラーがないか確認しました。
- ログの確認
sudo tail -n 20 /var/log/secure
sshd 関連のログを探します。
May 17 12:34:18 localhost sshd(pam_google_authenticator)[37213]: Accepted google_authenticator for infected May 17 12:34:18 localhost sshd(pam_google_authenticator)[37213]: Failed to create tempfile "/home/infected/.google_authenticator~rBs26i": Permission denied May 17 12:34:18 localhost sshd(pam_google_authenticator)[37213]: Failed to update secret file "/home/infected/.google_authenticator": Permission denied May 17 12:34:20 localhost sshd[37210]: error: PAM: Authentication failure for infected from ::1 May 17 12:34:22 localhost sshd[37210]: Connection closed by authenticating user infected ::1 port 60116 [preauth]
冒頭に「Accepted google_authenticator」とあるので、認証コードは正しく承認されているように見えます。 しかし、直後に「Failed to create~」「Failed to update」という記述があり、なんらか処理に失敗しているとわかります。 なお、ログ中の infected はユーザ名なので、環境によって異なります。
どうもワンタイムパスワードの設定ファイルに関する処理に失敗しているようです。
当該ファイル「.google_authenticator」のパーミッションは 600 になっていました。
試しに chmod 666 .google_authenticator
として 666 に変更してみます。
May 17 12:34:35 localhost sshd(pam_google_authenticator)[36991]: Secret file "/home/infected/.google_authenticator" permissions (0666) are more permissive than 0600 May 17 12:34:35 localhost sshd(pam_google_authenticator)[36991]: No secret configured for user infected, asking for code anyway. May 17 12:34:48 localhost sshd(pam_google_authenticator)[36991]: Invalid verification code for infected May 17 12:34:50 localhost sshd[36988]: error: PAM: Authentication failure for infected from ::1 May 17 12:34:50 localhost sshd[36988]: Connection closed by authenticating user infected ::1 port 60114 [preauth]
違うそうじゃないと怒られます。むしろ 666 であることを指摘されているので、 chmod 600 .google_authenticator
として 600 に戻しておきました。
ログの確認(SELinux 関連)
以前に SELinux の影響でうまくファイルにアクセスできないことがあったので、SELinux 関連のログを確認しました。
- ログの確認
sudo cat /var/log/messages | grep 'SELinux is preventing' | less
May 17 12:34:18 localhost platform-python[37425]: SELinux is preventing /usr/sbin/sshd from setattr access on the file .google_authenticator~FnhmUt.#012#012***** Plugin catchall (100. confidence) suggests **************************#012#012If you believe that sshd should be allowed setattr access on the .google_authenticator~FnhmUt file by default.#012Then you should report this as a bug.#012You can generate a local policy module to allow this access.#012Do#012allow this access for now by executing:#012# ausearch -c 'sshd' --raw | audit2allow -M my-sshd#012# semodule -X 300 -i my-sshd.pp#012
SELinux が .google_authenticator っぽいファイルへのアクセスについて怒っているようなログが残っていました。 少し読みにくいので #012 を改行に変えて書き直します。
May 17 12:34:18 localhost platform-python[37425]: SELinux is preventing /usr/sbin/sshd from setattr access on the file .google_authenticator~FnhmUt. ***** Plugin catchall (100. confidence) suggests ************************** If you believe that sshd should be allowed setattr access on the .google_authenticator~FnhmUt file by default. Then you should report this as a bug. You can generate a local policy module to allow this access. Do allow this access for now by executing: # ausearch -c 'sshd' --raw | audit2allow -M my-sshd # semodule -X 300 -i my-sshd.pp#012
sshd が不用意に許可されていないファイルにアクセスしていることを SELinux が検知して止めているようです。
対処方法については具体的なコマンドが示されていました。やさしい。。。
ですが、今回の場合はこの指示のとおりのコマンドを入力してもうまくいきません。
これについて、エラー文字列で調べたところ、以下のサイトに解決方法が記載されていました。
- Two factor ssh login, Google authenticator and SELinux
https://blog.boa.nu/2012/11/two-factor-ssh-login-google-authenticator-and-selinux.html
ここに書かれている「Plan B」を試してみます。 要は sshd が既にアクセス許可を得ている.ssh/ 配下にファイルを持ってくればいいという方法です。
以下の通り設定を追加して、設定した場所にファイルを移動させます。
sudo vim /etc/pam.d/sshd
auth required pam_google_authenticator.so secret=/home/${USER}/.ssh/.google_authenticator
上記の方法で無事にログインできるようになりました。*8
付録 B
google-authenticator のオプションについて
Option | Description |
---|---|
-t | ワンタイムパスワードを時間ベースの方式 (TOTP) で生成します。 |
-d | 同じワンタイムパスワードの再使用を禁止します。 |
-R M -r N | M 秒あたりのログイン回数を N 回に制限します。 |
-e | 緊急ログイン用コードの生成数を指定します。 |
-f | 設定ファイルの保存確認を省略します。 |
--secret | 設定ファイルの保存場所を指定します。 |
pam_google_authenticator.so のオプションについて
Option | Description |
---|---|
nullok | ワンタイムパスワードを未設定(.google_authenticator が存在しないユーザ)の場合は ワンタイムパスワードによる認証を省略することを許可します。 |
echo_verification_code | ワンタイムパスワードを入力する際、そのまま画面に表示します。 |
secret | ワンタイムパスワードの設定ファイルの場所を指定します。 |
テストに用いた CentOS のバージョン等
$ cat /etc/redhat-release CentOS Linux release 8.0.1905 (Core) $ uname -a Linux localhost.localdomain 4.18.0-80.el8.x86_64 #1 SMP Tue Jun 4 09:19:46 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
参考文献
GitHub - google/google-authenticator-libpam
https://github.com/google/google-authenticator-libpam#google-authenticator-pam-moduleTwo factor ssh login, Google authenticator and SELinux
https://blog.boa.nu/2012/11/two-factor-ssh-login-google-authenticator-and-selinux.htmlerror : Failed to update secret file "/home/testuser1/.google_authenticator": Permission denied · Issue #101 · google/google-authenticator-libpam · GitHub
https://github.com/google/google-authenticator-libpam/issues/101
5分でできる!SSH + Google Authenticator 二段階認証設定(CentOS7) | あぱーブログ
https://blog.apar.jp/linux/12502/Linuxサーバーへのログインを2段階認証にしてみた - ニフクラ ブログ
https://blog.pfs.nifcloud.com/20191002_2factor_authenticationQRコードを素早く作成する方法 | LFI
https://linuxfan.info/make-qrcodesshd_config&PAMの設定 | OpenGroove
https://open-groove.net/linux/sshd_config-option/
Microsoft Authenticator – オンライン アカウントの安全なアクセスと管理
https://www.microsoft.com/ja-jp/account/authenticatorNew Google Authenticator update makes it worth using again
https://www.bleepingcomputer.com/news/security/new-google-authenticator-update-makes-it-worth-using-again/
更新履歴
- 2020/05/17 新規作成
- 2020/05/17 sshd の設定後に reload するよう追記。アプリの表記を「iPhone」から「iOS」に変更。
- 2020/05/17 冒頭に Google Authenticator PAM module 配布サイトへのリンクを追加。
- 2020/05/18 Microsoft Authenticator の公式サイトを本文中から参考文献に移動。
- 2020/05/18 一部文言を修正。
- 2020/05/21 Google Authenticator アプリについての注釈を追記。
- 2023/01/10 一部リンク切れの旨を追記
*1:公開鍵認証を利用している場合は少しだけ設定方法が異なります。参考文献に記載したサイトなどをご参照ください。
*2:QRコード読み取りではなく、表示されるシークレットキーを手打ちすることでも登録できます。
*3:何をどこまで重視するか次第ですが、 Microsoft Authenticator は iCloud などと連携できるので端末変更時の移行が楽です。
*4:Google Authenticator も Android 版のバージョン 5.10 (2020年5月頃リリース)では端末間でのデータ移行ができるようになったようです。なお、記事執筆時点で iOS 向けにはアップデート版のリリースはされていません。
*5:Google Authenticator もチャレンジレスポンス認証の一種ということのよう。
*6:再読み込みしなくても反映されているようにも見えましたが、sshd がどのタイミングで設定情報を確認しているのかまで未確認のため、念を入れて再読み込みしておきます。
*7:設定ファイルの再読み込み sudo systemctl reload sshd でもよいかも。
*8:公式サイトの issue にも同様のトラブルシューティングが記載されています。 -> https://github.com/google/google-authenticator-libpam/issues/101