2023/06/07

AWS CLIでSSOログインするときのちょっとお役立ち情報

ごく稀に書くお役立ち情報シリーズです。

  • AWS CLIでSSOログインするときに開くブラウザを指定したい
  • それをsshのProxyCommandに仕込んでEC2のtcp/22ポートをフルオープンせずSSHしたい

というお話です。

最近うちの会社にもSSOできるIdPが導入されたのでAWSもSSOできるようにする流れが来ています。それに先立ち技術調査…というわけでもないですけど、せっかくだし自分の個人のAWSアカウントもSSO出来るようにするか〜ということで、個人のGoogle Workspace(無償版G Suiteで使ってたやつ)をIdPにしてAWS SSOを設定しました。ちなみにAWS SSOは最近名前が変わってAWS IAM Identity Centerになりましたが、この記事ではとりあえず略して(馴染みのある名前で)AWS SSOと呼ぶことにします。

さて、AWS SSOを設定してGoogleアカウントでログインできるようにしたのはいいとして、そもそも元々自分の個人のAWSアカウントとGoogle WorkspaceはSAML連携の設定をしていたので単純にAWS SSOでAWS Console入れるようにしただけだとむしろクリック数が増えてて旨味がありません。

じゃあなんでAWS SSOを設定したかというと、AWS CLIでSSOログインできるようになって、そうするとお手元にIAM Userのアクセスキーなどを持たなくてよくなるというところが主な狙いです。セキュリティの向上ですね。必要に応じて aws sso login したときに初めて有効期限つきのクレデンシャルがふってくるので、万が一なにかがどうにかなっちゃったとしても、クレデンシャルに有効期限がついていれば被害の軽減に役立ちます。

AWS CLIのSSO設定は、 aws configure sso とかをやればいいのでドキュメントを読みながら設定すればサクッといけます。一通り設定したあとは、SSOセッションの有効期限を調整して使い始めればOKです。私はあまり短すぎてもイライラするので、18時間に設定して aws sso loginしたらその日いっぱいは再ログインしなくても使えるみたいな感じにしています。

これで必要に応じて aws sso login すればブラウザが開いてIdPで認証をし、ブラウザでAllowをポチっとおせばクレデンシャルが降ってくる感じになりました。便利ですね。これでもうIAM Userのアクセスキーはいらん! ということで私はこれの設定をしたら速効でアクセスキー無効にしました。

AWS CLIのSSOログインのブラウザを指定したい

ところで、私の環境依存の話ではあるのですが、このフローにはちょっと不満があります。AWS CLIが開くブラウザはデフォルトブラウザで、デフォルトブラウザに複数のGoogleアカウントでログインしていると、毎回Googleアカウントを選択しないといけないんですよねぇ。クリック数が1回増えるし、手が滑ってIdP設定してないアカウントをクリックしてしまうと403エラーになるしでいいことがありません。起動するブラウザを指定できれば、1個しかGoogleアカウントを使ってないブラウザを起動してAllowを1回クリックするだけでいいようにできるのですが… というのが今日の本題です。

その辺ググってみると、AWS CLIのGithubリポジトリにそれっぽいissueがあったりもするのですが、GUIセッションがない端末用に --no-browser フラグを追加するのは対応されましたが自由にブラウザを指定するフラグなどは用意されませんでした。

そのissueには「WSLだと環境変数BROWSERを設定したら指定できるぜ」みたいな事が出てきたりして一体それはどういう仕組みなんだみたいな感じになったのでAWS CLIのソースをたくさん読んでみたところ、AWS CLIがブラウザを起動するのは最終的にPython3のwebbrowserモジュールに任せていることがわかりました。で、このドキュメントを読んでいくと「環境変数 BROWSER が存在する場合はデフォルトのブラウザリストに先立ちこっちを試す」みたいなことが書かれています。そういうことね!

環境変数で起動したいブラウザのパスを設定すればいいのは分かりましたが、わたしがブラウザ起動したかったのはmacOSなので、ちょっと一手間必要です。macOSのコマンドラインからGUIのアプリを起動するにはopenコマンドを使います。Safariを起動するなら open -a Safari とかになります。で、これをそのまま環境変数BROWSERに設定してもうまく行かないので、結論としてはシェルスクリプトにして、環境変数BROWSERにはそのシェルスクリプトへのパスを設定しましょう、という感じになります。

#!/bin/sh

open -a "Safari" $@

こんな感じのシンプルなシェルスクリプトを作って run_browser.sh とかのファイル名でどこかに保存しておき、+x パーミッションを付けておきます。これを環境変数BROWSERに設定してやればOKです。BROWSER=$HOME/run_browser.sh aws sso login を実行すれば、デフォルトブラウザではなく、ちゃんと run_browser.sh で設定したブラウザでIdPにアクセスしにいくはずです。

ssm-agent経由のSSHログインにaws sso loginを挟みたい

個人のAWSアカウントに立ってるEC2にsshするのをssm-agent経由で出来るようにして、EC2を0.0.0.0/0に対して22番ポートあけるのをそもそも辞めたいみたいなことを考えていたので、その辺も叶える~/.ssh/config をこんな感じで書いています。これは、AWS CLIのpowawaというプロファイルを利用し、SSOセッションが期限切れだったらaws sso loginする、そうじゃなければ普通に aws ssm start-session する、というようなコマンドラインです。

host my-ec2
    user XXXX
    hostname i-00XXXXXXXXXX
    ProxyCommand sh -c "(aws sts get-caller-identity --profile powawa || BROWSER=$HOME/run_browser.sh aws sso login --profile powawa) && aws ssm start-session target %h --document-name AWS-Start-SSHSession --parameters 'portNumber=%p' --profile powawa"

この設定を書いておいて ssh my-ec2 とやると、

  • AWS CLIのSSOセッションが生きてるか確認して
  • 生きてなかったらブラウザを開いて aws sso loginして
  • aws ssm start-session してssm-agentをつかってProxyCommandにポート転送する

という感じでSSH接続が確立できます。体感としてはsshコマンドを実行するとブラウザが立ち上がってAllowするとSSH接続が確立する、という感じになります。~/.ssh/confighostname%h に展開されるので、hostname にEC2のインスタンスIDを書いておくというのがこの設定のチャームポイントです。

うされもん @acidlemonについて

|'-')/ acidlemonです。鎌倉市在住で、鎌倉で働く普通のITエンジニアです。

30年弱住んだ北海道を離れ、鎌倉でまったりぽわぽわしています。

外部サイト情報

  • twitter
  • github
  • facebook
  • instagram
  • work on kayac