aws-vaultをLinux環境でも使う方法【セキュリティ向上】

青い背景にAWSロゴ画像

aws-vaultは、アクセスキー等のAWSの認証情報をセキュアに保管し、より便利に使用することができるツールです。

Linux環境でaws-vaultを使用する方法について解説しているサイトがあまりなく、導入に手間取ったので、導入手順やハマったポイントについて残しておきます。

aws-vaultの特徴

よりセキュアな認証情報の保管と利用を実現

AWS CLIなどのAWSコマンドラインツールを使用する際には、環境変数や、~/.aws/credentials などに、平文でアクセスキーを保存するのが通常です。

これでは自分以外のユーザーからも認証情報が見えてしまう可能性があり、少し心許ないです。ノートPCなどにAWS CLIを入れて使用している場合、外出先で端末を落とした場合にアクセスキーを抜かれたりする危険もあります。

aws-vaultを利用すると、OSの機密情報ストア※1Windowsでは資格情報マネージャー、macOSではキーチェーンなどを利用して、認証情報を暗号化して保存することができるので仮に端末が乗っ取られたり、紛失したりした場合でも、簡単には認証情報を悪用できなくなります

aws-vaultのアーキテクチャイメージ

また、aws-vaultを使用してAWS CLI等からの操作を行う際には、コマンド実行前にAWS STS(AWS Secure Token Service)というAWSのサービスを利用し、一時的セキュリティ認証情報を取得します。

これは、有効期間が半永続的なアクセスキーと異なり、有効期間が短い(数秒~12時間で任意に設定可能)ため、仮にコマンド実行中に何らかの理由で認証情報が奪われた場合でも、悪用の機会を短く抑えることが可能になります

クロスプラットフォームである

Windows、macOS、Linuxディストリビューション(CentOSやUbuntuなど)に対応しており、およそほとんどの環境で動作します

MFAやAssumeRoleとの組み合わせにおいても使いやすい

MFAやAssumeRoleが必要になる環境では、アクセスキーを直接使う場合よりもAWS CLI等の操作が増えて面倒になります。aws-vaultはこれを少し簡略化してくれるという、副次的なメリットもあります。

なぜaws-vaultを使おうと思ったのか

こちらの章では、aws-vaultを使用する理由の一例として、私がなぜaws-vaultを使おうと思ったのかについて触れたいと思います。

興味がない方は、aws-vaultのインストール方法まで飛ばしてください。

 

きっかけは、AWSでの技術検証を目的に、権限の強いIAMユーザーを作成し使おうとしたことでした。

色々なサービスを様々なユースケースで使ってみるにあたり、検証を行うごとに最小権限のIAMユーザーを払い出すのが面倒になり、AdministratorAccess権限を付与したユーザーを利用したいと思いました。技術検証ということで、当然のようにそのIAMユーザーでアクセスキーを発行したのですが、さすがにこれを開発機に直に置いておくのは心配です。

そこで、AdministratorAccess権限を持つユーザーに、すべての操作に対してMFA認証を必須とするIAMポリシーを付与することで、万が一アクセスキーが漏洩してもそれを手に入れた攻撃者が何もできないように設定しました。

とはいえ、AWS CLIをMFA認証ありで使うのは少し面倒くさいのです。(MFAの認証の期限が切れるまでは一時的な認証情報を使い回せはするのですが、その一時的認証情報を取得するコマンドが長ったらしくて面倒)

さらに、インフラのコード化に使用しているterraformが、MFAに対応しておらず、使えない…

ですがaws-vaultを利用すれば、

  • terraformもほとんど今まで通りの使い方で利用可能
  • MFA認証も簡単(6桁のキーを入力するだけ)
  • おまけに平文で保存されていたアクセスキーを暗号化することで少しセキュアに

と、上記の問題をすべて解決することができるのです。便利ですね。

aws-vaultのインストール方法

aws-vaultのインストール方法について解説します。

ディストリビューションによって微妙に手順は異なりますが、全体感は掴めるはずです。今回インストールしたディストリビューションは、CentOS 7.8.2003です。

aws-vaultのダウンロード&インストール

インストールといっても、ビルド済みのバイナリが配布されているので、ダウンロードしてPATHの通ったディレクトリに配置するだけです。ダウンロード先のURLは、適宜最新のものを下記から確認するようにしてください。

https://github.com/99designs/aws-vault/tags

$ curl -L https://github.com/99designs/aws-vault/releases/download/v6.2.0/aws-vault-linux-amd64 -o /usr/local/bin/aws-vault
$ chmod 755 /usr/local/bin/aws-vault
$ aws-vault --version
v6.2.0

依存関係のダウンロード&インストール

前述したように、aws-vaultはOSの機密情報ストアを利用してAWSアクセスキーを暗号化します。Linuxでは、暗号化の方式として、passfileを利用できます。file は、単純な暗号化ファイルを利用する方式で、コマンド実行の度にファイルのパスワードを毎回入力しなければいけないため、pass がおすすめです。

pass方式の暗号化は、アクセスキーの暗号化にLinuxで利用可能なパスワードマネージャのpassを利用するので、まずはこちらが動作する環境を作る必要があります。

コマンド例にある pass の最新バージョンのダウンロード先は、下記を参照。

https://git.zx2c4.com/password-store/

# 依存パッケージのインストールに必要なツールのインストール(未インストールの場合)
$ yum install make unzip
# passの依存パッケージのインストール(未インストールの場合)
$ yum install gnupg2 tree

# passのダウンロード&インストール
$ curl https://git.zx2c4.com/password-store/snapshot/password-store-1.7.3.zip -o password-store-1.7.3.zip
$ unzip password-store-1.7.3.zip
$ rm -f password-store-1.7.3.zip
$ cd password-store-1.7.3/
$ make install

$ pass --version
============================================
= pass: the standard unix password manager =
=                                          =
=                  v1.7.3                  =
=                                          =
=             Jason A. Donenfeld           =
=               Jason@zx2c4.com            =
=                                          =
=      http://www.passwordstore.org/       =
============================================

ちなみに、passの正体は単なるシェルスクリプトなので、makeにgcc系統のビルドツールは不要です。

pass / GnuPGのセットアップ

passはGnuPGを利用します。GnuPGとは、OpenPGPという暗号化プロトコルに準拠したツールで、実際にはGnuPGがファイルの暗号化/復号を実行します。

# 暗号化/復号に使用する鍵の生成
$ gpg --gen-key
...中略...
ご希望の鍵の種類を選択してください:
   (1) RSA と RSA (デフォルト)
   (2) DSA と Elgamal
   (3) DSA (署名のみ)
   (4) RSA (署名のみ)
あなたの選択は? 1

# RSAの鍵長は、2048ビット以上にすること
RSA 鍵は 1024 から 4096 ビットの長さで可能です。
鍵長は? (2048) 2048
要求された鍵長は2048ビット

# よりセキュアにしたい場合はお好みでどうぞ。
鍵の有効期限を指定してください。
         0 = 鍵は無期限
      <n>  = 鍵は n 日間で期限切れ
      <n>w = 鍵は n 週間で期限切れ
      <n>m = 鍵は n か月間で期限切れ
      <n>y = 鍵は n 年間で期限切れ
鍵の有効期間は? (0)0
(null)は無期限です
これで正しいですか? (y/N) y

# 今回のユースケースにおいては、下記は適当に入力しても問題ありません
GnuPGはあなたの鍵を識別するためにユーザIDを構成する必要があります。
本名: <名前>
電子メール・アドレス: <メールアドレス>
コメント:
次のユーザIDを選択しました:
    "tom <tom@example.com>"

名前(N)、コメント(C)、電子メール(E)の変更、またはOK(O)か終了(Q)? O
秘密鍵を保護するためにパスフレーズがいります。 # 秘密鍵の保護に利用するパスワードを入力

たくさんのランダム・バイトの生成が必要です。キーボードを打つ、マウスを動かす、
ディスクにアクセスするなどの他の操作を素数生成の間に行うことで、乱数生成器に
十分なエントロピーを供給する機会を与えることができます。

gpg: 鍵5435AB3Fを絶対的に信用するよう記録しました
公開鍵と秘密鍵を作成し、署名しました。

以下略...

鍵の生成には時間がかかるので(私の環境では10分弱)、気長に待ちましょう。

続いて、passのセットアップを実施します。

# pass init <先ほど入力したメールアドレス>
$ pass init tom@example.com
Password store initialized for tom@example.com

環境変数の設定(aws-vaultから利用)

~/.bash_profile に下記を追記

AWS_VAULT_PASS_PREFIXには、アクセスキーを格納するディレクトリの親ディレクトリを指定できます。必須ではないですが、aws-vaultで利用しているディレクトリだということを明記できるので必要に応じて設定します。

AWS_SESSION_TOKEN_TTLには、AWS STSから払い出される一時的な認証情報の有効期限を指定できます。デフォルトは1時間です。必要に応じて、12時間まで延長することができます。※2AssumeRoleを使用する場合は、1時間が上限です最大で12時間アクセスキーの暗号鍵のパスワードを入力することなく、AWS CLI等のツールを使用することができます。(MFAを使用している場合も、初回の認証から最大で12時間はMFAキー入力が不要となります)

export AWS_VAULT_PASS_PREFIX=aws-vault
export AWS_SESSION_TOKEN_TTL=3h

上記で一時的な認証情報の期限を延ばした場合など、必要に応じて下記設定も行ってください。

$ echo "default-cache-ttl 10800" >> ~/.gnupg/gpg-agent.conf
$ chmod 600 ~/.gnupg/gpg-agent.conf
$ gpg-connect-agent reloadagent /bye

上記は、「passでアクセスキーの復号時に入力するパスワードを何秒キャッシュしておくか」という設定です。(デフォルトは5分)

これを延ばすことで、AWS CLIコマンド実行前に毎度パスワードを入力する必要がなくなります。

aws-vaultのセットアップ

# <任意のプロファイル名>でいうところの「プロファイル」はAWS CLIのプロファイルと同じような概念です
$ aws-vault add <任意のプロファイル名>
Enter Access Key ID: <アクセスキーID>
Enter Secret Access Key: <シークレットアクセスキー>
Added credentials to profile "example" in vault

# passが保管している機密情報の一覧
$ pass
Password Store
└── aws-vault
    └── example

MFAを併せて使用する場合

~/.aws/config にMFAデバイスのARNを追記する必要があります。

MFAデバイスのARNは、マネジメントコンソールのIAMのユーザー詳細ページから確認することができます。

https://console.aws.amazon.com/iam/home?region=us-east-1#/users

[profile exaple]
mfa_serial=arn:aws:iam::123456789012:mfa/example

aws-vaultの使用方法

コマンドの書式は下記です。

aws-vault exec <プロファイル名> — <AWS CLI等の実行コマンド>

$ aws-vault exec example -- aws s3 ls

# 先ほど設定した、秘密鍵を保護するパスワードを入力する
┌─────────────────────────────────────────────────┐
│ OpenPGP証明書の秘密鍵のロックを解除するためにパスフレーズを入力してください:
│ "tom <tom@example.com>"                  │
│ 2048ビット RSA 鍵, ID DFB512CA,                 │
│ 作成日付 2020-10-11 (主鍵ID 5435AB3F)。         │
│                                                 │
│                                                 │
│ パスフレーズ ________________________________________
│                                                 │
│      <OK>                           <Cancel>    │
└─────────────────────────────────────────────────┘

Enter token for arn:aws:iam::123456789012:mfa/example: <6桁のMFA認証コード> # MFA有効の場合のみ
# パスフレーズとMFA認証コードが正しければ正常にコマンドが実行される
2020-10-10 21:44:31 test-bucket-20201010-210000

ちなみに、上記手順で得た一時的な認証情報もしっかりと暗号化されて保管されています。

$ pass
Password Store
└── aws-vault
    ├── sts.GetSessionToken,dXQxNDIy,,0123456789 # 一時的な認証情報
    └── example

さらに詳細な使用方法は、下記を参照のこと。

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

構築時にハマったポイント

gpg: decryption failed: No secret key

AWS CLI等のコマンド実行時に、下記のようなエラーが表示され、コマンドが実行できない。

$ aws-vault exec profile -- terraform init
gpg: cancelled by user
gpg: decryption failed: No secret key
aws-vault: error: exec: Failed to get credentials for profile: exit status 2

GnuPGやpassの設定が正しいにも関わらず、このエラーが出る場合、何らかの理由でアクセスキー復号用のパスワードをたずねるダイアログが表示されないことが原因でした。

環境変数 GPG_TTY を操作中のターミナルに設定してやると、正常にコマンドが実行されるようになりました。

$ export GPG_TTY=$(tty)

$ aws-vault exec profile -- terraform init

Initializing the backend...

Successfully configured the backend "s3"! Terraform will automatically
use this backend unless the backend configuration changes.

以下略...

InvalidClientTokenId: The security token included in the request is invalid

こちらはコマンド実行時に、「セキュリティトークンが不正だよ」と怒られるパターン。

ほかのコマンドは成功するのに、このコマンドだけはエラーが出るという状況。

aws-vault exec profile -- terraform plan

...中略...

Error: Error reading IAM Group Administrator: InvalidClientTokenId: The security token included in the request is invalid
        status code: 403, request id: d6edc1d1-8554-4e6a-af11-5aa4dde35777

エラーメッセージにもありますが、IAMグループを操作するAPIを叩いた際に、セキュリティトークン周りでエラーが発生しました。

原因はというと、下記に記載がありました。

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison

 

上記ページにある表の、GetSessionTokenという欄を見ると、

リクエストに MFA 情報が含まれていない場合は、IAM API オペレーションを呼び出せません。

とあります。GetSessionTokenは、一時的セキュリティ認証情報を取得するAPIのことで、まさにaws-vailtで内部的に呼び出されるものです。要するに、一時的な認証情報を使ってAWSのAPIを呼び出す場合、MFA認証を行わない限りIAM関連の操作はできない。ということでした。

前述したような方法でMFA認証を実施するよう設定してやると、正常にコマンドが実行されるようになりました。

まとめ

aws-vaultのインストールと使用の方法は以上となります。

手順が多めで導入は少し面倒ですが、一度やってしまえば快適かつセキュアにAWS CLI等を操作できるようになりますので、ぜひ試してみてください。

参考

pass – ArchWiki

https://wiki.archlinux.jp/index.php/Pass

 

GnuPG – ArchWiki

https://wiki.archlinux.jp/index.php/GnuPG

 

 

脚注   [ + ]

1. Windowsでは資格情報マネージャー、macOSではキーチェーンなど
2. AssumeRoleを使用する場合は、1時間が上限です

あわせて読みたい

コメントを残す

質問・感想などお気軽にどうぞ。
*が付いている項目は入力必須です。メールアドレス以外の項目が公開されます。
スパム防止のため、コメント反映まで少々時間がかかります。