とことんDevOps | 日本仮想化技術のDevOps技術情報メディア

DevOpsに関連する技術情報を幅広く提供していきます。

日本仮想化技術がお届けする「とことんDevOps」では、DevOpsに関する技術情報や、日々のDevOps業務の中での検証結果、TipsなどDevOpsのお役立ち情報をお届けします。
主なテーマ: DevOps、CI/CD、コンテナ開発、IaCなど
読者登録と各種SNSのフォローもよろしくお願いいたします。

AWS VaultでAWS CLIをセキュアに使う

AWS CLIは~/.aws/credentialsに平文でクレデンシャルを保存します。簡単にクレデンシャルが確認できてしまうのでコンピューターにロックをかけないまま離席してしまった日には漏れていてもおかしくありません。そこでクレデンシャルを暗号化しシステムのキーストアに保存するAWS Vaultを使ってみます。

AWS Vault

github.com

AWS Vaultはシステムのキーストアにクレデンシャルを保存することでセキュリティを担保します。対応しているキーストアは以下から確認できます。

https://github.com/99designs/aws-vault?tab=readme-ov-file#vaulting-backends

個人的にpassに対応してるのが好印象ですね、これを見た時に使うことを決意しました。

使い方

使い方の詳細については公式ドキュメントをご覧ください。コマンドラインオプションや環境変数でも色々できそうです。

  • AWS Vaultにプロファイルを追加

    aws-vault addコマンドを実行するとキーIDやシークレットを聞かれるので入力します。dummyという名前でプロファイルを追加してみます。

   $ aws-vault add dummy             
   Enter Access Key ID: ABCDEFGHIJKLMNOP
   Enter Secret Access Key: ****************************************
   Added credentials to profile "dummy" in vault

初めて使用する場合はパスワードの設定を聞かれるので、キーストアに登録するパスワードを入力します。

もしパスワードがわからなくなってしまった場合は復旧することができない?と思うので、諦めて登録したDBを削除するしかない気がします。macOSの場合は↓です。

   rm ~/Library/Keychains/aws-vault.keychain-db

Windowsは使ってないのでわかりません。

  • 登録されているプロファイルを確認

    aws-vault listコマンドで登録されているプロファイルを確認できます。

   $ aws-vault list     
   Profile                  Credentials              Sessions                     
   =======                  ===========              ========                     
   dummy                    dummy                    -
  • プロファイルを使ってコマンドを実行

    登録されているプロファイルを使ってコマンドを実行するにはaws-vault exec <profile-name> -- command ...を実行します。実行するコマンドの前に--をつけているのは、実行するコマンドのコマンドラインオプションをAWS Vaultに取られないようにするためです。--をAWS Vaultに渡すことで、あなたのコマンドラインオプションはここまでよっというのを伝えています。

   $ aws-vault exec dummy -- aws sts get-caller-identity --output table
   -----------------------------------------------------------------------------------
   |                               GetCallerIdentity                                 |
   +--------------+----------------------------------------+-------------------------+
   |    Account   |                 Arn                    |         UserId          |
   +--------------+----------------------------------------+-------------------------+
   |  123456789012|  arn:aws:iam::123456789012:user/dummy  |  ABCDEFGHIJKLMNOPQRSTU  |
   +--------------+----------------------------------------+-------------------------+ 

AWS Vaultからクレデンシャルを取得するためにキーチェーンパスワードを求めてきます。パスワードを入力して「常に許可」としておけば次からは聞かれてないと思いますが、ロックをかけないまま離席したいのなら「許可」をポチって一時的に許可するのがいいかもしれません。私は離席するときに必ずロックをかけるので「常に許可」にしてあります。

  • プロファイルを恒久的に使用する

    aws-vault execコマンドの引数に実行するコマンドを指定することで一時的に指定のプロファイルのアカウントを使用しました。しかし、すべてのコマンドでaws-vault execを先頭につけるのは少々手間です。そこでサブシェルを取得して、シェルを抜けるまでの間、指定のプロファイルでコマンドを実行できるようにします。

   $ aws-vault exec dummy
   Starting subshell /usr/local/bin/zsh, use `exit` to exit the subshell

   $ aws sts get-caller-identity --output table
   -----------------------------------------------------------------------------------
   |                               GetCallerIdentity                                 |
   +--------------+----------------------------------------+-------------------------+
   |    Account   |                 Arn                    |         UserId          |
   +--------------+----------------------------------------+-------------------------+
   |  123456789012|  arn:aws:iam::123456789012:user/dummy  |  ABCDEFGHIJKLMNOPQRSTU  |
   +--------------+----------------------------------------+-------------------------+ 

サブシェルに入るとAWS_VAULTという環境変数にプロファイル名が入ります。

exitコマンドやCtrl-dを押下するとサブシェル抜けられます。

  • クレデンシャルをローテートする

    AWS Vaultにはクレデンシャルをローテートする機能も付属しています。

   $ aws-vault rotate dummy
   Rotating credentials stored for profile 'dummy' using master credentials (takes 10-20 seconds)
   Creating a new access key
   Created new access key ****************WXYZ
   Deleted 1 sessions for playground
   Deleting old access key ****************RSTU
   Deleted old access key ****************RSTU
   Finished rotating access key 

もし↓のようなエラーが出たらIAMユーザーのMFAが有効になっているのかもしれません。

    Rotating credentials stored for profile 'dummy' using a session from profile 'dummy' (takes 10-20 seconds)
   Creating a new access key
   aws-vault: error: rotate: Error creating a new access key: operation error IAM: CreateAccessKey, https response error 
   StatusCode: 403, RequestID: 1234abcd-56ef-78gh-9012-123456abcdef, api error InvalidClientTokenId: The security 
   token included in the request is invalid

--no-sessionオプションをつけることでMFAの要求を回避し、ローテーションを実行できます。詳しくはこちら

   $ aws-vault rotate --no-session dummy
  • プロファイルでAWSコンソールにログイン

    これは特に説明できることはありません。aws-vault loginを実行するとデフォルトブラウザが起動してAWSコンソールにログインできます。わざわざログイン画面に色々入力する必要がなくて結構便利です。

   aws-vault login dummy
  • プロファイルを削除

    不要になったプロファイルは削除できます。

   $ aws-vault remove dummy
   Delete credentials for profile "dummy"? (y|N) y
   Deleted credentials.

   $ aws-vault list        
Profile                  Credentials              Sessions                    
=======                  ===========              ========                                             
dummy                    -                        -

スイッチロール

複数のAWSアカウントを行ったり来たりするときにスイッチロールを使用できると便利ですよね。AWSコンソールは別のAWSアカウントにログインするときに今ログインしてるアカウントからログアウトさせられますが、スイッチロールを使用するとログイン、ログアウトが発生しません。

どこか1つのAWSアカウントでIAMユーザーを発行しておき、開発、ステージング、本番のAWSアカウントをスイッチロールできるようにしておくというような使い方も一般的です。AWS CLIもスイッチロールに対応しています。

~/.aws/configに以下の記述をすることで、スイッチロールが可能です。

[profile dummy]
region = ap-northeast-1

[profile switch-role]
region = ap-northeast-1
source_profile = dummy
role_arn = arn:aws:iam::123456789012:role/<role-name>

source_profileにはスイッチロール元のプロファイルを、role_arnにはスイッチロール先で設定されているRole ARNを記述します。しかし、スイッチロール元のアカウントがMFAを必須にするような制限を、スイッチロール先のロールに設定されている場合は↑の例だけではスイッチロールできません。例えば以下のように設定されている場合です。

MFA 保護 API アクセスの設定 - AWS Identity and Access Management

AWS VaultはMFAにも対応しています。

https://github.com/99designs/aws-vault/blob/master/USAGE.md#mfa

先ほどの~/.aws/configを以下のように修正します。

[profile dummy]
region = ap-northeast-1

[profile switch-role]
region = ap-northeast-1
source_profile = dummy
role_arn = arn:aws:iam::123456789012:role/<role-name>
mfa_serial = arn:aws:iam::111111111111:mfa/<mfa-name>

role_arnにはスイッチ先のロールARNを、mfa_serialにはスイッチ元のIAMユーザーに登録されているMFAのARNを入力してください。こうすることで、switch-roleプロファイルでコマンドを実行するときにMFAの認証がされるので、スイッチロールが可能になります。

$ aws-vault exec switch-role aws sts get-caller-identity
Enter MFA code for arn:aws:iam::111111111111:mfa/<mfa-name>: 123123

{
    "UserId": "ABCDEFGHIJKLMNOPQRSTU:1234567890123456789",
    "Account": "123456789012",
    "Arn": "arn:aws:sts::1234567890:assumed-role/<role-name>/1234567890123456789"
}

まとめ

AWS Vaultなかなかいいですね。~/.aws/credentialsがなくなるのもいいですし、サブシェルでプロファイルを恒久的に使用できるのもいいです。なによりバックエンドにpassを指定できるのが、個人的にはベストヒットでした、pass好きなんですよね。

AWS Vaultこれから積極的に使っていこうと思います。