[AWS] Site-to-Site VPN 구성하기
aws workshop studio의 [PRD] 2024 ConntectX for Partners - Hybrid Network using AWS VPN의 lab을 정리한 내용이다.
시나리오는 다음과 같다.
AnyCompany는 현재 서울에 본사(headquater, HQ)를 두고있으며 On-prem IDC 또한 서울에 위치하여 사용하고 있습니다.
1) 클라우드 워크로드의 도입으로 인하여 AWS로의 마이그레이션이 이루어지고 있지만 여전히 IDC의 몇몇 데이터 및 워크로드가 필요합니다.
2) 또한, 브라질 상파울루 오피스와의 안정적인 네트워크 연결이 필요하나, 물리적으로 매우 먼 거리와 현지 공인망의 불안정성으로 인하여 네트워크 상황이 불안정합니다.
3) 최근 팬데믹 시기를 지나며, 원격 및 재택 근무자가 늘어나 IDC로의 안전한 접근 뿐 아니라, AWS 워크로드로의 안전한 접속이 필요합니다.
서울 리전에 위 사진과 같이 HQ의 AWS VPC에 Transit Gateway가 배포되어있으며, on-premise IDC를 시뮬레이션한 환경에 CGW(Customer Gateway)가 구성이되어있다.
두 네트워크 사이에 Site-to-Site VPN을 구성한다.
Transit Gateway Attachment 생성하기
서울 리전에 TGW는 생성이 되어있으며, HQ-AWS-VPC와의 attachment도 이미 설정이 되어있다.
HQ-IDC와 TGW의 attachment를 생성해야한다.
1. VPC 콘솔의 VPC -> Transit Gateway -> Transit gateway attachemnets 메뉴에서 Create transit gateway attachment를 클릭한다.
2. Attachment type을 VPN으로 선택 후, Transit gateway ID의 드롭다운 메뉴를 선택하여
생성되어있는 TGW를 선택한다.
VPN Attachment에서 새로운 CGW와의 연결을 구성할 것이기 때문에 New를 선택한 후
가상의 On-premise 환경의 CGW 공인 IP를 입력해준다.
3. 터널 옵션에 값을 입력 후 생성이 완료되면, Transit Gateway -> Transit gateway route tables 메뉴로 이동하여
Transit Gateway의 default 라우팅 테이블을 선택 후 하단의 Association 탭에서 VPN이 associated 상태인지 확인한다.
위 과정이 모두 수행되면, 아래의 과정이 완료된다.
- 온프레미스의 고객 게이트웨이 디바이스를 나타내는 Customer Gateway를 생성
- HQ-VPC-TGW에 VPN 연결 생성
VPN Connection 확인하기
TGW Attachment를 생성하면서 Attachment type이 VPN이었기 때문에,
이 과정에서 CGW와 VPN 연결이 함께 생성되었다. 생성된 VPN 연결을 확인해보자
1. VPC 콘솔의 VPN -> Site-to-Site VPN connections 메뉴를 클릭 후,
해당 터널을 선택하고 Tunnel Details에서 터널의 IP 정보를 확인한다.
2. Outside IP Address가 온프레미스의 CGW 디바이스에서 IPsec 설정에 필요하므로 메모해둔다.
3. 터널 정보 상단의 Downloads configuration 버튼을 클릭하면, 각 CGW 디바이스 제공업체 별 configuration 파일을 다운로드 받을 수 있다.
4. VPN connection의 상태가 Available이 되면, 추후 모니터링을 위해 Actions > Modify VPN Tunnel Options에서 Tunnel activity log를 활성화해준다.
VPN 터널이 활성화 된 이후에 옵션을 바꾸려면, 5분에서 10분정도의 다운타임이 발생하므로
초기 셋팅에서 로그 기능 활성화를 해주는 것이 좋다.
온프레미스 라우터 설정하기
고객 게이트웨이 디바이스, 혹은 라우터에서 VPN 설정을 해줘야한다.
해당 실습에서는 가상의 라우터를 EC2에 구성을 한 상태다.
다이나믹 라우팅이 가능한 라우터 구성을 위해 사용된 라우터는 다음과 같다.
- StrongSWAN (IPsec)
- Quagga (BGP routing)
1. 온프레미스 고객 게이트웨이 디바이스 서버에 접속을 해준다.
2. 아래 스크립트를 서버에서 생성 후 실행해준다.
#!/bin/bash
#
# StrongSwan(IPSec) + Quaaga (BGP) Setup Script for EC2 Virtual Router
# - 2023/02/23
#
# How to use
# 1. Allocate EIP to EC2 located at public subnet
# 2. Create CGW which is using EIP of EC2 virtual router,
# and then make S2S VPN tunnel connection between TGW and the CGW
# 3. From the VPN tunnel config, get two of Outside IPs and run this script
#
# CGW(EC2 Instance) Eth0
pCgwEth0Ip=$(hostname -i)
pCgwEip=$(curl -s ifconfig.me)
pCgwCidr="`echo $pCgwEth0Ip | cut -d "." -f 1-2`.0.0/16"
# IPSec Tunnel #1 Info
pTu1CgwOutsideIp=$pCgwEip
pTu1CgwInsideIp=169.254.11.2
pTu1VgwInsideIp=169.254.11.1
# IPSec Tunnel #2 Info
pTu2CgwOutsideIp=$pCgwEip
pTu2CgwInsideIp=169.254.12.2
pTu2VgwInsideIp=169.254.12.1
#BGP ASN and PSK Info
pVgwAsn=64512
pCgwAsn=65016
pTuPsk=strongswan_awsvpn
echo "=============================================================="
echo " Let's begin to set up IPSEC/BGP using StrongSWAN and Quagga "
echo "--------------------------------------------------------------"
echo " 0. strongswan and quagga has been installed "
echo "----------------------------------------------------------"
echo " 1. IPSec Info - Input VPN Tunnel Outside IP addresses "
read -p " - Tunnel #1 Outside IP Addr : " pTu1VgwOutsideIp
read -p " - Tunnel #2 Outside IP Addr : " pTu2VgwOutsideIp
echo "----------------------------------------------------------"
echo " 2. BGP Info - ASN numbers are set as below"
echo " - TGW ASN Number (64512-65534) : $pVgwAsn "
echo " - CGW ASN Number (64512-65534) : $pCgwAsn "
echo "=========================================================="
read -p " informations above is correct? If yes, please continue (y/N)? " answer2
echo
if [ "${answer2,,}" != "y" ]
then
exit 100
fi
echo "3. Set IPSEC config on /etc/strongswan/ipsec.conf "
cat <<EOF > /etc/strongswan/ipsec.conf
#
# /etc/strongswan/ipsec.conf
#
conn %default
# Authentication Method : Pre-Shared Key
leftauth=psk
rightauth=psk
# Encryption Algorithm : aes-128-cbc
# Authentication Algorithm : sha1
# Perfect Forward Secrecy : Diffie-Hellman Group 2
ike=aes128-sha1-modp1024!
# Lifetime : 28800 seconds
ikelifetime=28800s
# Phase 1 Negotiation Mode : main
aggressive=no
# Protocol : esp
# Encryption Algorithm : aes-128-cbc
# Authentication Algorithm : hmac-sha1-96
# Perfect Forward Secrecy : Diffie-Hellman Group 2
esp=aes128-sha1-modp1024!
# Lifetime : 3600 seconds
lifetime=3600s
# Mode : tunnel
type=tunnel
# DPD Interval : 10
dpddelay=10s
# DPD Retries : 3
dpdtimeout=30s
# Tuning Parameters for AWS Virtual Private Gateway:
keyexchange=ikev1
rekey=yes
reauth=no
dpdaction=restart
closeaction=restart
leftsubnet=0.0.0.0/0,::/0
rightsubnet=0.0.0.0/0,::/0
leftupdown=/etc/strongswan/ipsec-vti.sh
installpolicy=yes
compress=no
mobike=no
conn TU1
# Customer Gateway
left=${pCgwEth0Ip}
leftid=${pTu1CgwOutsideIp}
# Virtual Private Gateway
right=${pTu1VgwOutsideIp}
rightid=${pTu1VgwOutsideIp}
auto=start
mark=100
conn TU2
# Customer Gateway
left=${pCgwEth0Ip}
leftid=${pTu2CgwOutsideIp}
# Virtual Private Gateway
right=${pTu2VgwOutsideIp}
rightid=${pTu2VgwOutsideIp}
auto=start
mark=200
EOF
echo "4. Set IPSEC config on /etc/strongswan/ipsec.secrets "
cat <<EOF > /etc/strongswan/ipsec.secrets
#
# /etc/strongswan/ipsec.secrets
#
${pTu1CgwOutsideIp} ${pTu1VgwOutsideIp} : PSK ${pTuPsk}
${pTu2CgwOutsideIp} ${pTu2VgwOutsideIp} : PSK ${pTuPsk}
EOF
echo "5. Set IPSEC tunnel options on /etc/strongswan/ipsec-vti.sh "
cat <<EOF > /etc/strongswan/ipsec-vti.sh
#!/bin/bash
#
# /etc/strongswan/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
TU1)
VTI_INTERFACE=vti1
VTI_LOCALADDR=${pTu1CgwInsideIp}/30
VTI_REMOTEADDR=${pTu1VgwInsideIp}/30
;;
TU2)
VTI_INTERFACE=vti2
VTI_LOCALADDR=${pTu2CgwInsideIp}/30
VTI_REMOTEADDR=${pTu2VgwInsideIp}/30
;;
esac
case "\${PLUTO_VERB}" in
up-client)
#\$IP tunnel add \${VTI_INTERFACE} mode vti local \${PLUTO_ME} remote \${PLUTO_PEER} okey \${PLUTO_MARK_OUT_ARR[0]} ikey \${PLUTO_MARK_IN_ARR[0]}
\$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
#/etc/init.d/bgpd reload || /etc/init.d/quagga force-reload bgpd
;;
down-client)
#\$IP tunnel del \${VTI_INTERFACE}
\$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
# Disable IPv4 ICMP Redirect
sysctl -w net.ipv4.conf.eth0.accept_redirects=0
sysctl -w net.ipv4.conf.eth0.send_redirects=0
EOF
sudo chmod +x /etc/strongswan/ipsec-vti.sh
echo "6. Set BGP setting using Quagga /etc/quagga/bgpd.conf "
cat <<EOF > /etc/quagga/bgpd.conf
#
# /etc/quagga/bgpd.conf
#
router bgp ${pCgwAsn}
bgp router-id ${pTu1CgwInsideIp}
neighbor ${pTu1VgwInsideIp} remote-as ${pVgwAsn}
neighbor ${pTu2VgwInsideIp} remote-as ${pVgwAsn}
network ${pCgwCidr}
EOF
echo "7. Start StrongSWAN and Quagga BGP "
sudo systemctl enable --now strongswan
sudo systemctl start zebra
sudo systemctl enable zebra
sudo systemctl start bgpd
sudo systemctl enable bgpd
sudo chmod -R 777 /etc/quagga/
sudo strongswan restart
echo "=========================================================="
echo " Using below command, verify IPSec Tunnel and BGP Routing tables"
echo " -. IPsec status : sudo strongswan statusall "
echo " -. Routing tables : sudo ip route "
echo " -. BGP detail config : Enter teminal mode > sudo vtysh and then > show ip bgp "
echo "=========================================================="
해당 스크립트는 아래의 과정을 자동으로 수행한다.
- VPN Tunnel Outside IP를 입력받는다.
- StrongSWAN을 이용한 IPsec 설정에 필요한 ipsec.conf, ipsec.secrets, ipsec-vti.sh를 /etc/strongswan/에 생성한다.
- IPv4 forwarding을 enable 시킨다.
- Quagga BGP를 설정한다.
- StrongSWAN과 Quagga를 시작한다.
3. 실행이 완료되면 VPN 연결에서 확인한 터널의 Outside IP를 차례대로 입력하고 설정을 시작한다.
4. 명령어를 이용하여 설정이 잘 적용되어있는지 확인한다.
sudo strongswan statusall
스크립트에서 입력한 Outside IP와 IPsec connection을 잘 맺고있는지 확인 할 수 있다.
5. 콘솔로 돌아와 VPN 터널의 status가 모두 up인지 확인한다.
Site-to-Site VPN을 구성함으로써 AWS VPC와 온프레미스 IDC간의 네트워크 연결을 구성하여
AWS 서버에서 IDC의 데이터 및 워크로드를 사용할 수 있게되었다.
'💻 CSP > AWS' 카테고리의 다른 글
[AWS] Client VPN (1) (0) | 2024.02.26 |
---|---|
[AWS] On-Premises와 AWS간의 Hybrid DNS (0) | 2024.02.23 |
[AWS] Site-to-site VPN (0) | 2024.02.21 |
[AWS] profile 확인 (0) | 2024.01.02 |
[AWS Cli] 리전에서 사용가능한 인스턴스 유형 확인하기 (0) | 2023.12.29 |