電通総研 テックブログ

電通総研が運営する技術ブログ

IDP(adfs)の認証情報でアクセスキー、シークレットキーなしでaws session managerを使う方法

初めに

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の利用が可能となります

実装の概要

  1. AWS Tools for Windows PowerShellで、IdP(ADFS)よりAWSのアクセス権取得
  2. STSトークンを取り、AWS CLIが使える形式で保存
  3. 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 CLIaws 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.taichiShodoで執筆されました