[AWS] Site-to-Site VPNを使ってFortigateとオンプレ接続
はじめに
AWSとオンプレ環境を安価に接続できるSit-to-Site VPNの構築について説明します。オンプレ側(カスタマー側)のVPN装置はFortigateです。FortigateはGUIではなくCLIで構築します。
Site-to-Site VPNは、AWSとオンプレ間のルーティングにスタティックルーティングとBGPの二種を選択することが可能です。今回はシングル構成のためスタティックルートでも問題はありませんが、一般的な本番環境の場合は回線冗長を行い片系に障害が発生してもBGPにて自動切り替わりするように設計します。そのため、今回はテスト的にBGPで構築します。
構成
構築開始時点の構成は下記の通りとなります。基本的なVPCやサブネット、EC2インスタンス等、またオンプレ側のFortigateは構築済みとします。
下図は今回の構築後の構成となり、オンプレ~AWSのVPN構築が対象となります。
早速ですが以降で設定方法について説明します。
設定(AWS)
AWS カスタマーゲートウェイの設定
『VPC』から、「仮想プライベートネットワーク (VPN)」>「カスタマーゲートウェイ」>「仮想プライベートゲートウェイを作成」を選択します。
「カスタマーゲートウェイを作成」の画面が表示されたら下図のようにパラメーターを入力します。
「BGP ASN」は4バイト形式が可能なので当方は2100000001としました。こちらのASNは後にFortigateのBGPで設定するASNです。
「IPアドレス」はFortigateのWAN側インタフェースのアドレスを指定します。(IPsecの終端IPアドレス)
全ての入力が完了したら、「カスタマーゲートウェイを作成」を押し完了させます。
「Available」になることを確認します。
仮想プライベートゲートウェイ
次に「仮想プライベートネットワーク (VPN)」>「仮想プライベートゲートウェイ」>「仮想プライベートゲートウェイを作成」を選択します。
「仮想プライベートゲートウェイを作成」の画面が表示されたら下図のようにパラメーターを入力していきます。
「カスタムASNの入力」があり、AmazonデフォルトASNでも問題はありませんが、当方はAS番号を管理したいのでカスタムASNを選択し、4200000001としました。こちらはAWS側のBGPで使用されるASNとなります。
入力が完了したら、「仮想プライベートゲートウェイを作成」を押し完了させます。
作成した仮想プライベートゲートウェイをVPNにアタッチします。
アタッチされると状態が「Attached」になります。
Site-to-Site VPN 接続
次に「仮想プライベートネットワーク (VPN)」>「Site-to-Site VPN 接続」>「VPN 接続を作成する」を選択します。
「VPN接続を作成する」の画面が表示されたら下図のようにパラメーターを入力/選択していきます。
「ターゲットゲートウェイのタイプ」と「カスタマーゲートウェイ」では上記で作成した二つを指定します。
「ルーティングオプション」はBGPを使用するので「動的(BGPが必要)」を選択します。
その他はデフォルトで「VPN接続を作成する」を押し完了させます。
ここまで進めるとAWS側のステータスが確認できます。先ほど作成した「vpn01」を選択し、「トンネルの詳細」を参照してみます。
トンネルは2本用意されるためTunnnel1とTunnel2が存在します。
「外部IPアドレス」がAWS側がIPsecを終端するIPアドレスです。
「内部IPv4CIDR」がトンネルインタフェースに設定するネットワークアドレスです。またBGPのネイバーアドレスとしても使用されます。
「ステータス」はVPNとBGPの状態を表します。
ルートテーブルのルート伝播
今回はBGPでルーティングをさせるため、予めVPCに割り当てている(またはサブネットに関連付けをしている)ルートテーブルにてルート伝播を設定します。
本設定を行うことで、仮想プライベートゲートウェイがBGPでオンプレ側のルート情報(192.168.0.0/24)を学習した後に、仮想プライベートゲートウェイから当該ルートテーブルにルート情報が伝播され、ルーティングが自動でインストールされます。
ルート伝播の設定は以上です。
構築
設定(オンプレ Fortigate)
続けてFortigate側の設定を行いますが、その前に、AWS側でSite-to-Site VPNの設定を完了させると各ベンダーのサンプルコンフィグと設定手順がセットになったテキストをダウンロードできます。カスタマーゲートウェイや仮想プライベートゲートウェイで入力した値が反映されたサンプルコンフィグであり設定作業に活用すると便利なのでダウンロードします。
残念ながらあらゆる機種/バージョン用のコンフィグは用意されていません。そのため、機種やOSバージョンによっては不完全なコンフィグとなっているので環境に沿った多少の改変が必要です。今回はサンプルコンフィグの説明は省き、当方が投入し問題なくVPN+BGPが動作したコンフィグを紹介します。(ベースはサンプルコンフィグです)
config vpn ipsec phase1-interface
edit "P1_AWS-vpn1-T1"
set interface "wan1"
set local-gw 61.26.71.188
set keylife 28800
set peertype any
set proposal aes256-sha256
set dpd on-idle
set dhgrp 2
set nattraversal disable
set remote-gw 35.75.134.253
set psksecret ********************* ★サンプルコンフィグに記載あり
set dpd-retryinterval 10
next
edit "P1_AWS-vpn1-T2"
set interface "wan1"
set local-gw 61.26.71.188
set keylife 28800
set peertype any
set proposal aes256-sha256
set dpd on-idle
set dhgrp 2
set nattraversal disable
set remote-gw 54.150.121.161
set psksecret ********************* ★サンプルコンフィグに記載あり
set dpd-retryinterval 10
next
end
config vpn ipsec phase2-interface
edit "P2_AWS-vpn1-T1"
set phase1name "P1_AWS-vpn1-T1"
set proposal aes256-sha256
set dhgrp 2
set keepalive enable
set keylifeseconds 3600
next
edit "P2_AWS-vpn1-T2"
set phase1name "P1_AWS-vpn1-T2"
set proposal aes256-sha256
set dhgrp 2
set keepalive enable
set keylifeseconds 3600
next
end
config system interface
edit "P1_AWS-vpn1-T1"
set vdom "root"
set ip 169.254.244.158 255.255.255.255
set allowaccess ping
set type tunnel
set tcp-mss 1379
set remote-ip 169.254.244.157 255.255.255.252
set snmp-index 15
set interface "wan1"
next
edit "P1_AWS-vpn1-T2"
set vdom "root"
set ip 169.254.218.34 255.255.255.255
set allowaccess ping
set type tunnel
set tcp-mss 1379
set remote-ip 169.254.218.33 255.255.255.252
set snmp-index 17
set interface "wan1"
next
end
config router access-list
edit "ACL-192.168.0.0/24"
config rule
edit 1
set prefix 192.168.0.0 255.255.255.0
set exact-match enable
next
end
next
end
config router aspath-list
edit "ASP_LIST1"
config rule
edit 1
set action permit
set regexp "_4200000001_"
next
end
next
end
config router route-map
edit "RM_IN_1"
config rule
edit 1
set match-as-path "ASP_LIST1"
set set-local-preference 200
next
end
next
edit "RM_IN_2"
config rule
edit 1
set match-as-path "ASP_LIST1"
set set-local-preference 150
next
end
next
edit "RM_OUT_2"
config rule
edit 1
set match-ip-address "ACL-192.168.0.0/24"
set set-aspath "2100000901" "2100000902"
next
end
next
end
config router bgp
set as 2100000001
set router-id 61.26.71.188
set keepalive-timer 10
set holdtime-timer 30
config neighbor
edit "169.254.244.157"
set remote-as 4200000001
set route-map-in "RM_IN_2"
next
edit "169.254.218.33"
set soft-reconfiguration enable
set remote-as 4200000001
set route-map-in "RM_IN_1"
set route-map-out "RM_OUT_2"
next
end
config network
edit 1
set prefix 192.168.0.0 255.255.255.0
next
end
end
config firewall policy
edit 201
set name "ALL<--AWS"
set srcintf "P1_AWS-vpn1-T1" "P1_AWS-vpn1-T2"
set dstintf "any"
set srcaddr "all"
set dstaddr "all"
set action accept
set schedule "always"
set service "ALL"
next
edit 202
set name "ALL-->AWS"
set srcintf "any"
set dstintf "P1_AWS-vpn1-T1" "P1_AWS-vpn1-T2"
set srcaddr "all"
set dstaddr "all"
set action accept
set schedule "always"
set service "ALL"
next
end
BGPの設定について補足します。今回、Tunnelとしては1と2の2本構成です。それぞれTunnel毎にBGPネイバーを張るので、Active/Standby構成となります。(Active/Activeにすると通信の行きと戻りで違うTunnelを通る可能性があります。今回のFortigateのようにFirewall製品をVPN装置にすると行きと戻りが変わるとステートフルインスペクションが効き通信できません)
Active/Standbyの設計ですが、AWSのBGPは「AS_PATHプリペンド」「Local Preference」のパス属性を使って経路制御を行います。
「AS_PATHプリペンド」はオンプレのルート情報(192.168.0.0/24)を「オンプレからAWSに広報するルート」に対しASパスとして遠く見させることでStanby経路とさせます。今回は、「192.168.0.0/24」ルートを広報するときはASパス「"2100000901″ “2100000902"」を追加して広報する設定をしています。
「Local Preference」はAWSのルート情報(10.1.0.0/16)を「AWSからオンプレに広報されてくるルート」に対して優先度をつける設定になります。今回は、Tunnel1から「ASN:4200000001」が含まれているルート情報を受信した場合「値200」、Tunnel2から同様のルート情報を受信した場合は「値150」を付ける、という設定を行い、通常であればTunnel1をActiveとし、Tunnele2をStandbyにしています。
参考までに受信ルートと広報ルートを載せときます。
■受信ルート
FGT60D # get router info bgp network
BGP table version is 37, local router ID is 61.26.71.188
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
S Stale
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight RouteTag Path
*> 10.1.0.0/16 169.254.218.33 200 200 0 0 4200000001 i
* 169.254.244.157 100 150 0 0 4200000001 i
*> 192.168.0.0 0.0.0.0 100 32768 0 i
Total number of prefixes 2
■Tunnel1の広報ルート
FGT60D # get router info bgp neighbors 169.254.244.157 advertised-routes
BGP table version is 37, local router ID is 61.26.71.188
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight RouteTag Path
*> 10.1.0.0/16 169.254.244.158 200 0 0 4200000001 i
*> 192.168.0.0 169.254.244.158 100 32768 0 i
Total number of prefixes 2
■Tunnel2の広報ルート
FGT60D # get router info bgp neighbors 169.254.218.33 advertised-routes
BGP table version is 37, local router ID is 61.26.71.188
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight RouteTag Path
*> 192.168.0.0 169.254.218.34 100 32768 0 2100000901 2100000902 i
Total number of prefixes 1
Fortigate側の設定変更は以上です。
ステータス確認(VPNとBGP)
AWS側のステータス確認
『VPC』から、「仮想プライベートネットワーク (VPN)」>「Site-to-Site VPN 接続」を選択し、先ほど作成した「vpn01」を選択します。
VPNとBGPが正常の場合ステータスが「Up」となり、詳細が「1 BGP ROUTES」となります。
続いてルートテーブルを選択し、仮想プライベートゲートウェイからオンプレ環境のルート情報を学習していることを確認します。(192.168.0.0/24のルートが表示されていること)
Fortigateのステータス確認
続いてFortigate側のステータスを確認していきます。
- diagnose vpn ike gateway list … IKEの状態確認です。IKEの接続が行われていると以下のように表示されます。
- diagnose vpn tunnel list … VPN接続が正常の場合、中段にある「SA:」行より下の項目が表示されるようになります。
FGT60D # diagnose vpn ike gateway list
vd: root/0
name: P1_AWS-vpn1-T1
version: 1
interface: wan1 5
addr: 61.26.71.188:500 -> 35.75.134.253:500
virtual-interface-addr: 169.254.244.158 -> 169.254.244.157
created: 97s ago
IKE SA: created 1/1 established 1/1 time 20/20/20 ms
IPsec SA: created 1/1 established 1/1 time 10/10/10 ms
id/spi: 1033 20d8355009e10b62/c747807e667e2dfb
direction: initiator
status: established 97-96s ago = 20ms
proposal: aes256-sha256
key: 3a98944f9fc8e679-7e9b226f40603975-1894a5dd2cad6bce-309a8c12df9853c1
lifetime/rekey: 28800/28403
DPD sent/recv: 00000004/234cbd2d
vd: root/0
name: P1_AWS-vpn1-T2
version: 1
interface: wan1 5
addr: 61.26.71.188:500 -> 54.150.121.161:500
virtual-interface-addr: 169.254.218.34 -> 169.254.218.33
created: 97s ago
IKE SA: created 1/1 established 1/1 time 20/20/20 ms
IPsec SA: created 1/1 established 1/1 time 10/10/10 ms
id/spi: 1034 07ccf56926072fb6/9aa20ac3255b43ec
direction: initiator
status: established 97-96s ago = 20ms
proposal: aes256-sha256
key: ea53a3ea1ae00772-7130cdcfcb4ea762-5470c7475ed7eb68-502d44849c0c8841
lifetime/rekey: 28800/28403
DPD sent/recv: 00000004/1506db74
FGT60D #
FGT60D # diagnose vpn tunnel list
------------------------------------------------------
name=P1_AWS-vpn1-T1 ver=1 serial=6 61.26.71.188:0->35.75.134.253:0
bound_if=5 lgwy=static/1 tun=intf/0 mode=auto/1 encap=none/8 options[0008]=npu
proxyid_num=1 child_num=0 refcnt=6 ilast=0 olast=0 ad=/0
stat: rxp=1 txp=1 rxb=124 txb=60
dpd: mode=on-idle on=1 idle=10000ms retry=3 count=0 seqno=6
natt: mode=none draft=0 interval=0 remote_port=0
proxyid=P2_AWS-vpn1-T1 proto=0 sa=1 ref=2 serial=1
src: 0:0.0.0.0/0.0.0.0:0
dst: 0:0.0.0.0/0.0.0.0:0
SA: ref=6 options=10227 type=00 soft=0 mtu=1358 expire=3215/0B replaywin=1024
seqno=17 esn=0 replaywin_lastseq=00000001 itn=0
life: type=01 bytes=0/0 timeout=3303/3600
dec: spi=ba4eece7 esp=aes key=32 2dad952128c494a9de9dbd9bd4b90f595599a83c59b0e1913b6f030acb685295
ah=sha256 key=32 b110aa3cece99c2712f0986bc6d1a6ad9b55da091d1df8b457eb2495796046e5
enc: spi=c40ec561 esp=aes key=32 16f60d0490d676a2cf3a83ced6a2b00dc5721037c7700b8c8aa90665b00ee3a7
ah=sha256 key=32 3134db492e47d05fdeec7bf563195190876d2ba43fdd34d1c0ca5f9758077e2b
dec:pkts/bytes=1/60, enc:pkts/bytes=22/3032
npu_flag=03 npu_rgwy=35.75.134.253 npu_lgwy=61.26.71.188 npu_selid=6
------------------------------------------------------
name=P1_AWS-vpn1-T2 ver=1 serial=7 61.26.71.188:0->54.150.121.161:0
bound_if=5 lgwy=static/1 tun=intf/0 mode=auto/1 encap=none/8 options[0008]=npu
proxyid_num=1 child_num=0 refcnt=6 ilast=1 olast=1 ad=/0
stat: rxp=1 txp=1 rxb=124 txb=60
dpd: mode=on-idle on=1 idle=10000ms retry=3 count=0 seqno=4
natt: mode=none draft=0 interval=0 remote_port=0
proxyid=P2_AWS-vpn1-T2 proto=0 sa=1 ref=2 serial=1
src: 0:0.0.0.0/0.0.0.0:0
dst: 0:0.0.0.0/0.0.0.0:0
SA: ref=6 options=10227 type=00 soft=0 mtu=1358 expire=3214/0B replaywin=1024
seqno=1d esn=0 replaywin_lastseq=00000001 itn=0
life: type=01 bytes=0/0 timeout=3301/3600
dec: spi=ba4eece8 esp=aes key=32 8a2500d622f863b785023850ffa03c8f23ddcacb4387398fe4a166c72e13e7b5
ah=sha256 key=32 b24f59d76728fd3e8a0f1fdb663394257fd551b53bcf9def0dd403361173fb8c
enc: spi=ccab7328 esp=aes key=32 c73f9f1fb27c2eab8a5d165886a3391c7ec1c6018249792124e8ef1f4c755f71
ah=sha256 key=32 c15211347b1e7807ef8fe6a64478f06a265e2d3b91def77409e89749e6b34a3c
dec:pkts/bytes=1/60, enc:pkts/bytes=28/3792
npu_flag=03 npu_rgwy=54.150.121.161 npu_lgwy=61.26.71.188 npu_selid=7
FGT60D #
- get router info bgp summary … 正常の場合、各ネイバーのUp時間が表示され、State/PfxRcdが1(または1以上の整数)になります。
FGT60D # get router info bgp summary
BGP router identifier 61.26.71.188, local AS number 2100000001
BGP table version is 4
2 BGP AS-PATH entries
0 BGP community entries
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
169.254.218.33 4 4200000001 19 19 3 0 0 00:02:16 1
169.254.244.157 4 4200000001 15 17 3 0 0 00:01:57 1
Total number of neighbors 2
FGT60D #
- get router info routing-table all … VPCの10.1.0.0/16をBGPで学習していることを確認します。
FGT60D # get router info routing-table all
Routing table for VRF=0
Codes: K - kernel, C - connected, S - static, R - RIP, B - BGP
O - OSPF, IA - OSPF inter area
N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
E1 - OSPF external type 1, E2 - OSPF external type 2
i - IS-IS, L1 - IS-IS level-1, L2 - IS-IS level-2, ia - IS-IS inter area
* - candidate default
S* 0.0.0.0/0 [5/0] via 61.26.71.129, wan1
B 10.1.0.0/16 [20/100] via 169.254.244.157, P1_AWS-vpn1-T1, 00:04:07
C 61.26.71.128/25 is directly connected, wan1
C 169.254.218.32/30 is directly connected, P1_AWS-vpn1-T2
C 169.254.218.34/32 is directly connected, P1_AWS-vpn1-T2
C 169.254.244.156/30 is directly connected, P1_AWS-vpn1-T1
C 169.254.244.158/32 is directly connected, P1_AWS-vpn1-T1
S 192.168.0.0/16 [10/0] is directly connected, P1_IPSEC_RTX
C 192.168.0.0/24 is directly connected, internal1
FGT60D #
疎通確認と障害試験
疎通確認
続けてオンプレの環境からpingとssh確認をします。
C:\Users\ktrwa>ping 10.1.1.100
10.1.1.100 に ping を送信しています 32 バイトのデータ:
10.1.1.100 からの応答: バイト数 =32 時間 =20ms TTL=253
10.1.1.100 からの応答: バイト数 =32 時間 =19ms TTL=253
10.1.1.100 からの応答: バイト数 =32 時間 =15ms TTL=253
10.1.1.100 からの応答: バイト数 =32 時間 =14ms TTL=253
10.1.1.100 の ping 統計:
パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
最小 = 14ms、最大 = 20ms、平均 = 17ms
C:\Users\ktrwa>
障害試験
AWSのSite-to-Site VPNは先述の通りTunnelを2本張ってBGPでルーティングさせています。そのため、片方のTunnelが落ちてももう片方のTunnelで通信が継続するはずです。
早速ですが、Tunnel1のインタフェースをdownさせ疑似障害を発生させ通信が継続するか確認します。
FGT60D # config system interface
<省略>
FGT60D (interface) #
FGT60D (interface) # edit "P1_AWS-vpn1-T1"
FGT60D (P1_AWS-vpn1-T1) # set status down
FGT60D (P1_AWS-vpn1-T1) # end
FGT60D #
ルーティングテーブルを参照すると、10.1.0.0/16のルート情報はBGPで学習していますが、出力インタフェースが「P1_AWS-vpn1-T2」となり、Tunnel2になっています。(先ほどの正常時「P1_AWS-vpn1-T1」でTunnel1でした)
FGT60D # get router info routing-table all
Routing table for VRF=0
Codes: K - kernel, C - connected, S - static, R - RIP, B - BGP
O - OSPF, IA - OSPF inter area
N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
E1 - OSPF external type 1, E2 - OSPF external type 2
i - IS-IS, L1 - IS-IS level-1, L2 - IS-IS level-2, ia - IS-IS inter area
* - candidate default
S* 0.0.0.0/0 [5/0] via 61.26.71.129, wan1
B 10.1.0.0/16 [20/100] via 169.254.218.33, P1_AWS-vpn1-T2, 00:01:05
C 61.26.71.128/25 is directly connected, wan1
C 169.254.218.32/30 is directly connected, P1_AWS-vpn1-T2
C 169.254.218.34/32 is directly connected, P1_AWS-vpn1-T2
S 192.168.0.0/16 [10/0] is directly connected, P1_IPSEC_RTX
C 192.168.0.0/24 is directly connected, internal1
FGT60D #
一応、AWSのSite-to-Site VPNで状態を確認したところ、片側はDown状態であることが確認できます。
この状態で、オンプレのクライアントからpingとsshで疎通確認をしてみると問題ありません。
C:\Users\ktrwa>ping 10.1.1.100
10.1.1.100 に ping を送信しています 32 バイトのデータ:
10.1.1.100 からの応答: バイト数 =32 時間 =17ms TTL=253
10.1.1.100 からの応答: バイト数 =32 時間 =18ms TTL=253
10.1.1.100 からの応答: バイト数 =32 時間 =17ms TTL=253
10.1.1.100 からの応答: バイト数 =32 時間 =16ms TTL=253
10.1.1.100 の ping 統計:
パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
最小 = 16ms、最大 = 18ms、平均 = 17ms
C:\Users\ktrwa>
以上で片方のTunnelが落ちても通信が問題ないことが確認できました。(当然ではありますがFortigate側のインターネット回線が落ちてしまった場合はTunnel1も2も落ちるため通信不可となります。)
まとめ
以上がSite-to-Site VPNを使った構築手順でした。AWS側のGUIが非常にわかりやすく作られており、エンタープライズ系の製品にてVPNを設計したことのある方ならすぐにでも構築ができると思います。また、サンプルコンフィグをダウンロードすることでカスタマーの負荷を減らし工数の削減に繋がるつくりになっておりオンプレ側の方も非常に簡単に構築ができました。
今後は別の記事にてトランジットゲートウェイの構築や今回構築したVPNとの連携なども記事にしていこうと思います。
ディスカッション
コメント一覧
まだ、コメントがありません