こんにちは、SCSKの内ヶ島です。
オンプレミス環境から手軽にAWS Site-to-Site VPN接続の検証環境を構築する方法を紹介します。
この記事では、CloudFormationを使った環境を一括管理し、Amazon Linux 2023のリポジトリに含まれるLibreswanを用いてVPN接続を行います。
はじめに
AWS Site-to-Site VPN接続は、オンプレミス環境とAWS環境を安全に接続するための重要な技術です。
しかし、VPN接続の検証には通常、実機のVPN機器が必要となりハードルが高いものでした。
そこで今回の検証では、以下の2点を主な目標として設定しました。
- ソフトウェアVPNを用いてVPN接続が正常に機能すること
- 環境全体をCloudFormationで管理し、簡単に作成・削除できること
実機のVPN機器がなくても、AWSの環境内で完結した形でVPN接続の検証が可能になります。
また、CloudFormationを活用することで、環境の再現性と管理の容易さを実現しています。
環境構成
今回構築する環境は以下の通りです。
- オンプレミス側(AWS上に疑似環境として構築)
– VPC (10.0.0.0/22)
– プライベートサブネット (10.0.0.0/24)
– パブリックサブネット (10.0.1.0/24)
– EC2インスタンス x2(VPN装置、クライアント想定) - AWS側
– VPC (192.168.0.0/22)
– プライベートサブネット (192.168.0.0/24)
– EC2インスタンス(AWSサーバー想定)
– カスタマーゲートウェイ、仮想プライベートゲートウェイ
CloudFormationテンプレート
今回の検証環境構築には、オンプレミス環境用とAWS環境用の2つのCloudFormationテンプレートを使用しています。
CloudFormationテンプレートの特徴
複雑なVPN検証環境を簡単に、そして再現性高く構築することができます。
両環境とも、インターネットに直接接続せずにパッケージ管理やシステム更新が可能な、セキュアな設計となっています。
以下の内容を生成AIを使ってCloudFormationテンプレートを作成しました。
長いテンプレートの記述ミスや整合性をある程度チェックできるので便利です。
共通の特徴
- VPC構成: 両テンプレートともVPCとサブネットを設定
- EC2インスタンス: Amazon Linux 2023のEC2インスタンスを作成
- セキュリティグループ: 必要最小限のトラフィックのみを許可するセキュリティグループを設定
- IAMロールとVPCエンドポイント: Systems Manager Session Managerを使用してEC2インスタンスに接続できるよう、必要なIAMロールとVPCエンドポイント(SSM、EC2メッセージ、SSMメッセージ)を設定
- S3 VPCエンドポイント: EC2インスタンスがインターネットを経由せずにS3にアクセスできるよう、S3用のVPCゲートウェイエンドポイントを設定。これにより、dnfやyumを使用したパッケージのインストールが可能となる。
- タグ付け: すべてのリソースにタグを付け、管理を容易にしている。タグのプレフィックスはパラメータとして指定可能
オンプレミス環境用テンプレート(Onpre_resource.yaml)の固有の特徴
- サブネット構成: パブリックサブネットとプライベートサブネットの両方を作成
- EC2インスタンス(パブリックサブネット): VPN装置役のEC2インスタンス(Elastic IP付与)。ネットワークの送信元/送信先チェックをオフ
- EC2インスタンス(プライベートサブネット): クライアント役のEC2インスタンス
- ルーティング: プライベートサブネットからのトラフィックをパブリックEC2インスタンス(疑似NATゲートウェイ)経由でルーティング
- インターネットゲートウェイ: パブリックサブネット用にインターネットゲートウェイを設定
AWS環境用テンプレート(AWS_resource.yaml)の固有の特徴
- サブネット構成: プライベートサブネットのみを作成します。
- VPNリソース: カスタマーゲートウェイ、仮想プライベートゲートウェイ、VPN接続、VPN接続ルートを作成
- パラメータ: カスタマーゲートウェイのIPアドレスをパラメータとして受け取る
- EC2インスタンス: プライベートサブネット内に1つのEC2インスタンスを作成(VPN経由でアクセスされるサーバー役)
CloudFormationテンプレート
オンプレミス環境用テンプレート(Onpre_resource.yaml)
AWSTemplateFormatVersion: '2010-09-09'
Description: 'VPC with Public and Private Subnets, EC2 Instances, SSM access, and S3 Endpoint'
Parameters:
TagPrefix:
Type: String
Default: '00000'
Description: 'Prefix for resource tags'
AmazonLinux2023AMI:
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
Default: /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-x86_64
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/22
EnableDnsHostnames: true
EnableDnsSupport: true
Tags:
- Key: Name
Value: !Sub '${TagPrefix}-VPC'
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Sub '${TagPrefix}-IGW'
InternetGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
InternetGatewayId: !Ref InternetGateway
VpcId: !Ref VPC
PublicSubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: !Select [0, !GetAZs '']
CidrBlock: 10.0.1.0/24
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub '${TagPrefix}-Public-Subnet'
PrivateSubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: !Select [1, !GetAZs '']
CidrBlock: 10.0.0.0/24
MapPublicIpOnLaunch: false
Tags:
- Key: Name
Value: !Sub '${TagPrefix}-Private-Subnet'
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub '${TagPrefix}-Public-RT'
PrivateRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub '${TagPrefix}-Private-RT'
PublicRoute:
Type: AWS::EC2::Route
DependsOn: InternetGatewayAttachment
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
PrivateRoute:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTable
DestinationCidrBlock: 0.0.0.0/0
InstanceId: !Ref PublicEC2Instance
PublicSubnetRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet
RouteTableId: !Ref PublicRouteTable
PrivateSubnetRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnet
RouteTableId: !Ref PrivateRouteTable
PublicSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub '${TagPrefix}-Public-SG'
GroupDescription: 'Security group for public EC2 instance'
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: -1
FromPort: -1
ToPort: -1
CidrIp: 10.0.0.0/22
SecurityGroupEgress:
- IpProtocol: -1
FromPort: -1
ToPort: -1
CidrIp: 0.0.0.0/0
Tags:
- Key: Name
Value: !Sub '${TagPrefix}-Public-SG'
PrivateSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub '${TagPrefix}-Private-SG'
GroupDescription: 'Security group for private EC2 instance'
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: -1
FromPort: -1
ToPort: -1
SourceSecurityGroupId: !Ref PublicSecurityGroup
SecurityGroupEgress:
- IpProtocol: -1
FromPort: -1
ToPort: -1
CidrIp: 0.0.0.0/0
Tags:
- Key: Name
Value: !Sub '${TagPrefix}-Private-SG'
EndpointSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub '${TagPrefix}-Endpoint-SG'
GroupDescription: 'Security group for VPC Endpoints'
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 443
ToPort: 443
SourceSecurityGroupId: !Ref PrivateSecurityGroup
- IpProtocol: tcp
FromPort: 443
ToPort: 443
SourceSecurityGroupId: !Ref PublicSecurityGroup
Tags:
- Key: Name
Value: !Sub '${TagPrefix}-Endpoint-SG'
PublicEC2Instance:
Type: AWS::EC2::Instance
Properties:
InstanceType: t3.micro
ImageId: !Ref AmazonLinux2023AMI
SubnetId: !Ref PublicSubnet
SecurityGroupIds:
- !Ref PublicSecurityGroup
IamInstanceProfile: !Ref EC2InstanceProfile
SourceDestCheck: false
Tags:
- Key: Name
Value: !Sub '${TagPrefix}-Onpre-Public-EC2'
PrivateEC2Instance:
Type: AWS::EC2::Instance
Properties:
InstanceType: t3.micro
ImageId: !Ref AmazonLinux2023AMI
SubnetId: !Ref PrivateSubnet
SecurityGroupIds:
- !Ref PrivateSecurityGroup
IamInstanceProfile: !Ref EC2InstanceProfile
Tags:
- Key: Name
Value: !Sub '${TagPrefix}-Onpre-Private-EC2'
PublicEIP:
Type: AWS::EC2::EIP
Properties:
Domain: vpc
InstanceId: !Ref PublicEC2Instance
Tags:
- Key: Name
Value: !Sub '${TagPrefix}-Public-EIP'
EC2InstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Path: "/"
Roles:
- !Ref EC2SSMRole
S3Endpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcId: !Ref VPC
ServiceName: !Sub 'com.amazonaws.${AWS::Region}.s3'
VpcEndpointType: Gateway
RouteTableIds:
- !Ref PrivateRouteTable
EC2SSMRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
- arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
Tags:
- Key: Name
Value: !Sub '${TagPrefix}-EC2-SSM-Role'
SSMEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
ServiceName: !Sub 'com.amazonaws.${AWS::Region}.ssm'
VpcId: !Ref VPC
VpcEndpointType: Interface
PrivateDnsEnabled: true
SubnetIds:
- !Ref PrivateSubnet
- !Ref PublicSubnet
SecurityGroupIds:
- !Ref EndpointSecurityGroup
SSMMessagesEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
ServiceName: !Sub 'com.amazonaws.${AWS::Region}.ssmmessages'
VpcId: !Ref VPC
VpcEndpointType: Interface
PrivateDnsEnabled: true
SubnetIds:
- !Ref PrivateSubnet
- !Ref PublicSubnet
SecurityGroupIds:
- !Ref EndpointSecurityGroup
Outputs:
PublicEC2InstanceId:
Description: 'Public EC2 Instance ID'
Value: !Ref PublicEC2Instance
PrivateEC2InstanceId:
Description: 'Private EC2 Instance ID'
Value: !Ref PrivateEC2Instance
PublicEIP:
Description: 'Elastic IP for Public EC2 Instance'
Value: !Ref PublicEIP
AWS環境用テンプレート(AWS_resource.yaml)
AWSTemplateFormatVersion: '2010-09-09'
Description: 'VPC with Private Subnet, EC2 Instance, Site-to-Site VPN, and S3 Endpoint'
Parameters:
TagPrefix:
Type: String
Default: '00000'
Description: 'Prefix for resource tags'
CustomerGatewayIp:
Type: String
Description: 'Public IP address of your Customer Gateway'
AmazonLinux2023AMI:
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
Default: '/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-x86_64'
Description: 'Amazon Linux 2023 AMI ID'
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 192.168.0.0/22
EnableDnsHostnames: true
EnableDnsSupport: true
Tags:
- Key: Name
Value: !Sub '${TagPrefix}-VPC'
PrivateSubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: !Select [0, !GetAZs '']
CidrBlock: 192.168.0.0/24
MapPublicIpOnLaunch: false
Tags:
- Key: Name
Value: !Sub '${TagPrefix}-Private-Subnet'
PrivateRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub '${TagPrefix}-Private-RT'
PrivateSubnetRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnet
RouteTableId: !Ref PrivateRouteTable
VPNSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub '${TagPrefix}-VPN-SG'
GroupDescription: 'Security group for VPN connection and SSM'
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: -1
FromPort: -1
ToPort: -1
CidrIp: 10.0.0.0/22
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 192.168.0.0/22
Tags:
- Key: Name
Value: !Sub '${TagPrefix}-VPN-SG'
EC2Instance:
Type: AWS::EC2::Instance
Properties:
InstanceType: t3.micro
ImageId: !Ref AmazonLinux2023AMI
SubnetId: !Ref PrivateSubnet
SecurityGroupIds:
- !Ref VPNSecurityGroup
IamInstanceProfile: !Ref EC2InstanceProfile
Tags:
- Key: Name
Value: !Sub '${TagPrefix}-AWS-Private-EC2'
EC2InstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Path: "/"
Roles:
- !Ref EC2SSMRole
S3Endpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcId: !Ref VPC
ServiceName: !Sub 'com.amazonaws.${AWS::Region}.s3'
VpcEndpointType: Gateway
RouteTableIds:
- !Ref PrivateRouteTable
EC2SSMRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
- arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
Tags:
- Key: Name
Value: !Sub '${TagPrefix}-EC2-SSM-Role'
CustomerGateway:
Type: AWS::EC2::CustomerGateway
Properties:
Type: ipsec.1
BgpAsn: 65000
IpAddress: !Ref CustomerGatewayIp
Tags:
- Key: Name
Value: !Sub '${TagPrefix}-CustomerGateway'
VirtualPrivateGateway:
Type: AWS::EC2::VPNGateway
Properties:
Type: ipsec.1
Tags:
- Key: Name
Value: !Sub '${TagPrefix}-VPNGateway'
VPNGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref VPC
VpnGatewayId: !Ref VirtualPrivateGateway
VPNConnection:
Type: AWS::EC2::VPNConnection
DependsOn:
- VirtualPrivateGateway
- VPNGatewayAttachment
Properties:
Type: ipsec.1
CustomerGatewayId: !Ref CustomerGateway
VpnGatewayId: !Ref VirtualPrivateGateway
StaticRoutesOnly: true
Tags:
- Key: Name
Value: !Sub '${TagPrefix}-VPNConnection'
VPNConnectionRoute:
Type: AWS::EC2::VPNConnectionRoute
DependsOn: VPNConnection
Properties:
DestinationCidrBlock: 10.0.0.0/22
VpnConnectionId: !Ref VPNConnection
VPNRoute:
Type: AWS::EC2::Route
DependsOn: VPNGatewayAttachment
Properties:
RouteTableId: !Ref PrivateRouteTable
DestinationCidrBlock: 10.0.0.0/22
GatewayId: !Ref VirtualPrivateGateway
SSMEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcId: !Ref VPC
ServiceName: !Sub 'com.amazonaws.${AWS::Region}.ssm'
VpcEndpointType: Interface
PrivateDnsEnabled: true
SubnetIds:
- !Ref PrivateSubnet
SecurityGroupIds:
- !Ref VPNSecurityGroup
EC2MessagesEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcId: !Ref VPC
ServiceName: !Sub 'com.amazonaws.${AWS::Region}.ec2messages'
VpcEndpointType: Interface
PrivateDnsEnabled: true
SubnetIds:
- !Ref PrivateSubnet
SecurityGroupIds:
- !Ref VPNSecurityGroup
SSMMessagesEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcId: !Ref VPC
ServiceName: !Sub 'com.amazonaws.${AWS::Region}.ssmmessages'
VpcEndpointType: Interface
PrivateDnsEnabled: true
SubnetIds:
- !Ref PrivateSubnet
SecurityGroupIds:
- !Ref VPNSecurityGroup
Outputs:
EC2InstanceId:
Description: 'EC2 Instance ID'
Value: !Ref EC2Instance
CustomerGatewayId:
Description: 'Customer Gateway ID'
Value: !Ref CustomerGateway
VirtualPrivateGatewayId:
Description: 'Virtual Private Gateway ID'
Value: !Ref VirtualPrivateGateway
VPNConnectionId:
Description: 'VPN Connection ID'
Value: !Ref VPNConnection
環境構築手順
なるべく少ない手数で再現性のある構築を進めるため、CloudShellでAWS CLIを用いて作業します。
AWSマネジメントコンソールの上部または左下の「>_」マークをクリックします。
立ち上がってきたCloudShell画面で「Open <リージョン名> environment」をクリックします。
Shellを打ち込める画面が出てきます。
# タグのプレフィックスを設定(任意の文字列を指定してください)
TAGPREFIX=00000
# オンプレ側構築
aws cloudformation deploy \
--stack-name "VPNtest-Onpre-${TAGPREFIX}" \
--template-file Onpre_resource.yaml \
--capabilities CAPABILITY_IAM \
--parameter-overrides TagPrefix=${TAGPREFIX}
# オンプレ側のVPN機器となるEC2インスタンスのGlobalIPを取得
GLOBALIP=`aws ec2 describe-addresses --query 'Addresses[].PublicIp' --filter "Name=tag:Name,Values=${TAGPREFIX}-Public-EIP" --output text` && echo ${GLOBALIP}
# AWS側構築
aws cloudformation deploy \
--stack-name "VPNtest-AWS-${TAGPREFIX}" \
--template-file AWS_resource.yaml \
--capabilities CAPABILITY_IAM \
--parameter-overrides TagPrefix=${TAGPREFIX} CustomerGatewayIp=${GLOBALIP}
VPN設定
AWS Site-to-Site VPNではオンプレ側VPN機器の設定サンプルをダウンロードできます。
オンプレ側ではソフトウェアVPNのLibreswanを使用しますが、該当するものがないので類似するOpenswanの設定サンプルをダウンロードします。
VPN設定ダウンロード
[VPC] – [Site-to-Site VPN 接続]
[設定をダウンロードする]
[ベンダー] Openswan
[プラットフォーム] Openswan
[ソフトウェア] Openswan 2.6.38+
[IKEバージョン] ikev1
を指定し、[ダウンロード]
ここでダウンロードした設定ファイルの一部を用いて、Libreswanの設定をしていきます。
Libreswan設定
LibreswanからAWS Site-to-Site VPNへの接続に利用するトンネルは1本のみとします。(2本用いるHA構成も可能だが「気軽な」検証にならないため)
AWS Systems Manager Session Managerを用いてオンプレ側Public EC2インスタンスにログインします。
[EC2] – [インスタンス] より、ログインしたいインスタンスにチェックを入れ、[接続] をクリックします。
[セッションマネージャー] タブを選択し、[接続] をクリックします。

# Libreswanインストール
sudo dnf install -y libreswan
# カーネルパラメータ修正
echo 'net.ipv4.ip_forward=1' | sudo tee -a /etc/sysctl.d/custom-ip-forwarding.conf
sudo sysctl -p /etc/sysctl.d/custom-ip-forwarding.conf
# Libreswan設定
sudo vi /etc/ipsec.conf
config setup ブロックに下記設定のみを追記します。
protostack=netkey
# ダウンロードしたVPN設定から接続部分を抜き出して貼り付け、内容を書き換える
# Tunnel1の部分のみ。
sudo vi /etc/ipsec.d/aws.conf
conn Tunnel1
authby=secret
auto=start
left=%defaultroute
leftid=<オンプレ側のGlobalIP> # 記載のものをそのまま入力
right=<AWS側のGlobalIP> # 記載のものをそのまま入力
type=tunnel
ikelifetime=8h
keylife=1h
phase2alg=aes128-sha1;modp2048 # 末尾のmodp1024をmodp2048に変更
ike=aes128-sha1;modp2048 # 末尾のmodp1024をmodp2048に変更
auth=esp # この行は削除
keyingtries=%forever
keyexchange=ike
leftsubnet=10.0.0.0/22 # leftがオンプレ側(今設定しているほう)
rightsubnet=192.168.0.0/22 # rightがAWS側
dpddelay=10
dpdtimeout=30 # この行は削除
retransmit-timeout=30s # この行を追加
dpdaction=restart_by_peer
# シークレット情報を張り付ける
# ※Tunnel1もののみをそのまま貼り付け、Tunnel2のキーは貼り付けない
sudo vi /etc/ipsec.d/aws.secrets
<オンプレ側のGlobalIP> <AWS側のGlobalIP>: PSK "<キー情報>"
sudo systemctl start ipsec
sudo systemctl status ipsec
exit
VPNトンネル接続確認
[VPC] – [Site-to-Site VPN]
作成したVPN接続を選択
[トンネルの詳細] タブを選択
1つのトンネルが接続されていることを確認します。(リロードしながら少し待つ必要があります)
もう一つはダウンのままで構いません。
接続確認
IPアドレスを確認
TAGPREFIX=00000
aws ec2 describe-instances \
--filters "Name=instance-state-name,Values=running" "Name=tag:Name,Values=*${TAGPREFIX}*" \
--query "Reservations[*].Instances[*].[PrivateIpAddress, Tags[?Key=='Name'].Value | [0]]" \
--output text
以下のようにIPアドレスが出力されます。このIPアドレスを用いて接続確認をしていきます。
10.0.0.148 00000-Onpre-Private-EC2 192.168.0.34 00000-AWS-Private-EC2 10.0.1.145 00000-Onpre-Public-EC2
通信確認
pingによる通信確認
AWS Systems Manager Session Managerを用いてオンプレ側プライベートEC2へログインします。
# AWS側プライベートEC2のIPに向けて通信確認 ping 192.168.0.34
→オンプレ側からAWS側へ通信できることを確認します。
同じく、AWS側プライベートEC2へログインします。
ping 10.0.0.148
→AWS側からオンプレ側へ通信できることを確認します。
HTTPによる通信確認
AWS側プライベートEC2で下記を実行します。
cd ~ touch iam_aws_private python3 -m http.server 8000
今度は、オンプレ側プライベートEC2で下記を実行します。
curl 192.168.0.34:8000
→ディレクトリの中身が見えることを確認します(VPN接続先のiam_aws_privateファイルが見える)
AWS側プライベートEC2で、オンプレ側からアクセスがあったログを確認できます。
オンプレ側の通信確認
AWS側の通信確認
トラブルシューティング
VPN接続で問題が発生した場合は、以下の点を確認してください
- セキュリティグループの設定
- ルートテーブルの設定
- Libreswanの設定ファイル
- VPNログ(sudo journalctl -u ipsec)
クリーンアップ
検証が終わったら、以下のコマンドで環境を削除します
# CloudFormationスタックを削除
aws cloudformation delete-stack --stack-name "VPNtest-Onpre-${TAGPREFIX}"
aws cloudformation delete-stack --stack-name "VPNtest-AWS-${TAGPREFIX}"
# スタック削除を待つ
aws cloudformation wait stack-delete-complete --stack-name "VPNtest-Onpre-${TAGPREFIX}" &
aws cloudformation wait stack-delete-complete --stack-name "VPNtest-AWS-${TAGPREFIX}" &
wait
# 2つのスタックが削除され、プロンプトが戻れば終了
CloudShellの終了は、CloudShell画面の [アクション] – [削除] を選択し、表示された確認画面で「delete」と入力し、[削除] ボタンを押します。
参考資料
ソフトウェア VPN から AWS Site-to-Site VPN
https://docs.aws.amazon.com/ja_jp/whitepapers/latest/aws-vpc-connectivity-options/software-vpn-to-aws-site-to-site-vpn.html
OS設定でNATインスタンスのチュートリアルを参考にしました(特にnet.ipv4.ip_forward=1の設定)
https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/work-with-nat-instances.html
SSMへの接続用VPCエンドポイントを作成の際、ec2messages:* エンドポイントは作成の必要がなくなりました。https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/systems-manager-setting-up-messageAPIs.html
SSM Agent のバージョン 3.3.40.0 以降、Systems Manager は、使用可能な場合には ec2messages:* エンドポイント (Amazon Message Delivery Service) の代わりに ssmmessages:* エンドポイント (Amazon Message Gateway Service) を使用するようになりました。
まとめ
今回の記事では、AWSでのSite-to-Site VPN接続の検証環境構築方法を紹介しました。CloudFormationを使うことで、複雑な環境も簡単に構築・管理できることがお分かりいただけたかと思います。
実際の本番環境では、セキュリティやパフォーマンスなどさらに考慮すべき点がありますが、この記事がVPN検証の参考になれば幸いです。










