こんにちは、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検証の参考になれば幸いです。