SSMエージェントはIAMロールの夢を見るか を語りました #jawsug #opsjaws

SSMエージェントがどうかは知りませんが、わたしはよくIAMロールの夢をみます。

コンバンハ、IAMロール *1です。

わたしは IAM ロールが好きです。EC2 もそこそこ好きです。そんな中、OpsJAWS Meetup#27 EC2の運用と監視が開催されました。

Ops な皆さん、こんにちは!

EC2 使ってますか?使っていますよね。誰もが使ったことがある基本的なサービスですし、今でも活躍の場は多いと思います。 EC2 の運用と監視について改めて学び直します。

EC2 がテーマのようです。EC2 がテーマなのですが、わたしはどうしても IAM ロールの話がしたいです。


EC2、運用……と言えば Systems Manager……
Systems Manager でノード管理するには SSM エージェントが必要……
SSM エージェントが AWS API を実行するには IAM ロールの権限が必要!
……
よし、繋がった!


ということで、「SSMエージェントはIAMロールの夢を見るか」というタイトルで登壇することにしました。

登壇資料

よくわからないタイトルの意味は何?

「SSMエージェントはIAMロールの夢を見るか」というタイトルを見て、何を意味するか分かった方はいるでしょうか。いないと思います。なぜなら、わたしも分かっていないからです。

本当は「SSMエージェントはIAMロールを引き受けるのか」というタイトルにする予定でした。ただ、「ちょっとタイトルとして面白くないな……」という思いが頭によぎったため、盛ったタイトルにしました。

「SSMエージェントはIAMロールを引き受けるのか」というタイトルも、それはそれで意味が分からないですね。

SSMエージェントはどうにかして権限を確保している

「ユーザーが SSM を通じて EC2 インスタンスを操作する」と考えると、ユーザーから EC2 インスタンスの方向へ働きかけている矢印が目に浮かびます。例えば SSM セッションマネージャーで EC2 インスタンスに接続する、というケースではまさにそういったイメージが浮かぶのではないでしょうか。

実際に発生している通信を考えてみると、SSM エージェントからアウトバウンド方向の通信も発生します。セッションマネージャーで接続する際も、SSM エージェントから SSM エンドポイントへの API 実行が行われています。言い換えればそのための権限が必要です。さらに、例えばセッションマネージャーの接続ログを S3 バケットに出力したい、となれば S3 への書き込み権限も必要になります。

opsjaws_ssm_agent_1

SSM エージェントに必要な権限を持たせるには、以下のいずれかが必要です。

  • EC2 インスタンスにインスタンスプロファイルをアタッチする
  • リージョンで Systems Manager の Default Host Management Configuration(DHMC)を有効にする

SSM エージェントは上記のいずれか、あるいは両方で設定された IAM ロールの権限を利用します。その権限の利用のプロセスにおいて、IAM ロールを引き受けるのでしょうか。

IAM ロールを引き受けるとは

「IAM ロールを引き受ける」とは何でしょうか。

ざっくり理解したい方は、以下のエントリをご参照ください。

少しまとめると、以下の考え方になります。

  • IAMロール自体はAPI実行の主体にはならない
  • IAMロールを引き受けたセッションが実行主体になる
  • セッションはsts:AssumeRoleにより発行された一時的なクレデンシャルを使用する
    • アクセスキーID
    • シークレットアクセスキー
    • セッショントークン
  • sts:AssumeRoleを実行する主体がいる

ここで、わたしが手元の端末で AWS CLI を実行するケースを考えます。IAM ユーザーchiba-userのアクセスキーを端末に設定し、chiba-roleを AssumeRole してコマンドを実行します。AssumeRole はAWS CLI のプロファイルで設定をしているとしましょう。 *2

opsjaws_ssm_agent_cli

この時、以下の2段階のプロセスを踏むことになります。

  • IAM ユーザーchiba-userchiba-roleを対象にsts:AssumeRoleを実施
  • 払い出された一時的なクレデンシャルを設定し、「chiba-roleを引き受けたセッション」として後続のコマンドを実施

ここで、IAM ロールchiba-role引き受けたのは誰でしょうか?

  • わたし
  • 端末
  • AWS CLI
  • IAM ユーザーchiba-user

この並びで考えれば、IAM ユーザーchiba-userである、と考えるのが自然です。sts:AssumeRoleを実行したプリンシパルが IAM ロールを引き受ける主体である、と考えるとしっくりきます。

EC2 のコントロールプレーンとデータプレーン

AWS のほぼすべてのサービスは「コントロールプレーン」「データプレーン」から構成されます。

ゾーンサービスである EC2 は、リージョン単位で「リージョナルコントロールプレーン」があり、そこにぶら下がる形で個々の「ゾーナルコントロールプレーン」があり、それぞれに1:1で紐づく形で「データプレーン」が存在します。

今回は「コントロールプレーン」と「データプレーン」の粒度に丸めて考えます。乱暴な分類ですが、「コントロールプレーン=AWSレイヤ」「データプレーン=OSレイヤ」と考えるとある程度実態に即していると思います。

opsjaws_data_plane

データプレーンは仮想マシン(EC2インスタンス)や仮想ネットワーク(VPC)が稼働している領域です。コントロールプレーンは AWS API のリクエストを受け付け、データプレーンに対して変更を加える役割を持ちます。例えば EC2 インスタンスの新規作成や、インスタンスタイプの変更などです。また、コントロールプレーンには EC2 インスタンス ID やインスタンスに付与されたタグの情報も格納されます。データプレーンに存在する OS の世界から見れば、自身をホストするインスタンスの情報などメタな情報は把握していない、という考え方です。

ここで、EC2 インスタンスにインストールされた SSM エージェントがどこに位置するかを考えると、当然データプレーンとなります。

SSM エージェントは IAM ロールを引き受けるのか

SSM エージェントが直接sts:Assumeroleを実行することはありません。そもそもそこに必要な権限を有していないし、VPC を通じて STS サービスに疎通することもありません。

STS_AssumeRole_jaws

sts:AssumeRoleを実行するのは以下の主体です。

対象ロール sts:AssumeRole実行元
インスタンスプロファイルにアタッチされたロール EC2サービス(EC2インスタンス)
DHMCで指定されたロール SSMサービス

両者によって取得された一時的なクレデンシャルは、最終的に EC2 のコントロールプレーンに格納されます。データプレーンに存在する SSM エージェントは、インスタンスメタデータサービスに対してアクセスすることでその情報を取得できます。

opsjaws_instancesmetadata

なお、これらのクレデンシャルにはOSログインしたユーザーもアクセスできます。インスタンスプロファイルにアタッチされたロールから取得した一時的なクレデンシャルは、`http://169.254.169.254/latest/meta-data/iam/security-credentials/{IAMロール名}`にアクセスすることで、取得できます。

DHMCで指定されたロールから取得した認証情報の場合は、インスタンスメタデータ経由でOSユーザーが直接アクセスするパスはありません。ただ、SSMエージェントが取得したクレデンシャルは/var/lib/amazon/ssm/credentials(Linuxの場合)に保存されるため、そのファイルにアクセスすることで取得できます。

SSM エージェントは IAM ロールの夢を見ない

ということで、少し脱線しましたが、最終的な結論は「SSMエージェントはIAM ロールは引き受けない」になります。

SSM エージェントは、別のプリンシパルが引き受けた IAM ロールの認証情報を利用して AWS API を実行します。EC2 上のアプリケーションにどのようにして認証情報を使用するのか、に思いを馳せるとちょっとだけ楽しいですよね。

終わりに

「OpsJAWS Meetup#27 EC2の運用と監視」での登壇レポートでした。

EC2がテーマなのに、無理やりIAMロールの話をしました。別に知ったから何か役に立つかというとそうでもないですが、わたしはこの手の話が大好きです。

話そうと思ったけど時間的に入れられなかったのは以下のあたりです。

何らか面白ければ幸いです。

以上、 チバユキ (@batchicchi) がお送りしました。

参考資料

脚注

  1. IAMロールが好きなあまり自分のことをIAMロールだと思い込んでいる成人男性、略してIAMロールです。
  2. 例えば以下のように設定します。 https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_use_switch-role-cli.html