Akamai's cloud computing servicesのグローバルネットワークについて
Akamai's cloud computing servicesの各リージョン間にはAkamai Global Networkが構築されており、ほぼすべてのリージョンがこの経路を利用して通信することができます。
実際に通信する際には、各リージョンで作成したVLAN内のインスタンスから別リージョンに接続する際にPublicIP経由でアクセスする必要があります。
しかし、通信を暗号化させた状態で通信させたい要件がある際には経路を安全に確保する必要があります。
今回はリージョン間の通信をVPNで接続し、冗長性を保てる構成で接続する構成を紹介します。
本構成図は以下となります。
本構成で利用するオープンソースのソフトウェアについて
本構成を実現するために、いくつかのオープンソースのソフトウェアを利用しています。
- 安全な通信経路を確立するために、strongSwanを利用。
- 経路を冗長化するために、FRRoutingを利用。
- ゲートウェイを冗長化するために、Keepalivedを利用。
strongSwan とは
strongSwanはLinuxカーネル上で動作するIPsecを実装できるVPNソリューションです。IKEv1とIKEv2をサポートしており、エンドツーエンドのセキュアな通信を提供することができます。
FRRouting とは
Free Range Routing(FRR)は、Quaggaから派生したUNIX/Linuxプラットフォーム上で動作するルーティングプロトコルを管理するソリューションです。
BGP/OSPF/RIP/MPLSなどのさまざまなルーティングプロトコルを実装しており、Cisco独自のEIGRPもサポートしています。
Keepalivedとは
KeepalivedはLinux上で動作するオープンソースソフトウェアで、サービスの高可用性とロードバランシングを提供します。Linux Virtual Serverを用いたレイヤー4ロードバランシングと、VRRPを利用した冗長化を実現し、サービスのダウンタイムを最小に抑えることができます。
Akamai's cloud computing servicesの2つのリージョンを接続する
今回の手順に関しては、シンガポールとUS アトランタのリージョンを接続する構成です。
インスタンスの構築
今回、疎通確認用のインスタンスとVPN/ルーティング用のインスタンスは、Linode 4 GBで作成します。
OSはUbuntu 22.04 LTSを利用しています。
各インスタンスを起動したらPublic IP Addressを控えておきます。
また、同一リージョン内にあるインスタンスからの疎通を実現するため、VLANインターフェイスを追加します。
strongSwanのインストール
4台あるVPNインスタンスにstrongSwanをインストールします。
apt update
apt install strongswan
ipsec.confを設定し、トンネルインターフェースの設定をします。
root@localhost:~# vim /etc/ipsec.conf
config setup
charondebug="all"
uniqueids=yes
strictcrlpolicy=no
conn TUNNEL1
auto=start
compress=no
type=tunnel
leftsubnet=0.0.0.0/0,::/0
rightsubnet=0.0.0.0/0,::/0
authby=secret
keyexchange=ikev2
fragmentation=yes
ike=aes256-sha1-modp1024!
esp=aes256-sha1!
ikelifetime=28800s
lifetime=3600s
dpdaction=restart
dpddelay=60s
dpdtimeout=120s
closeaction=none
rekey=yes
installpolicy=yes
leftupdown=/etc/ipsec-vti.sh
left=<自身のLinode Public IP>
right=<対向のLinode Public IP>
mark=101
認証にPSK: Pre-Shared Keyを利用するため、ランダムな文字列を発行します。
root@localhost:~# openssl rand -base64 32
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
発行したランダムな文字列をipsec.secretsに保存します。
root@localhost:~# vim /etc/ipsec.secrets
<自身のLinode Public IP> <対向のLinode Public IP> : PSK "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
トンネルインターフェースUP/DOWNの際に動作するスクリプトを記載します。
root@localhost:~# vim /etc/ipsec-vti.sh
#!/bin/bash
#
# /etc/ipsec-vti.sh
#
IP=$(which ip)
IPTABLES=$(which iptables)
PLUTO_MARK_OUT_ARR=(${PLUTO_MARK_OUT//// })
PLUTO_MARK_IN_ARR=(${PLUTO_MARK_IN//// })
case "$PLUTO_CONNECTION" in
TUNNEL1)
VTI_INTERFACE=vti1
VTI_LOCALADDR=169.254.0.2/30 # 各インスタンスの自身のIPを入れてください
VTI_REMOTEADDR=169.254.0.1/30 # 各インスタンスの対向のIPを入れてください
;;
esac
# output parameters to /var/log/syslog for debug
logger "ipsec-vti.sh: ================================================="
logger "ipsec-vti.sh: PLUTO_CONNECTION = ${PLUTO_CONNECTION}"
logger "ipsec-vti.sh: PLUTO_VERB = ${PLUTO_VERB}"
logger "ipsec-vti.sh: VTI_INTERFACE = ${VTI_INTERFACE}"
logger "ipsec-vti.sh: PLUTO_ME = ${PLUTO_ME}"
logger "ipsec-vti.sh: PLUTO_PEER = ${PLUTO_PEER}"
logger "ipsec-vti.sh: PLUTO_MARK_IN_ARR[0] = ${PLUTO_MARK_IN_ARR[0]}"
logger "ipsec-vti.sh: PLUTO_MARK_OUT_ARR[0] = ${PLUTO_MARK_OUT_ARR[0]}"
logger "ipsec-vti.sh: PLUTO_MARK_IN = ${PLUTO_MARK_IN}"
logger "ipsec-vti.sh: VTI_LOCALADDR = ${VTI_LOCALADDR}"
logger "ipsec-vti.sh: VTI_REMOTEADDR = ${VTI_REMOTEADDR}"
logger "ipsec-vti.sh: ================================================="
case "${PLUTO_VERB}" in
up-client)
$IP link add ${VTI_INTERFACE} type vti local ${PLUTO_ME} remote ${PLUTO_PEER} okey ${PLUTO_MARK_OUT_ARR[0]} ikey ${PLUTO_MARK_IN_ARR[0]}
sysctl -w net.ipv4.conf.${VTI_INTERFACE}.disable_policy=1
sysctl -w net.ipv4.conf.${VTI_INTERFACE}.rp_filter=2 || sysctl -w net.ipv4.conf.${VTI_INTERFACE}.rp_filter=0
$IP addr add ${VTI_LOCALADDR} remote ${VTI_REMOTEADDR} dev ${VTI_INTERFACE}
$IP link set ${VTI_INTERFACE} up mtu 1436
$IPTABLES -t mangle -I FORWARD -o ${VTI_INTERFACE} -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
$IPTABLES -t mangle -I INPUT -p esp -s ${PLUTO_PEER} -d ${PLUTO_ME} -j MARK --set-xmark ${PLUTO_MARK_IN}
$IP route flush table 220
;;
down-client)
$IP link del ${VTI_INTERFACE}
$IPTABLES -t mangle -D FORWARD -o ${VTI_INTERFACE} -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
$IPTABLES -t mangle -D INPUT -p esp -s ${PLUTO_PEER} -d ${PLUTO_ME} -j MARK --set-xmark ${PLUTO_MARK_IN}
;;
esac
# Enable IPv4 forwarding
sysctl -w net.ipv4.ip_forward=1
sysctl -w net.ipv4.conf.eth0.disable_xfrm=1
sysctl -w net.ipv4.conf.eth0.disable_policy=1
sysctl -w net.ipv4.conf.eth1.disable_xfrm=1
sysctl -w net.ipv4.conf.eth1.disable_policy=1
実行権限を付与します。
chmod +x /etc/ipsec-vti.sh
サービスを起動します。
systemctl start strongswan-starter.service
systemctl enable strongswan-starter.service
トンネルがUPになっており、接続先へICMPの疎通が取れることを確認します。
root@localhost:~# ipsec status
Security Associations (1 up, 0 connecting):
TUNNEL1[35]: ESTABLISHED 110 minutes ago, 139.162.23.72[139.162.23.72]...23.239.17.252[23.239.17.252]
TUNNEL1{36}: INSTALLED, TUNNEL, reqid 1, ESP SPIs: c4672a30_i c4020d9c_o
TUNNEL1{36}: 0.0.0.0/0 ::/0 === 0.0.0.0/0 ::/0
root@localhost:~# ip addr show vti1
324: vti1@NONE: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1436 qdisc noqueue state UNKNOWN group default qlen 1000
link/ipip 139.162.23.72 peer 23.239.17.252
inet 169.254.0.2 peer 169.254.0.1/30 scope global vti1
valid_lft forever preferred_lft forever
inet6 fe80::200:5efe:8ba2:1748/64 scope link
valid_lft forever preferred_lft forever
root@localhost:~# ping 169.254.0.1
PING 169.254.0.1 (169.254.0.1) 56(84) bytes of data.
64 bytes from 169.254.0.1: icmp_seq=1 ttl=64 time=208 ms
64 bytes from 169.254.0.1: icmp_seq=2 ttl=64 time=208 ms
64 bytes from 169.254.0.1: icmp_seq=3 ttl=64 time=208 ms
^C
--- 169.254.0.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2001ms
rtt min/avg/max/mdev = 207.895/207.947/208.039/0.065 ms
strongSwanの設定は完了です。
FRRoutingのインストール
4台あるVPNインスタンスにFRRoutingをインストールし、BGPによる動的ルーティングを構築します。
sudo apt install frr
BGPを有効化します。
sudo sed -i.org 's/bgpd=no/bgpd=yes/' /etc/frr/daemons
サービスを再起動します。
sudo systemctl restart frr
sudo systemctl enable frr
コンソールにログインし、BGPの設定を行います。
コメントが記載されている行を各インスタンスの値に合わせて設定してください。
vtysh
Hello, this is FRRouting (version 8.1).
Copyright 1996-2005 Kunihiro Ishiguro, et al.
localhost# conf t
localhost(config)#
! AS番号は各インスタンスの値を設定
router bgp 65001
bgp log-neighbor-changes
no bgp ebgp-requires-policy
bgp graceful-restart
timers bgp 3 9
! 同リージョン内のVPNインスタンスのIPとASを設定
neighbor 10.0.1.101 remote-as 65001
! 対向リージョンのVPNインスタンスのIPとASを設定
neighbor 169.254.0.1 remote-as 65000
!
address-family ipv4 unicast
! 経路を伝搬するネットワークを設定
network 10.0.1.0/24
! 同リージョン内のVPNインスタンスのIPを設定
neighbor 10.0.1.101 next-hop-self
! 同リージョン内のVPNインスタンスのIPを設定
neighbor 10.0.1.101 soft-reconfiguration inbound
! 対向リージョンのVPNインスタンスのIPを設定
neighbor 169.254.0.1 soft-reconfiguration inbound
exit-address-family
exit
!
end
BGPの接続が行えていることを確認します。
localhost# show ip bgp summary
IPv4 Unicast Summary (VRF default):
BGP router identifier 139.162.23.72, local AS number 65001 vrf-id 0
BGP table version 631
RIB entries 3, using 552 bytes of memory
Peers 2, using 1446 KiB of memory
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd PfxSnt Desc
10.0.1.101 4 65001 37292 34317 0 0 0 1d03h38m 2 2 N/A
169.254.0.1 4 65000 39545 39558 0 0 0 02:05:45 1 2 N/A
Total number of neighbors 2
BGPの経路が学習できていることを確認します。
localhost# show ip route bgp
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
f - OpenFabric,
> - selected route, * - FIB route, q - queued, r - rejected, b - backup
t - trapped, o - offload failure
B>* 10.0.2.0/24 [20/0] via 169.254.0.1, vti1, weight 1, 02:05:46
設定を保存します。
localhost# write memory
Note: this version of vtysh never writes vtysh.conf
Building Configuration...
Integrated configuration saved to /etc/frr/frr.conf
[OK]
以上でFRRoutingのインストールは完了です。
Keepalivedのインストール
4台あるVPNインスタンスにKeepalivedをインストールし、ゲートウェイを冗長化します。
sudo apt install keepalived
同リージョン内のVPNインスタンスの片方をMaster側に設定します。
root@localhost:~# vim /etc/keepalived/keepalived.conf
vrrp_instance Instance1 {
state MASTER
interface eth1
virtual_router_id 10
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass password
}
virtual_ipaddress {
10.0.1.201←VLAN内で利用していないIPを設定
}
}
同リージョン内のVPNインスタンスのもう片方をBackup側に設定します。
root@localhost:~# vim /etc/keepalived/keepalived.conf
vrrp_instance Instance2 {
state BACKUP
interface eth1
virtual_router_id 10
priority 99
advert_int 1
authentication {
auth_type PASS
auth_pass password
}
virtual_ipaddress {
10.0.1.201←VLAN内で利用していないIPを設定
}
}
Config Testを行い、何も出力されないことを確認します。(異常がある場合のみ出力されます)
keepalived --config-test
サービスを起動します。
systemctl start keepalived
systemctl enable keepalived
Masterに設定した側にvirtual_ipaddressが付与されていることを確認します。
root@localhost:~# ip addr show eth1
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 90:de:01:3d:72:5b brd ff:ff:ff:ff:ff:ff
inet 10.0.1.10/24 brd 10.0.1.255 scope global eth1
valid_lft forever preferred_lft forever
inet 10.0.1.201/32 scope global eth1
valid_lft forever preferred_lft forever
inet6 fe80::92de:1ff:fe3d:725b/64 scope link
valid_lft forever preferred_lft forever
ICMPインスタンスの設定
疎通確認を行うためのインスタンスに経路の追加設定を行います。
Network設定の書き換えを行うため、上書きされないようにAuto-configure networkingを無効にします。
無効にした後に設定を追記します。
vim /etc/systemd/network/05-eth1.network
[Route]
Destination=10.0.2.0/24←対向のネットワークを記載
Gateway=10.0.1.201←Keepalivedで設定した同リージョン内のIPを記載
設定を反映させます。
netplan apply
通信確認
対向の疎通確認用インスタンスにICMPが通るか確認をします。
root@localhost:~# ping 10.0.1.5
PING 10.0.1.5 (10.0.1.5) 56(84) bytes of data.
64 bytes from 10.0.1.5: icmp_seq=1 ttl=62 time=213 ms
64 bytes from 10.0.1.5: icmp_seq=2 ttl=62 time=211 ms
64 bytes from 10.0.1.5: icmp_seq=3 ttl=62 time=212 ms
64 bytes from 10.0.1.5: icmp_seq=4 ttl=62 time=211 ms
64 bytes from 10.0.1.5: icmp_seq=5 ttl=62 time=212 ms
64 bytes from 10.0.1.5: icmp_seq=6 ttl=62 time=212 ms
64 bytes from 10.0.1.5: icmp_seq=7 ttl=62 time=213 ms
64 bytes from 10.0.1.5: icmp_seq=8 ttl=62 time=211 ms
^C
--- 10.0.1.5 ping statistics ---
8 packets transmitted, 8 received, 0% packet loss, time 7002ms
rtt min/avg/max/mdev = 211.332/211.946/212.941/0.650 ms
今回は速度の測定も実施しています。
root@localhost:~# iperf3 -c 10.0.1.5
Connecting to host 10.0.1.5, port 5201
[ 5] local 10.0.2.5 port 50990 connected to 10.0.1.5 port 5201
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-1.00 sec 393 KBytes 3.22 Mbits/sec 0 108 KBytes
[ 5] 1.00-2.00 sec 5.89 MBytes 49.4 Mbits/sec 0 3.04 MBytes
[ 5] 2.00-3.00 sec 12.5 MBytes 105 Mbits/sec 0 6.01 MBytes
[ 5] 3.00-4.00 sec 13.8 MBytes 115 Mbits/sec 0 6.01 MBytes
[ 5] 4.00-5.00 sec 12.5 MBytes 105 Mbits/sec 0 6.01 MBytes
[ 5] 5.00-6.00 sec 13.8 MBytes 115 Mbits/sec 0 6.01 MBytes
[ 5] 6.00-7.00 sec 13.8 MBytes 115 Mbits/sec 0 6.01 MBytes
[ 5] 7.00-8.00 sec 13.8 MBytes 115 Mbits/sec 0 6.01 MBytes
[ 5] 8.00-9.00 sec 13.8 MBytes 115 Mbits/sec 0 6.01 MBytes
[ 5] 9.00-10.00 sec 13.8 MBytes 115 Mbits/sec 0 6.01 MBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 114 MBytes 95.4 Mbits/sec 0 sender
[ 5] 0.00-10.21 sec 113 MBytes 92.8 Mbits/sec receiver
アトランタからシンガポールリージョンの速度は100Mbpsほど出ていることがわかりました。
まとめ
今回の構成ではアトランタからシンガポールリージョンを接続しましたが、接続先を増やしていくことで、3リージョン、4リージョンと接続数を増やしていくことが可能です。
高可用性が求められるリージョン間通信などでのユースケース等に利用していただければと思います。
関連記事
アカマイ・テクノロジーズ合同会社はQiitaでAkamai's cloud computing services関連など開発者向けの記事を掲載しております。