こんにちは、今回はAzure上のサーバにワンタイムパスワード認証(後記OTP認証)を導入し、「SSHキー認証 or パスワード認証」+「OTP認証」のニ要素認証を実現したいと思います。
通常、AzureでCentOSサーバを初期構築した場合のログイン方法はSSHキー認証もしくはパスワード認証となっていますので、OTP認証を導入することでよりセキュアなログインになると思います。
OTP認証の実装は「Google Authenticator PAM module」を利用したいと思います。
Google Authenticator PAM moduleとは
Googleが開発した手軽にOTP認証を実現するPAMモジュールです。
動作概要として、予めログインサーバで秘密鍵を生成、その秘密鍵を携帯端末などにインストールされたトークンソフトウェアに転送します。
トークンソフトウェアは秘密鍵から認証コードを生成し、それをログイン時に入力することでOTP認証を実現します。
つまり、ログインサーバとトークンソフトウェアには同じ秘密鍵が登録されたいるため、同じ方式で生成された双方の認証コードは一致するはずなので、認証が成り立つ訳です。
OTP認証の方式
OTP認証には以下の二つの方式があります。
・HOTP (HMAC-Based One-Time Password Algorithm):
ワンタイムパスワード生成回数をベースに認証コードを生成
・TOTP (Time-Based One-Time Password Algorithm):
時刻をベースに認証コードを生成
どちらが安全かというと、詳しい説明はここでは省略しますが、前者のHOTPとなります。
但し、HOTPは非常にシビアです。何故なら、認証回数と認証コードの生成回数を一致させる必要があり、認証を誤った場合でも認証回数がカウントされてしまうため、更新回数とずれる可能性が非常に大きいです。そのため、厳密な運用管理が必要となります。
今回は様々なアプリケーションやサービスで実績のあるTOTPを実装します。
OTP認証の実装
では早速、構築してみましょう。
以降はroot権限のあるユーザでの操作を想定しています。
仮想マシン構成
インスタンスサイズ:A2 Basic (Core:2/RAM:3.5GB)
OS:CentOS release 7.2 x86_64
パッケージのインストール
必要なパッケージをインストールします。
# yum install autoconf automake libtool git pam-devel
Google Authenticator PAM moduleのビルド
Google Authenticator PAM moduleはGitHubからダウンロードし、ビルドする必要があります。
# git clone https://github.com/google/google-authenticator.git # cd ./google-authenticator/libpam # ./bootstrap.sh # ./configure # make # make install # cp -p /usr/local/lib/security/pam_google_authenticator.so /usr/lib64/security/
各設定変更
[SSHD設定変更] # cp -p /etc/ssh/sshd_config /etc/ssh/sshd_config.org # vi /etc/ssh/sshd_config # diff /etc/ssh/sshd_config.org /etc/ssh/sshd_config 83c83 < ChallengeResponseAuthentication no --- > ChallengeResponseAuthentication yes # systemctl reload sshd [PAM設定変更] # vi /etc/pam.d/google-auth # cat /etc/pam.d/google-auth #%PAM-1.0 auth required pam_env.so auth sufficient pam_google_authenticator.so try_first_pass nullok user=root secret=/var/mfa/${USER}/.google_authenticator auth requisite pam_succeed_if.so uid >= 500 quiet auth required pam_deny.so
■pam_google_authenticator.so
secret=[ファイル名]:シークレットファイルの格納場所を指定。環境変数利用可能。
user=[ユーザ名]:シークレットファイルを読み取るユーザを指定。
nullok:シークレットファイルが指定の格納場所に無かった場合はOTP認証を無視(認証したことに)する。
※この設定は危険なオプションのため、安定動作後に削除した方がいいです。
# cp -p /etc/pam.d/sshd /etc/pam.d/sshd.org # vi /etc/pam.d/sshd # diff /etc/pam.d/sshd.org /etc/pam.d/sshd 4d3 > auth substack google-auth # cat /etc/pam.d/sshd #%PAM-1.0 auth required pam_sepermit.so auth substack password-auth auth substack google-auth auth include postlogin (省略)
OTP認証の実装はこれで終わりです。
OTP認証の事前作業
ここからはOTP認証するための事前準備となります。
テスト用ユーザ作成
テスト用ユーザを作成します。
# useradd testuser
シークレットファイルの生成
デフォルトではユーザホーム配下にシークレットファイルが作成されます。
シークレットファイルは秘密鍵や緊急用バックアップコードなどが記載されている非常に危険なファイルです。
今回はホーム配下には作成せず、/var/mfa/配下にユーザ名のディレクトリを作成し、そこに秘密鍵を生成するようにします。
# mkdir -pm 700 /var/mfa/testuser/ # /usr/local/bin/google-authenticator -s /var/mfa/testuser/.google_authenticator -l "SIOS-AZURE01" -i ""
■google-authenticator
-s:秘密鍵の生成場所を指定します。
-l:トークンソフトウェア上で表示されるラベル名です。デフォルトでは”ユーザ名@ホスト名”となります。
-i:トークンソフトウェア上で表示される発行名です。デフォルトでは”ホスト名”となります。
Do you want authentication tokens to be time-based (y/n) y https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/SIOS-AZURE01%3Fsecret%3DUQ6VLQKN6GJBNWPSCJBOG5EQEM
Your new secret key is: L2AR2YZE5F46U3K5XCQDWDDRWM Your verification code is 152796 Your emergency scratch codes are: 33438824 82126793 78192952 29437113 99200784 Do you want me to update your "/var/mfa/testuser/.google_authenticator" file? (y/n) y # シークレットファイルの生成場所を確認 By default, three tokens are valid at any one time. This accounts for generated-but-not-used tokens and failed login attempts. In order to decrease the likelihood of synchronization problems, this window can be increased from its default size of 3 to 17. 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. By default, this limits attackers to no more than 3 login attempts every 30s. Do you want to enable rate-limiting (y/n) y
トークンソフトウェアに認証情報を登録
携帯端末に「Microsoft Authenticator」をインストールし、上記で表示されたバーコードを読み取るまたは、ログインID及び「Your new secret key is」のコードをを手入力することで、認証コードが表示されます。
OTP認証ログイン
では、ログインテストをしてみましょう。
サーバにログインするターミナルの種類により、若干ログイン操作が異なります。
Tera Termの場合
①ユーザ名を入力し、「チャレンジレスポンス認証を使う」を選択します。
②パスワードを入力します。
③トークンソフトウェアを参照し、認証コードを入力します。
Puttyの場合
①ユーザ名を入力します。
②パスワードを入力します。
③トークンソフトウェアを参照し、認証コードを入力します。
最後に
今回は「Google Authenticator PAM module」を利用して、OTP認証の実装をご紹介させて頂きましたが、運用するためにはシークレットファイルの管理をどうするかが肝となると思います。
シークレットファイルは上記でも記載しましたが秘密鍵などを含む非常に危険なファイルです。
もしログインするサーバ単位でシークレットファイルを作成した場合は、その分をトークンソフトウェアにも登録する必要があるため、管理が非常に煩雑になります。
踏み台となるログインサーバでシークレットファイルを集中管理するなど、運用を十分考慮した上で実装頂ければと思います。
サイオステクノロジー株式会社 山田
関連ドキュメント
Google Authenticator PAM module
https://github.com/google/google-authenticator
HOTP (HMAC-Based One-Time Password Algorithm)
https://www.ietf.org/rfc/rfc4226.txt
TOTP (Time-Based One-Time Password Algorithm)
https://tools.ietf.org/html/rfc6238