こんにちは。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サポートへ問い合わせする前にご自身で疎通テストを実施し到達不能箇所を特定した上で調査していただければ幸いです。
本記事が皆様のお役にたてば幸いです。
ではサウナラ~?




