AWS CLIのaws loginコマンドをリモートマシンで使う
ども、大瀧です。先日リリースされたAWS CLIの aws login コマンドは、AWSのAPIキーを使わずにAWSの一時認証情報を取得できる新しい機能です。使い方は以下の記事が詳しいです。
AWS CLIはWindows PCやMacbookなど手元のマシンで実行するほかにも、EC2インスタンスやDev Containerなどネットワーク越しのリモートマシンで実行することもあるでしょう。本ブログではリモートマシンで aws login を実行する方法をご紹介します。
--remote オプションで aws login を実行する
いきなり結論ですが、リモートマシンで実行する場合は --remote オプションを付与しましょう。オプションを付与することで一時認証情報を取得する方式が変わり、リモートマシンでの実行に適した利用ができます。
$ aws login --remote
Browser will not be automatically opened.
Please visit the following URL:
https://ap-northeast-1.signin.aws.amazon.com/v1/authorize?response_type=code&client_id=arn%3Aaws%3Asignin%3A%3A%3Adevtools%2Fcross-device&state=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&code_challenge_method=SHA-256&scope=openid&redirect_uri=https%3A%2F%2Fap-northeast-1.signin.aws.amazon.com%2Fv1%2Fsessions%2Fconfirmation&code_challenge=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Enter the authorization code displayed in your browser:
端末に表示されるURLに手元のWebブラウザでアクセスすると以下のセッション選択画面になります。(有効なAWS Management Consoleのログインセッションが無い場合はログインを促されます) セッションを選択しましょう。

セッションを選択すると検証コードをクリップボードにコピーすることを促す画面に切り替わります。「検証コードをコピー」ボタンをクリックしてクリップボードにコピーし、端末にペーストします。

Enter the authorization code displayed in your browser: XXXXXXXXXXXXXXXXXXX
Updated profile default to use arn:aws:sts::123456789012:assumed-role/XXXX/XXXX credentials.
$
これで --remote オプションなしで実行する場合と同様、リモートマシンに一時認証情報のキャッシュが保存され、利用できるようになりました。
aws login はどうやってWebブラウザから端末にセッション情報を渡しているのか
通常の aws login では、Webブラウザでセッションを選択すると検証コードのコピペなしで一時認証の保存が実行されました。どうやってセッション情報を端末に渡しているのでしょうか。これは、WebブラウザでアクセスするURLの差異にヒントがあります。
--remote オプション指定 |
WebブラウザでアクセスするURL |
|---|---|
| あり | https:// ap-northeast-1.signin.aws.amazon.com/v1/authorize?response_type=code&client_id=arn%3Aaws%3Asignin%3A%3A%3Adevtools%2F cross-device &state=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&code_challenge_method=SHA-256&scope=openid&redirect_uri= https%3A%2F%2Fap-northeast-1.signin.aws.amazon.com%2Fv1%2Fsessions%2Fconfirmation &code_challenge=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX |
| なし | https:// ap-northeast-1.signin.aws.amazon.com/v1/authorize?response_type=code&client_id=arn%3Aaws%3Asignin%3A%3A%3Adevtools%2F same-device &state=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&code_challenge_method=SHA-256&scope=openid&redirect_uri= http%3A%2F%2F127.0.0.1%3A52084%2Foauth%2Fcallback &code_challenge=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX |
後半にある redirect_uri が --remote なしでは http://127.0.0.1:52084/oauth/callback とあり、ループバックアドレスの52084番ポートにリダイレクトするようになっています。(ポート番号は、実行するたびに変わるエフェメラルなポートです。)Webブラウザの操作をする前に別の端末を起動し、以下のコマンドでListenしているポート一覧を見てみます。(macOSの場合)
% sudo lsof -i -P | grep "LISTEN"
Password: <sudoのパスワードを入力>
launchd 1 root 7u IPv6 0xad8a10da062a99f4 0t0 TCP *:22 (LISTEN)
:(略)
aws 15304 XXXX 4u IPv4 0x1aff7f2fc9ea53c5 0t0 TCP *:52084 (LISTEN)
:(略)
(LISTEN)
%
aws コマンドでポートをListenしているのがわかりますね。aws コマンドはWebブラウザのリダイレクトによるアクセスを受けるために一時的にWebサーバーを立ち上げているようです。URLのスキーマは http で暗号化通信ではないので、 tcpdump でキャプチャしつつ、セッションを選択してみます。
$ sudo tcpdump -i lo0 -A tcp port 52084
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on lo0, link-type NULL (BSD loopback), snapshot length 524288 bytes
:(略)
20:57:09.630734 IP localhost.64786 > localhost.52084: Flags [P.], seq 1:2296, ack 1, win 6380, options [nop,nop,TS val 1536632555 ecr 840265205], length 2295
E. +..@.@..............H.J..I........ .....
[.&.2.m.GET /oauth/callback?code=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&state=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX HTTP/1.1
Host: 127.0.0.1:52084
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
sec-ch-ua: "Chromium";v="142", "Google Chrome";v="142", "Not_A Brand";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: ja,en-US;q=0.9,en;q=0.8
:(略)
リクエストのクエリに --remote オプション実行時と同様の検証コードが含まれていることがわかりました。リモートマシンの localhost はリモートマシン自身であり、Webブラウザを実行するローカルマシンとは異なるので、 --remote オプションではローカルマシンのクリップボードによるコピー&ペーストで明示的に検証コードを受け渡すわけですね。
まとめ
AWS CLIのaws loginコマンドをリモートマシンで使うための --remote オプションをご紹介しました。
例としてEC2を引き合いにしましたが、EC2にはIAMロールという認証情報を取得する別の仕組みがあるのにあえて aws loginを使うユースケースがあるでしょうか。EC2を実行するAWSアカウントとは別のAWSアカウントのS3にアクセスするようなクロスアカウント構成には複雑な設定が必要であり、IAMロールは、基本的には事前にIAMロールの権限を設定する静的な構成と言えるでしょう。例えば、EC2インスタンスでの作業中にAmazon S3のファイルを aws s3 cp コマンドでさっとダウンロードしたい、そんなときにクロスアカウントかどうかを問わずにシンプルに一時認証できる aws login が便利なのかなぁと思っています。ただし、 aws login コマンドは ~/.aws/config をカジュアルに書き換えるのと一時認証情報のキャッシュを残すので、本番インスタンスでの使用はお勧めしません。








