初めに
ISID X(クロス)イノベーション本部 の三浦です。
筆者の関わってる案件では、セキュリティーの強化の一環として、AWS session manager利用を推進しております。 session managerを利用するとEC2アクセス時に下記のようなメリットがあります(※1)。
- ssh,rdp接続のためのpublic ipを付与する必要がなくなる
- プライベートなサブネットのec2にも、踏み台等を経由せずにアクセス可能
- ssh,rdp接続のためのSGインバウンド許可IP制御が不要となる
- 認証情報をAWSの権限に集約でき、window、linuxのユーザー管理を減らせる
- 接続ログ、監査ログを、session mangerで一元管理できる
しかし、そこで問題になってくるのがセキュリティー強化のためにsession manger用のアクセスキー、シークレットキーを 配布すると今度はその管理が煩雑となり、セキュリティーリスクとなる課題があります。
そこで、AWS Tools for Windows PowerShellからIdP(adfs)接続用のコマンドレット(Set-AWSSamlRoleProfile)を使い(※2)アクセスキー、シークレットキーの配布なしにsession mangerを利用する方法を記述します。
が、現在の仕様では、PowerShellからsession managerの開始のAPIを単純に呼び出しても動作しません(※3)。 しかし、一工夫することにより、アクセスキー、シークレットキーなしでセキュアにsession mangerの利用が可能となります
実装の概要
- AWS Tools for Windows PowerShellで、IdP(ADFS)よりAWSのアクセス権取得
- STSトークンを取り、AWS CLIが使える形式で保存
- AWS CLIからsession manger実行
これだけとなります。adfsへのアクセスのところのみPowerShellをもちい、AWS CLIでsession mangerを呼び出すだけとなります。
ソースコード例
Import-Module -Name AWS.Tools.Common Import-Module -Name AWS.Tools.SecurityToken function start-ssm { [CmdletBinding()] Param( [string]$awsAccountId = $null, [string]$adfsRoleName = "ADFS-RoleName", [string]$ec2InstanceId = $null, [string]$localPortNumber = "13389" ) $profileName = $awsAccountId + ":role/" + $adfsRoleName $roleArn = "arn:aws:iam::" + $awsAccountId + ":role/" + $adfsRoleName ### XXXXXXXXXXXの部分は適宜、お使いのADFSのドメインに置き換えてください。筆者はadfs v3で動作確認をしております $endpoint = "https://XXXXXXXXXXX/adfs/ls/IdpInitiatedSignOn.aspx?loginToRp=urn:amazon:webservices" $epName = Set-AWSSamlEndpoint -Endpoint $endpoint -StoreAs ADFS-Demo -AuthenticationType NTLM $r = Set-AWSSamlRoleProfile -EndpointName $epName -StoreAllRoles $Creds = (Use-STSRole -Region ap-northeast-1 -ProfileName $profileName -RoleArn $roleArn -RoleSessionName $adfsRoleName).Credentials ### 動作をわかりやすくするために、下記三行でSTSの内容をコンソール出力しています $Creds.AccessKeyId $Creds.SecretAccessKey $Creds.SessionToken aws configure set region ap-northeast-1 --profile adfstemp aws configure set aws_access_key_id $Creds.AccessKeyId --profile adfstemp aws configure set aws_secret_access_key $Creds.SecretAccessKey --profile adfstemp aws configure set aws_session_token $Creds.SessionToken --profile adfstemp ## 下記はRDPのポートフォワーディング用の例となります $ssmParam = "portNumber=3389, localPortNumber=" + $localPortNumber aws ssm start-session --target $ec2InstanceId --document-name AWS-StartPortForwardingSession --parameters $ssmParam --profile adfstemp }
- Set-AWSSamlEndpoint、 Set-AWSSamlRoleProfileを用いて、IdP(ADFS)よりAWSのアクセス権取得
- Use-STSRoleを用いてAWS CLI用の認証情報を取得し、aws configureで保存
- AWS CLIのaws ssm start-sessionで、session mangerを開始
としてしてるだけの、非常にシンプルなコードとなります。
最後に
ということで、今回は、アクセスキー、シークレットキーを発行せずに、session mangerを利用する例をご紹介いたしました。筆者は、200アカウントぐらいの管理をしており、これを個別のiam userのアクセスキー、シークレットキーで管理しようとすると非常につらいものがあります。 そのため、認証情報を、IdPサーバーに寄せた運用をしております。
アクセスキー管理に悩まれてる方は、ぜひ、一度、IdPサーバからSTSを取得する運用を試されてはいかがでしょうか?
(※1) session mangerの概要、様々な使い方については、クラスメソッド様のブログに多数記事 がございますので、session mangerってなんだっけ?という方は、そちらを見ていただくのがおすすめです。
(※2) AWS Tools for Windows PowerShellを用いると、標準ツールのみで非常に簡単にadfsから認証情報の取得が可能です。
(※3) 「PowerShellからsession managerの開始ができない件」については、クラスメソッドさんが詳細を書かれていますので、詳細が気になる方はこちらをご参照ください。 PowerShellでSSMのポートフォワーディングを試してみた(けど駄目だったはなし)
執筆:@miura.toshihiko、レビュー:@sato.taichi (Shodoで執筆されました)