VyOSを利用したVPN環境構築(静的ルーティング編)
みなさん、こんにちは!
AWS事業本部の青柳@福岡オフィスです。
静的ルーティングによる サイト間VPN接続 を検証する必要があったため、オープンソースのソフトウェアルーターである VyOS を使ってVPN環境を構築しました。
なお、VyOSを利用した動的ルーティング (BGP) によるVPN接続については、下記のブログエントリで紹介されています。
VyOS1.2を利用したVPN環境構築 | Developers.IO
VyOSを利用したVPN環境構築 | Developers.IO
構成
下図のような構成を構築します。
東京リージョンをAWS側、シンガポールリージョンをオンプレミス側にそれぞれ見立ててサイト間VPN接続を構築します。
東京リージョンには 仮想プライベートゲートウェイ (VGW) を配置します。
シンガポールリージョンには カスタマーゲートウェイデバイス (オンプレミス側ルーター) としてVyOSがインストールされたEC2インスタンスを配置します。
各リージョンのプライベートサブネットに、動作検証用のEC2インスタンス (Linux+nginx) を配置します。
構築手順
1. ベース環境の作成
VPN環境の構築を始める前に、まず、ベースとなるネットワーク環境 (VPC、サブネットなど) と動作確認用EC2インスタンスを作成します。
今回はCloudFormationで作成しました。
ベース環境作成CloudFormationテンプレート (クリックすると展開します)
--- AWSTemplateFormatVersion: "2010-09-09" Description: "VPN TEST: Base environment (VPC and EC2)" Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: "General Information" Parameters: - SystemName - Environment - Label: default: "Network Configuration" Parameters: - CidrBlockVPC - CidrBlockSubnetPublic1 - CidrBlockSubnetPrivate1 - CidrBlockRemoteNetwork - Label: default: "EC2 Instance Configuration" Parameters: - EC2ImageID - EC2InstanceType - EC2KeyName - EC2VolumeType - EC2VolumeSize Parameters: SystemName: Type: String AllowedValues: - tokyo - singapore Environment: Type: String Default: dev AllowedValues: - dev - str - prd CidrBlockVPC: Type: String AllowedValues: - 10.0.0.0/16 - 192.168.0.0/16 CidrBlockSubnetPublic1: Type: String AllowedValues: - 10.0.0.0/24 - 192.168.0.0/24 CidrBlockSubnetPrivate1: Type: String AllowedValues: - 10.0.128.0/24 - 192.168.128.0/24 CidrBlockRemoteNetwork: Type: String AllowedValues: - 192.168.128.0/24 - 10.0.128.0/24 EC2ImageID: Type: AWS::SSM::Parameter::Value<String> Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 EC2InstanceType: Type: String Default: t3.micro EC2KeyName: Type: AWS::EC2::KeyPair::KeyName EC2VolumeType: Type: String Default: gp2 EC2VolumeSize: Type: String Default: 8 Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref CidrBlockVPC EnableDnsSupport: true EnableDnsHostnames: true InstanceTenancy: default Tags: - Key: Name Value: !Sub "${SystemName}-${Environment}-vpc" - Key: System Value: !Ref SystemName - Key: Environment Value: !Ref Environment InternetGateway: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: !Sub "${SystemName}-${Environment}-igw" - Key: System Value: !Ref SystemName - Key: Environment Value: !Ref Environment VPCGatewayAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: InternetGatewayId: !Ref InternetGateway VpcId: !Ref VPC SubnetPublic1: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC AvailabilityZone: !Select - 0 - Fn::GetAZs: !Ref AWS::Region CidrBlock: !Ref CidrBlockSubnetPublic1 MapPublicIpOnLaunch: true Tags: - Key: Name Value: !Sub "${SystemName}-${Environment}-public1-subnet" - Key: System Value: !Ref SystemName - Key: Environment Value: !Ref Environment SubnetPrivate1: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC AvailabilityZone: !Select - 0 - Fn::GetAZs: !Ref AWS::Region CidrBlock: !Ref CidrBlockSubnetPrivate1 Tags: - Key: Name Value: !Sub "${SystemName}-${Environment}-private1-subnet" - Key: System Value: !Ref SystemName - Key: Environment Value: !Ref Environment EIPNatGateway: DependsOn: - VPCGatewayAttachment Type: AWS::EC2::EIP Properties: Domain: vpc NatGateway: DependsOn: - EIPNatGateway - SubnetPublic1 Type: AWS::EC2::NatGateway Properties: AllocationId: !GetAtt EIPNatGateway.AllocationId SubnetId: !Ref SubnetPublic1 Tags: - Key: Name Value: !Sub "${SystemName}-${Environment}-natgateway" - Key: System Value: !Ref SystemName - Key: Environment Value: !Ref Environment RouteTablePublic: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: !Sub "${SystemName}-${Environment}-public-rtb" - Key: System Value: !Ref SystemName - Key: Environment Value: !Ref Environment RouteTablePrivate: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: !Sub "${SystemName}-${Environment}-private-rtb" - Key: System Value: !Ref SystemName - Key: Environment Value: !Ref Environment RouteIGW: DependsOn: - VPCGatewayAttachment Type: AWS::EC2::Route Properties: RouteTableId: !Ref RouteTablePublic DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway RouteNatGateway: DependsOn: - NatGateway Type: AWS::EC2::Route Properties: RouteTableId: !Ref RouteTablePrivate DestinationCidrBlock: 0.0.0.0/0 NatGatewayId: !Ref NatGateway RouteTableAssociationPublic1: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref SubnetPublic1 RouteTableId: !Ref RouteTablePublic RouteTableAssociationPrivate1: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref SubnetPrivate1 RouteTableId: !Ref RouteTablePrivate IAMRoleSSM: Type: AWS::IAM::Role Properties: RoleName: !Sub "${SystemName}-${Environment}-ssm-role" AssumeRolePolicyDocument: | { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } ManagedPolicyArns: - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore Path: / IAMInstanceProfileSSM: Type: AWS::IAM::InstanceProfile Properties: InstanceProfileName: !Sub "${SystemName}-${Environment}-ssm-role" Roles: - !Ref IAMRoleSSM Path: / SecurityGroupServer: Type: AWS::EC2::SecurityGroup Properties: GroupName: !Sub "${SystemName}-${Environment}-server-sg" GroupDescription: "Security group for servers" VpcId: !Ref VPC SecurityGroupIngress: - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: !Ref CidrBlockRemoteNetwork Description: "HTTP access from remote network" - IpProtocol: icmp FromPort: -1 ToPort: -1 CidrIp: !Ref CidrBlockRemoteNetwork Description: "ICMP access from remote network" Tags: - Key: Name Value: !Sub "${SystemName}-${Environment}-server-sg" - Key: System Value: !Ref SystemName - Key: Environment Value: !Ref Environment EC2Instance: Type: AWS::EC2::Instance Properties: ImageId: !Ref EC2ImageID InstanceType: !Ref EC2InstanceType KeyName: !Ref EC2KeyName BlockDeviceMappings: - DeviceName: /dev/xvda Ebs: VolumeType: !Ref EC2VolumeType VolumeSize: !Ref EC2VolumeSize NetworkInterfaces: - DeviceIndex: 0 SubnetId: !Ref SubnetPrivate1 GroupSet: - !Ref SecurityGroupServer IamInstanceProfile: !Ref IAMInstanceProfileSSM UserData: Fn::Base64: !Sub | #!/bin/bash -xe amazon-linux-extras install -y nginx1 systemctl enable nginx systemctl start nginx SYSTEM_NAME=${SystemName} echo Hello! I\'m ${!SYSTEM_NAME^^} Web Server! > /usr/share/nginx/html/index.html Tags: - Key: Name Value: !Sub "${SystemName}-${Environment}-server" - Key: System Value: !Ref SystemName - Key: Environment Value: !Ref Environment Outputs: VPC: Value: !Ref VPC Export: Name: !Sub "${AWS::StackName}::VPC" SubnetPublic1: Value: !Ref SubnetPublic1 Export: Name: !Sub "${AWS::StackName}::SubnetPublic1" SubnetPrivate1: Value: !Ref SubnetPrivate1 Export: Name: !Sub "${AWS::StackName}::SubnetPrivate1" RouteTablePublic: Value: !Ref RouteTablePublic Export: Name: !Sub "${AWS::StackName}::RouteTablePublic" RouteTablePrivate: Value: !Ref RouteTablePrivate Export: Name: !Sub "${AWS::StackName}::RouteTablePrivate" IAMRoleSSM: Value: !Ref IAMRoleSSM Export: Name: !Sub "${AWS::StackName}::IAMRoleSSM" IAMInstanceProfileSSM: Value: !Ref IAMInstanceProfileSSM Export: Name: !Sub "${AWS::StackName}::IAMInstanceProfileSSM" SecurityGroupServer: Value: !Ref SecurityGroupServer Export: Name: !Sub "${AWS::StackName}::SecurityGroupServer" EC2Instance: Value: !Ref EC2Instance Export: Name: !Sub "${AWS::StackName}::EC2Instance"
CloudFormationテンプレートは東京・シンガポールの各リージョンで共通です。
各リージョン毎に、パラメータは以下のように指定してください。
パラメータ名 | 設定値 (東京リージョン) | 設定値 (シンガポールリージョン) |
---|---|---|
SystemName | tokyo | singapore |
CidrBlockVPC | 10.0.0.0/16 | 192.168.0.0/16 |
CidrBlockSubnetPublic1 | 10.0.0.0/24 | 192.168.0.0/24 |
CidrBlockSubnetPrivate1 | 10.0.128.0/24 | 192.168.128.0/24 |
CidrBlockRemoteNetwork | 192.168.128.0/24 | 10.0.128.0/24 |
EC2KeyName | (任意のキーペア) | (任意のキーペア) |
このCloudFormationテンプレートで作成される「動作確認用EC2インスタンス」のポイントは以下の通りです:
- UserDataを使ってnginxを自動的にインストール
- Systems Managerのセッションマネージャーを使って操作できるように、IAMインスタンスプロファイルを設定
- 対向リージョンのプライベートサブネットからのICMPおよびHTTPによるアクセスを許可するセキュリティグループ
2. VyOSインスタンスの作成
シンガポールリージョンに、ルーターとなるVyOSインスタンスを作成します。
こちらも同様にCloudFormationで作成します。
VyOSインスタンス作成CloudFormationテンプレート (クリックすると展開します)
--- AWSTemplateFormatVersion: "2010-09-09" Description: "VPN TEST: VyOS EC2 Instance (site-to-site VPN router)" Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: "General Information" Parameters: - SystemName - Environment - Label: default: "Network Configuration" Parameters: - CidrBlockAllowAccessRouter - IPAddressAllowSSH - Label: default: "EC2 Instance Configuration" Parameters: - EC2ImageID - EC2InstanceType - EC2KeyName - EC2VolumeType - EC2VolumeSize - Label: default: "CloudFormation Stack Reference" Parameters: - StackVPC Parameters: SystemName: Type: String Default: singapore Environment: Type: String Default: dev AllowedValues: - dev - str - prd CidrBlockAllowAccessRouter: Type: String Default: 192.168.128.0/24 IPAddressAllowSSH: Type: String EC2ImageID: Type: AWS::EC2::Image::Id Default: ami-070a39a224bab5d4f # VyOS (HVM) 1.2.4-9c9395f4-e891-4577-82e9-a6d5bccfb3c9-ami-00c8302b5b62b168a.4 @ ap-southeast-1 EC2InstanceType: Type: String Default: t3.large EC2KeyName: Type: AWS::EC2::KeyPair::KeyName EC2VolumeType: Type: String Default: gp2 EC2VolumeSize: Type: String Default: 10 StackVPC: Type: String Resources: SecurityGroupVyOS: Type: AWS::EC2::SecurityGroup Properties: GroupName: !Sub "${SystemName}-${Environment}-router-sg" GroupDescription: "Security group for servers" VpcId: {"Fn::ImportValue": !Sub "${StackVPC}::VPC"} SecurityGroupIngress: - IpProtocol: -1 FromPort: -1 ToPort: -1 CidrIp: !Ref CidrBlockAllowAccessRouter Description: "Access by all protocols from allowed network" - IpProtocol: tcp FromPort: 22 ToPort: 22 CidrIp: !Ref IPAddressAllowSSH Description: "SSH access from my IP address" Tags: - Key: Name Value: !Sub "${SystemName}-${Environment}-router-sg" - Key: System Value: !Ref SystemName - Key: Environment Value: !Ref Environment EC2InstanceVyOS: Type: AWS::EC2::Instance Properties: ImageId: !Ref EC2ImageID InstanceType: !Ref EC2InstanceType KeyName: !Ref EC2KeyName BlockDeviceMappings: - DeviceName: /dev/xvda Ebs: VolumeType: !Ref EC2VolumeType VolumeSize: !Ref EC2VolumeSize NetworkInterfaces: - DeviceIndex: 0 SubnetId: {"Fn::ImportValue": !Sub "${StackVPC}::SubnetPublic1"} GroupSet: - !Ref SecurityGroupVyOS SourceDestCheck: false Tags: - Key: Name Value: !Sub "${SystemName}-${Environment}-router" - Key: System Value: !Ref SystemName - Key: Environment Value: !Ref Environment EIPVyOS: Type: AWS::EC2::EIP Properties: Domain: vpc EIPAssociationVyOS: Type: AWS::EC2::EIPAssociation Properties: AllocationId: !GetAtt EIPVyOS.AllocationId InstanceId: !Ref EC2InstanceVyOS Outputs: SecurityGroupVyOS: Value: !Ref SecurityGroupVyOS Export: Name: !Sub "${AWS::StackName}::SecurityGroupVyOS" EC2InstanceVyOS: Value: !Ref EC2InstanceVyOS Export: Name: !Sub "${AWS::StackName}::EC2InstanceVyOS" EC2InstanceVyOSPublicIP: Value: !GetAtt EC2InstanceVyOS.PublicIp Export: Name: !Sub "${AWS::StackName}::EC2InstanceVyOSPublicIP" EC2InstanceVyOSPrivateIP: Value: !GetAtt EC2InstanceVyOS.PrivateIp Export: Name: !Sub "${AWS::StackName}::EC2InstanceVyOSPrivateIP"
パラメータは以下のように指定してください。
パラメータ名 | 設定値 |
---|---|
IPAddressAllowSSH | SSH接続元IPアドレス (例:11.22.33.44/32) |
EC2KeyName | (任意のキーペア) |
StackVPC | 「1. ベース環境の構築」で作成したCloudFormationスタック名 |
マネジメントコンソールで作成する場合は、以下の点に留意してください。
- AMIは、キーワード「VyOS」で検索してヒットした中から「AWS Marketplace」のものを選択
- セキュリティグループは以下のインバウンドルールを設定
- すべてのトラフィック: シンガポールリージョンのプライベートサブネット (192.168.128.0/24)
- SSH: マイIP
- インスタンス作成後、「送信元/送信先チェック」を「無効」に設定
3. VPN関連リソースの作成
東京リージョンで、VPN関連のAWSリソースを設定していきます。
(1) カスタマーゲートウェイを作成する
マネジメントコンソールで [VPC]-[カスタマーゲートウェイ] を開きます。
[カスタマーゲートウェイの作成] をクリックします。
項目 | 設定値 |
---|---|
名前 | 任意の名前 (例:tokyo-dev-cgw) |
ルーティング | 「静的」 |
IPアドレス | 作成したVyOSインスタンスのパブリックIPアドレス |
(「Certificate ARN」「Device」は省略します)
(2) 仮想プライベートゲートウェイを作成して、VPCにアタッチする
マネジメントコンソールで [VPC]-[仮想プライベートゲートウェイ] を開きます。
[仮想プライベートゲートウェイの作成] をクリックします。
項目 | 設定値 |
---|---|
名前 | 任意の名前 (例:tokyo-dev-vgw) |
ASN | 「AmazonのデフォルトASN」 |
作成した仮想プライベートゲートウェイを選択して、[アクション]-[VPCにアタッチ]を選択します。
「tokyo-dev-vpc」を選択して「はい、アタッチします」を選択します。
(3) VPN接続を作成する
マネジメントコンソールで [VPC]-[サイト間のVPN接続] を開きます。
[VPN接続の作成] をクリックします。
項目 | 設定値 |
---|---|
名前タグ | 任意の名前 (例:tokyo-dev-vpn) |
Target Gateway Type | 「Virtual Private Gateway」 |
仮想プライベートゲートウェイ | 作成した仮想プライベートゲートウェイ (tokyo-dev-vgw) |
カスタマーゲートウェイ | 「既存」 |
Customer Gateway ID | 作成したカスタマーゲートウェイ (tokyo-dev-cgw) |
ルーティングオプション | 「静的」 |
静的IPプレフィックス | 192.168.128.0/24 |
(「トンネルオプション」は全てデフォルトのままにします)
作成直後は「状態」が「保留中」になります。
状態が「使用可能」になるまで待ちます。(数分間)
(4) ルートテーブルでルート伝播を有効にする
マネジメントコンソールで [VPC]-[ルートテーブル] を開きます。
プライベートサブネットのルートグループ「tokyo-dev-private-rtb」を選択します。
[ルート伝播] タブを開いて、[ルート伝達の編集] をクリックします。
仮想プライベートゲートウェイ「tokyo-dev-vgw」の [伝播] にチェックを入れて、[保存] をクリックします。
「伝播」欄が「はい」になったことを確認します。
なお、この時点では、実際のルート追加はまだ行われません。
4. VyOSの設定
シンガポールリージョンで、VyOSインスタンスにルーターの設定を行っていきます。
(1) ルーター設定ファイルのテンプレートをダウンロードする
ルーターの設定を行う前に、東京リージョン側で「サイト間VPN接続」画面で [設定のダウンロード] をクリックして、ルーター設定ファイルのテンプレート をダウンロードします。
ここが今回の作業のポイントの一つです。
動的ルーティング (BGPあり) のVPN接続を作成した場合、ここで「ベンダー」に「Vyatta」を選択してVyOS向けの設定ファイルをダウンロードすることができました。(VyattaはVyOSの前身となるソフトウェア)
ところが、静的ルーティングのVPN接続の場合は、同じ画面で「Vyatta」が選択肢に現れないため、ダウンロードすることができません。
そのため、ここでは「Generic」を選択して汎用の設定ファイルを入手することにします。
(汎用と言っても、ダウンロードした設定ファイルが各ベンダーのルーターにそのまま投入できる訳ではなく、設定に必要なパラメーターが列挙されたファイルになっています)
(2) VyOSの設定ファイルを準備する
VyOS向けの設定ファイルをダウンロードすることができませんので、一から記述することにします。
ただし、大部分の設定内容は動的ルーティングの場合と同じですので、動的ルーティング用Vyatta向け設定ファイルを基に記述することができます。
今回、以下のような 静的ルーティング用VyOS向け設定ファイルのテンプレート を用意しました。
# Site-to-Site VPN Configuration for VyOS (v1.2) using static routing # IKE Configuration set vpn ipsec ike-group AWS lifetime '28800' set vpn ipsec ike-group AWS proposal 1 dh-group '2' set vpn ipsec ike-group AWS proposal 1 encryption 'aes128' set vpn ipsec ike-group AWS proposal 1 hash 'sha1' set vpn ipsec ike-group AWS dead-peer-detection action 'restart' set vpn ipsec ike-group AWS dead-peer-detection interval '15' set vpn ipsec ike-group AWS dead-peer-detection timeout '30' # ESP Configuration set vpn ipsec esp-group AWS compression 'disable' set vpn ipsec esp-group AWS lifetime '3600' set vpn ipsec esp-group AWS mode 'tunnel' set vpn ipsec esp-group AWS pfs 'enable' set vpn ipsec esp-group AWS proposal 1 encryption 'aes128' set vpn ipsec esp-group AWS proposal 1 hash 'sha1' # WAN Interface Configuration set vpn ipsec ipsec-interfaces interface 'eth0' # Tunnel Interface Configuration # (Tunnel #1) set interfaces vti vti0 address '<<TUNNEL1_LOCAL_INTERNAL_IP_ADDRESS>>/30' set interfaces vti vti0 description 'VPC tunnel 1' set interfaces vti vti0 mtu '1436' # (Tunnel #2) set interfaces vti vti1 address '<<TUNNEL2_LOCAL_INTERNAL_IP_ADDRESS>>/30' set interfaces vti vti1 description 'VPC tunnel 2' set interfaces vti vti1 mtu '1436' # Tunnel IPsec Configuration # (Tunnel #1) set vpn ipsec site-to-site peer <<TUNNEL1_REMOTE_EXTERNAL_IP_ADDRESS>> authentication mode 'pre-shared-secret' set vpn ipsec site-to-site peer <<TUNNEL1_REMOTE_EXTERNAL_IP_ADDRESS>> authentication pre-shared-secret '<<TUNNEL1_PRE_SHARED_KEY>>' set vpn ipsec site-to-site peer <<TUNNEL1_REMOTE_EXTERNAL_IP_ADDRESS>> description 'VPC tunnel 1' set vpn ipsec site-to-site peer <<TUNNEL1_REMOTE_EXTERNAL_IP_ADDRESS>> ike-group 'AWS' set vpn ipsec site-to-site peer <<TUNNEL1_REMOTE_EXTERNAL_IP_ADDRESS>> local-address '<<ROUTER_LAN_IP_ADDRESS>>' set vpn ipsec site-to-site peer <<TUNNEL1_REMOTE_EXTERNAL_IP_ADDRESS>> vti bind 'vti0' set vpn ipsec site-to-site peer <<TUNNEL1_REMOTE_EXTERNAL_IP_ADDRESS>> vti esp-group 'AWS' # (Tunnel #2) set vpn ipsec site-to-site peer <<TUNNEL2_REMOTE_EXTERNAL_IP_ADDRESS>> authentication mode 'pre-shared-secret' set vpn ipsec site-to-site peer <<TUNNEL2_REMOTE_EXTERNAL_IP_ADDRESS>> authentication pre-shared-secret '<<TUNNEL2_PRE_SHARED_KEY>>' set vpn ipsec site-to-site peer <<TUNNEL2_REMOTE_EXTERNAL_IP_ADDRESS>> description 'VPC tunnel 2' set vpn ipsec site-to-site peer <<TUNNEL2_REMOTE_EXTERNAL_IP_ADDRESS>> ike-group 'AWS' set vpn ipsec site-to-site peer <<TUNNEL2_REMOTE_EXTERNAL_IP_ADDRESS>> local-address '<<ROUTER_LAN_IP_ADDRESS>>' set vpn ipsec site-to-site peer <<TUNNEL2_REMOTE_EXTERNAL_IP_ADDRESS>> vti bind 'vti1' set vpn ipsec site-to-site peer <<TUNNEL2_REMOTE_EXTERNAL_IP_ADDRESS>> vti esp-group 'AWS' # Static Routing Configuration # (Tunnel #1) set protocols static route <<REMOTE_NETWORK_CIDR>> next-hop <<TUNNEL1_REMOTE_INTERNAL_IP_ADDRESS>> # (Tunnel #2) set protocols static route <<REMOTE_NETWORK_CIDR>> next-hop <<TUNNEL2_REMOTE_INTERNAL_IP_ADDRESS>>
<<プレースホルダ名>> の部分を、下表に準じて値を当てはめていくことで設定ファイルを作成します。
ルーター全体の設定
マネジメントコンソールで各値を確認して、該当する項目の値を当てはめます。
プレースホルダ項目 | 設定値 |
---|---|
ROUTER_LAN_IP_ADDRESS |
VyOSインスタンスのプライベートIPアドレス |
LOCAL_NETWORK_CIDR |
192.168.128.0/24 (シンガポール側のプライベートサブネットCIDR) |
REMOTE_NETWORK_CIDR |
10.0.128.0/24 (東京側のプライベートサブネットCIDR) |
Tunnel #1 の設定
ダウンロードした汎用設定ファイルの「IPSec Tunnel #1」セクションを参照して、該当する項目の値を当てはめます。
プレースホルダ項目 | 参照する値 |
---|---|
TUNNEL1_PRE_SHARED_KEY |
#1: Internet Key Exchange Configuration > Pre-Shared Key |
TUNNEL1_LOCAL_INTERNAL_IP_ADDRESS |
#3: Tunnel Interface Configuration > Inside IP Addresses > Customer Gateway |
TUNNEL1_REMOTE_INTERNAL_IP_ADDRESS |
#3: Tunnel Interface Configuration > Inside IP Addresses > Virtual Private Gateway |
TUNNEL1_REMOTE_EXTERNAL_IP_ADDRESS |
#3: Tunnel Interface Configuration > Outside IP Addresses > Virtual Private Gateway |
以下は、ダウンロードした汎用設定ファイルの抜粋です。
IPSec Tunnel #1 ================================================================================ #1: Internet Key Exchange Configuration (中略) - IKE version : IKEv1 - Authentication Method : Pre-Shared Key - Pre-Shared Key : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX - Authentication Algorithm : sha1 - Encryption Algorithm : aes-128-cbc - Lifetime : 28800 seconds - Phase 1 Negotiation Mode : main - Diffie-Hellman : Group 2 (中略) #3: Tunnel Interface Configuration (中略) Outside IP Addresses: - Customer Gateway : xx.xx.xx.xx - Virtual Private Gateway : xx.xx.xx.xx Inside IP Addresses - Customer Gateway : 169.254.xx.xx/30 - Virtual Private Gateway : 169.254.xx.xx/30 (後略)
Tunnel #2 の設定
「Tunnel #1」と同様にして、ダウンロードした汎用設定ファイルの「IPSec Tunnel #2」セクションを参照して、該当する項目の値を当てはめます。
プレースホルダ項目 | 参照する値 |
---|---|
TUNNEL2_PRE_SHARED_KEY |
#1: Internet Key Exchange Configuration > Pre-Shared Key |
TUNNEL2_LOCAL_INTERNAL_IP_ADDRESS |
#3: Tunnel Interface Configuration > Inside IP Addresses > Customer Gateway |
TUNNEL2_REMOTE_INTERNAL_IP_ADDRESS |
#3: Tunnel Interface Configuration > Inside IP Addresses > Virtual Private Gateway |
TUNNEL2_REMOTE_EXTERNAL_IP_ADDRESS |
#3: Tunnel Interface Configuration > Outside IP Addresses > Virtual Private Gateway |
(3) VyOSに設定ファイルを投入する
VyOSインスタンスにSSHで接続します。(ユーザー名:vyos)
設定モードに遷移します。
$ configure
プロンプトが「#」に変わります。
設定ファイルの内容をコピー&ペーストします。(コメント行も含めて丸ごとコピペして構いません)
# # Site-to-Site VPN Configuration for VyOS (v1.2) using static routing # # # IKE Configuration # set vpn ipsec ike-group AWS lifetime '28800' # set vpn ipsec ike-group AWS proposal 1 dh-group '2' # set vpn ipsec ike-group AWS proposal 1 encryption 'aes128' # set vpn ipsec ike-group AWS proposal 1 hash 'sha1' (中略) # # Static Routing Configuration # # (Tunnel #1) # set protocols static route <<REMOTE_NETWORK_CIDR>> next-hop <<TUNNEL1_REMOTE_INTERNAL_IP_ADDRESS>> # # (Tunnel #2) # set protocols static route <<REMOTE_NETWORK_CIDR>> next-hop <<TUNNEL2_REMOTE_INTERNAL_IP_ADDRESS>>
設定をコミットします。
# commit
コミット結果がエラーとならないことを確認して、設定を保存します。
# save
設定モードから抜けます。
# exit
(4) VyOS側でIPsec状態を確認する
参照モード (プロンプトが「$」) で以下のコマンドを実行します。
$ show vpn ike sa Peer ID / IP Local ID / IP ------------ ------------- XX.XX.XX.XX 192.168.0.XX Description: VPC tunnel 1 State IKEVer Encrypt Hash D-H Group NAT-T A-Time L-Time ----- ------ ------- ---- --------- ----- ------ ------ up IKEv1 aes128 sha1_96 2(MODP_1024) no 3600 28800 Peer ID / IP Local ID / IP ------------ ------------- XX.XX.XX.XX 192.168.0.XX Description: VPC tunnel 2 State IKEVer Encrypt Hash D-H Group NAT-T A-Time L-Time ----- ------ ------- ---- --------- ----- ------ ------ up IKEv1 aes128 sha1_96 2(MODP_1024) no 3600 28800
$ show vpn ipsec sa Connection State Up Bytes In/Out Remote address Remote ID Proposal ---------------------------- ------- ----------- -------------- ---------------- ----------- ------------------------------------------------ peer-XX.XX.XX.XX-tunnel-vti up 118 seconds 0B/0B XX.XX.XX.XX N/A AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_1024 peer-XX.XX.XX.XX-tunnel-vti up 118 seconds 0B/0B XX.XX.XX.XX N/A AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_1024
いずれのコマンドも「State」欄が「up」になっていることを確認します。
(5) VyOSインスタンスを参照するようにルートテーブルを設定
マネジメントコンソールで [EC2]-[インスタンス] を開きます。
VyOSのインスタンス「singapore-dev-router」を選択して、ENIのIDを確認します。
[VPC]-[ルーティングテーブル] を開きます。
プライベートサブネットのルートテーブル「singapore-dev-private-rbt」を選択します。
[ルート] タブを開いて、[ルートの編集] をクリックします。
[ルートの追加] をクリックして、以下のルートを追加します。
項目 | 設定値 |
---|---|
送信先 | 10.0.128.0/24 (東京側のプライベートサブネットCIDR) |
ターゲット | 上で確認した「VyOSインスタンスのENI ID」 |
[ルートの保存] をクリックして設定を保存します。
5. 仮想プライベートゲートウェイ側の確認
東京リージョンで、仮想プライベートゲートウェイとルートテーブルの状態を確認します。
(1) VPN接続のトンネルが「アップ」になっていることを確認
マネジメントコンソールで [VPC]-[サイト間のVPN接続] を開きます。
[tokyo-dev-vpn] を選択して、[Tunnel Details] タブを開きます。
[Tunnel State] で各トンネルの「スタータス」欄が「アップ」になっていることを確認します。
(2) ルートテーブルにルートが伝播していることを確認
マネジメントコンソールで [VPC]-[ルートテーブル] を開きます。
プライベートサブネットのルートグループ「tokyo-dev-private-rtb」を選択します。
[ルート] タブを開きます。
以下のルートが追加されていることを確認します。
- 送信先: 192.168.128.0/24
- ターゲット: 仮想プライベートゲートウェイ
- ステータス: active
- 伝播済み: はい
6. 疎通確認を行う
まず、東京リージョン・シンガポールリージョンの各サーバー間でICMPによる疎通確認を行います。
各サーバーのプライベートIPアドレスを確認して、pingを実行しましょう。
(サーバーへはSystems Managerのセッションマネージャーで接続することができます)
東京 → シンガポール
sh-4.2$ ping 192.168.128.151 PING 192.168.128.151 (192.168.128.151) 56(84) bytes of data. 64 bytes from 192.168.128.151: icmp_seq=1 ttl=254 time=71.9 ms 64 bytes from 192.168.128.151: icmp_seq=2 ttl=254 time=71.9 ms 64 bytes from 192.168.128.151: icmp_seq=3 ttl=254 time=71.8 ms 64 bytes from 192.168.128.151: icmp_seq=4 ttl=254 time=71.9 ms 64 bytes from 192.168.128.151: icmp_seq=5 ttl=254 time=72.0 ms ・・・
シンガポール → 東京
sh-4.2$ ping 10.0.128.50 PING 10.0.128.50 (10.0.128.50) 56(84) bytes of data. 64 bytes from 10.0.128.50: icmp_seq=1 ttl=253 time=72.1 ms 64 bytes from 10.0.128.50: icmp_seq=2 ttl=253 time=72.0 ms 64 bytes from 10.0.128.50: icmp_seq=3 ttl=253 time=71.9 ms 64 bytes from 10.0.128.50: icmp_seq=4 ttl=253 time=72.0 ms 64 bytes from 10.0.128.50: icmp_seq=5 ttl=253 time=72.0 ms ・・・
続いて、各サーバー間でアプリケーションによる通信確認を行います。
ここでは、curl
コマンドにより双方にHTTPリクエストを行ってみます。
東京 → シンガポール
sh-4.2$ curl http://192.168.128.151 Hello! I'm SINGAPORE Web Server!
シンガポール → 東京
sh-4.2$ curl http://10.0.128.50 Hello! I'm TOKYO Web Server!
正常に通信が行えました!
※ IPsecの状態が正常であることを確認している場合、サーバー間の通信がうまくいかないのは「ルーティングの設定」「セキュリティグループの設定」である可能性が大です。各設定を見直してみてください。
おわりに
ルーターが冗長化されていなかったり、ネットワーク構成がそれほど複雑でない場合は、静的ルーティングで運用している場合も多いかと思います。
そのような環境で検証を行う際の参考になれば幸いです。