AWS Systems Managerにはセッションという機能があり、管理下のEC2インスタンスのシェルへのアクセスや、ポート転送でのアクセスができます。このSystems Managerのセッション経由でのOSシェルアクセスや、ポート転送を使ったRDP接続を試してみるためのおおよその手順をまとめてみました。
概要
以下を行います。
- 準備
2. プライベートサブネットとパブリックサブネットを持つVPCを作成
3. 両サブネットにEC2インスタンスを作成 - EC2インスタンスをSystems Manager管理対象化
- Sytems Managerのセッションでシェル(
sh
/PowerShell
)接続 - セッション情報(操作内容を含む)の記録
- エンドポイント経由でのプライベートサブネットへの接続
- AWS CLIでの接続とRDP接続
準備
初期構成として、プライベートサブネットとパブリックサブネットにそれぞれEC2インスタンスがおかれた構成を作成します。
以降の説明ではここで作成したインスタンス名、サブネット名等を使いますが、もし既存環境があって読み替えができるようであれば、そちらを使っても構いません。
VPCの作成
下図のように、プライベートサブネットとパブリックサブネットを持つVPCを作成します。
- AWSコンソールから「VPC」サービスを開く。
- 「VPCダッシュボード」が表示される。まずElastic IPを作成しておく。
3. 左側のメニューから「Elastic IP」をクリックする。
4. 「新しいアドレスの割り当て」をクリックする。
5. 「新しいアドレスの割り当て」画面で「割り当て」をクリックする - 左側のメニューから「VPCダッシュボード」をクリックする。
- 「VPCウィザードの起動」をクリックする。
- 「ステップ1: VPC設定の選択」が表示される。「パブリックとプライベートサブネットを持つVPC」を選択する。
- 「ステップ2:パブリックとプライベートサブネットを持つVPC」で、以下を指定する。
10. 図の通りにVPC名、パブリックサブネット名、プライベートサブネット名、アベイラビリティゾーンを指定する。
11. Elastic IP割当てIDで、上で作成したElastic IPを選択する。
12. 「VPCの作成」をクリックする。
これで図のようなVPC、サブネット、Internet Gateway、NAT Gateway、ルーティングテーブルが作成されます。
EC2インスタンスの作成
プライベートサブネットとパブリックサブネットにそれぞれEC2インスタンスを配置します。パブリックサブネットにはLinuxとWindowsの2台のインスタンスを配置します。
まずキーペアを作成しておきます。
- AWSコンソールから「EC2」サービスを開く。
- 左側のメニューから「キーペア」をクリックする。
- 「キーペアを作成」をクリックする。
- 名前は任意の名称、ファイル形式は「pem」を選択し、「キーペアを作成」をクリックする。
- ダウンロードされたpemファイルを適当な場所に保管しておく。
次にパブリックサブネットで使用するセキュリティグループを作成しておきます。
- AWSコンソールから「VPC」サービスを開く。
- 左側のメニューから「セキュリティグループ」をクリック。
- 「セキュリティグループの作成」をクリック。
- 「セキュリティグループ名」は「Web-SG」、「説明」は「Allow HTTP/HTTPS from any」、「VPC」は「vpc-ssm-test」を指定し、作成。
- セキュリティグループの一覧から「Web-SG」を選択し、「アクション > インバウンドルールルールの編集」を選択。
- 「ルールの追加」をクリックし、「タイプ」に「HTTP」、ソースに「0.0.0.0/0」を指定。
- 同様に「HTTPS」「SSH」「RDP」に対して、ソースを「0.0.0.0/0」とするルールを追加。
8.「ルールの保存」をクリック。
同様にプライベートサブネットで使用するセキュリティグループを、以下の内容で作成しておきます。
- セキュリティグループ名は「DB-SG」。
- インバウンドルールはタイプ「MYSQL/AURORA」「SSH」「RDP」をそれぞれ、ソース「10.0.0.0/16」に対して追加
使用するキーペアとセキュリティグループが用意できたので、EC2インスタンスを作成していきます。
パブリックサブネットにLinuxのEC2インスタンスを作成します。
- AWSコンソールから「EC2」サービスを開く。
- 左側のメニューから「インスタンス」をクリックする。
- 「インスタンスの作成」をクリックする。
- 「ステップ1: Amazonマシンイメージ(AMI)」で、先頭にある無料利用枠の対象の「Amazon Linux 2 AMI (HVM), SSD Volume Type」を選択。
- 「ステップ2: インスタンスタイプの選択」で、無料利用枠の対象の「t2.micro」を選択。
- 「ステップ3: インスタンスの詳細の設定」で、ネットワークは「vpc-ssm-test」、サブネットは「subnet-public-1a」、「自動割り当てパブリックIP」は「有効」を選択。
- 「ステップ4: ストレージの追加」はそのまま。
- 「ステップ5: タグの追加」では「クリックしてNameタグを追加します」をクリックし、「Linux Web Instance」を指定。
- 「ステップ6: セキュリティグループの設定」では「既存のセキュリティグループを選択する」を選択し、名前が「Web-SG」のものを選択。
- 「ステップ7: インスタンス作成の確認」では「起動」をクリック。
- 「既存のキーペアを選択するか、新しいキーペアを作成します。」で、上で作成したキーペアを指定し、確認チェックボックスをチェックして、「インスタンスの作成」をクリック。
同様にパブリックサブネットにWindowsのEC2インスタンスを、以下の内容で作成しておきます。
- Amazonマシンイメージ(AMI)は、__
Windows
を検索__し、先頭にある無料利用枠の対象の「 Microsoft Windows Server 2019 Beta 」を選択。 - ネットワークは「vpc-ssm-test」、サブネットは「subnet-public-1a」、「自動割り当てパブリックIP」は「有効」を選択。
- Nameタグは「 Windows Web Instance 」を指定。
- セキュリティグループは「Web-SG」を選択。
同様にプライベートサブネットにLinuxのEC2インスタンスを、以下の内容で作成しておきます。
- Amazonマシンイメージ(AMI)は、先頭にある無料利用枠の対象の「Amazon Linux 2 AMI (HVM), SSD Volume Type」を選択。
- ネットワークは「vpc-ssm-test」、サブネットは「 subnet-private-1a 」、「自動割り当てパブリックIP」は「 無効 」を選択。
- Nameタグは「 DB Instance 」を指定。
- セキュリティグループは「 DB-SG 」を選択。
これで図のようなセキュリティグループとEC2インスタンスが追加されます。
仮想マシンが起動したら、以下の接続を確認しておいてください。
- Linux Web Instance(パブリックサブネットに配置したLinuxインスタンス)へのssh接続。「SSH を使用した Linux インスタンスへの接続 - Amazon Elastic Compute Cloud」の手順で実施します。シェルへのログインが確認できればすぐに
exit
して構いません。 - Windows Web Instance(パブリックサブネットに配置したWindowsインスタンス)へのリモートデスクトップ接続。「Windows インスタンスへの接続 - Amazon Elastic Compute Cloud」の「RDP クライアントを使用して Windows インスタンスに接続」手順で実施します。リモートデスクトップへのログインが確認できればすぐに切断して構いません。
- DB Instance(プライベートサブネットに配置したLinuxインスタンス)へのssh接続。インターネットからは直接接続できないので、Linux Web Instanceにssh接続し、ここからさらにDB Instanceにssh接続して確認します。
EC2インスタンスをSystems Manager管理対象化
Systems Managerの管理対象となっているインスタンスは「Managed Instance」と呼ばれれ、セッションを使ったシェルアクセスが可能になります。以下では作成したEC2インスタンスをManaged Instanceにするための設定を行います。その後、Systems ManagerでManaged Instanceになったことを確認します。
「AWS Systems Manager のセットアップ - AWS Systems Manager」のから、まず「ステップ 4: Systems Manager の IAM インスタンスプロファイルの作成」を行います。インスタンスプロファイスは、ここではEC2インスタンスに割り当てるロールのことだと思っておいてください(違いに興味があればこちらなどを参照)。ここでは最小限のロールを作成します。
- AWSコンソールから「IAM」サービスを開く。
- 左側のメニューから「ロール」をクリックする。
- 「ロールの作成」をクリックする。
- 「信頼されたエンティティの種類」は「AWSサービス」、「ユースケースの選択」は「EC2」を選択。
- 「Attachアクセス権限ポリシー」では「AmazonSSMManagedInstanceCore」を選択。
- 「ロールの作成」で任意のロール名(例えば「MySSMRoleForInstancesQuickSetup」)を指定し、「ロールの作成」をクリック。
次に「ステップ 5: IAM インスタンスプロファイルを Amazon EC2 インスタンスにアタッチする」を行います。
- AWSコンソールから「EC2」サービスを開く。
- 左側のメニューから「インスタンス」をクリックする。
- 対象のインスタンスをすべて選択し、「アクション > インスタンスの状態 > 停止」を選択。
-
Linux Web Instance
が停止したら選択し、「アクション > インスタンスの設定 > IAMロールの割り当て/置換」を選択。 - 「IAMロール」にステップ4で作成したロールを選択し、「適用」をクリック。
-
Windows Web Instance
DB Instance
についても手順4.~5.を実施。 - 対象のインスタンスをすべて選択し、「アクション > インスタンスの状態 > 開始」を選択。
これで最小限の設定が終了です。本来はこの他にSSMエージェントのインストールが必要ですが、事前インストールされたAmazon Linux 2およびWindows Server 2019イメージをEC2インスタンス作成手順で選択しているため、ここでは不要です。
AWS Systems Managerで、Managed Instanceになっていることを確認します。
- AWSコンソールから「Systems Manager」サービスを開く。
- 左側のメニューから「マネージドインスタンス」をクリックする。
- マネージドインスタンスに、ステップ5で設定対象にしたEC2インスタンスが表示されていることを確認する。
Sytems Managerのセッションでシェル接続
Managed Instanceに対して、Systems Managerからシェルアクセスします。これが確認出来たら、セキュリティグループの設定でSSHやRDP通信を遮断してしまうことにします。
Managed Instanceに対して、Systems Managerからシェルアクセスします。
- AWSコンソールから「Systems Manager」サービスを開く。
- 左側のメニューから「セッションマネージャー」をクリックする。
- 「セッションの開始」をクリックする。
- 「Linux Web Instance」を選択し、「セッションを開始する」をクリックする。
- シェル(
sh
)画面が表示されたら、「exit」を実行してセッションを終了する。 - 「DB Instance」に対しても、4.~5.の手順でシェルへのアクセスを確認する。
- 「Windows Web Instance」に対しても、4.~5.の手順でシェル(
PowerShell
)へのアクセスを確認する。
sshやRDP通信が(特にインターネットから直接)できないようにします。
- AWSコンソールから「VPC」サービスを開く。
- 左側のメニューから「セキュリティグループ」をクリックする。
- 「Web-SG」を選択し、「アクション > インバウンドルールの編集」を選択。
- タイプが「SSH」「RDP」の行を、右端の「×」をクリックして削除後、「ルールの保存」をクリック。
- 「DB-SG」についても、手順3.~4.を実施。
念のためもう一度、Systems Managerのセッションマネージャーから、各EC2インスタンスのシェルにアクセスできることを確認しておいてもいいかもしれません。これができれば、sshやRDPがなくてもOSを管理する術があることになります。攻撃対象になる箇所をできるだけ少なくしておくという基本的な考え方に従って、sshやrdpアクセスを閉じた状態にしておけるということでもあります。
セッション情報(操作内容を含む)の記録
セッションでの接続までは、この時点でもセッションマネージャーの「セッション履歴」に記録されています。ここでは操作内容もS3とCloudWatch Logsに記録できるように構成します。
記録用のS3バケットを作成しておきます。
- AWSコンソールから「S3」サービスを開く。
- 左側のメニューから「バケット」をクリックする。
- 「バケットを作成」をクリックする。
- 任意のバケット名(例えば
YOURNAME_ssm_session_YYYYMMDD
)を指定し、「バケットを作成」をクリック。
記録用のCloudWatchロググループを作成しておきます。
- AWSコンソールから「CloudWatch」サービスを開く。
- 左側のメニューから「ロググループ」をクリックする。
- 「ロググループを作成」をクリック。
- 任意のロググループ名(例えば
/ssm/session_logs
)を指定し、「作成」をクリック。
セッションの操作内容をS3バケットやCloudWatch Logsに書込めるよう、EC2インスタンスに割り当てたロール(インスタンスプロファイル)に権限を追加します。
- AWSコンソールから「IAM」サービスを開く。
- 左側のメニューから「ロール」をクリック。
- 一覧から、作成したロール(例えば「MySSMRoleForInstancesQuickSetup」)をクリック。
- 「ポリシーをアタッチする」をクリック。
-
AmazonS3GFullAccess
にチェック。S3への記録に必要なもので、本来はカスタムポリシーを作成して選択する方がよい(最小権限の原則)が、ここではこれで代用。 -
CloudWatchAgentServerPolicy
にチェック。CloudWatchへの記録に必要。 - 「ポリシーのアタッチ」をクリック。
最後に、セッションの記録の設定をします。
- AWSコンソールから「Systems Manager」サービスを開く。
- 左側のメニューから「セッションマネージャー」をクリックする。
- 右側の「設定」タブを選択。
- 「編集」をクリック。
- 「Amazon S3 バケットにセッション出力を書き込む」設定。
6. 「S3バケット」にチェック。
7. 「ログデータを暗号化する」のチェックを外す(S3バケット作成時に暗号化を有効にしている場合はチェックを入れたままにする)。
8. 「S3バケット名」で、作成したS3バケットを選択。 - 「CloudWatch Logs にセッション出力を送信する」設定。
10. 「CloudWatch Logs」にチェック。
11. 「CloudWatchのロググループ」で、作成したロググループを選択。 - 「保存」をクリック。
実際にセッションを利用してみて、セッション内容の記録を確認します。
- AWSコンソールから「Systems Manager」サービスを開く。
- 左側のメニューから「セッションマネージャー」をクリック。
- 「セッションの開始」をクリックする。
- いずれかのインスタンスを選択し、「セッションを開始する」をクリック。
- 「exit」を実行してセッションを終了する。
- 「セッションの履歴」タブをクリック。
- 最新のセッションの「出力場所」列で「Amazon S3」をクリック。
- 表示されたログを「ダウンロード」し、内容を確認。
- 「セッションの履歴」に戻り、最新のセッションの「出力場所」列で「CloudWatch Logs」をクリック。
- 表示されたログの内容を確認。
エンドポイント経由でのプライベートサブネットへの接続
EC2インスタンスとSystems Managerの間の通信を、エンドポイント経由に変更します。これにより、ネットワークトラフィックをAmazon ネットワークに限定し、インターネットにアクセスできないプライベートサブネットのEC2インスタンスもSystems Managerの管理下に入れることができます。
まずエンドポイント用のセキュリティグループを作成します。
- AWSコンソールから「VPC」サービスを開く。
- 左側のメニューから「セキュリティグループ」をクリックする。
- 「セキュリティグループの作成」をクリックする。
- 「セキュリティグループ名」に「SSM-SG」、「説明」に「Allow HTTPS access from managed instances.」、VPCに「vpc-ssm-test」を指定し、「作成」をクリック。
- セキュリティグループ一覧画面で、「SSM-SG」を選択し、「アクション > インバウンドルールの編集」を選択。
- 「ルールの追加」をクリックし、「タイプ」に「HTTPS」、「ソース」に「10.0.0.0/16」を指定し、「ルールの保存」をクリック。
エンドポイントを作成します。
- AWSコンソールから「VPC」サービスを開く。
- 左側のメニューから「エンドポイント」をクリック。
- 「エンドポイントの作成」をクリック。
- 「サービス名」に「com.amazonaws.ap-northeast-1.ssm」、「VPC」に「vpc-ssm-test」、「アベイラビリティゾーン」に「ap-northeast-1a」、「サブネット」に「subnet-private-1a」、「セキュリティグループ」に「SSM-SG」を選択し、「エンドポイントの作成」をクリック。
- 手順3.~4.を「com.amazonaws.ap-northeast-1.ssmmessages」についても実行。
- 手順3.~4.を「com.amazonaws.ap-northeast-1.ec2messages」についても実行。
- 「エンドポイントの作成」をクリックする。
- 「サービス名」に「com.amazonaws.ap-northeast-1.s3」、「VPC」に「vpc-ssm-test」、「ルートテーブル」は表示されるものすべてを選択し、「エンドポイントの作成」をクリック。
これでプライベートサブネットからインターネットへの接続は(SSMでの管理のためには)不要になったはずなので、NATゲートウェイを削除してしまうことにします。
- AWSコンソールから「VPC」サービスを開く。
- 左側のメニューから「NATゲートウェイ」をクリック。
- NATゲートウェイを選択し、「アクション > NATゲートウェイの削除」を選択。
- 左側のメニューから「サブネット」をクリック。
- 「subnet-private-1a」のルートテーブル列に表示されているリンクをクリック。
- ルートテーブルの詳細が表示されるので、「アクション > ルートの編集」を選択。
- 「送信先」が「0.0.0.0/0」、「ターゲット」が削除したNATゲートウェイの行を右、端の「×」をクリックして削除後、「ルートの保存」をクリック。
一通りの変更が済んだので、各EC2インスタンスがAWS Systems Managerからエンドポイント経由での通信で管理されることを確認します。
- AWSコンソールから「EC2」サービスを開く。
- 左側のメニューから「インスタンス」をクリックする。
- 対象のインスタンスをすべて選択し、「アクション > インスタンスの状態 > 停止」を選択。
- 対象のインスタンスをすべて選択し、「アクション > インスタンスの状態 > 開始」を選択。
- AWSコンソールから「Systems Manager」サービスを開く。
- 左側のメニューから「マネージドインスタンス」をクリックする。
- マネージドインスタンスに、ステップ5で設定対象にしたEC2インスタンスが表示されていることを確認する。
セッション(シェルへのアクセス)も引き続き可能で、セッション内容も記録されることを確認します。
- AWSコンソールから「Systems Manager」サービスを開く。
- 左側のメニューから「セッションマネージャー」をクリック。
- 「セッションの開始」をクリックする。
- 「DB Instance」を選択し、「セッションを開始する」をクリック。
- 「exit」を実行してセッションを終了する。
- 「セッションの履歴」タブをクリック。
- 最新のセッションの「出力場所」列で「Amazon S3」をクリック。
- 表示されたログを「ダウンロード」し、内容を確認。
- 「セッションの履歴」に戻り、最新のセッションの「出力場所」列で「CloudWatch Logs」をクリック。
- 表示されたログの内容を確認。
これで、インターネットからのsshやrdpをセキュリティグループレベルで遮断できただけでなく、インターネットとの接続経路も持たないプライベートサブネットのEC2インスタンスもシェルを使って管理できることになります。
AWS CLIでの接続とRDP接続
ここまではAWSの管理コンソール(Web画面)からセッションを使ってきましたが、ここではAWS CLIからセッションを使ってみます。またAWS CLIからのセッションではポーロフォワーディングができるので、これを介してRDP接続をしてみます。
AWS CLIとSession Managerプラグインの準備
ローカル環境にAWS CLIとSession Managerプラグインが必要です。以下から各OS用のAWS CLIとSession Managerを導入します。
- AWS CLI バージョン 2 のインストール - AWS Command Line Interface
- (オプション) AWS CLI 用の Session Manager Plugin をインストールする - AWS Systems Manager
AWS CLIを未使用であれば、以下のAWS CLIのかんたん設定(aws configure
)を行います。
AWS CLIでの接続
接続対象のEC2インスタンスのインスタンスIDを、AWSの管理コンソール(Web画面)か、以下のコマンド実行結果で確認しておきます。
aws ec2 describe-instances --query "Reservations[].Instances[].[InstanceId,Tags]"
AWSコマンドでセッションを実行します。
aws ssm start-session --target instance-id
Linuxインスタンスでは sh
、Windowsインスタンスでは PowerShell
に接続されることを確認出来たら、 exit
でセッションを終了します。
AWSの管理コンソールで、Systems Managerのセッションマネージャーを開き、セッション履歴を確認します。このセッションもセッション履歴が残されており、操作内容がS3およびCloudWatch Logsに記録されていることを確認します。
ポート転送によるRDP接続
AWS CLIによるポート転送を利用して、セッション経由でRDP接続なども可能です。WindowsインスタンスのインスタンスIDを確認の上、以下を実行します。
aws ssm start-session --target instance-id --document-name AWS-StartPortForwardingSession --parameters "portNumber=3389, localPortNumber=13389“
リモートデスクトップ接続を起動し、localhost:13389に接続します。Windowsデスクトップ画面が表示されたら、管理者のID(Administrator)とパスワードでサインインします。
サインインが確認出来たら、RDP接続を切断します。先ほど同様に、セッション履歴を確認します。ポート転送での接続では、セッション(接続)履歴はあるものの、操作内容のS3やCloudWatch Logsへの記録はされていません。
まとめ
ここまでの手順を試してみることで、EC2インスタンスのOSへの操作には、インターネット経由または踏み台サーバー経由のssh/RDPの代わりに、Systtems Managerのセッションを使うという選択肢があることが実感できるかと思います。
この方式は、操作内容などの記録も取れること、インターネットへのアクセスをもたないEC2インスタンスにも適用できることなどがメリットになりそうです。一方で、Managed Instanceとして正しく構成できていること、接続が対象のEC2インスタンスのOS上でSSMエージェントが動作している間に限られることなどがデメリット、ないしリスクとなりそうです。つまり、トラブルシュートのタイミングではつながらない可能性が考えられれます。また実環境に適用する上では、セッションを利用できる人とS3等に残されるセッション記録を操作できる人を分ける権限構成など、まだ考慮したいことがあります。
こうした検討にも、試行環境のつくり方として役立てば幸いです。
参考情報
各手順は主に以下のドキュメントを元にしました。
-
AWS Systems Manager のセットアップ - AWS Systems Manager
- ステップ 4: Systems Manager の IAM インスタンスプロファイルの作成 - AWS Systems Manager
- ステップ 5: IAM インスタンスプロファイルを Amazon EC2 インスタンスにアタッチする - AWS Systems Manager
- ステップ 6: (オプション) プライベートクラウドエンドポントの作成 - AWS Systems Manager
- Windows インスタンスで SSM エージェント をインストールし設定する - AWS Systems Manager
- Amazon EC2 Linux インスタンスで SSM エージェント をインストールし設定する - AWS Systems Manager
- SSH を使用した Linux インスタンスへの接続 - Amazon Elastic Compute Cloud
- Windows インスタンスへの接続 - Amazon Elastic Compute Cloud
- AWS CLI バージョン 2 のインストール - AWS Command Line Interface
- (オプション) AWS CLI 用の Session Manager Plugin をインストールする - AWS Systems Manager
- AWS CLI の設定 - AWS Command Line Interface
私自身の試行では、以下も参考にしました(JAWS DAYS 2019および2020のセッションが試行の動機でした)。
- 1日でSSHをやめることができた話 ~AWS Systems Manager Session Manager 導入と運用Tips~ | JAWS DAYS 2019
- AWS Systems Manager Session ManagerとIAMでシンプルにユーザーを管理する | JAWS DAYS 2020
- 20180725 AWS Black Belt Online Seminar AWS Systems Manager
本ページ内容は筆者が参照の便のためにある時点でまとめた個人的なメモです。内容を保証するものではなく、また筆者の所属組織等とは一切かかわりがありません。