VyOSを用いたAWSリージョン間のVPN接続手順です。
リージョンを跨いだ Windows 同士で ping 疎通とリモートデスクトップ接続を行うことが目的です。
以下の記事を参考に実践した内容になります。
- https://dev.classmethod.jp/server-side/network/vyos-aws/
- https://dev.classmethod.jp/cloud/aws/vyos-aws-vpn/
- https://qiita.com/t11a/items/9d732ae647ed878e4625
構成イメージ
設定手順 (もくじ)
- [Tokyo/Singapore] 構成に登場する VPC、Subnet、EC2 インスタンスの作成
- [Singapore] VyOS の 送信元/送信先チェックを無効化
- [Tokyo] カスタマーゲートウェイの作成
- [Tokyo] 仮想プライベートゲートウェイの作成、アタッチ
- [Tokyo] VPN 接続の作成
- [Tokyo] VPN 設定の変更
- [Singapore] VPN 設定を VyOS に反映
- [Singapore] ルートテーブルに 10.0.1.0/24 を追加
- [Tokyo] ルートテーブルの経路伝播を有効化
- [Singapore] 192.168.2.0/24 へのネクストホップ設定
具体的な内容を以下に記載します。
1. [Tokyo/Singapore] 構成に登場する VPC、Subnet、EC2 インスタンスの作成
CloudFomationを用意しました。ご活用下さい。
AWSTemplateFormatVersion: '2010-09-09'
Description: "Create VPC-A"
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: "Network Configuration"
Parameters:
- VPCName
- VPCCider
- IGWName
- RouteTableName
- NetworkAclName
- SubnetName01
- SubnetCider01
- SubnetName02
- SubnetCider02
- Label:
default: "EC2 Configuration"
Parameters:
- EC2Name
- EC2ImageID
- EC2InstanceType
- EC2KeyPair
- EC2VolumeSize
- SecurityGroupName
Parameters:
VPCCider:
Type: String
Default: 10.0.0.0/16
VPCName:
Type: String
Default: tokyo-prd-vpc
IGWName:
Type: String
Default: tokyo-prd-igw
RouteTableName:
Type: String
Default: tokyo-prd-rtb
NetworkAclName:
Type: String
Default: tokyo-prd-acl
SubnetName01:
Type: String
Default: tokyo-prd-subnet01
SubnetName02:
Type: String
Default: tokyo-prd-subnet02
SubnetCider01:
Type: String
Default: 10.0.1.0/24
SubnetCider02:
Type: String
Default: 10.0.2.0/24
SecurityGroupName:
Type: String
Default: tokyo-prd-server-sg
EC2Name:
Type: String
Default: tokyo-prd-server
EC2ImageID:
Type: String
Default: ami-00e1adcac4c0bbe13
EC2InstanceType:
Type: String
Default: t2.micro
EC2KeyPair:
Type: AWS::EC2::KeyPair::KeyName
EC2VolumeSize:
Type: String
Default: 35
Resources:
myVPC:
Type: "AWS::EC2::VPC"
Properties:
CidrBlock: !Ref VPCCider
Tags:
- Key: Name
Value: !Ref VPCName
myIGW:
Type: "AWS::EC2::InternetGateway"
Properties:
Tags:
- Key: Name
Value: !Ref IGWName
myAttachIGW:
Type: "AWS::EC2::VPCGatewayAttachment"
Properties:
VpcId: !Ref myVPC
InternetGatewayId: !Ref myIGW
myRouteTable:
Type: "AWS::EC2::RouteTable"
Properties:
VpcId: !Ref myVPC
Tags:
- Key: Name
Value: !Ref RouteTableName
myPublicrtb:
Type: "AWS::EC2::Route"
Properties:
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref myIGW
RouteTableId: !Ref myRouteTable
myACL:
Type: "AWS::EC2::NetworkAcl"
Properties:
Tags:
- Key: Name
Value: !Ref NetworkAclName
VpcId: !Ref myVPC
myNetworkEgressAclEgressEntry:
Type: "AWS::EC2::NetworkAclEntry"
Properties:
CidrBlock: 0.0.0.0/0
Egress: true
NetworkAclId: !Ref myACL
Protocol: -1
RuleAction : allow
RuleNumber : 100
myNetworkEgressAclIngressEntry:
Type: "AWS::EC2::NetworkAclEntry"
Properties:
CidrBlock: 0.0.0.0/0
Egress: false
NetworkAclId: !Ref myACL
Protocol: -1
RuleAction : allow
RuleNumber : 100
mySubnet1a:
Type: "AWS::EC2::Subnet"
Properties:
VpcId: !Ref myVPC
AvailabilityZone: ap-northeast-1a
CidrBlock: !Ref SubnetCider01
Tags:
- Key: Name
Value: !Ref SubnetName01
mySubnet1c:
Type: "AWS::EC2::Subnet"
Properties:
VpcId: !Ref myVPC
AvailabilityZone: ap-northeast-1c
CidrBlock: !Ref SubnetCider02
Tags:
- Key: Name
Value: !Ref SubnetName02
myPublicRtb1:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
SubnetId: !Ref mySubnet1a
RouteTableId: !Ref myRouteTable
myPublicRtb2:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
SubnetId: !Ref mySubnet1c
RouteTableId: !Ref myRouteTable
myAclAssociation1:
Type: "AWS::EC2::SubnetNetworkAclAssociation"
Properties:
SubnetId: !Ref mySubnet1a
NetworkAclId: !Ref myACL
myAclAssociation2:
Type: "AWS::EC2::SubnetNetworkAclAssociation"
Properties:
SubnetId: !Ref mySubnet1c
NetworkAclId: !Ref myACL
mySecurityGroup:
Type: "AWS::EC2::SecurityGroup"
Properties:
VpcId: !Ref myVPC
GroupName: !Ref SecurityGroupName
GroupDescription: "SecurityGroup for Server"
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: '3389'
ToPort: '3389'
CidrIp: 0.0.0.0/0
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: '3389'
ToPort: '3389'
CidrIp: 192.168.2.0/24
SecurityGroupIngress:
- IpProtocol: icmp
FromPort: '-1'
ToPort: '-1'
CidrIp: 192.168.1.0/24
SecurityGroupIngress:
- IpProtocol: icmp
FromPort: '-1'
ToPort: '-1'
CidrIp: 192.168.2.0/24
Tags:
- Key: Name
Value: !Ref SecurityGroupName
myServer:
Type: "AWS::EC2::Instance"
Properties:
AvailabilityZone: ap-northeast-1a
ImageId: !Ref EC2ImageID
InstanceType: !Ref EC2InstanceType
KeyName: !Ref EC2KeyPair
BlockDeviceMappings:
- DeviceName: /dev/sda1
Ebs:
VolumeType: gp2
VolumeSize: !Ref EC2VolumeSize
DeleteOnTermination: true
SecurityGroupIds:
- !Ref mySecurityGroup
SubnetId: !Ref mySubnet1a
Tags:
- Key: Name
Value: !Ref EC2Name
AWSTemplateFormatVersion: '2010-09-09'
Description: "Create VPC-B"
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: "Network Configuration"
Parameters:
- VPCName
- VPCCider
- IGWName
- RouteTableName
- NetworkAclName
- SubnetName01
- SubnetCider01
- SubnetName02
- SubnetCider02
- Label:
default: "EC2 Configuration [VyOS]"
Parameters:
- EC2Name01
- EC2ImageID01
- EC2InstanceType01
- EC2KeyPair01
- EC2VolumeSize01
- SecurityGroupName01
- Label:
default: "EC2 Configuration [Windows]"
Parameters:
- EC2Name02
- EC2ImageID02
- EC2InstanceType02
- EC2KeyPair02
- EC2VolumeSize02
- SecurityGroupName02
Parameters:
VPCCider:
Type: String
Default: 192.168.0.0/16
VPCName:
Type: String
Default: singapore-prd-vpc
IGWName:
Type: String
Default: singapore-prd-igw
RouteTableName:
Type: String
Default: singapore-prd-rtb
NetworkAclName:
Type: String
Default: singapore-prd-acl
SubnetName01:
Type: String
Default: singapore-prd-subnet01
SubnetCider01:
Type: String
Default: 192.168.1.0/24
SubnetName02:
Type: String
Default: singapore-prd-subnet02
SubnetCider02:
Type: String
Default: 192.168.2.0/24
EC2Name01:
Type: String
Default: singapore-prd-vyos
EC2ImageID01:
Type: String
Default: ami-0ab2e769
EC2InstanceType01:
Type: String
Default: t2.micro
EC2KeyPair01:
Type: AWS::EC2::KeyPair::KeyName
EC2VolumeSize01:
Type: String
Default: 4
SecurityGroupName01:
Type: String
Default: singapore-prd-vyos-sg
EC2Name02:
Type: String
Default: singapore-prd-server
EC2ImageID02:
Type: String
Default: ami-035c1e57873991ca2
EC2InstanceType02:
Type: String
Default: t2.micro
EC2KeyPair02:
Type: AWS::EC2::KeyPair::KeyName
EC2VolumeSize02:
Type: String
Default: 35
SecurityGroupName02:
Type: String
Default: singapore-prd-server-sg
Resources:
myVPC:
Type: "AWS::EC2::VPC"
Properties:
CidrBlock: !Ref VPCCider
Tags:
- Key: Name
Value: !Ref VPCName
myIGW:
Type: "AWS::EC2::InternetGateway"
Properties:
Tags:
- Key: Name
Value: !Ref IGWName
myAttachIGW:
Type: "AWS::EC2::VPCGatewayAttachment"
Properties:
VpcId: !Ref myVPC
InternetGatewayId: !Ref myIGW
myRouteTable:
Type: "AWS::EC2::RouteTable"
Properties:
VpcId: !Ref myVPC
Tags:
- Key: Name
Value: !Ref RouteTableName
myPublicrtb:
Type: "AWS::EC2::Route"
Properties:
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref myIGW
RouteTableId: !Ref myRouteTable
myACL:
Type: "AWS::EC2::NetworkAcl"
Properties:
Tags:
- Key: Name
Value: !Ref NetworkAclName
VpcId: !Ref myVPC
myNetworkEgressAclEgressEntry:
Type: "AWS::EC2::NetworkAclEntry"
Properties:
CidrBlock: 0.0.0.0/0
Egress: true
NetworkAclId: !Ref myACL
Protocol: -1
RuleAction : allow
RuleNumber : 100
myNetworkEgressAclIngressEntry:
Type: "AWS::EC2::NetworkAclEntry"
Properties:
CidrBlock: 0.0.0.0/0
Egress: false
NetworkAclId: !Ref myACL
Protocol: -1
RuleAction : allow
RuleNumber : 100
mySubnet1a:
Type: "AWS::EC2::Subnet"
Properties:
VpcId: !Ref myVPC
AvailabilityZone: ap-southeast-1a
CidrBlock: !Ref SubnetCider01
Tags:
- Key: Name
Value: !Ref SubnetName01
mySubnet1c:
Type: "AWS::EC2::Subnet"
Properties:
VpcId: !Ref myVPC
AvailabilityZone: ap-southeast-1c
CidrBlock: !Ref SubnetCider02
Tags:
- Key: Name
Value: !Ref SubnetName02
myPublicRtb1:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
SubnetId: !Ref mySubnet1a
RouteTableId: !Ref myRouteTable
myPublicRtb2:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
SubnetId: !Ref mySubnet1c
RouteTableId: !Ref myRouteTable
myAclAssociation1:
Type: "AWS::EC2::SubnetNetworkAclAssociation"
Properties:
SubnetId: !Ref mySubnet1a
NetworkAclId: !Ref myACL
myAclAssociation2:
Type: "AWS::EC2::SubnetNetworkAclAssociation"
Properties:
SubnetId: !Ref mySubnet1c
NetworkAclId: !Ref myACL
mySecurityGroup1:
Type: "AWS::EC2::SecurityGroup"
Properties:
VpcId: !Ref myVPC
GroupName: !Ref SecurityGroupName01
GroupDescription: "SecurityGroup for vyos"
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: '22'
ToPort: '22'
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: '3389'
ToPort: '3389'
CidrIp: 192.168.2.0/24
- IpProtocol: icmp
FromPort: '-1'
ToPort: '-1'
CidrIp: 192.168.2.0/24
Tags:
- Key: Name
Value: !Ref SecurityGroupName01
mySecurityGroup2:
Type: "AWS::EC2::SecurityGroup"
Properties:
VpcId: !Ref myVPC
GroupName: !Ref SecurityGroupName02
GroupDescription: "SecurityGroup for Server"
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: '3389'
ToPort: '3389'
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: '3389'
ToPort: '3389'
CidrIp: 10.0.1.0/24
- IpProtocol: icmp
FromPort: '-1'
ToPort: '-1'
CidrIp: 10.0.1.0/24
Tags:
- Key: Name
Value: !Ref SecurityGroupName02
myServer01:
Type: "AWS::EC2::Instance"
Properties:
AvailabilityZone: ap-southeast-1a
ImageId: !Ref EC2ImageID01
InstanceType: !Ref EC2InstanceType01
KeyName: !Ref EC2KeyPair01
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
VolumeType: gp2
VolumeSize: !Ref EC2VolumeSize01
DeleteOnTermination: true
SecurityGroupIds:
- !Ref mySecurityGroup1
SubnetId: !Ref mySubnet1a
Tags:
- Key: Name
Value: !Ref EC2Name01
myServer02:
Type: "AWS::EC2::Instance"
Properties:
AvailabilityZone: ap-southeast-1c
ImageId: !Ref EC2ImageID02
InstanceType: !Ref EC2InstanceType02
KeyName: !Ref EC2KeyPair02
BlockDeviceMappings:
- DeviceName: /dev/sda1
Ebs:
VolumeType: gp2
VolumeSize: !Ref EC2VolumeSize02
DeleteOnTermination: true
SecurityGroupIds:
- !Ref mySecurityGroup2
SubnetId: !Ref mySubnet1c
Tags:
- Key: Name
Value: !Ref EC2Name02
myServer01EIP:
Type: "AWS::EC2::EIP"
Properties:
InstanceId: !Ref myServer01
今回は以下の AMI を使用しました。
リージョン | AMI ID | AMI名 |
---|---|---|
Tokyo | ami-00e1adcac4c0bbe13 | Windows_Server-2012-R2_RTM-Japanese-64Bit-Base-2018.11.19 |
Singapore | ami-0ab2e769 | VyOS (HVM) 1.1.8-66e10eda-0acd-4301-9012-3113b2cfa4f5-ami-220db358.4 |
Singapore | ami-035c1e57873991ca2 | Windows_Server-2012-R2_RTM-Japanese-64Bit-Base-2018.11.19 |
VyOS の AMI は marketplace のイメージを使用しています。
marketplace は使用する前にSubscribe
が必要になるため、ご注意下さい。
参考 : CloudFormationでMarketplaceのAMIを使う時のたった1つの注意点
2. [Singapore] VyOS の 送信元/送信先チェックを無効化
EC2 の設定で VyOS の 送信元/送信先チェック
を False
に設定します。
3. [Tokyo] カスタマーゲートウェイの作成
今回の構成は VyOS がカスタマーゲートウェイにあたります。
VyOS の EIP を設定し、ルーティングは静的
で作成します。
4. [Tokyo] 仮想プライベートゲートウェイの作成、アタッチ
ASNはAmazonデフォルトを選択します。
作成した仮想プライベートゲートウェイは VPC にアタッチします。
5. [Tokyo] VPN 接続の作成
作成したカスタマーゲートウェイ、仮想プライベートゲートウェイを指定します。
ルーティングオプションは動的
を設定します。
6. [Tokyo] VPN 設定の変更
作成した VPN 接続の設定をダウンロードします。
ダウンロードした設定ファイルは編集が必要です。
以下の箇所を変更します。
(変更前)
set vpn ipsec site-to-site peer ***** local-address [VyOSインスタンスのEIP]
set protocols bgp 65000 network 0.0.0.0/0
(変更後)
set vpn ipsec site-to-site peer ***** local-address [VyOSインスタンスのプライベートIP]
set protocols bgp 65000 network 192.168.1.0/24
7. [Singapore] VPN 設定を VyOS に反映
!
の箇所以外を貼り付けます。
Welcome to VyOS
Linux vyatta 3.13.11-1-amd64-vyos #1 SMP Thu Oct 26 15:20:46 CEST 2017 x86_64
Welcome to VyOS.
This system is open-source software. The exact distribution terms for
each module comprising the full system are described in the individual
files in /usr/share/doc/*/copyright.
vyos@VyOS-AMI:~$
vyos@VyOS-AMI:~$ configure
[edit]
vyos@VyOS-AMI# set vpn ipsec ike-group AWS lifetime '28800'
[edit]
vyos@VyOS-AMI# set vpn ipsec ike-group AWS proposal 1 dh-group '2'
[edit]
・
・
・
vyos@VyOS-AMI# compare
[edit interfaces]
+vti vti0 {
・
・
・
vyos@VyOS-AMI# commit
[edit]
vyos@VyOS-AMI# save
Saving configuration to '/config/config.boot'...
Done
[edit]
vyos@VyOS-AMI#
[edit]
vyos@VyOS-AMI# exit
exit
vyos@VyOS-AMI:~$
コマンドは VyOS のユーザーガイドで確認できます。
8. [Singapore] ルートテーブルに 10.0.1.0/24、10.0.2.0/24 を追加
Tokyo 側への通信が VyOS を経由するようにルートを追加します。
ターゲットは VyOS の eni を指定します。
eni はインスタンスのネットワークインタフェースで確認できます。
9. [Tokyo] ルートテーブルの経路伝播を有効化
Singapore 側への通信は仮想プライベートゲートウェイを経由するようにルートを追加する必要があります。
今回は VyOS に設定した ルート情報を Tokyo にアドバタイズする方法でルートを追加します。
Tokyo のルートテーブルの経路伝播を有効にします。
VyOS の BGP に設定した 192.168.1.0/24 がルートテーブルに追加されました。
この時点で Win1 <--> VyOS 間の ping 疎通が確認できます。
VyOS --> Win1 の ping は interface を指定すると可能です。
vyos@VyOS-AMI:~$ ping 10.0.1.xxx interface 192.168.1.xxx
PING 10.0.1.xxx (10.0.1.xxx) from 192.168.1.xxx : 56(84) bytes of data.
64 bytes from 10.0.1.xxx: icmp_req=1 ttl=128 time=73.4 ms
64 bytes from 10.0.1.xxx: icmp_req=2 ttl=128 time=73.5 ms
64 bytes from 10.0.1.xxx: icmp_req=3 ttl=128 time=73.7 ms
64 bytes from 10.0.1.xxx: icmp_req=4 ttl=128 time=73.4 ms
Win2 --> win1 間の ping 疎通は、Tokyo 側に戻りのルーティングが無いため疎通しません。
10. [Singapore] 192.168.2.0/24 へのネクストホップ設定
Windows2 -> Windows1 を疎通させるためには、 VyOS に 192.168.2.0/24 に対する通信の転送先を追加します。
追加したルーティング設定は Tokyo へアバタイズされ、 Windows1 -> Windows2 への通信も仮想プライベートゲートウェイを経由するようになります。
以下の設定をVyOSに反映します。
# set protocols static route 192.168.2.0/24 next-hop '192.168.1.1'
# set protocols bgp 65000 network '192.168.2.0/24'
この時点で Win2 --> Win1 間の ping 疎通が確認できます。
C:\Users\Administrator>ping 10.0.1.xxx
10.0.1.xxx に ping を送信しています 32 バイトのデータ:
10.0.1.xxx からの応答: バイト数 =32 時間 =76ms TTL=127
10.0.1.xxx からの応答: バイト数 =32 時間 =74ms TTL=127
10.0.1.xxx からの応答: バイト数 =32 時間 =74ms TTL=127
10.0.1.xxx からの応答: バイト数 =32 時間 =74ms TTL=127
リモートデスクトップ接続も接続することができました。
VyOS の config は以下のようになりました。
vyos@VyOS-AMI:~$ show configuration
interfaces {
ethernet eth0 {
address dhcp
duplex auto
hw-id aa:bb:cc:dd:ee:ff
smp_affinity auto
speed auto
}
loopback lo {
}
vti vti0 {
address 169.254.xxx.xxx/30
description "VPC tunnel 1"
mtu 1436
}
vti vti1 {
address 169.254.xxx.xxx/30
description "VPC tunnel 2"
mtu 1436
}
}
protocols {
bgp 65000 {
neighbor 169.254.xxx.xxx {
remote-as 64512
soft-reconfiguration {
inbound
}
timers {
holdtime 30
keepalive 10
}
}
neighbor 169.254.xxx.xxx {
remote-as 64512
soft-reconfiguration {
inbound
}
timers {
holdtime 30
keepalive 10
}
}
network 192.168.1.0/24 {
}
network 192.168.2.0/24 {
}
}
static {
route 192.168.2.0/24 {
next-hop 192.168.1.1 {
}
}
}
}
service {
ssh {
disable-password-authentication
port 22
}
}
system {
config-management {
commit-revisions 20
}
console {
device ttyS0 {
speed 9600
}
}
host-name VyOS-AMI
login {
user vyos {
authentication {
encrypted-password ****************
plaintext-password ****************
public-keys development {
key ****************
type ssh-rsa
}
}
level admin
}
}
ntp {
server 0.pool.ntp.org {
}
server 1.pool.ntp.org {
}
server 2.pool.ntp.org {
}
}
package {
auto-sync 1
repository community {
components main
distribution helium
password ****************
url http://packages.vyos.net/vyos
username ""
}
}
syslog {
global {
facility all {
level notice
}
facility protocols {
level debug
}
}
}
time-zone UTC
}
vpn {
ipsec {
esp-group AWS {
compression disable
lifetime 3600
mode tunnel
pfs enable
proposal 1 {
encryption aes128
hash sha1
}
}
ike-group AWS {
dead-peer-detection {
action restart
interval 15
timeout 30
}
ikev2-reauth no
key-exchange ikev1
lifetime 28800
proposal 1 {
dh-group 2
encryption aes128
hash sha1
}
}
ipsec-interfaces {
interface eth0
}
site-to-site {
peer 52.193.xxx.xxx {
authentication {
mode pre-shared-secret
pre-shared-secret ****************
}
connection-type initiate
description "VPC tunnel 1"
ike-group AWS
ikev2-reauth inherit
local-address 192.168.1.xxx
vti {
bind vti0
esp-group AWS
}
}
peer 52.198.137.184 {
authentication {
mode pre-shared-secret
pre-shared-secret ****************
}
connection-type initiate
description "VPC tunnel 2"
ike-group AWS
ikev2-reauth inherit
local-address 192.168.1.xxx
vti {
bind vti1
esp-group AWS
}
}
}
}
}
VPN の設定を行うのは初めてでしたが実際に設定を行ってみることでイメージが掴めるようになりました。
VPN入門者向けに参考になれば幸いです。