AWS

LinuxインスタンスにSSM Session Manager経由でアクセスする

スポンサーリンク
LinuxインスタンスにSSM Session Manager経由でアクセスする AWS
スポンサーリンク
スポンサーリンク

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パターン確認します。

  1. SSHでアクセス ※ ①パターン
  2. SSM Session Manager経由でアクセス ※ ②パターン

なお本ページはLinuxインスタンスを対象とした内容です。WindowsインスタンスにSession Manager経由でアクセスする方法については、以下のページをご確認ください。

構築する環境

Amazon.co.jp: AWS認定資格試験テキスト AWS認定ソリューションアーキテクト - アソシエイト 改訂第2版 : NRIネットコム株式会社, 佐々木 拓郎, 林 晋一郎, 金澤 圭: 本
Amazon.co.jp: AWS認定資格試験テキスト AWS認定ソリューションアーキテクト - アソシエイト 改訂第2版 : NRIネットコム株式会社, 佐々木 拓郎, 林 晋一郎, 金澤 圭: 本
Diagram of accessing instance via SSM Session Manager

EC2インスタンスへのアクセス方法を、以下の2パターン確認します。

  1. インターネットゲートウェイ経由でSSHしてアクセスする方法 ※パターン1
  2. SSM用VPCエンドポイント経由でSSM Session Managerを使ってアクセスする方法 ※パターン2

環境構築用のCloudFormationテンプレートファイル

上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。

https://github.com/awstut-an-r/awstut-fa/tree/main/003

テンプレートファイルのポイント解説

今回の環境を構成するための、各テンプレートファイルのポイントを取り上げます。

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
・com.amazonaws.[region].ec2messages
・com.amazonaws.[region].ssmmessages

Systems Manager を使用してインターネットアクセスなしでプライベート EC2 インスタンスを管理できるように、VPC エンドポイントを作成するにはどうすればよいですか?

今回は、組み込み関数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でもリソースの作成状況を確認します。
まずパブリックサブネット用のルーティングテーブルを確認します。

The route table of a public subnet has a default route for Internet Gateway.

インターネットゲートウェイ向けのデフォルトルートが定義されています。このデフォルトルートによって、インターネット越しのSSH通信が可能となります。

次にプライベートサブネット用のルーティングテーブルを確認します。

The route table for private subnets does not have any special routes.

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

ではSSM用VPCエンドポイントの作成状況を確認します。

The ENI of the VPC endpoint for ec2messages is set to an address in a private subnet.
The ENI of the VPC endpoint for ssm is set to an address in a private subnet.
The ENI of the VPC endpoint for ssmmessages is set to an address in a private subnet.

いずれもプライベートサブネット(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を経由して、インスタンスにアクセスできることを確認しました。

タイトルとURLをコピーしました