使用 Quagga NHRPd 的动态多点 VPN (DMVPN) 第 3 阶段

来自 Alpine Linux
此材料建议合并 ...

应与动态多点 VPN (DMVPN)合并。(讨论

此材料正在进行中 ...

在此通知移除之前,请勿遵循此处的说明。
(最后编辑由 Sertonix 于 2023 年 11 月 17 日。)

概述

这是最著名的文档的后续,因为 opennhrp 已被重写为 quagga 插件 [1],支持与新的 Cisco FlexVPN 和 Strongswan 的互操作性。

此 NHRP 实现仍然有一些限制(多播尚未准备就绪,因此您需要使用 BGP 而不是 OSPF),但可在生产环境中使用。

注意:本文档假定所有 Alpine 安装都在无盘模式下运行,并且配置保存在 USB 密钥上


本操作指南将向您展示如何配置具有以下关键项的 DMVPN 解决方案

.1 使用 Strongswan 和 PSK 进行身份验证的 VPN 设置(所有 spoke 和 hub 之间使用相同的 PSK)

.2 使用 quagga.nhrpd 的 DMVPN 设置;

.3 用于宣告 LAN 子网的 iBGP

.4 允许 spoke 之间 NHRP 快捷方式的 Awall 规则


目标是使 spoke 节点的私有网络和 hub 能够通过动态创建的 VPN 相互通信。路由通过 BGP 学习,并且 IPSEC VPN 通过 PSK 验证。

逻辑设置配置如下所示

术语

NBMA
非广播多路访问 网络,如 RFC 2332 中所述
Hub
下一跳服务器 (NHS),在 NBMA 云中执行下一跳解析协议服务。
Spoke
下一跳解析协议客户端 (NHC),它启动各种类型的 NHRP 请求,以便获得对 NHRP 服务的访问。

硬件

为了支持 VIA Padlock 引擎,启用其模块

echo -e "padlock_aes\npadlock-sha" >> /etc/modules


Alpine 安装

按照关于如何创建可启动 USB 的说明进行操作。

Spoke 节点

Spoke 节点 1

网络配置

我们将按如下方式设置 spoke 节点 1


主机名 接口 描述 子网
Spoke 1 eth0 互联网 DHCP
eth1 LAN 192.168.10.0/24
gre1 隧道 172.16.1.1
Spoke 2 eth0 互联网 DHCP
eth1 LAN 192.168.20.0/24
gre1 隧道 172.16.2.1
Spoke 3 eth0 互联网 90.100.150.200
eth1 LAN 192.168.30.0/24
gre1 隧道 172.16.3.1


使用您喜欢的编辑器打开 /etc/network/interfaces 并添加接口

内容 /etc/network/interfaces

auto lo iface lo inet loopback auto eth0 iface eth0 inet dhcp auto eth1 iface eth1 inet static address 192.168.10.1 netmask 255.255.255.0


SSH

移除密码身份验证和 DNS 反向查找

sed -i "s/.PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config sed -i "s/.UseDNS yes/UseDNS no/" /etc/ssh/sshd_config


重启 ssh

rc-service sshd restart

GRE 隧道

使用您喜欢的编辑器打开 /etc/network/interfaces 并添加以下内容

内容 /etc/network/interfaces

auto gre1 iface gre1 inet static pre-up ip tunnel add gre1 mode gre key 42 ttl 64 dev eth0 || true address 172.16.1.1 netmask 255.255.255.255 post-down ip tunnel del $IFACE || true

启动新的 gre1 接口

ifup gre1

IPSEC

安装软件包

apk add strongswan

内容 /etc/swanctl/swanctl.conf

connections { dmvpn { version = 2 pull = no mobike = no dpd_delay = 15 dpd_timeout = 30 fragmentation = yes unique = replace rekey_time = 4h reauth_time = 13h proposals = aes256-sha512-ecp384 local { auth = psk id = spoke1 } remote { auth = psk } children { dmvpn { esp_proposals = aes256-sha512-ecp384 local_ts = dynamic[gre] remote_ts = dynamic[gre] inactivity = 90m rekey_time = 100m mode = transport dpd_action = clear reqid = 1 } } } }


内容 /etc/ipsec.secrets

# /etc/ipsec.secrets - strongSwan IPsec 密钥文件 %any : PSK "cisco12345678987654321"

启动服务

rc-service charon start rc-update add charon


路由

本节将配置使用 NHRP 支持修补的 quagga 路由协议套件。


apk add quagga-nhrp touch /etc/quagga/zebra.conf /etc/quagga/bgpd.conf /etc/quagga/nhrpd.conf

}


修复权限

chown -R quagga:quagga /etc/quagga

}


启动所有守护进程

rc-service zebra start rc-service bgpd start rc-service nhrpd start

配置为从启动时开始运行

rc-update add zebra nhrpd bgpd

现在我们将使用 vtysh cli 进行配置

vtysh configure terminal log syslog debug nhrp common router bgp 65000 bgp router-id 172.16.1.1 network 192.168.10.0/24 neighbor spokes-ibgp peer-group neighbor spokes-ibgp remote-as 65000 neighbor spokes-ibgp ebgp-multihop 1 neighbor spokes-ibgp disable-connected-check neighbor spokes-ibgp advertisement-interval 1 neighbor spokes-ibgp next-hop-self neighbor spokes-ibgp soft-reconfiguration inbound neighbor 172.16.0.1 peer-group spokes-ibgp exit nhrp nflog-group 1 interface gre1 ip nhrp network-id 1 ip nhrp nhs dynamic nbma 50.60.70.80 ip nhrp registration no-unique ip nhrp shortcut ipv6 nd suppress-ra no link-detect tunnel protection vici profile dmvpn tunnel source eth0 exit write mem


Hub 节点

我们将仅记录与 Spoke 节点设置不同的地方。


网络配置

NHS (Hub) 具有以下设置


主机名 接口 描述 子网
Hub eth0 互联网 50.60.70.80
eth1 LAN 192.168.1.0/24


使用您喜欢的编辑器打开 /etc/network/interfaces 并添加接口

内容 /etc/network/interfaces

auto lo iface lo inet loopback auto eth0 iface eth0 inet static address 50.60.70.80 netmask 255.255.255.0 gateway 50.60.70.1 auto eth1 iface eth1 inet static address 192.168.1.1 netmask 255.255.255.0


GRE 隧道

使用您喜欢的编辑器打开 /etc/network/interfaces 并添加以下内容

内容 /etc/network/interfaces

auto gre1 iface gre1 inet static pre-up ip tunnel add gre1 mode gre key 42 ttl 64 dev eth0 || true address 172.16.0.1 netmask 255.255.255.255 post-down ip tunnel del $IFACE || true

启动新的 gre1 接口

ifup gre1


路由

同样,路由直接使用 vtysh 配置

vtysh configure terminal log syslog debug nhrp common router bgp 65000 bgp router-id 172.16.0.1 bgp deterministic-med network 172.16.0.0/16 redistribute nhrp neighbor spokes-ibgp peer-group neighbor spokes-ibgp remote-as 65000 neighbor spokes-ibgp ebgp-multihop 1 neighbor spokes-ibgp disable-connected-check neighbor spokes-ibgp route-reflector-client neighbor spokes-ibgp next-hop-self all neighbor spokes-ibgp advertisement-interval 1 neighbor spokes-ibgp soft-reconfiguration inbound neighbor 172.16.1.1 peer-group spokes-ibgp exit interface gre1 ip nhrp network-id 1 ip nhrp nhs dynamic nbma 50.60.70.80 ip nhrp registration no-unique ip nhrp shortcut ipv6 nd suppress-ra no link-detect tunnel protection vici profile dmvpn tunnel source eth0 exit write mem


为您拥有的每个 spoke 节点添加行 neighbor %Spoke1_GRE_IP%...。例如,如果您想添加 gre1 地址为 172.16.3.1 的 spoke 节点

vtysh conf t router bgp 65000 neighbor 172.16.3.1 peer-group spokes-ibgp exit write mem


Awall

与 DMVPN 第 2 阶段不同,在第 3 阶段 DMVPN 中,HUB 是所有 spoke 的默认网关,然后 spoke 能够通过 NHRP 重定向直接相互通信。

(有关 DMVPN 第 1 阶段、第 2 阶段和第 3 阶段之间差异的良好解释,请参阅 https://ine.com/blog/2008-12-23-dmvpn-phase-3)。

这是通过使用 iptables nflog 发送流量指示通知来实现的。

这是 HUB 的完整防火墙配置,使用 Alpine 防火墙框架 Awall


使用您喜欢的编辑器打开 /etc/awall/optional/zones.json

内容 /etc/awall/optional/zones.json

{ "description": "区域 - 用于管理的区域定义", "variable": { "SUBNETS": [ "192.168.0.0/16", "172.16.0.0/16" ] }, "zone": { "DMVPN": { "addr": "$SUBNETS" } } }


现在,创建 /etc/awall/optional/inet.json

内容 /etc/awall/optional/inet.json

{ "description": "互联网 - 主机管理(速率受限)", "zone": { "INET": { "iface": "eth0" } }, "policy": [ { "in": "INET", "action": "drop" } ], "filter": [ { "in": "INET", "out": "_fw", "service": "ping", "action": "accept", "flow-limit": { "count": 10, "interval": 6 } }, { "in": "INET", "out": "_fw", "service": "ssh", "action": "accept", "conn-limit": { "count": 3, "interval": 60 } }, { "in": "_fw", "out": "INET", "service": [ "dns", "http", "ntp" ], "action": "accept" }, { "in": "_fw", "service": [ "ping", "ssh" ], "action": "accept" } ] }

现在,DMVPN 规则

内容 /etc/awall/optional/dmvpn.json

{ "description": "DMVPN 特定规则", "import": [ "inet", "zones" ], "variable": { "HUB": true }, "policy": [ { "in": "DMVPN", "out": "DMVPN", "action": "accept" } ], "zone": { "DMVPN": { "iface": "gre1", "addr": "$SUBNETS", "route-back": "$HUB" } }, "filter": [ { "in": "INET", "out": "_fw", "service": "ipsec", "action": "accept" }, { "in": "_fw", "out": "INET", "service": "ipsec", "action": "accept" }, { "in": "INET", "out": "_fw", "ipsec": "in", "service": "gre", "action": "accept" }, { "in": "_fw", "out": "INET", "ipsec": "out", "service": "gre", "action": "accept" }, { "in": "_fw", "out": "DMVPN", "service": "bgp", "action": "accept" }, { "in": "DMVPN", "out": "_fw", "service": "bgp", "action": "accept"}, { "out": "INET", "dest": "$SUBNETS", "action": "reject" } ] }

管理接口允许的流量


内容 /etc/awall/optional/management.json

{ "description": "主机管理(ssh、https、ping)", "import": [ "zones" ], "policy": [ { "in": "DMVPN", "out": "_fw", "action": "reject" } ], "filter": [ { "in": "DMVPN", "out": "_fw", "service": [ "ping", "ssh", "https", "bgp" ], "action": "accept" }, { "in": "_fw", "out": "DMVPN", "service": [ "ping", "ssh", "http", "http-alt", "https", "dns", "ntp" ], "action": "accept" } ] }

NHRP 重定向规则

内容 /etc/awall/optional/vpnredirect.json

{ "description": "NHRP 流量指示探测", "log": { "dmvpn": { "mode": "nflog", "group": 1, "range": 128, "limit": { "count": 6, "interval": 60, "mask": { "inet": { "src": 16, "dest": 16 }, "inet6": { "src": 48, "dest": 48 } } } } }, "packet-log": [ { "in": "DMVPN", "out": "DMVPN", "log": "dmvpn" } ] }


启用 awall 规则

awall enable zones awall enable inet awall enable dmvpn awall enable vpnredirect

应用 awall 规则

awall activate -f

IPSEC

安装软件包

apk add strongswan

内容 /etc/swanctl/swanctl.conf

connections { dmvpn { version = 2 pull = no mobike = no dpd_delay = 15 dpd_timeout = 30 fragmentation = yes unique = replace rekey_time = 4h reauth_time = 13h proposals = aes256-sha512-ecp384 local { auth = psk id = hub } remote { auth = psk } children { dmvpn { esp_proposals = aes256-sha512-ecp384 local_ts = dynamic[gre] remote_ts = dynamic[gre] inactivity = 90m rekey_time = 100m mode = transport dpd_action = clear reqid = 1 } } } }


内容 /etc/ipsec.secrets

# /etc/ipsec.secrets - strongSwan IPsec 密钥文件 %any : PSK "cisco12345678987654321"

启动服务

rc-service charon start rc-update add charon


现在,测试它是否工作。在本示例中,spoke 1 尝试连接到 spoke 3,后者通过 iBGP 宣告其子网 192.168.30.0/24,gre1 地址为 172.16.3.1,公共 ip 地址为 90.100.150.200。


第一个流量通过 HUB。

spoke1:~/root# traceroute -n 192.168.30.1 traceroute to 192.168.30.1 (192.168.30.1), 30 hops max, 38 byte packets 1 172.16.0.1 0.664 ms 0.461 ms 0.457 ms 2 192.168.30.1 0.907 ms 0.776 ms 0.771 ms

然后,一旦 VPN 创建完成,流量将直接到达 spoke 节点。

spoke1:~/root# traceroute -n 192.168.30.1 traceroute to 192.168.30.1 (192.168.30.1), 30 hops max, 38 byte packets 1 192.168.30.1 0.456 ms 0.385 ms 0.357 ms


使用 ipsec --status-all 您可以看到所有已创建的 VPN

spoke1:~/root# ipsec statusall Status of IKE charon daemon (strongSwan 5.3.2, Linux 3.18.20-1-grsec, i686): uptime: 9 days, since Aug 28 14:22:27 2015 worker threads: 11 of 16 idle, 5/0/0/0 working, job queue: 0/0/0/0, scheduled: 28 loaded plugins: charon random nonce x509 revocation constraints pubkey pkcs1 pkcs7 pkcs8 pkcs12 pgp dnskey sshkey pem openssl fips-prf gmp xcbc cmac curl sqlite attr kernel-netlink resolve socket-default farp stroke vici updown eap-identity eap-sim eap-aka eap-aka-3gpp2 eap-simaka-pseudonym eap-simaka-reauth eap-md5 eap-mschapv2 eap-radius eap-tls xauth-generic xauth-eap dhcp unity Listening IP addresses: 192.168.10.1 172.17.50.1 172.16.1.1 Connections: dmvpn: %any...%any IKEv2, dpddelay=15s dmvpn: local: [spoke1] uses pre-shared key authentication dmvpn: remote: uses pre-shared key authentication dmvpn: child: dynamic[gre] === dynamic[gre] TRANSPORT, dpdaction=clear Security Associations (3 up, 0 connecting): dmvpn[121]: ESTABLISHED 4 seconds ago, 172.17.50.1[spoke1]...90.100.150.200[spoke3] dmvpn[121]: IKEv2 SPIs: c770729967ea636c_i 0de8ffedbe32f21c_r*, rekeying in 3 hours, pre-shared key reauthentication in 12 hours dmvpn[121]: IKE proposal: AES_CBC_256/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/ECP_384 dmvpn{187}: INSTALLED, TRANSPORT, reqid 1, ESP in UDP SPIs: c132e6c3_i c49ae122_o dmvpn{187}: AES_CBC_256/HMAC_SHA2_512_256, 469 bytes_i (6 pkts, 2s ago), 326 bytes_o (6 pkts, 2s ago), rekeying in 90 minutes dmvpn{187}: 172.17.50.1/32[gre] === 90.100.150.200/32[gre] dmvpn[120]: ESTABLISHED 8 seconds ago, 172.17.50.1[spoke1]...90.100.150.200[spoke3] dmvpn[120]: IKEv2 SPIs: 46f81c8ec9a4b753_i* f768298b31ebe4da_r, rekeying in 3 hours, pre-shared key reauthentication in 11 hours dmvpn[120]: IKE proposal: AES_CBC_256/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/ECP_384 dmvpn{186}: INSTALLED, TRANSPORT, reqid 1, ESP in UDP SPIs: cad2c1c9_i cd5a287c_o dmvpn{186}: AES_CBC_256/HMAC_SHA2_512_256, 74 bytes_i (1 pkt, 2s ago), 46 bytes_o (1 pkt, 2s ago), rekeying in 91 minutes dmvpn{186}: 172.17.50.1/32[gre] === 90.100.150.200/32[gre] dmvpn[119]: ESTABLISHED 2 hours ago, 172.17.50.1[spoke1]...50.60.70.80[hub] dmvpn[119]: IKEv2 SPIs: 0e999ad802ced9cc_i* 6eaa469463601437_r, rekeying in 84 minutes, pre-shared key reauthentication in 8 hours dmvpn[119]: IKE proposal: AES_CBC_256/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/ECP_384 dmvpn{185}: INSTALLED, TRANSPORT, reqid 1, ESP in UDP SPIs: c84d6035_i cb72cd30_o dmvpn{185}: AES_CBC_256/HMAC_SHA2_512_256, 35764 bytes_i (473 pkts, 0s ago), 38266 bytes_o (384 pkts, 0s ago), rekeying in 46 minutes dmvpn{185}: 172.17.50.1/32[gre] === 50.60.70.80/32[gre]

参见