はじめに
AWS で EC2 インスタンスや RDS 等を構築したときに、どのようにアクセスをしていますか。よくあるのが、Public Subnet に踏み台サーバーを構築し、Security Group で特定の IP アドレスに限定してアクセスする方法です。特定の IP アドレスに限定させているので、大きな問題はないですが、それでもシステムに入るための入り口としての踏み台サーバーが、Public IP を持っているのはセキュリティ的に気になります。Public IP の削除が出来るのであれば、よりセキュアに構成ができます。
構成図で表すと、こんな感じです。
こういった課題感を解決するために、Session Manager で上記構成図の踏み台サーバーを無くすことが出来ます。Private Subnet に配置した EC2 インスタンスに直接リモートアクセスが出来るので、踏み台サーバー経由の侵入を防ぐことが出来ます。
この記事では、Session Manager の使い方を簡単に確認してみる内容となっています。
IAM Role の作成
以下の Document に従って、IAM Policy と、それに紐づく IAM Role を作成します。詳細は省略します。
Policy の JSON
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssmmessages:CreateControlChannel",
"ssmmessages:CreateDataChannel",
"ssmmessages:OpenControlChannel",
"ssmmessages:OpenDataChannel",
"ssm:UpdateInstanceInformation"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents",
"logs:DescribeLogGroups",
"logs:DescribeLogStreams"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"s3:GetEncryptionConfiguration"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"kms:Decrypt"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "kms:GenerateDataKey",
"Resource": "*"
}
]
}
EC2 Instance の作成
Session Manager を使ったリモートアクセスとして、適当に EC2 インスタンスを作成します。
OS は Amazon Linux 2 を選択します。Amazon Linux 2 には、ssm-agent が既にインストールされているため、楽に検証できます。
Instance Profile に、先ほど作成した IAM Role を指定します。
ネットワークなどは適当に指定して、Launch Instance で作成します。
Instance が作成されました。
作成すると、自動的に Systems Manager の Fleet Manager に EC2 インスタンスが登録されています。これを使って、Session Manager を使ったリモートアクセスが可能です。
Session Manager の接続方法
Session Manager を使った接続の方法には、いくつかの方法があります。個人的には以下の 4 つが代表的なものだと思います。それぞれ接続方法を確認してみましょう。
- マネージメントコンソールを使った接続 (Systems Manager Console)
- マネージメントコンソールを使った接続 (EC2 Console)
- AWS CLI で、リモート接続
- AWS CLI で、ポート転送で接続
上記 4 つ以外の方法は、AWS Document に一覧化されているので、興味があれば Document もどうぞ。
マネージメントコンソールを使った接続 (Systems Manager Console)
Session Manager の画面で、Start Session を押します。
Start Session
ブラウザ上で、Amazon Linux 2 の環境に、リモート接続できました。
ユーザー ssm-user
でリモート接続がされます。sudo コマンドが実行できるので、root ユーザーや ec2-user にスイッチが出来ます。
Session Manager のセッション上でキー入力した情報は、CloudWatch Logs に自動的に送付されます。監査ログとして保管をしても良いでしょう。
Log stream を開きます。
ログが取得されています。次の情報がわかります。
- Amazon Linux 2 上で実行したコマンドのログ
- 実行時間
- Session Manager で接続した User 名
マネージメントコンソールを使った接続 (EC2 Console)
EC2 Instance の Console 画面経由でも、Session Manager を開けます。対象のインスタンスを選択して、Connect を押します。
Session Manager を選択して、Connect を押します。
さきほどと同様に、Session Manager を使った接続が出来ました。接続した後の画面は、さっきと同じです。
実行したコマンドが、CloudWatch Logs に取得されています。
AWS CLI で、リモート接続
AWS CLI をインストールしている環境からも、リモート接続が可能です。
次のコマンドを実行します。
aws ssm start-session --target i-04c2e28d623aab574
実行例
> aws ssm start-session --target i-04c2e28d623aab574 --profile sub2
Starting session with SessionId: cliuser-0caa0dc5ee42e1294
sh-4.2$
ブラウザで接続したように、リモート接続ができています。このセッション上で、さまざまなコマンドの実行ができます。
CloudWatch Logs にログが取得されています。
AWS CLI で、ポート転送で接続
いままでとちょっと毛色が違うのですが、Session Manager を使ってポート転送ができます。今までの接続方法と違って、任意のポートに転送できるので、SSH 以外にも RDP や MySQL など、いろいろな接続ができます。
次のコマンドでポート転送を指定します。
- portNumber : 接続先のポート番号を指定します。今回は 22 を指定しているので、SSH をするためのポートです。
- localPortNumber : ローカルのポート番号を指定します。2222 を指定しています。
aws ssm start-session \
--target i-04c2e28d623aab574 \
--document-name AWS-StartPortForwardingSession \
--parameters '{"portNumber":["22"], "localPortNumber":["2222"]}'
実行例
上記のコマンドを実行した結果、localhost の 2222 ポートが、EC2 側の 22 ポートにフォワーディングされます。次のようにポート番号を指定して、SSH 接続をしてみます。
ssh ec2-user@localhost -p 2222
SSH で接続できました
- あくまて SSH のポート転送なので、ログインしているユーザーは ec2-user
CloudWatch にログは収集されません。
検証してわかったこと
-
Session Manager で取得できる Linux 上のコマンドのログは、少し見にくいところもある
-
Session Manager で OS 内のコマンド実行ログを収集してくれるのは、ポート転送ではないシンプルな
start-session
を使った接続のみ- RDS も同様にログが取得できない。Session Manager 以外のログ収集の仕組みを検討することは可能。
参考 URL