こんにちは。SCSKのふくちーぬです。
皆さんは、AWS内の疎通テストをどのように実施していますでしょうか。pingコマンドやTest-NetConnectionコマンドを利用しているでしょうか。
今回は、VPC Reachability Analyzerを用いた疎通テストの手法をご紹介します。
VPC Reachability Analyzer
AWS内のリソース間の接続性を擬似的にテストし、どの経路地点で問題があるか分析する機能です。
Reachability Analyzerを利用することで、ルートテーブルやセキュリティグループのどこに設定不備があるか表示され、どこのネットワークに問題があるか容易に切り分けすることができます。到達不能箇所を特定することで、通信の到達性に関する問題の解決を手助けしてくれます。
気になる料金は、一律で1回の分析あたり0.10 USDとなります。
アーキテクチャ
- EC2・VPCエンドポイントは、プライベートサブネットに配置する
- EC2からVPCエンドポイントに向けて、Reachability Analyzerを用いてTCP:443の疎通を実施する
検証①
- EC2インスタンスから、各VPCエンドポイントの疎通テストを実施し到達不能箇所を特定する
CloudFormationテンプレート(ネットワークスタック)
下記のリソースを作成するCloudFormationテンプレートです。
- VPC
- プライベートサブネット
- ルートテーブル
- セキュリティグループ
- VPCエンドポイント
- EC2
- IAMロール
以下のテンプレートをデプロイしてください。
AWSTemplateFormatVersion: 2010-09-09 Description: cfn private EC2 Parameters: ResourceName: Type: String Resources: # ------------------------------------------------------------# # VPC # ------------------------------------------------------------# VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: !Sub "${ResourceName}-VPC" # ------------------------------------------------------------# # Subnet # ------------------------------------------------------------# PrivateSubnet1a: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: 10.0.2.0/24 AvailabilityZone: ap-northeast-1a MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Sub "${ResourceName}-PrivateSubnet-1a" PrivateSubnet1c: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: 10.0.3.0/24 AvailabilityZone: ap-northeast-1c MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Sub "${ResourceName}-PrivateSubnet-1c" # ------------------------------------------------------------# # RouteTable # ------------------------------------------------------------# PrivateRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: !Sub "${ResourceName}-PrivateRouteTable" PrivateSubnet1aAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PrivateSubnet1a RouteTableId: !Ref PrivateRouteTable PrivateSubnet1cAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PrivateSubnet1c RouteTableId: !Ref PrivateRouteTable # ------------------------------------------------------------# # EC2 # ------------------------------------------------------------# EC2: Type: AWS::EC2::Instance Properties: ImageId: ami-0b193da66bc27147b InstanceType: t2.micro NetworkInterfaces: - AssociatePublicIpAddress: "true" DeviceIndex: "0" SubnetId: !Ref PrivateSubnet1a GroupSet: - !Ref EC2SecurityGroup Tags: - Key: Name Value: !Sub "${ResourceName}-ec2" EC2SecurityGroup: Type: "AWS::EC2::SecurityGroup" Properties: VpcId: !Ref VPC SecurityGroupIngress: - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: 10.0.0.0/16 GroupName: !Sub "${ResourceName}-ec2-sg" GroupDescription: !Sub "${ResourceName}-ec2-sg" Tags: - Key: "Name" Value: !Sub "${ResourceName}-ec2-sg" # ------------------------------------------------------------# # IAM Role # ------------------------------------------------------------# EC2Role: Type: AWS::IAM::Role Properties: Path: / RoleName: !Sub "${ResourceName}-ec2-Role" AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - ec2.amazonaws.com Action: - sts:AssumeRole MaxSessionDuration: 3600 ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM InstanceProfile: Type: AWS::IAM::InstanceProfile Properties: Path: / Roles: - !Ref EC2Role # ------------------------------------------------------------# # VPCEndpoint # ------------------------------------------------------------# SSMEndpoint: Type: AWS::EC2::VPCEndpoint Properties: ServiceName: !Sub "com.amazonaws.${AWS::Region}.ssm" SubnetIds: - !Ref PrivateSubnet1a - !Ref PrivateSubnet1c VpcId: !Ref VPC VpcEndpointType: Interface SecurityGroupIds: - !Ref EndpointSecurityGroup PrivateDnsEnabled: true EC2MessageEndpoint: Type: AWS::EC2::VPCEndpoint Properties: ServiceName: !Sub "com.amazonaws.${AWS::Region}.ec2messages" SubnetIds: - !Ref PrivateSubnet1a - !Ref PrivateSubnet1c VpcId: !Ref VPC VpcEndpointType: Interface SecurityGroupIds: - !Ref EndpointSecurityGroup PrivateDnsEnabled: true ssmmessagesEndpoint: Type: AWS::EC2::VPCEndpoint Properties: ServiceName: !Sub "com.amazonaws.${AWS::Region}.ssmmessages" SubnetIds: - !Ref PrivateSubnet1a - !Ref PrivateSubnet1c VpcId: !Ref VPC VpcEndpointType: Interface SecurityGroupIds: - !Ref EndpointSecurityGroup PrivateDnsEnabled: true EndpointSecurityGroup: Type: "AWS::EC2::SecurityGroup" Properties: VpcId: !Ref VPC GroupName: !Sub "${ResourceName}-endpoint-sg" GroupDescription: !Sub "${ResourceName}-endpoint-sg" Tags: - Key: "Name" Value: !Sub "${ResourceName}-ec2-sg"
CloudFormationテンプレート(分析スタック)
下記のリソースを作成するCloudFormationテンプレートです。
- パスと分析
以下のテンプレートをデプロイしてください。
AWSTemplateFormatVersion: 2010-09-09 Description: Rechability Analyzer Test Parameters: ResourceName: Type: String InstanceId: Type: String VPCeIdForSSM: Type: String VPCeIdForSSMMesssages: Type: String VPCeIdForEC2Messsages: Type: String Resources: # ------------------------------------------------------------# # Rechability Analyzer Test01 # ------------------------------------------------------------# EC2NetworkInsightsPathForSSM01: Type: "AWS::EC2::NetworkInsightsPath" Properties: Destination: !Ref VPCeIdForSSM FilterAtSource: DestinationPortRange: ToPort: 443 FromPort: 443 Protocol: "tcp" Source: !Ref InstanceId Tags: - Key: Name Value: !Sub ${ResourceName}-test01-ssm EC2NetworkInsightsPathForSSMMessages01: Type: "AWS::EC2::NetworkInsightsPath" Properties: Destination: !Ref VPCeIdForSSMMesssages FilterAtSource: DestinationPortRange: ToPort: 443 FromPort: 443 Protocol: "tcp" Source: !Ref InstanceId Tags: - Key: Name Value: !Sub ${ResourceName}-test01-ssmmessages EC2NetworkInsightsPathForEC2Messages01: Type: "AWS::EC2::NetworkInsightsPath" Properties: Destination: !Ref VPCeIdForEC2Messsages FilterAtSource: DestinationPortRange: ToPort: 443 FromPort: 443 Protocol: "tcp" Source: !Ref InstanceId Tags: - Key: Name Value: !Sub ${ResourceName}-test01-ec2messages EC2NetworkInsightsAnalysisForSSM01: Type: AWS::EC2::NetworkInsightsAnalysis Properties: NetworkInsightsPathId: !Ref EC2NetworkInsightsPathForSSM01 EC2NetworkInsightsAnalysisForSSMMessages: Type: AWS::EC2::NetworkInsightsAnalysis Properties: NetworkInsightsPathId: !Ref EC2NetworkInsightsPathForSSMMessages01 EC2NetworkInsightsAnalysisForEC2Message: Type: AWS::EC2::NetworkInsightsAnalysis Properties: NetworkInsightsPathId: !Ref EC2NetworkInsightsPathForEC2Messages01
分析結果の確認
以下のように、VPCエンドポイントにアタッチしているセキュリティグループに適切なインバウンドルールがないことが判明しました。
検証②
- 各VPCエンドポイントのセキュリティグループのインバウンドルール(インバウンドルールに、HTTPS:443を許可する)を修正する
- 再度疎通テストを実施し到達可能を確認する
CloudFormationテンプレート(ネットワークスタック)
VPCエンドポイントにアタッチ済みのセキュリティグループを修正を行います。
以下のテンプレートをデプロイして、スタックの更新をします。
AWSTemplateFormatVersion: 2010-09-09 Description: cfn private EC2 Parameters: ResourceName: Type: String Resources: # ------------------------------------------------------------# # VPC # ------------------------------------------------------------# VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: !Sub "${ResourceName}-VPC" # ------------------------------------------------------------# # Subnet # ------------------------------------------------------------# PrivateSubnet1a: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: 10.0.2.0/24 AvailabilityZone: ap-northeast-1a MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Sub "${ResourceName}-PrivateSubnet-1a" PrivateSubnet1c: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: 10.0.3.0/24 AvailabilityZone: ap-northeast-1c MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Sub "${ResourceName}-PrivateSubnet-1c" # ------------------------------------------------------------# # RouteTable # ------------------------------------------------------------# PrivateRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: !Sub "${ResourceName}-PrivateRouteTable" PrivateSubnet1aAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PrivateSubnet1a RouteTableId: !Ref PrivateRouteTable PrivateSubnet1cAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PrivateSubnet1c RouteTableId: !Ref PrivateRouteTable # ------------------------------------------------------------# # EC2 # ------------------------------------------------------------# EC2: Type: AWS::EC2::Instance Properties: ImageId: ami-0b193da66bc27147b InstanceType: t2.micro NetworkInterfaces: - AssociatePublicIpAddress: "true" DeviceIndex: "0" SubnetId: !Ref PrivateSubnet1a GroupSet: - !Ref EC2SecurityGroup Tags: - Key: Name Value: !Sub "${ResourceName}-ec2" EC2SecurityGroup: Type: "AWS::EC2::SecurityGroup" Properties: VpcId: !Ref VPC SecurityGroupIngress: - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: 10.0.0.0/16 GroupName: !Sub "${ResourceName}-ec2-sg" GroupDescription: !Sub "${ResourceName}-ec2-sg" Tags: - Key: "Name" Value: !Sub "${ResourceName}-ec2-sg" # ------------------------------------------------------------# # IAM Role # ------------------------------------------------------------# EC2Role: Type: AWS::IAM::Role Properties: Path: / RoleName: !Sub "${ResourceName}-ec2-Role" AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - ec2.amazonaws.com Action: - sts:AssumeRole MaxSessionDuration: 3600 ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM InstanceProfile: Type: AWS::IAM::InstanceProfile Properties: Path: / Roles: - !Ref EC2Role # ------------------------------------------------------------# # VPCEndpoint # ------------------------------------------------------------# SSMEndpoint: Type: AWS::EC2::VPCEndpoint Properties: ServiceName: !Sub "com.amazonaws.${AWS::Region}.ssm" SubnetIds: - !Ref PrivateSubnet1a - !Ref PrivateSubnet1c VpcId: !Ref VPC VpcEndpointType: Interface SecurityGroupIds: - !Ref EndpointSecurityGroup PrivateDnsEnabled: true EC2MessageEndpoint: Type: AWS::EC2::VPCEndpoint Properties: ServiceName: !Sub "com.amazonaws.${AWS::Region}.ec2messages" SubnetIds: - !Ref PrivateSubnet1a - !Ref PrivateSubnet1c VpcId: !Ref VPC VpcEndpointType: Interface SecurityGroupIds: - !Ref EndpointSecurityGroup PrivateDnsEnabled: true ssmmessagesEndpoint: Type: AWS::EC2::VPCEndpoint Properties: ServiceName: !Sub "com.amazonaws.${AWS::Region}.ssmmessages" SubnetIds: - !Ref PrivateSubnet1a - !Ref PrivateSubnet1c VpcId: !Ref VPC VpcEndpointType: Interface SecurityGroupIds: - !Ref EndpointSecurityGroup PrivateDnsEnabled: true EndpointSecurityGroup: Type: "AWS::EC2::SecurityGroup" Properties: VpcId: !Ref VPC SecurityGroupIngress: - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: 10.0.0.0/16 GroupName: !Sub "${ResourceName}-endpoint-sg" GroupDescription: !Sub "${ResourceName}-endpoint-sg" Tags: - Key: "Name" Value: !Sub "${ResourceName}-ec2-sg"
CloudFormationテンプレート(分析スタック)
再度パスの分析を実行します。
以下のテンプレートをデプロイして、スタックの更新をします。
AWSTemplateFormatVersion: 2010-09-09 Description: Rechability Analyzer Test Parameters: ResourceName: Type: String InstanceId: Type: String VPCeIdForSSM: Type: String VPCeIdForSSMMesssages: Type: String VPCeIdForEC2Messsages: Type: String Resources: # ------------------------------------------------------------# # Rechability Analyzer Test01 # ------------------------------------------------------------# EC2NetworkInsightsPathForSSM01: Type: "AWS::EC2::NetworkInsightsPath" Properties: Destination: !Ref VPCeIdForSSM FilterAtSource: DestinationPortRange: ToPort: 443 FromPort: 443 Protocol: "tcp" Source: !Ref InstanceId Tags: - Key: Name Value: !Sub ${ResourceName}-test01-ssm EC2NetworkInsightsPathForSSMMessages01: Type: "AWS::EC2::NetworkInsightsPath" Properties: Destination: !Ref VPCeIdForSSMMesssages FilterAtSource: DestinationPortRange: ToPort: 443 FromPort: 443 Protocol: "tcp" Source: !Ref InstanceId Tags: - Key: Name Value: !Sub ${ResourceName}-test01-ssmmessages EC2NetworkInsightsPathForEC2Messages01: Type: "AWS::EC2::NetworkInsightsPath" Properties: Destination: !Ref VPCeIdForEC2Messsages FilterAtSource: DestinationPortRange: ToPort: 443 FromPort: 443 Protocol: "tcp" Source: !Ref InstanceId Tags: - Key: Name Value: !Sub ${ResourceName}-test01-ec2messages EC2NetworkInsightsAnalysisForSSM01: Type: AWS::EC2::NetworkInsightsAnalysis Properties: NetworkInsightsPathId: !Ref EC2NetworkInsightsPathForSSM01 EC2NetworkInsightsAnalysisForSSMMessages01: Type: AWS::EC2::NetworkInsightsAnalysis Properties: NetworkInsightsPathId: !Ref EC2NetworkInsightsPathForSSMMessages01 EC2NetworkInsightsAnalysisForEC2Message01: Type: AWS::EC2::NetworkInsightsAnalysis Properties: NetworkInsightsPathId: !Ref EC2NetworkInsightsPathForEC2Messages01 # ------------------------------------------------------------# # Rechability Analyzer Test02 # ------------------------------------------------------------# EC2NetworkInsightsPathForSSM02: Type: "AWS::EC2::NetworkInsightsPath" Properties: Destination: !Ref VPCeIdForSSM FilterAtSource: DestinationPortRange: ToPort: 443 FromPort: 443 Protocol: "tcp" Source: !Ref InstanceId Tags: - Key: Name Value: !Sub ${ResourceName}-test02-ssm EC2NetworkInsightsPathForSSMMessages02: Type: "AWS::EC2::NetworkInsightsPath" Properties: Destination: !Ref VPCeIdForSSMMesssages FilterAtSource: DestinationPortRange: ToPort: 443 FromPort: 443 Protocol: "tcp" Source: !Ref InstanceId Tags: - Key: Name Value: !Sub ${ResourceName}-test02-ssmmessages EC2NetworkInsightsPathForEC2Messages02: Type: "AWS::EC2::NetworkInsightsPath" Properties: Destination: !Ref VPCeIdForEC2Messsages FilterAtSource: DestinationPortRange: ToPort: 443 FromPort: 443 Protocol: "tcp" Source: !Ref InstanceId Tags: - Key: Name Value: !Sub ${ResourceName}-test02-ec2messages EC2NetworkInsightsAnalysisForSSM02: Type: AWS::EC2::NetworkInsightsAnalysis Properties: NetworkInsightsPathId: !Ref EC2NetworkInsightsPathForSSM02 EC2NetworkInsightsAnalysisForSSMMessages02: Type: AWS::EC2::NetworkInsightsAnalysis Properties: NetworkInsightsPathId: !Ref EC2NetworkInsightsPathForSSMMessages02 EC2NetworkInsightsAnalysisForEC2Message02: Type: AWS::EC2::NetworkInsightsAnalysis Properties: NetworkInsightsPathId: !Ref EC2NetworkInsightsPathForEC2Messages02
分析結果の確認
VPCエンドポイントへの擬似的な疎通テストが成功していることを確認しました。
この後の作業としては、実際に各エンドポイントのAPIを叩くことにより適切なレスポンスが返却されるかテストしていただく流れになるかと思います。その際に、例えばアクセスエラーが出ればIAMロールの権限不足である可能性が濃厚となります。
最後に
いかがだったでしょうか。
VPC Reachability Analyzerを用いて、容易に疎通テストを実行することができました。
検証作業等でネットワーク疎通不可事象が発生することが多いかと思います。その際には、AWSサポートへ問い合わせする前にご自身で疎通テストを実施し到達不能箇所を特定した上で調査していただければ幸いです。
本記事が皆様のお役にたてば幸いです。
ではサウナラ~🔥