LinuxインスタンスにSSM Session Manager経由でアクセスする構成
EC2インスタンスにSSM Session Manager経由でアクセスする構成を確認します。
Session Manager は完全マネージド型の AWS Systems Manager 機能です。ブラウザベースのインタラクティブなワンクリックシェルまたは AWS CLI を介して Amazon EC2 インスタンスを管理できます。Session Manager を使用して、アカウント内のインスタンスとのセッションを開始できます。セッションの開始後、他の接続タイプと同様、bash コマンドを実行できます。
Session Manager を使用した Linux インスタンスへの接続
SSM Session Managerを使用したインスタンスへのアクセスは、一般的なSSHでのアクセスと比べてさまざまなメリットがあります。特に注目すべきポイントは、リモートアクセス用のポート開放が不要になる点と、踏み台サーバも不要になる点です。
インスタンスでインバウンド SSH ポートとリモート PowerShell ポートを開いたままにすると、エンティティが許可されていないコマンドや、悪意のあるコマンドをインスタンス上で実行するリスクが大幅に増加します。Session Manager は、これらの着信ポートを閉じることにより、SSH キーと証明書、踏み台ホスト、およびジャンプボックスの管理からユーザーを解放して、セキュリティ体制を向上させるのに役立ちます。
AWS Systems Manager Session Manager
今回はEC2インスタンスへのアクセス方法を、以下の2パターン確認します。
- SSHでアクセス ※ ①パターン
- SSM Session Manager経由でアクセス ※ ②パターン
なお本ページはLinuxインスタンスを対象とした内容です。WindowsインスタンスにSession Manager経由でアクセスする方法については、以下のページをご確認ください。
構築する環境

EC2インスタンスへのアクセス方法を、以下の2パターン確認します。
- インターネットゲートウェイ経由でSSHしてアクセスする方法 ※パターン1
- SSM用VPCエンドポイント経由でSSM Session Managerを使ってアクセスする方法 ※パターン2
環境構築用のCloudFormationテンプレートファイル
上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。
テンプレートファイルのポイント解説
今回の環境を構成するための、各テンプレートファイルのポイントを取り上げます。
VPCエンドポイントを使用する場合は、VPCのDNS機能を有効化する
VPCのパラメータを確認します。
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VPCCidrBlock
EnableDnsHostnames: true
EnableDnsSupport: true
Code language: YAML (yaml)
VPCエンドポイントを設置する場合、VPCで2つのパラメータを設定する必要があります。
インターフェイス VPC エンドポイント ( AWS PrivateLink ) でプライベート DNS を使用する場合は、enableDnsHostnames 属性と enableDnsSupport 属性の両方を true に設定する必要があります。
VPC 内の DNS 属性
上記に従い、2プロパティを「true」に設定します。
ルーティング設定比較
ルーティング関係のリソースを確認します。
まずパブリックサブネット側、つまりSSHでアクセスするEC2インスタンス①用の設定を確認します。
Resources:
IGW:
Type: AWS::EC2::InternetGateway
IGWAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref IGW
PublicSubnet:
Type: AWS::EC2::Subnet
Properties:
CidrBlock: !Ref CidrIp1
VpcId: !Ref VPC
AvailabilityZone: !Sub ${AWS::Region}${AvailabilityZone1}
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
RouteToInternet:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref IGW
PublicSubnetRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet
RouteTableId: !Ref PublicRouteTable
Code language: YAML (yaml)
インターネットゲートウェイを定義後、パブリックサブネット用のルートテーブルを用意し、同ゲートウェイ向けのデフォルトルートを作成します。デフォルトルートはDestinationCidrBlockプロパティに「0.0.0.0/0」を指定することで作成できます。
次にプライベートサブネット側、つまりSSM Session Managerを使用して、VPCエンドポイント経由でアクセスするEC2インスタンス②用の設定を確認します。
Resources:
PrivateSubnet:
Type: AWS::EC2::Subnet
Properties:
CidrBlock: !Ref CidrIp2
VpcId: !Ref VPC
AvailabilityZone: !Sub ${AWS::Region}${AvailabilityZone2}
Code language: YAML (yaml)
こちらでは、特にルーティングの設定は不要です。サブネットの定義のみ行います。
セキュリティグループ設定比較
セキュリティグループを設定を確認します。
まずEC2インスタンス①のセキュリティグループを確認します。
Resources:
InstanceSecurityGroup1:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub ${Prefix}-InstanceSecurityGroup1
GroupDescription: Allow SSH.
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: !Ref SSHPort
ToPort: !Ref SSHPort
CidrIp: 0.0.0.0/0
Code language: YAML (yaml)
こちら側では、SSHのインバウンド通信を許可するように設定を行います。これでSSHでインターネット越しに、インスタンスにアクセスすることが可能になります。
次にEC2インスタンス②のセキュリティグループを確認します。
Resources:
InstanceSecurityGroup2:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub ${Prefix}-InstanceSecurityGroup2
GroupDescription: Deny All.
VpcId: !Ref VPC
Code language: YAML (yaml)
こちらでは特定のインバウンド通信を許可しません。これは後述のVPCエンドポイント用のセキュリティグループで示されているように、インスタンス側からエンドポイント向きに、アウトバウンド通信を行うためです。
最後にVPCエンドポイント用のセキュリティグループを確認します。
Resources:
EndpointSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub ${Prefix}-EndpointSecurityGroup
GroupDescription: Allow HTTPS from InstanceSecurityGroup2.
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: !Ref HTTPSPort
ToPort: !Ref HTTPSPort
SourceSecurityGroupId: !Ref InstanceSecurityGroup2
Code language: YAML (yaml)
インスタンス②からのHTTPS通信(443/tcp)を許可します。これはVPCエンドポイントを作成する上での要件の1つです。
VPC エンドポイントにアタッチされたセキュリティグループでは、マネージドインスタンスのプライベートサブネットから、ポート 443 で着信接続を許可する必要があります。着信接続が許可されていない場合、マネージドインスタンスは SSM および EC2 エンドポイントに接続できません。
VPC エンドポイントの制約と制限
SSM Session Manager用のVPCエンドポイント設定
Resources:
SSMEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
PrivateDnsEnabled: true
SecurityGroupIds:
- !Ref EndpointSecurityGroup
ServiceName: !Sub com.amazonaws.${AWS::Region}.ssm
SubnetIds:
- !Ref PrivateSubnet
VpcEndpointType: Interface
VpcId: !Ref VPC
EC2MessagesEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
PrivateDnsEnabled: true
SecurityGroupIds:
- !Ref EndpointSecurityGroup
ServiceName: !Sub com.amazonaws.${AWS::Region}.ec2messages
SubnetIds:
- !Ref PrivateSubnet
VpcEndpointType: Interface
VpcId: !Ref VPC
SSMMessagesEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
PrivateDnsEnabled: true
SecurityGroupIds:
- !Ref EndpointSecurityGroup
ServiceName: !Sub com.amazonaws.${AWS::Region}.ssmmessages
SubnetIds:
- !Ref PrivateSubnet
VpcEndpointType: Interface
VpcId: !Ref VPC
Code language: YAML (yaml)
PrivateDnsEnabledプロパティに「true」を指定して、プライベートDNSを有効化します。なお本パラメータはデフォルトで有効です。
SecurityGroupIdsプロパティで、先述のVPCエンドポイント用セキュリティグループを指定します。ServiceNameプロパティで作成するエンドポイントのサービスを指定します。SSM Session Managerを使用して、EC2インスタンスにアクセスするために必要なサービスは以下の3つです。
・com.amazonaws.[region].ssm
Systems Manager を使用してインターネットアクセスなしでプライベート EC2 インスタンスを管理できるように、VPC エンドポイントを作成するにはどうすればよいですか?
・com.amazonaws.[region].ec2messages
・com.amazonaws.[region].ssmmessages
今回は、組み込み関数Fn::Subを使用して、CloudFormationの擬似パラメータAWS::Regionを埋め込み、各サービス名を指定します。今回は3つのサービスへのアクセスが必要ですので、各サービス用にVPCエンドポイントを作成します。
SubnetIdsプロパティにプライベートサブネットを指定します。VpcEndpointTypeプロパティに「Interface」を指定します。VPCエンドポイントは大別すると、ゲートウェイ型とインターフェース型の2種類ありますが、今回はインターフェース型で作成します。
インターフェイスエンドポイントは、サブネットの IP アドレス範囲のプライベート IP アドレスを持つ Elastic Network Interface です。サポートされている AWS のサービスまたは VPC エンドポイントサービスへのトラフィックのエントリポイントとして機能します。インターフェイスエンドポイントは を使用します AWS PrivateLink
VPC エンドポイント
使い分けですが、ゲートウェイ型はDynamoDBおよびS3のみを対象としたエンドポイントサービスですので、今回はインターフェース型を指定します。
EC2設定比較
まずSSHでアクセスするEC2インスタンス①を確認します。
Resources:
Instance1:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref ImageId
InstanceType: !Ref InstanceType
KeyName: !Ref KeyName
NetworkInterfaces:
- AssociatePublicIpAddress: true
DeviceIndex: 0
SubnetId: !Ref PublicSubnet
GroupSet:
- !Ref InstanceSecurityGroup1
Code language: YAML (yaml)
ポイントは2点です。
1点目はキーペアに関する設定です。EC2インスタンスにSSHするためには、キーペアを作成し、指定する必要があります。今回は「MyKeyPair」というキーペアを作成しているものとして記載しています。なおキーペアの作成に関しては、Amazon EC2 キーペアの作成、表示、削除をご確認ください。
2点目はパブリックアドレスに関する設定です。インターネット向けの通信を行うためには、インスタンスにパブリックアドレスを付与する必要があります。AssociatePublicIpAddressプロパティに「true」を設定することで、インスタンスの起動時に、自動的にパブリックアドレスを付与することができます。
次にVPCエンドポイント経由でアクセスするインスタンス②を確認します。
Resources:
Instance2:
Type: AWS::EC2::Instance
Properties:
IamInstanceProfile: !Ref InstanceProfile
ImageId: !Ref ImageId
InstanceType: !Ref InstanceType
NetworkInterfaces:
- DeviceIndex: 0
SubnetId: !Ref PrivateSubnet
GroupSet:
- !Ref InstanceSecurityGroup2
InstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Path: /
Roles:
- !Ref InstanceRole
InstanceRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: sts:AssumeRole
Principal:
Service:
- ec2.amazonaws.com
- ssm.amazonaws.com
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
Code language: YAML (yaml)
ポイントはインスタンスにIAMロールを関連付け、SSMへのアクセス権限を付与するという点です。
AWS 管理ポリシー [AmazonSSMManagedInstanceCore] を含むインスタンスプロファイルが既にインスタンスにアタッチされている場合、Session Manager に必要なアクセス許可は既に付与されています。
ステップ 2: Session Manager のアクセス許可を持つ IAM インスタンスプロファイルを確認または作成する
上述の通りにIAMロールを作成し、インスタンスプロファイルを通じて、インスタンス②にアタッチします。なおSSM Session Manager経由でインスタンスにアクセスするためには、上記に加え、SSMエージェントのインストール等が必要になりますが、Amazon Linux 2ベースのインスタンスでは、デフォルトで同エージェントがインストールされているため、追加の対応は不要です。
環境構築
CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。
CloudFormationスタックを作成し、スタック内のリソースを確認する
CloudFormationスタックを作成します。
AWS CLIからCloudFormationを実行する手順については、以下のページをご確認ください。
各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。
- Instance1のID:i-08ee670b7a7c1ce63
- Instance2のID:i-0a06995e9b6eada48
- Instance1のパブリックDNS名:ec2-13-113-95-51.ap-northeast-1.compute.amazonaws.com
- PublicSubnetのID:subnet-06d397c402ed5c23f
- PrivateSubnetのID:subnet-0303094396a6d4af4
- インターネットゲートウェイのID:igw-0ac078662be74efc1
- EC2MessagesEndpointのID:vpce-0ed32ba52c8d38306
- EC2MessagesEndpointのDNS名:ec2messages.ap-northeast-1.amazonaws.com
- SSMEndpointのID:vpce-06231300ba511d2ba
- SSMEndpointのDNS名:ssmmessages.ap-northeast-1.amazonaws.com
- SSMMessagesEndpointのID:vpce-0f8005d988b7fb2bf
- SSMMessagesEndpointのDNS名:ssm.ap-northeast-1.amazonaws.com
AWS Managemet Consoleでもリソースの作成状況を確認します。
まずパブリックサブネット用のルーティングテーブルを確認します。

インターネットゲートウェイ向けのデフォルトルートが定義されています。このデフォルトルートによって、インターネット越しのSSH通信が可能となります。
次にプライベートサブネット用のルーティングテーブルを確認します。

こちらは特別なルートは設定されていません。SSM用VPCエンドポイントはインターフェース型であるため、ルーティング設定は不要だからです。
ではSSM用VPCエンドポイントの作成状況を確認します。



いずれもプライベートサブネット(10.0.2.0/24)内のアドレスが設定されていることがわかります。このように3エンドポイントはインターフェース型ですので、サブネット内のアドレスが割り当てられるため、ルーティング設定が不要になるということがわかります。
動作確認1:SSHでインスタンスにアクセス
準備が整いましたので、実際に挙動を確認します。
まずSSHでインスタンスにアクセスする方法を確認します。クライアント側でSSHを実行します。
$ ssh -i MyKeyPair.pem ec2-13-113-95-51.ap-northeast-1.compute.amazonaws.com
__| __|_ )
_| ( / Amazon Linux 2 AMI
___|\___|___|
https://aws.amazon.com/amazon-linux-2/
[ec2-user@ip-10-0-1-215 ~]$
Code language: Bash (bash)
先ほど確認したパブリックDNS名に対して、SSHを実行します。SSH実行時に、キーペアのプライベートキーを指定します。
[ec2-user@ip-10-0-1-215 ~]$ ec2-metadata -i
instance-id: i-08ee670b7a7c1ce63
Code language: Bash (bash)
このようにSSH後は、自由にコマンドを実行することができます。
動作確認2:SSM Session Manager経由でインスタンスにアクセス
続いてSSM Session Manager経由で、インスタンスにアクセスする方法を確認します。
AWS CLIからアクセスします。
$ aws ssm start-session --target i-0a06995e9b6eada48
Starting session with SessionId: root-00836994a7865c011
sh-4.2$
Code language: Bash (bash)
targetオプションにアクセスするインスタンスIDを指定します。
sh-4.2$ ec2-metadata -i
instance-id: i-0a06995e9b6eada48
Code language: Bash (bash)
このようにアクセス後は、自由にコマンドを実行することができます。
試しに各VPCエンドポイントのDNS名を名前解決してみます。
sh-4.2$ nslookup ec2messages.ap-northeast-1.amazonaws.com
Server: 10.0.0.2
Address: 10.0.0.2#53
Non-authoritative answer:
Name: ec2messages.ap-northeast-1.amazonaws.com
Address: 10.0.2.208
sh-4.2$ nslookup ssmmessages.ap-northeast-1.amazonaws.com
Server: 10.0.0.2
Address: 10.0.0.2#53
Non-authoritative answer:
Name: ssmmessages.ap-northeast-1.amazonaws.com
Address: 10.0.2.147
sh-4.2$ nslookup ssm.ap-northeast-1.amazonaws.com
Server: 10.0.0.2
Address: 10.0.0.2#53
Non-authoritative answer:
Name: ssm.ap-northeast-1.amazonaws.com
Address: 10.0.2.141
Code language: Bash (bash)
Management Consoleで確認した通り、プライベートサブネット内のアドレスが返ってきました。こうしてSSM通信用トラフィックは、同サブネット内の各VPCエンドポイントのENIにスイッチングされます。
まとめ
Linuxインスタンスにアクセスする方法を2パターン確認しました。
1つ目はキーペアを指定して、SSHでインスタンスにアクセスできることを確認しました。
2つ目はSSM Session Managerを経由して、インスタンスにアクセスできることを確認しました。