Open3
CloudShellの権限を外部にHTTPで提供する方法(認証付き)
前提条件
AWS CloudShell 上でログイン中の権限 (そのCloudShellをマネージメントコンソールで開いている人の権限) を取得する方法はこう。
$ curl -H "Authorization: $AWS_CONTAINER_AUTHORIZATION_TOKEN" \
localhost:1338/latest/meta-data/container/security-credentials
{
"LastUpdated": "1970-01-01T00:00:00Z",
"Type": "",
"AccessKeyId": "xxxxxxx",
"SecretAccessKey": "yyyyyyyy",
"Token": "zzzzz",
"Expiration": "2021-05-12T15:42:56Z",
"Code": "Success"
}
これで取得した AccessKeyId, SecretAccessKey, Token を使うとCloudShellと同じ権限を得られる。
つまり CloudShell 上の localhost:1338 を外部に公開できれば、外部から (Authorization: $AWS_CONTAINER_AUTHORIZATION_TOKEN) を付けてHTTPでアクセスキーが取得できる。
ngrok とか cloudflared を使うとそれができる。
CloudShell 上で $AWS_CONTAINER_AUTHORIZATION_TOKEN を取得して、localhost:1338 へのトンネルを作成。
$ echo $AWS_CONTAINER_AUTHORIZATION_TOKEN
abcdefgxxxxxxxxxx==
$ cloudflared tunnel --url localhost:1338
そこで作成された URL (例 xxxx-yyyy-zzzz.trycloudflare.com ) に対して外部からアクセスすればアクセスキーが取得できる。
$ curl -H "Authorization: abcdefgxxxxxxxxxx==" \
https://xxxx-yyyy-zzzz.trycloudflare.com/latest/meta-data/container/security-credentials
{
"LastUpdated": "1970-01-01T00:00:00Z",
"Type": "",
"AccessKeyId": "xxxxxxx",
(略
何が嬉しいか
比較的強い権限が必要な操作 (terraform apply
など) を、AWS外部から実行するための権限をHTTPで提供できる。外部にはエンドポイントURLとAWS_CONTAINER_AUTHORIZATION_TOKENを渡してアクセスする。
永続的なアクセスキーを外部に預けるのに比べて、以下の利点がある。
- 人が CloudShell を起動して、トンネルを立ち上げているときだけ有効なエンドポイントになる
- CloudShell を落としたり、時限で落とされたりしたら無効になる
- トンネルを落とせば使えない
- $AWS_CONTAINER_AUTHORIZATION_TOKEN も CloudShell を再起動すれば変更されるので永続的ではない
懸念点
ngrok や cloudflared を使う場合、その内部をアクセスキーが通過するので、そこを信頼できるかどうか。
AWS 自身が同様のサービスを提供してくれればこの懸念は (信頼をAWSに寄せるという形で) 解消される (最高)