Tech Sketch Bucket of Technical Chips by TIS Inc.

Google Authenticatorを用いた二要素認証をSSHに導入

Pocket

今回はオープンな認証規格であるOATHに対応しているGoogle Authenticatorを使って、
ソフトウェアトークンによるワンタイムパスワードを用いた二要素認証を、SSHのログインに適用してみました。


二要素認証とは

近年、ID/Passwordに加えて、認証デバイスによって生成される毎回異なる値を認証に用いる、
ワンタイムパスワードを用いた二要素認証が様々な所で使われています。

以前から、一定時間ごとに表示される数字が切り替わるような、
ハードウェアトークンを用いたワンタイムパスワードは色々な所で使われていました。
オンラインバンキングを利用したことがある人であれば、実際にトークンをお持ちの人もいるでしょう。
お金に関わる所以外では、オンラインゲームの認証などでも使われています。

一方で最近は、ハードウェアトークンではなく、ソフトウェアトークンを用いたワンタイムパスワードも使われ始めています。
例えばAmazon Web ServiceやGoogle Appsなどが、ソフトウェアトークンによるワンタイムパスワードに対応しています。
ソフトウェアトークンはスマートフォンなどにインストールされたアプリケーションによって毎回異なる数値が生成されるため、
専用の機器の必要が無く、普段持ち歩いているスマートフォンだけで利用することが出来ます。

それでは実際に試してみましょう。

サーバ側のSSH認証をワンタイムパスワードに対応

まずは、サーバ側のSSH認証をワンタイムパスワードに対応させます。

今回はサーバ側の環境として、Ubuntu 11.10のマシンを使用しました。
以下の設定を適用するとパスワードだけではSSHでログインできなくなってしまうので、
SSH以外のログイン手段が無い場合は、念のため公開鍵認証でログインできるユーザを用意しておいてください。
公開鍵認証の場合はPAMを通らないので従来通りログインできるはずです。

作業としては単純で、Google AuthenticatorのPAM Moduleをインストールし、PAMとSSHの設定を変更するだけです。
Ubuntu 11.10以降の場合、aptを使うことで簡単にGoogle AuthenticatorのPAM Moduleをインストールできます。
Ubuntuでそれ以前のバージョンを利用している場合や他のディストリビューションの場合は、以下からソースを取得してインストールすることも出来ます。

注意点として、SSHの設定でChallengeResponseAuthenticationを有効にした結果、PermitRootLogin が without-password になっていても、rootアカウントのChallengeResponseAuthenticationでの認証は可能になってしまいます。
必要であれば、PermitRootLoginを no にするか、PAM側でrootでのログインを禁止する設定などを追記して下さい。

また他の注意点として、今回は時間ベースのワンタイムパスワードを利用します。
この方式は時刻を基準にワンタイムパスワードを検証しているため、サーバ側の時刻と端末側の時刻が大きくずれているとログインに失敗します。
サーバ側の時刻同期を行っていない場合、NTPを使って同期するようにしておいて下さい。

ユーザ側のスマートフォンにGoogle Authenticatorをインストール

次に、ユーザ側のスマートフォンをソフトウェアトークンとして利用するため、Google Authenticatorのアプリをインストールします。
Android/iOSともに、マーケットでGoogle Authenticator, またはGoogle認証システムで検索すると見つかると思います。
アプリの使い方について詳しく知りたい場合は、以下のGoogleのサイトをご覧下さい。
http://support.google.com/accounts/bin/answer.py?hl=ja&answer=1066447

各マーケットのアプリのページは以下の通りです。今回はAndroid版を利用しました。
Android: Google認証システム
iOS: Google Authenticator

ユーザ用のsecret keyをサーバ側で発行し、端末に登録

最後に、ワンタイムパスワードを設定したいユーザでサーバにログインし、secret keyを発行してスマートフォン側に登録します。

google-authenticatorコマンドを実行すると、secret keyと、secret keyのQRコードが表示されるURLが出力されます。
(サーバ側にlibqrencodeがインストールされている場合は、QRコードそのものも標準出力に表示されます)
また端末を紛失するなどしてsecret keyを失ってしまった際の緊急用コードとして、1回だけ使用できるemergency scratch codeというものが5つ出力されているはずです。
他のログイン手段を持っていないのであれば、控えておいて他者の目の届かない所に保管しておきましょう。
secret keyを紛失した場合は、上記のコマンドを再度実行することで再発行できます。

secret keyが発行されたので、今度はそれをスマートフォン側のアプリに登録します。
Google Authenticatorのアプリを起動して、メニューからアカウントを設定を選択すると、
「バーコードをスキャン」という選択肢と「提供されたキーを入力」という選択肢が出てきます。
「バーコードをスキャン」の場合、先ほど表示されたURLにあるQRコードを読み取るだけで登録が完了します。
「提供されたキーを入力」の場合、アカウント名、先ほど表示されたsecret key、
ワンタイムパスワードの方式 (今回はtime-basedにするかの問いにyと答えているので時間ベース)を入力すれば登録が完了します。

以上で準備は完了です。

実際にログインしてみる

では実際にSSHで接続してみましょう。
接続の方法は従来のパスワード認証の場合と変わりません。
接続すると、従来通りパスワードを聞かれた後、Verification codeの入力を求められます。
ここで先ほどのGoogle認証システムのアプリを起動し、30秒ごとに切り替わっている6桁の数値を入力して下さい。
パスワードと6桁の数値の両方が正しければ、認証に成功します。

まとめ

Google Authenticatorを使うことで、SSHに簡単にワンタイムパスワードを導入することができました。
最近は個人へのスマートフォンの普及が進んでいますし、企業内でのスマートフォンの活用も徐々に広がりつつあります。
専用のハードウェアトークンが無くともこういった機器で代用が可能になっています。

今回はGoogle AuthenticatorのPAM Moduleを使ってSSHにワンタイムパスワードを適用しましたが、他にもApacheのBasic認証をワンタイムパスワードに対応させるmod-authn-otpなど、ワンタイムパスワードを利用できる場面は色々あります。
パスワード認証では公開したくないが、鍵は持ち運びたくないといった場合に、選択肢の一つとして検討してみてはどうでしょうか。

エンジニア採用中!私たちと一緒に働いてみませんか?