1. VPN介绍
1.1. 什么是VPN
VPN可以通过在L2或L3层建立一条逻辑链路让广域网上多个内网能够相互访问。VPN的实现方式很多,有基于租用专用物理线路实现的(如帧中继和ATM,专用线路贵但QoS好,对语音等对延迟敏感的数据流至关重要,可运行上层的IP,IPX, AppleTalk,IP多播多种协议),也有基于以太网的虚连接的实现方式(不是专用线路,灵活,数据通道不安全要结合如IPSec来保证)分类如下:
- ATM和帧中继都是L2层VPN
- GRE,L2TP,MPLS和IPSec属于L3层VPN技术
GRE VPN:建VPN很方便,但没有安全机制,需结合IPSec来支持身份验证、完整性、访问控制和机密性。
SSL VPN:这种VPN的最大好处在于,仅需要一个单独的TCP或UDP端口便可以轻易穿越大多数防火墙进行数据传送
MPLS VPN:当使用GRE这些遂道技术来实现VPN时,因为是点至点的,当新添一个站点,需修改每个站点的VPN配置。MPLS是在传数据之前就先用L3层的路由机制将L2层的标签在途径的每个路由器上都事先算好了,并且这种标签是自动配置的,所以添加一个新站点很方便
1.2. IPSec VPN
IPSec的使用模式:
- IPSec传输模式:传输过程中IPSec源端点不会修改IP报中的目标IP地址。
- IPSec遂道模式:传输过程中IPSec源端点会修改IP报中的目标IP地址。
在openstack neutron中使用的就是IPSec的遂道模式。
IPSec中的两个重要协议: - AH:它使用消息摘要算法生成一个散列值,包括不变的报头字段(如源IP,目标IP),不同于ESP,不提供机密性,即不加密数据本身,所以不是很有用。计算报头摘要时要排除一些可变字段(如服务类型ToS,标记,分段偏移、存活时间TTL和报头校验和)。关于IPSec与NAT,NAT要发挥作用,它可能要修改IP源地址、目标地址、源端口、目标端口、IP和TCP报头的校验和、TCP序列号和确认号以及有效负载中的IP地址。因为,使用AH时,NAT不可行。
- ESP:ESP协议是在Linux内核(NETEY / XFRM)IPsec中实现的对等体约定策略的实际规范。提供机密性、数据完整性、数据来源验证和反重放功能。对于IPSec传输模式,使用ESP时NAT依然不可行。但在遂道模式下,只要NAT执行1:1的地址转换,不将多个内网地址转换一个外部地址并使用端口来区分它们,NAT和ESP便可以共存。一个最简单的办法就是在IPSec之间执行NAT,但这并非总是可能的,所以有了NAT跨越技术(NAT Traversal, NAT-T),它由三部分组成,首先判断远程peer是否支持NAT跨越,其次是检测peer之间的路径上是否有NAT;最后是决定如何使用UDP封闭来处理NAT。
1.3. IPsec IKE密钥交换协议
Internet 密钥交换(IPsec IKE)是 IPsec 体系结构中的一种主要协议。它是一种混合协议,使用部分 Oakley 和部分 SKEME,并协同 ISAKMP 提供密钥生成材料和其它安全连系,比如用于 IPsec DOI 的 AH 和 ESP 。
IKE协议的目的是认证(使用VPN的预共享密钥,公开密钥加密,自由连接)对等体来动态生成密钥并与VPN对等体共享密钥。 IPsec第二阶段的加密密钥也取决于IKE。 Libreswan使用项目的pluto程序实现IKE协议。
1.4. libreswan 简介
LibreSwan是IPsec协议的开源实现,它基于FreeSwan项目,可以在RedHat的Linux发行版上使用该软件包。关于LibreSwan的IPsec协议的两个部分的简要信息如下所述。
基于IPsec的VPN由Internet密钥交换协议和封装安全有效载荷 (ESP)协议组成。
Libreswan功能
- 支持基于预共享密钥的认证。
- 支持基于公钥的认证。
- 支持IKE v1 / v2版本的密钥交换。
- 支持NSS加密库。
- 还支持Xauth和DNSSec。
2. 环境介绍
2.1. 目的
使用libreswan搭建ipsec点对点隧道实现两IDC内网网段互通,或者实现物理机网络与云平台内部网络直接互通。
2.2. 部署架构图
环境:
IDC-物理区域:
内网网段: 192.168.122.0/24
公网ip: 172.19.0.145
主机版本: fedora34
IDC-云平台区域:
内网网段:192.168.1.0/24
公网ip: 172.19.3.107
主机版本: kylin v10
实现云平台区域192.168.1.0/24到物理区域192.168.122.0/24互通
3. 云环境部署(各环境有异)
3.1. 云平台安装部署
参考各个云平台进行部署
3.2. 创建VPN网关
登录云平台,在网络管理->VPN处找到VPN配置项
在页面的右上角,单击“新建网关”
弹出“创建VPN网关”对话框
填写名称“test”,填写描述信息,选择路由“admin”,路由为连接外部网络的路由器
单击确定后创建成功,如下图所示
补充(网络管理->路由器):
路由器信息如下:
进入路由器查看详细信息:
3.3. 创建VPN隧道
创建VPN网关后,切换至“VPN隧道”项,单击“创建VPN隧道”
弹出“创建VPN隧道”对话框,如下图:
填写名称“test”,选择VPN网关“test”,填写对端网关“172.19.0.145”,预共享密钥“abc123123”,mtu为“1500”等,点击“下一步”如下:
在内部网段处选择需要对外互通的“192.168.1.0/24”,对端网段填写“192.168.122.0/24”,点击“下一步”如下:
IKE配置,版本、加密算法、认证算法、有效期、前向安全性等配置保持默认,若要修改,对端相应配置也要保持一致,点击“下一步”如下:
IPsec配置,加密算法、认证算法、报文封装模式、安全协议、有效期、前向安全性等配置保持默认,若要修改,确保与对端相应配置保持一致,点击“确定”如下:
3.4. 查看配置文件
3.4.1. 查看路由器详细信息
查看路由器的详细信息,注意ID如下:
3.4.2. 进入l3容器
生成的配置文件,首先登录网络节点,由于是容器部署,需要进入l3容器里面
docker exec -it -u 0 neutron_l3_agent bash
3.4.3. 进入ipsec配置目录
cd /var/lib/neutron/ipsec/0b97aeea-052e-4eee-ace4-21a39de69045/
3.4.4. 查看secrets配置
3.4.5. 查看ipsec配置
4. 物理环境部署
以下操作基于RHEL/CENTOS/Fedora 系统dnf/yum仓库中提供了libreswan的包
4.1. libreswan安装
sudo dnf install libreswan
4.2. 配置内核参数
在libereswan软件安装中,内置了一下需要修改的内核参数[ /etc/sysctl.d/50-libreswan.conf ]。但这些还不够,ipsec是一个路由协议,需要开启如下参数,切换到超级用户模式下执行:
开启路由转发功能
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
关闭源路由验证
echo "net.ipv4.conf.all.rp_filter = 0" >> /etc/sysctl.d/50-libreswan.conf
echo "net.ipv4.conf.default.rp_filter = 0" >> /etc/sysctl.d/50-libreswan.conf
echo "net.ipv4.conf.eth0.rp_filter = 0" >> /etc/sysctl.d/50-libreswan.conf
关闭icmp重定向
sysctl -a | egrep "ipv4.*(accept|send)_redirects" | awk -F "=" '{print$1"= 0"}' >> /etc/sysctl.d/50-libreswan.conf
加载生效内核参数
sysctl -p && sysctl -p /etc/sysctl.d/50-libreswan.conf
4.3. 启动服务,验证内核配置是否正常
采用sudo或者切换到超级用户模式下执行
systemctl start ipsec
ipsec verify
要确保所有检查都为OK
4.4. 防火墙策略开放udp500 和 udp4500端口
针对 Internet Key Exchange (IKE) 协议的 UDP 端口 500
针对 IKE NAT-Traversal的 UDP 端口 4500
针对 Encapsulated Security Payload (ESP) IPsec 数据包的端口 50
针对 Authenticated Header (AH) IPsec 数据包(非常见)的端口 51
通过netstat -tlunp | grep -E ‘500|4500’查看
保障防火墙关闭或者开通udp500 和udp4500 策略
关闭防火墙systemctl status firewalld
或者开启防火墙状态下配置放行规则如下:
firewall-cmd --add-port={4500,500}/udp --permanent
firewall-cmd --add-protocol={50,51} --permanent
firewall-cmd --add-service=ipsec --permanent
firewall-cmd --reload
查看是否生效执行如下:
firewall-cmd --query-port={4500,500}/udp
firewall-cmd --query-protocol={50,51}
firewall-cmd --query-service=ipsec
若需要删除端口执行如下:
firewall-cmd --remove-port={4500,500}/udp --permanent
查看当前打开了哪些服务和端口,可指定zone
firewall-cmd --zone=public --list-ports
firewall-cmd --list-services
4.5. 配置预共享密钥
ipsec ike支持 预共享秘钥,证书,x.509 等方式验证,在这里我们使用预共享秘钥
可以直接配置在/etc/ipsec.secrets中或者新建一个文件比如/etc/ipsec.d/test.secrets
内容如下:
源ip 目的ip : PSK “key” (0.0.0.0 所有ip)
0.0.0.0 0.0.0.0 : PSK "abc123123"
或者
172.19.0.145 172.19.3.107 : PSK "abc123123"
我们使用abc123123作为我们的连接的密钥,若写成0.0.0.0则表示作为所有连接的密钥
4.6. 配置ipsec连接
4.6.1. 主配置
cat /etc/ipsec.conf
# /etc/ipsec.conf - Libreswan 4.0 configuration file
#
# see 'man ipsec.conf' and 'man pluto' for more information
#
# For example configurations and documentation, see https://libreswan.org/wiki/
config setup
# If logfile= is unset, syslog is used to send log messages too.
# Note that on busy VPN servers, the amount of logging can trigger
# syslogd (or journald) to rate limit messages.
logfile=/var/log/pluto.log
#
# Debugging should only be used to find bugs, not configuration issues!
# "base" regular debug, "tmi" is excessive (!) and "private" will log
# sensitive key material (not available in FIPS mode). The "cpu-usage"
# value logs timing information and should not be used with other
# debug options as it will defeat getting accurate timing information.
# Default is "none"
# plutodebug="base"
# plutodebug="tmi"
plutodebug="none"
#
# Some machines use a DNS resolver on localhost with broken DNSSEC
# support. This can be tested using the command:
# dig +dnssec DNSnameOfRemoveServer
# If that fails but omitting '+dnssec' works, the system's resolver is
# broken and you might need to disable DNSSEC.
# dnssec-enable=no
#
# To enable IKE and IPsec over TCP for VPN server. Requires at least
# Linux 5.7 kernel. For TCP support as a VPN client, specify
# tcp-remote-port=4500 in the client conn section.
# listen-tcp=yes
virtual_private=%v4:192.168.1.0/24,%v4:192.168.122.0/24
# if it exists, include system wide crypto-policy defaults
include /etc/crypto-policies/back-ends/libreswan.config
# It is best to add your IPsec connections as separate files
# in /etc/ipsec.d/
include /etc/ipsec.d/*.conf
4.6.2. 创建连接配置
可配置在 /etc/ipsec.conf或者/etc/ipsec.d/test.conf
conn 4e82e2aa-9ac1-4ecd-9e1f-c503cce75585
# NOTE: a default route is required for %defaultroute to work...
leftnexthop=%defaultroute
rightnexthop=%defaultroute
left=172.19.0.145
leftid=172.19.0.145
auto=start
# NOTE:REQUIRED
# [subnet]
leftsubnet=192.168.122.0/24
# [updown]
# What "updown" script to run to adjust routing and/or firewalling when
# the status of the connection changes (default "ipsec _updown").
# "--route yes" allows to specify such routing options as mtu and metric.
leftupdown="ipsec _updown --route yes"
######################
# ipsec_site_connections
######################
# [peer_address]
right=172.19.3.107
# [peer_id]
rightid=172.19.3.107
# [peer_cidrs]
rightsubnets={ 192.168.1.0/24 }
# rightsubnet=networkA/netmaskA, networkB/netmaskB (IKEv2 only)
# [mtu]
mtu=1500
# [dpd_action]
dpdaction=hold
# [dpd_interval]
dpddelay=30
# [dpd_timeout]
dpdtimeout=120
# [auth_mode]
authby=secret
######################
# IKEPolicy params
######################
#ike version
ikev2=never
# [encryption_algorithm]-[auth_algorithm]-[pfs]
ike=aes128-sha1;modp1536
# [lifetime_value]
ikelifetime=3600s
# NOTE: it looks lifetime_units=kilobytes can't be enforced (could be seconds, hours, days...)
##########################
# IPsecPolicys params
##########################
# [transform_protocol]
phase2=esp
# [encryption_algorithm]-[auth_algorithm]-[pfs]
phase2alg=aes128-sha1;modp1536
# [encapsulation_mode]
type=tunnel
# [lifetime_value]
lifetime=3600s
# lifebytes=100000 if lifetime_units=kilobytes (IKEv2 only)
4.6.3. 重启两端服务建立ipsec隧道
systemctl restart ipsec && tailf /var/log/pluto.log
发现日志中“IPsec SA established tunnel mode”则为隧道建立成功
5. 验证
通过相互之间互ping来验证是否成功,若ping不通,考虑防火墙规则是否设置正确、或者关闭,若虚拟机在云环境中,确保安全组已经开通放行
6. 参考文献
https://blog.csdn.net/weixin_43423965/article/details/105071519
https://lingxiankong.github.io/2013-11-21-VPNaaS.html