SSHの認証をMFAに
目次
経緯
最近、ランサムやらサイバー攻撃によるシステムへの侵入によって企業の個人情報が漏洩する事件を目の当たりにする。
こういうのを見ていると、こっちもなんかせんといかんかなと不安になる。
ということで、SSHを多要素認証にしてみる。
煩わしくなったらすぐやめよう。

仕組み
サーバ側にTOTPの仕組みを入れて、SSHの認証方式にそれを追加するだけ。
具体的には、Google Authenticator(以下、GA)を入れて、サーバにて生成アルゴリズムを入れて準備しておく。
スマホにもGAを入れておき、このサーバのセキュリティコードを読ませて、同じアルゴリズムでOTPを生成すると。
あとは、SSHDの認証方式の変更と、認証に使っているPAMにGA認証を追加して、振る舞いを決めてあげればよい。
LPICの勉強していれば簡単に構築できるやつ。
PAMなんて久しぶりに触るなぁ、requiredとrequisiteとsufficientとか勉強したな。
ただもう全然覚えてない。
flowchart TD a[SSHD] b[/Auth Methods\] c([Google Authenticator]) d(Pubkey) e([Password]) a---b b-.-od b-.-o|PAM|c b-.-x|PAM|e style a fill:#F79D28,color:#666 style b fill:#996 style c fill:#bbb,color:#555 style e fill:#2893F7 style d fill:#914D91
要件
基本的に私しか使わないので、MFAをグローバルな設定にしてもよいが、何かの拍子でログイン出来なくなるのを避けるために、内部アクセスは通常通り公開鍵認証とする。
必要なもの
- Google Authenticator for PAM
- Google Authenticator for Android(iOS版のどちらか)
- Google Authenticator for iOS(Android版のどちらか)
構築
さて、構築していく。
まずはスマホに上のGAは入れておいて、セットアップしておく。
Google Authenticator
さて、次にサーバにGAを入れる。
ここではdebian 11での例。
以下のコマンドで導入。
$ sudo apt install libpam-google-authenticator |
続いて、個人ユーザ(ここでは私)のセットアップ。
$ google-authenticator |
どデカいQRコードが表示されるので、スマホのGAにて読み取る。
すると、GAのTOTPの一覧に新しく現れるので、そこに表示されるOTPを入力すると認証されるので、バックアップコードが表示されるはず。
そのあとのインストラクションのことを説明。
- 同じ認証トークン(OTP)を何回も利用することを拒否するかを聞いている。この制限により30秒ごとに1度しか使うことが許されなくなる。ただ、セキュリティは格段に上がるので、これはYesにしたほうが良いと思う。
- 既定では認証トークンは30秒ごと生成されると。クライアント・サーバ間の時間のずれの可能性を補うため、現在のトークンだけではなくその前後1つも許可することによって最大30秒のずれが許容されると。既定ではね。これを前後8つまで許容するかと聞いている。前後最大4分が許容される仕組み。これはちょっとどうなんだろう、結構寛大な設定に感じる。Noにすると、既定。ただここでは一旦Yesにして様子をみることに。
- ログイン試行回数を30秒毎に3回までに制限される。これはYesでよい。
で、Secret Keyとバックアップコード、この3つの設定は$HOME/.google_authenticatorに保存される。
SSHD
さて次に、SSHDの設定を変更する。
基本は公開鍵認証でログインしているので、PAMの有効化とキーボードインタラクティブの設定を入れていく。
LAN内のログインでは公開鍵認証のみにする。
$ sudo vi /etc/ssh/sshd_config |
PAM
次に、sshのPAM認証部分を設定していく。
ちなみに、requiredは必ず成功を要求する条件で処理を後ろに流す。
requisiteは必ず成功を要求する条件で失敗したらその場で処理を打ち切る。
sufficientは成功していると他のrequiredが失敗していない限り成功という結果になりそれ以降は処理されない。
LPICで勉強したやつ。懐かしい。
設定の仕方としては、GAの認証部分のみを切り出して別ファイルにしてSSHDの認証部分に置き換える。
今回はもともとのUnix認証部分を思い切って止めて、GAに置き換えてみる。
$ sudo vi /etc/pam.d/google-auth #ファイルを新規作成 |
テスト
さて準備ができているはずなので、試してみる。
クライアントはWindowsであればWSL、MacBookならTerminal、Linuxはまぁ、Gnome-Terminalかな。
$ ssh hostname |
なんかできてる。よいのでは。
細かい設定が必要になった場合は、もっと頭悩ませることになるのかも。