AWS System Manager のSession ManagerとFleet Managerを使ってみる
System Managerとは何?
公式ドキュメントの最初に以下のように説明されています。
この一文からではよくわからないという人も多いのではないのではないでしょうか。
というわけでもう少し噛み砕いてみます。
System Managerには多くの機能が組み込まれていますが大きく以下の4つに分類できます。
運用管理
アプリケーション管理
変更管理
ノード管理
本記事ではそのうちノード管理の「Session Manager」機能を使ってSystemManager経由でSSH/RDPできるようにする方法を紹介します。
まずSession Managerを使用するためにはSSM Agentをセットアップし、System Managerへ接続する必要があります。
ただし、メジャーなAMIだとSSMAがプリインストールされている場合もあるのでそういったAMIを利用すると楽でしょう。
また、EC2インスタンスにIAM インスタンスプロファイルを設定し、SSMエージェントがSystemManagerに接続できるようにする必要があります。AmazonSSMRoleForInstancesQuickSetupのプロファイルを設定しておくと良いでしょう。
Host Management
手始めにSystem ManagerのQuick Setupから「Host Management」の機能を有効化します。この操作によってSSMエージェントをインストールしたAWS Organization内(スコープ選択できます。)のすべてのEC2インスタンスがSystemManagerに接続できるようになります。
設定項目にRoleを付与するオプションがあるのでチェックをつけておくとよいでしょう。
VPCエンドポイント作成
VPCエンドポイントはゲートウェイ型でもインターフェース型でもどちらでも可です。これらはAzureでいうところのServiceEndpointとPrivateEndpointの違い、と説明すればわかりやすいかもしれません。
SessionManagerでアクセスしたいEC2インスタンスから以下3つのエンドポイントへのアクセスを許可する必要があります。
ec2messages.region.amazonaws.com
ssm.region.amazonaws.com
ssmmessages.region.amazonaws.com
ec2messages.region.amazonaws.com は サービスで「com.amazonaws.ap-northeast-1.ec2messages」等という形式で検索に出てくるのでこれを指定し、出てきたサービスを指定してVPCとプライベートサブネットを指定して作成します。
作成はサービスごとに行います。
接続
セッションマネージャーの画面「セッションを開始」を押すとターゲットにできるインスタンス一覧が出てきます。ここから対象を選んで「Start session」して少し待つと以下のようにコンソールが開きました。
以下の画面ではUbuntuですが、WindowsではPowerShellのスクリプト画面になります。RDPしたい場合はFleetManagerを使用しましょう。
インスタンスへの接続をIAMユーザーごとに制限する
先程は強い権限をもっているユーザーで接続したため、権限を気にせず接続できましたが、セキュリティ観点ではよくありません。
というわけで権限制御を試したいと思います。
セッションマネージャーでのインスタンスアクセスを制御するためのIAMポリシーをIAMユーザー、またはユーザーが所属するIAMグループに付与します。※グループのインラインポリシー機能を使ってもOKです。
以下のJSONは上記を実現するためのIAMポリシーの一例です。
Resource部分にあるARNのregionとaccount-id, instance-idが変数となっているため、それぞれ適宜変更してポリシーを作成します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssm:StartSession"
],
"Resource": [
"arn:aws:ec2:region:account-id:instance/instance-id"
]
},
{
"Effect": "Allow",
"Action": [
"ssm:DescribeSessions",
"ssm:GetConnectionStatus",
"ssm:DescribeInstanceInformation",
"ssm:DescribeInstanceProperties",
"ec2:DescribeInstances"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ssm:TerminateSession",
"ssm:ResumeSession"
],
"Resource": [
"arn:aws:ssm:*:*:session/${aws:userid}-*"
]
}
]
}
FleetManagerからRDP接続する場合は「ssm-guiconnect:StartConnection」Actionを許可する必要がある。
検証
実際に検証してみます。
検証は以下の流れで行います。
IAMユーザーを用意し、ubuntuインスタンスのみにアクセスできるようにポリシーを設定する
ubuntuとwindowsのEC2インスタンスをそれぞれ用意する。
ポリシー設定済みのIAMインスタンスでSessionManagerのホスト一覧を表示
ubuntuとWindowsの2つのインスタンスが表示されている
windowsインスタンスには接続できない※想定どおりの権限エラー
ubuntuインスタンスには接続できる
Fleet ManagerからEC2にRDPする
許可するポリシーが少し変わります。
Fleet ManagerによるRDP接続はSessionManagerの機能も利用するようで、ssm:StartSessionに加えてssm-guiconnect:StartConnectionアクションを追加で許可する必要があります。また、許可対象もインスタンスに加えて「arn:aws:ssm:region::document/AWS-StartPortForwardingSession」リソースに許可を追加する必要があります。
許可対象を制限する場合は*をインスタンスIDにするだけです。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssm:StartSession",
"ssm-guiconnect:StartConnection"
],
"Resource": [
"arn:aws:ec2:ap-northeast-1:720936319346:instance/*",
"arn:aws:ssm:ap-northeast-1::document/AWS-StartPortForwardingSession"
]
},
{
"Effect": "Allow",
"Action": [
"ssm:DescribeSessions",
"ssm:GetConnectionStatus",
"ssm:DescribeInstanceInformation",
"ssm:DescribeInstanceProperties",
"ssm-guiconnect:GetConnection",
"ec2:DescribeInstances",
"ec2:GetPasswordData"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ssm:TerminateSession",
"ssm:ResumeSession",
"ssm-guiconnect:CancelConnection",
"ssm:DescribeSessions",
"ssm:GetConnectionStatus"
],
"Resource": [
"arn:aws:ssm:*:*:session/${aws:userid}-*"
]
}
]
}
これで無事接続できました。
まとめ
Session Manager と Fleet Managerを使って無事、プライベートサブネット上にあるEC2インスタンスにSSH/RDP接続できました。
インターネット公開する必要もないのでセキュアですし、SSMAgentがプリインストールされたAMIを使えばEC2プロファイル(ロール)を付与するだけで接続できるようになるので非常に便利に感じました。
VPNはもういらないですね。