家のサーバのsshdへはパスワード認証を無効にして公開鍵認証でログインしていて、接続元のホストを制限しているのだけれど、ふと、踏み台ホストに置いてある私有鍵のパスフレーズを解析されると怖いと思い立って、外からのログインの時には公開鍵認証に加えてTOTPを要求するように設定してみました。
Ubuntu 18.04 LTSのserver版での作業記録です。作業前には、sshdでは公開鍵認証のみが有効になっていました。外からは家庭用ルータのポート転送で接続されます。
TOTPの用意
TOTPはGoogle Authenticatorなどで表示される、シークレットと現在時刻から生成される、30秒ごとに変化する6桁の数字です。Aptパッケージをインストールすることで認証に用いるPAMとTOTPを設定するCLIが利用できるようになりました。
インストール
sudo apt update; sudo apt install libpam-google-authenticator
設定
ログイン先のユーザーとして下記を実行すると、~/.google_authenticator
が生成されてシークレットが保存されます。電話のTOTPアプリの設定には表示されるQRコードを利用できます。QRコードが期待どおり表示されるように端末を広めにしておくと良さそうです。
google-authenticator
PAMの設定
/etc/pam.d/sshd
を編集し、sshdが
- PAM経由でパスワード認証をしないよう、
common-auth
の行をコメントアウトして無効にして、 - TOTP認証をするよう、直下に下記の行を追加
します。
#@include common-auth
auth required pam_google_authenticator.so
sshdの設定
sshdが公開鍵に加えてPAM経由での認証を要求するよう、そして、ローカルなネットワーク(ここでは192.168.0.0/16
)からの接続では公開鍵で認証を済ますように、/etc/ssh/sshd_config
のChallengeResponseAuthentication no
のあたりを下記のように編集します。手元ではlocalhostからのログインは::1
からと認識されるようです。
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
Match Address 192.168.0.0/16,::1
AuthenticationMethods publickey
Match all
この設定を加えて1週間、cronから自動的にログインしてsshするタスクが失敗するのに気づきました。自動運転に使うローカルなアカウントにはTOTPを要求しないようにsshd_config
を下記のような感じに編集しました。だんだん穴が増えていく。
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
Match Address 192.168.0.0/16,::1
AuthenticationMethods publickey
Match User automation,backup
AuthenticationMethods publickey
Match all
sshdの再起動
sshdを再起動して設定を反映します。設定がうまくいかなかった場合にログインできなくならないよう、新規に接続できることを確認できるまで、ログインしてある端末を手元に残しておくと良いでしょう。
sudo service sshd restart