本文IPsec部分参考 sqzhao 的CSDN 博客 ,原文地址请点击:https://blog.csdn.net/sqzhao/article/details/76093994?utm_source=copy
一、方案背景
两台centos7服务器构建安全的VPN通道实现内网互通,IPsec接收端需要有弹性IP且安全组放通发起端的UDP500和UDP4500端口。
二、IP规划
接收端:
IPsec地址:192.168.255.31/32,GRE地址:192.168.254.1/30
发起端:
IPsec地址:192.168.255.28/32,GRE地址:192.168.254.2/30
三、部署IPsec
3.1、安装所需软件
yum install epel-release
yum install strongswan openssl iproute iptables
3.2、生成证书(在接收端生成,将client.cert.p12复制到发起端)
export PUBLIC_IP=x.x.x.x # 这里换成接收端的公网IP
mkdir -p /usr/local/ipsec && cd /usr/local/ipsec/
strongswan pki --gen --outform pem > ca.pem
strongswan pki --self --in ca.pem --dn "C=CN, O=VPN, CN=strongSwan CA" --ca --lifetime 3652 \
--outform pem > ca.cert.pem
strongswan pki --gen --outform pem > server.pem
strongswan pki --pub --in server.pem | strongswan pki --issue --lifetime 3652 --cacert ca.cert.pem \
--cakey ca.pem --dn "C=CN, O=VPN, CN=${PUBLIC_IP}" --san="${PUBLIC_IP}" \
--flag serverAuth --flag ikeIntermediate --outform pem > server.cert.pem
strongswan pki --gen --outform pem > client.pem
strongswan pki --pub --in client.pem | strongswan pki --issue --lifetime 3652 --cacert ca.cert.pem \
--cakey ca.pem --dn "C=CN, O=VPN, CN=strongSwan Client" --outform pem > client.cert.pem
openssl pkcs12 -export -inkey client.pem -in client.cert.pem -name "strongSwan Client" \
-certfile ca.cert.pem -caname "strongSwan CA" -out client.cert.p12
# Export Password: ###输入私钥密码,这里的密码需要配置到发起端ipsec.secrets文件里
3.3、copy证书到对应文件夹(client.cert.p12是由上一步接收端生成的,直接copy过来)
# 接收端证书
cp -r ca.cert.pem /etc/strongswan/ipsec.d/cacerts/
cp -r server.cert.pem /etc/strongswan/ipsec.d/certs/
cp -r server.pem /etc/strongswan/ipsec.d/private/
cp -r client.cert.pem /etc/strongswan/ipsec.d/certs/
cp -r client.pem /etc/strongswan/ipsec.d/private/
# 发起端证书
cp -r client.cert.p12 /etc/strongswan/ipsec.d/private/
3.4、接收端配置文件和密码文件
cat >strongswan.conf <<EOF
# strongswan.conf - strongSwan configuration file
#
# Refer to the strongswan.conf(5) manpage for details
#
# Configuration changes should be made in the included files
charon {
load_modular = yes
duplicheck.enable = no
compress = yes
plugins {
include strongswan.d/charon/*.conf
}
dns1 = 8.8.8.8
}
include strongswan.d/*.conf
EOF
cat > ipsec.conf << EOF
# ipsec.conf - strongSwan IPsec configuration file
# basic configuration
config setup
# strictcrlpolicy=yes
uniqueids = never
# Add connections here.
conn %default
left=%any
leftsubnet=192.168.255.31/32
right=%any
rightsourceip=192.168.255.28/32
dpdaction=clear
conn IKEv2-CERT
keyexchange=ikev2
leftauth=pubkey
leftcert=server.cert.pem
rightauth=pubkey
rightcert=client.cert.pem
auto=start
EOF
cat >ipsec.secrets <<EOF
# ipsec.secrets - strongSwan IPsec secrets file
: RSA server.pem
: PSK "12345678"
stone : XAUTH "PCeva2016"
stone : EAP “PCeva2016"
EOF
cp -r strongswan.conf ipsec.conf ipsec.secrets /etc/strongswan/
3.5、发起端配置文件和加密文件
cat > strongswan.conf <<EOF
# strongswan.conf - strongSwan configuration file
#
# Refer to the strongswan.conf(5) manpage for details
#
# Configuration changes should be made in the included files
charon {
load_modular = no
plugins {
include strongswan.d/charon/*.conf
resolve {
file = /etc/resolv.conf
}
}
}
include strongswan.d/*.conf
EOF
cat > ipsec.conf <<EOF
# ipsec.conf - strongSwan IPsec configuration file
# basic configuration
config setup
# strictcrlpolicy=yes
uniqueids = never
# Add connections here.
conn %default
dpdaction=clear
conn rw
keyexchange=ikev2
left=%any
leftsourceip=%config
leftauth=pubkey
leftid="C=CN, O=VPN, CN=strongSwan Client"
right=${PUBLIC_IP}
rightid="C=CN, O=VPN, CN=${PUBLIC_IP}"
rightsubnet=192.168.255.31/32
rightauth=pubkey
auto=start
EOF
cat > ipsec.secrets <<EOF
# ipsec.secrets - strongSwan IPsec secrets file
: P12 client.cert.p12 "admin" # 这里的admin是3.2里输入的密码
: PSK "12345678"
stone : XAUTH "PCeva2016"
stone : EAP “PCeva2016"
EOF
cp -f ipsec.conf ipsec.secrets strongswan.conf /etc/strongswan/
3.6、启动strongswan并检查IPsec状态
strongswan start/restart/stop
strongswan status
# 正常输出:
Security Associations (1 up, 0 connecting):
IKEv2-CERT[11]: ESTABLISHED 2 hours ago, 172.31.28.1[C=CN, O=VPN, CN=x.x.x.x]...x.x.x.x[C=CN, O=VPN, CN=strongSwan Client]
IKEv2-CERT{40}: INSTALLED, TUNNEL, reqid 10, ESP in UDP SPIs: cc60cb68_i c56c711e_o
IKEv2-CERT{40}: 192.168.255.31/32 === 192.168.255.28/32
ip address ls eth0
# 正常输出:
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc pfifo_fast state UP qlen 1000
link/ether 06:b3:38:c9:2f:5f brd ff:ff:ff:ff:ff:ff
inet 172.31.28.1/20 brd 172.31.31.255 scope global dynamic eth0
valid_lft 2973sec preferred_lft 2973sec
inet 192.168.255.31/32 scope global eth0
valid_lft forever preferred_lft forever
ping 192.168.255.28 -c 1
ping 192.168.255.31 -c 1
四、GRE配置和路由配置(另一端的GRE配置互换IP即可)
#!/bin/bash
remote_ipsec=192.168.255.31
local_ipsec=192.168.255.28
remote_gre=192.168.254.1
local_gre=192.168.254.2
gre_mask=30
remote_subnets=(172.31.0.0/16) # 数组中每个子网用空格隔开
strongswan status
ping -c 1 -W 1 ${remote_ipsec} &>/dev/null
if [ $? -eq 0 ];then
echo ">>>ipsec ok"
echo ">>>start add gre tunnel"
modprobe ip_gre
ip tunnel del tunnel0
ip tunnel add tunnel0 mode gre remote ${remote_ipsec} local ${local_ipsec}
ip link set tunnel0 up mtu 1400
ip address add ${local_gre}/${gre_mask} peer ${remote_gre}/${gre_mask} dev tunnel0
# ip route add ${remote_subnet} via ${remote_gre} dev tunnel0
ping -c 1 -W 1 ${remote_gre} &>/dev/null
if [ $? -eq 0 ]; then
echo ">>>gre tunnel ok"
fi
else
echo ">>>ipsec error, exit"
exit 1
fi
echo ">>>start add ip route"
for subnet in ${remote_subnets[@]}
do
ip route add ${subnet} via ${remote_gre} dev tunnel0
done
五、配置VPC路由和NAT
VPC路由表中访问对端内网网段的路由指向本端的ECS主机
隧道内的流量从tunnel0接口进来从eth0出去,转换为eth0的接口IP
接收端NAT:
iptables -t nat -A POSTROUTING -s 172.16.0.0/16 -o eth0 -j SNAT --to 172.18.0.1
iptables -t nat -A POSTROUTING -s 172.17.0.0/16 -o eth0 -j SNAT --to 172.18.0.1
发起端NAT:
iptables -t nat -A POSTROUTING -s 172.18.0.0/16 -o eth0 -j SNAT --to 172.16.0.1