在 Alpine Linux 上设置 DMVPN

来自 Alpine Linux

设置 mGRE 隧道

我们首先在网络配置中添加 mGRE 隧道。

Contents of /etc/networking/interfaces

... auto gre1 iface gre1 inet static pre-up ip tunnel add $IFACE mode gre key 42 ttl 64 dev br0 || true address 192.168.148.2 netmask 255.255.255.255 post-down ip tunnel del $IFACE || true
注意: 与 IPSec VPN 结合使用,这允许在连接的网络之间传递路由信息。
注意: 标准 GRE 隧道将指定其起点和终点。对于 mGRE 隧道,我们不分配起点/终点,它将由 NHRP 动态管理
注意: 隧道密钥是一个 32 位数字,分配给隧道的两端。密钥通过 `add gre tunnel` 命令添加,可以通过 `set gre tunnel` 命令修改或删除。隧道密钥提供了一种较弱的安全形式,因为除非外部方注入隧道的数据包包含正确的隧道密钥值,否则将被拒绝。密钥还允许数据包在多点网络中的特定隧道中传输,因为密钥标识了一个隧道的每一端。

设置 IPSec VPN

为了加密此隧道及其中的流量,我们将使用 strongswan ipsec 及其 vici 插件。vici 插件提供 VICI,即 Versatile IKE Configuration Interface(多功能 IKE 配置接口)。顾名思义,它为外部应用程序提供了一个接口,不仅可以配置,还可以控制和监视 IKE 守护进程 charon。为此,我们还需要 Alpine Linux 中默认的 Strongswan 的修改版本。

apk add strongswan

模板

模板取自其他 Wiki 文档。

Contents of /etc/swanctl/swanctl.conf

connections { dmvpn { version = 2 # enable IKEv2 pull = no # IKEv1 only. Push enabled. IKEv2 does not support pull. mobike = no # disable support for mobile clients tunnel migration dpd_delay = 15 # Interval to check the liveness of a peer if not traffic has passed dpd_timeout = 30 # IKEv1 only fragmentation = yes # NOTE: has recently been added. docs are outdated. unique = replace # replace connection if it already exists rekey_time = 4h # rekey is by default already 4h reauth_time = 13h # re authenticate ipsec tunnel proposals = aes256-sha512-ecp384 # docs say default is considered safe and has good interoperability local { certs = cert # certificates used for authentication auth = pubkey # a private key associated to a usable certificate id = spoke1 # IKE identity which should be included in the certificate. ie fqdn } remote { auth = pubkey # Authentication to expect from remote } children { # what is the difference between remote and children? local and remote is only to specify authentication? dmvpn { esp_proposals = aes256-sha512-ecp384 # docs say default is considered safe and has good interoperability local_ts = dynamic[gre] # traffic selectors, dynamic to use outer address of virtual ip. restrict to GRE protocol remote_ts = dynamic[gre] # traffic selectors, dynamic to use outer address of virtual ip. restrict to GRE protocol inactivity = 90m # close CHILD_SA after inactivity rekey_time = 100m # Time to schedule CHILD_SA rekeying mode = transport # IPsec Mode to establish CHILD_SA with dpd_action = clear # default is clear reqid = 1 # why not use dynamic reqids, allocated incrementally? } } } }
注意: 为了控制 IPSec VPN,NHRP 将通过其 vici 插件(Versatile IKE Configuration Interface)与 Strongswan 通信。
注意: 你将需要 fabled 修改的 Strongswan 版本,你可以在 Alpine Linux Git 仓库中找到它

Spoke 1

Contents of /etc/swanctl/swanctl.conf

connections { dmvpn { version = 2 mobike = no dpd_delay = 15 fragmentation = yes unique = replace reauth_time = 13h proposals = aes256-sha512-ecp384 local { certs = spoke1.pem auth = pubkey id = spoke1.vpn.domain.tld } remote { auth = pubkey id = hub.vpn.domain.tld } children { dmvpn { esp_proposals = aes256-sha512-ecp384 local_ts = dynamic[gre] remote_ts = dynamic[gre] inactivity = 90m rekey_time = 100m mode = transport } } } }

HUB

Contents of /etc/swanctl/swanctl.conf

connections { dmvpn { version = 2 mobike = no dpd_delay = 15 fragmentation = yes unique = replace reauth_time = 13h proposals = aes256-sha512-ecp384 local { certs = spoke1.pem auth = pubkey id = hub.vpn.domain.tld } remote { auth = pubkey } children { dmvpn { esp_proposals = aes256-sha512-ecp384 local_ts = dynamic[gre] remote_ts = dynamic[gre] inactivity = 90m rekey_time = 100m mode = transport } } } }

生成 PKI 证书

提示: The ipsec pki 命令套件允许你运行一个简单的公钥基础设施。生成 RSA 和 ECDSA 公钥对,创建包含 subjectAltNames 的 PKCS#10 证书请求,创建 X.509 自签名终端实体和根 CA 证书,颁发由 CA 私钥签名并包含 subjectAltNames、CRL 分发点和 OCSP 服务器 URI 的终端实体和中间 CA 证书。你还可以从私钥、证书请求和证书中提取原始公钥,并计算两种基于 SHA1 的密钥 ID。

首先,生成一个私钥,默认情况下生成一个 2048 位 RSA 密钥

ipsec pki --gen > caKey.der

现在使用生成的密钥自签名一个 CA 证书

ipsec pki --self --in caKey.der --dn "C=CH, O=strongSwan, CN=strongSwan CA" --ca > caCert.der

根据你的需要调整 distinguished name (DN),它将包含在所有颁发的证书中。

对于每个对等方,即网络中的所有 VPN 客户端和 VPN 网关,生成一个单独的私钥,并使用你的新 CA 颁发匹配的证书

ipsec pki --gen > peerKey.der ipsec pki --pub --in peerKey.der | ipsec pki --issue --cacert caCert.der --cakey caKey.der --san host.vpn.example.tld --dn "C=CH, O=strongSwan, CN=peer" > peerCert.der

注意: 第二个命令提取公钥并使用你的 CA 颁发证书。
注意: 当在 local/remote 配置中使用 id 时,你需要在证书中使用 `--san host.vpn.example.tld` 添加此 id

证书吊销列表 (CRL)

如果需要吊销终端实体证书,可以使用 `ipsec pki --signcrl` 命令生成证书吊销列表 (CRL)。

ipsec pki --signcrl --cacert caCert.der --cakey caKey.der --reason superseded --cert peerCert.der > crl.der

注意: 用 `--cacert` 给出的证书必须是 CA 证书或具有 crlSign 扩展密钥用法的证书(`--flag crlSign`)。

安装证书

在每个对等方上,将以下证书和密钥存储在 `/etc/ipsec.d/` 子目录树中

/etc/swanctl/rsa/hubKey.der holds the private key of the given peer.
/etc/swanctl/x509/hubCert.der holds the end entity certificate of the given peer.
/etc/swanctl/x509ca/caCert.der holds the CA certificate which issued and signed all peer certificates.
提示: 永远不要将证书颁发机构 (CA) 的私钥 `caKey.der` 存储在可以持续直接访问互联网的主机上(例如 VPN 网关),因为盗窃此主签名密钥将完全损害你的 PKI。
注意: 可选地,CRL 可以存储在以下目录中(如果证书包含 CRL 的 URL,它将按需获取:`/etc/ipsec.d/crls/crl.der` 保存由 CA 签名(或包含 crlSign EKU 的证书)的 CRL。

Quagga/NHRP

添加所需的软件包

apk add iptables quagga-nhrp

发送流量指示 (重定向) 通知

iptables -A FORWARD -i gre1 -o gre1 \ -m hashlimit --hashlimit-upto 4/minute --hashlimit-burst 1 \ --hashlimit-mode srcip,dstip --hashlimit-srcmask 16 --hashlimit-dstmask 16 \ --hashlimit-name loglimit-0 -j NFLOG --nflog-group 1 --nflog-range 128

提示: 我们从数据包中过滤 HRHP 信息,并将它们提供给 NHRP 守护进程

配置 Quagga

注意: Quagga 需要使用 vty shell 进行配置。以下部分分为几个部分,但都在同一个 shell 中运行。

vtysh

常规

configure terminal
log syslog
debug nhrp common

BGP 配置

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
exit

NHRP 配置

interface gre1
 tunnel protection vici profile dmvpn
 tunnel source br0
 ip nhrp network-id 1
 ip nhrp shortcut
 ip nhrp registration no-unique
 ip nhrp nhs dynamic nbma hub1.vpn.domain.tld
 ipv6 nd suppress-ra
 no link-detect
exit

保存配置

exit
write mem

向 Hub 添加 Spoke

注意: 对于你添加的每个 Spoke,你需要将 gre ip 地址添加到 bgp 配置中,与上面配置中的类似

vtysh

conf terminal
router bgp 65000
 neighbor 172.16.3.1 peer-group spokes-ibgp
exit
write mem
提示: vty shell 中使用的大多数命令都类似于 Cisco 设备中的命令。这意味着你也可以从 Cisco 文档中收集信息

参见