Techtouch Developers Blog

テックタッチ株式会社の開発チームによるテックブログです

AWS MFAを一撃で認証するCLIコマンド作ってみた

adventCalendar-day7

この記事はテックタッチアドベントカレンダー7 日目の記事です。

6 日目はハルキスト伊藤(@ihiroky)による BHO (Browser Helper Object) をめぐる冒険 でした。

プロダクトオーナーの尾崎です。今年の最初に購入したスタンドアローン食器洗い機が便利すぎて、いまだに毎日心の中で感謝し続けている日々です。 今年買ってよかったものダントツ 1 位。ありがとう、サンコーさん。

この記事は何

既存のツールを組み合わせて、AWS CLI の MFA 認証の手間を省くことのできる CLI aws-mfa-shotgunを作ってみたので紹介します。

github.com

当記事では aws-mfa-shotgun を開発した過程とその安全性にまつわる考察を紹介します。

※aws-mfa-shotgun 自体の導入方法については当記事ではあまり触れませんので、README、特にOption to skip MFA code authenticationをご覧ください。

免責事項

当記事は第三者の開発したアプリケーションのリバースエンジニアリングなど不正な行為を推奨するものではありません。 各種サービス、アプリケーションをご利用される際は、それぞれの規約に従って利用されてください。 当記事の情報の使用に起因して生じる結果について一切の責任を負わないものとします。

現状と不満

AWSのベストプラクティスとして定義されているように、弊社では AWS IAM ユーザーに対して MFA を必須にして運用しています。 自ら IAM ユーザーの権限で AWS に対して CLI から何かしら操作をしようとした場合、MFA デバイスで生成される 6 桁の数字(以降、MFA トークン)が必要になるため、弊社ではお手製のシェルスクリプトを作って各自が実行していました。

# aws cliを触る前に忘れず実行する必要あり!
$ aws_mfa ikazoy 123456

スクリプトの例(Python と bash の違いはありますがほとんど同じ処理をしています) dev.classmethod.jp

このようなスクリプトでもある程度は実用に耐えるのですが、使っているうちに以下のような不満が出てきました。

  1. シェルのセッションが変わると再度認証する必要がある(tmux などでバンバン新しいシェルを立ち上げると特に面倒)
  2. 仕事、プライベートなど複数の AWS_PROFILE を利用すると、MFA デバイスの ARN が変わってしまうので、1 つのスクリプトで完結できない
  3. MFA トークンを CLI に入力するのが面倒くさい

順に解決していきます。

1. シェルが変わるたびに認証が必要な問題

github.com

こちら Ruby 製のスクリプトが非常によくできていました。 一度 MFA を通すと ~/.aws 以下に各 AWS_PROFILE ごとにセッション情報を記録しているため、有効期限内であればどのシェルでも確実に認証情報を再利用してくれます。

techtouchという名前の AWS_PROFILE で MFA したときのイメージ

$ cat ~/.aws/aws-mfa-secure-sessions/techtouch
{
  "access_key_id": "xxxxxxxxxxxxxxxxxxxxx",
  "secret_access_key": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "session_token": "IQoJxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx......",
  "expiration": "2020-12-06T15:29:35+00:00"
}

2. 複数のAWS_PROFILEが切り替えられない問題

前述のように aws-mfa-secure は AWS_PROFILE ごとに一時的な認証情報を保持するので、利用時に AWS_PROFILE を確実に指定*1するだけで問題ありません。

簡単ですね。

3. MFAトークンの入力が面倒くさい問題

MFA というと、スマートフォンで実施するのが一般的なイメージかと思いますが、Authyのデスクトップアプリを使うと、普段使っている PC を MFA デバイスとして使うことができます。 この時点で、「別の端末を開いて」「表示されている 6 桁の数字を手で打ち込む」という操作が、「PC 上で別のアプリケーションを開いて」「Authy のコピーボタンを押す&ペースト」となるので、いくぶんかは改善しているように見えます。

しかし、プログラマーの美徳を備えている怠惰な私は、さらに省力化するべく工夫をしました。

と言いながらもあまり大したことはやっていないのですが、MFA トークンを自動生成するための工程を紹介していきます。

  1. MFA トークンを生成するのに必要な secret key を入手する
  2. secret key をセキュアに保存する
  3. secret key から MFA トークンを生成する

トークン生成のためのsecret keyを入手する

macOS での手順*2を説明します。

  1. Authy デスクトップアプリケーションをインストール、目的の AWS アカウントを登録して MFA トークンを生成できるようにする
  2. open -a "Authy Desktop" --args --remote-debugging-port=5858 で Authy を起動する
  3. ブラウザで http://localhost:5858へアクセスする
  4. Twilio Authy というリンクをクリックする
  5. 開発者ツールが開くので、javascriptのコードを Console で実行する
  6. 上記の実行結果として表示される TOTP secret: xxxxxxxxxxxxxxxxxxxxxx部分をコピーする

Export TOTP tokens from Authy · GitHub この gist と一連の議論がたいへん参考になりました。紹介されている別の方法として、authy-exportというコマンドもあるようです。

qiita.com

補足:Authy から secret key を抜き出す方法は上記の記事のように Google Chrome 拡張を利用する方法も見つかりましたが、Authy の Google Chrome の拡張機能は 2020.1 に非推奨となっていますので、近い将来利用できなくなるものと思われます。

なお、後述の secret key の取り扱い、oathtool の利用に関しては上記の記事「CLI で Authy と共通の MFA Token を生成する」を参考にさせていただきました。ありがとうございます。

secret keyをセキュアに保存する

openssl を用いて secret key を暗号化、複合化しています。Authy から取り出した secret key を暗号化して~/.aws以下に保存します。

https://github.com/ikazoy/aws-mfa-shotgun/lib/aws_mfa_secure/base.rb#L117

secret keyからMFAトークンを生成する

OATH toolkitというコマンドを利用すると、簡単に Time-based One Time Password を生成できます。

https://github.com/ikazoy/aws-mfa-shotgun/blob/mfa-shotgun/lib/aws_mfa_secure/base.rb#L132

本当にセキュアなのか?

aws-mfa-shotgun により、Authy のアプリケーションを経由せずに MFA 認証を行えるようになりましたが、ここでセキュリティ面でのリスクについて考えます。

PCのみを使うことで"MFAとしての強度"が下がっているのでは?

スマートフォンにインストールしたアプリケーションで MFA トークンを生成するという従来の方法に比べて、MFA としての強度が下がっていると思われる方もいるかもしれません。

まさに同じ質問(筆者も最初は同様の疑問を持ちました)にAuthyのブログで「ログインに用いる端末と同様の端末を MFA に使用しても MFA として有効である」と回答されています。

two-factor authentication is still valid regardless of whether the second authentication factor “you have” comes from your cellphone, your tablet, or right from a desktop app on your laptop What really matters, is that it is something only you can have. When you register your laptop as a new device with the Authy App for PCs, we use the same secure registration process we use with the mobile app by verifying your identity with your cellphone number – something only you have access to.

PCの紛失、盗難時のリスクは?

Authy から secret key を抽出して別の場所で管理することで、万が一 PC の紛失、盗難が発生した場合のリスクはどうでしょうか? 私の考える答えは「ややリスクが上がっているが実効的はほとんど変わらない」です。

Authy に secret key の管理を任せていた場合、上記の手順で簡単に secret key を取り出すことができてしまいます。一方、今回のように secret key を暗号化して保存しておく方法は、ブルートフォースアタックによって破られる可能性が比較的高いので、そのぶん、攻撃手段を増やしているという点においてセキュリティリスクは少し上がっていると考えられます。

PC の紛失や盗難が発覚した時点で Authy に登録されているデバイスの無効化や AWS アカウントの無効化または更新を行うことが基本の対策になるでしょう。

マルウェアやフィッシングサイトへの対策は?

万が一、マルウェアに感染して PC 内のデータ(Web サイトの Cookie など)を盗まれてしまった場合を考慮すると、MFA の secret key の保存場所はセキュリティ対策において論点にならないでしょう。 また、同様にフィッシングサイトに機密情報を入力してしまうケースを考えた場合も、MFA の secret key の保存場所によってセキュリティリスクが上下することはないでしょう。

まとめ

当記事では、MFA の手間を安全に省きたいという欲求から、実際のツールを開発するまでの過程の紹介とその安全性(MFA 自体の安全性も少し)についての考察を行いました。 結論として、「従来の方法と同等に安全である」と断言できる方法ではないため、利用を検討される際はリスクについて十分に考慮していただくようお願いします。

明日は入澤による「少女に何が起ったか ~少女が他人のウェブサーバー構成を知るまでにやったいくつかのこと、そしてその結末~」です!弊社には文豪が多いようです。

*1:awsp や aws-profile-bash-prompt などのツールを使う選択肢もあり https://github.com/johnnyopao/awsp https://github.com/juhofriman/aws-profile-bash-prompt

*2:Windows, Linux の手順はリンク先 gist を参照