RouterOS的wireguard配置是做了一定的修改,把路由处理删除掉了,仅保留了连接功能,对于RouterOS这样的操作完全可以理解,路由需要管理员根据自身的需求进行配置,可能涉及到动态路由OSPF,RIP,BGP等,因此这部分与其他Linux发行版本的操作有区别,由于一开始使用RouterOS的wireguard导致对原生Wireguard路由部分理解缺失,特意补补。

特别说明:此文章需要读者具备基本的路由知识和一定linux基础

基本配置

安装和基本配置省略,直接看wg0.conf的配置文件:

[Interface]
ListenPort = 13233
Address = 10.20.0.2/24
PrivateKey = sFrr8TQpNkrLKpN7SoqpU0xTa0WWRbezX3Fj

[Peer]
PublicKey = SkxQ8Gc6z/GylCD1b2MNVyoFDLsrO29pAcbw2
AllowedIPs = 10.20.0.1/32,172.20.0.0/24
Endpoint = 192.168.99.30:13233

在这个配置文件中【interface】定义了wg接口的ListenPort监听端口13233、接口IP地址 10.20.0.2/24,PrivateKey私钥等信息

配置文件创建了一个远端节点【Peer】,Peer的公钥信息,AllowedIPs允许路由访问的IP地址,Endpoint指定了连接对端的IP地址和端口192.168.99.30:13233

启动wg0连接,显示了以下命令配置

root@myserver:/etc/wireguard# wg-quick up wg0
[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip -4 address add 10.20.0.2/24 dev wg0
[#] ip link set mtu 1420 up dev wg0
[#] ip -4 route add 172.20.0.0/24 dev wg0

网络操作包括创建接口,添加IP地址,设置mtu大小,

下面的一条路由设置,

ip -4 route add 172.20.0.0/24 dev wg0

添加了ipv4的路由 172.20.0.0/24 网关指向wg0

也就是说这里Wireguard根据allowedIPs,添加了路由,即到对端的网络IP段有172.20.0.0/24,需要注意对端的wg接口IP是10.20.0.1,包含在ip -4 address add 10.20.0.2/24 dev wg0 接口IP地址的子网中

多个Peer配置

在wg0.conf又增加一个远端节点Peer,当前设备与两个远端的Wireguard连接

[Peer]
PublicKey = sFrr8TQpNkrLKpN7SoqpU0xTa0WWRbezX3Fj
AllowedIPs = 10.20.0.1/32,172.20.0.0/24
Endpoint = 192.168.99.30:13233

[Peer]
PublicKey = NTSzq1IHgDuStFt8LTFFfAOUGq2DXvKvPaYd
AllowedIPs = 10.20.0.3/32,172.19.0.0/24
Endpoint = 192.168.99.31:13231

重新连接启动连接(不再写明wg-quick down wg0),

root@myserver:/etc/wireguard# wg-quick up wg0
[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip -4 address add 10.20.0.2/24 dev wg0
[#] ip link set mtu 1420 up dev wg0
[#] ip -4 route add 172.20.0.0/24 dev wg0
[#] ip -4 route add 172.19.0.0/24 dev wg0

可以看到新建立了一条静态路由 ip -4 route add 172.19.0.0/24 dev wg0

这部分在官方文档做了说明称为Cryptokey Routing

在上面的conf配置中,每个Peer将具有相应的AllowedIPs列表,匹配源IP的网络接口发送数据包。例如,当从对端SkxQ8Gc6z/…收到报文,经过解密和认证后,如果其源IP为10.20.0.1,则允许进入该接口,否则丢弃。

当本机网络接口想要向Peer发送数据包时,它会查看该数据包的目标IP,并将对每个Peer的AllowedIPs列表进行比较,以确定将其发送到哪个Peer。例如,如果要求网络接口发送目的IP为10.20.0.3的数据包,则使用NTSzq1I…的公钥进行加密发送。

可以理解为公钥和IP做了一一的映射关系,每一个wgx.conf配置文件,就是一张路由表。如果一张wg的路由表出现相同的路由,导致路由冲突,只会匹配conf中最后一个Peer的路由生效,其他会无法连接。

客户端的默认路由

现在wg0.conf仅作为客户端方式配置,AllowedIPs 设置为任意IP 0.0.0.0/0

[Interface]
ListenPort = 13233
Address = 10.20.0.2/24
PrivateKey = sFrr8TQpNkrLKpN7SoqpU0xTa0WWRbezX3Fj

[Peer]
PublicKey = SkxQ8Gc6z/GylCD1b2MNVyoFDLsrO29pAcbw
AllowedIPs = 0.0.0.0/0
Endpoint = 192.168.99.30:13233
PersistentKeepalive = 25

启动wg0

root@myserver:/etc/wireguard# wg-quick up wg0
[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip -4 address add 10.20.0.2/24 dev wg0
[#] ip link set mtu 1420 up dev wg0
[#] wg set wg0 fwmark 51820
[#] ip -4 route add 0.0.0.0/0 dev wg0 table 51820
[#] ip -4 rule add not fwmark 51820 table 51820
[#] ip -4 rule add table main suppress_prefixlength 0
[#] sysctl -q net.ipv4.conf.all.src_valid_mark=1
[#] iptables-restore -n

可以看到wireguard创建了一个51820的路由表,在51820路由表中的默认网关是wg0接口,针对iptable mangle标记fwmark 51820,分别在PREROUTING和POSTROUTING创建了两条连接mark规则,查看iptables配置:

root@myserver:/etc/wireguard# iptables -t mangle -L -nv
Chain PREROUTING (policy ACCEPT 3934 packets, 335K bytes)
pkts bytes target prot opt in out source destination
3731 319K CONNMARK udp -- * * 0.0.0.0/0 0.0.0.0/0 /* wg-quick(8) rule for wg0 */ CONNMARK restore
Chain POSTROUTING (policy ACCEPT 161 packets, 25336 bytes)
pkts bytes target prot opt in out source destination
23 1888 CONNMARK udp -- * * 0.0.0.0/0 0.0.0.0/0 mark match 0xca6c /* wg-quick(8) rule for wg0 */ CONNMARK save

fwmark 标记

Wireguard会标记用于建立隧道接口发出的所有数据包(wg set wg0 fwmark 51820),如果是用于建立隧道的数据走到wg0的路由表,会导致路由再次走到wg0接口,死循环无法建立隧道连接。

所以 ip -4 rule add not fwmark 51820 table 51820意思是说,只要配匹到fwmark 51820的标记都排除掉,其他的数据请使用 51820 路由表,通过 wg0 隧道出去。

suppress_prefixlength

ip -4 rule add table main suppress_prefixlength 0这条规则也很重要,意思是拒绝前缀长度小于或等于 0 的路由策略,在main表查询,那么什么样的地址范围前缀长度才会小于等于 0?只有一种可能:0.0.0.0/0,也就是默认路由。即在main路由表中除了默认路由,其他路由都会拒绝进入新创建的路由表51820(参考:彻底理解 WireGuard 的路由策略

多个Peer的默认路由

此时我们修改配置文件,将第一个peer的allowedIPs修改为0.0.0.0/0

[Interface]
ListenPort = 13233
Address = 10.20.0.2/24
PrivateKey = sFrr8TQpNkrLKpN7SoqpU0xTa0WWRbezX3Fj

[Peer]
PublicKey = SkxQ8Gc6z/GylCD1b2MNVyoFDLsrO29pAcbw2
AllowedIPs = 0.0.0.0/0
Endpoint = 192.168.99.30:13233

[Peer]
PublicKey = NTSzq1IHgDuStFt8LTFFfAOUGq2DXvKvPaY
AllowedIPs = 10.20.0.3/32,172.19.0.0/24
Endpoint = 192.168.99.31:13231

启动wg0配置会发生什么

root@myserver:/etc/wireguard# wg-quick up wg0
[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip -4 address add 10.20.0.2/24 dev wg0
[#] ip link set mtu 1420 up dev wg0
[#] ip -4 route add 172.19.0.0/24 dev wg0
[#] wg set wg0 fwmark 51820
[#] ip -4 route add 0.0.0.0/0 dev wg0 table 51820
[#] ip -4 rule add not fwmark 51820 table 51820
[#] ip -4 rule add table main suppress_prefixlength 0
[#] sysctl -q net.ipv4.conf.all.src_valid_mark=1

51820的路由表仍然会建立,除了建立wg隧道外的连接都会被放到51820路由表查询,但ip -4 route add 172.19.0.0/24 dev wg0此规则仍然是放在默认的main路由表,由于 ip -4 rule add table main suppress_prefixlength 0的规则,会排除在51820路由表查询

是不是有点乱?

下面具体看看路由表,先通过ip route查看默认的main路由表

root@myserver:/etc/wireguard# ip route
default via 192.168.99.1 dev ens18 proto static
10.20.0.0/24 dev wg0 proto kernel scope link src 10.20.0.2
172.19.0.0/24 dev wg0 scope link
192.168.99.0/24 dev ens18 proto kernel scope link src 192.168.99.20

第一条:默认网关192.168.99.1
第二条:10.20.0.0/24 wg0的直连路由
第三条:172.19.0.0/24走wg0接口查询路由,
第四条:192.168.99.0/24本地网卡ens18的直连路由

ip rule查看策略路由

root@myserver:/etc/wireguard# ip rule
0: from all lookup local
32764: from all lookup main suppress_prefixlength 0
32765: not from all fwmark 0xca6c lookup 51820
32766: from all lookup main
32767: from all lookup default

主要看下面两条规则
32764: from all lookup main suppress_prefixlength 0 拒绝前缀长度小于或等于 0 的路由规则在mian表查询,保障了本地设备在查询172.19.0.0/24的路由,在main表完成

32765: not from all fwmark 0xca6c lookup 51820,排除了wg隧道建立数据,剩下的到51820路由表查询

查看51820路由表

root@myserver:/etc/wireguard# ip route show table 51820
default dev wg0 scope link

只有一条默认路由走wg0网卡出去

其实两个peer使用了两张路由表查询main和51820,只是通过suppress_prefixlength 0规则,保障172.19.0.0/24的路由,在main表完成

指定路由表

如果需要将两个和多个Peer的路由放到一张表查看,就需要使用table属性,如下conf文件,增加了一个table=999

[Interface]
ListenPort = 13233
Address = 10.20.0.2/24
PrivateKey = sFrr8TQpNkrLKpN7SoqpU0xTa0WWRbezX3Fj
table = 999

[Peer]
PublicKey = SkxQ8Gc6z/GylCD1b2MNVyoFDLsrO29pAcbw2
AllowedIPs = 0.0.0.0/0
Endpoint = 192.168.99.30:13233

[Peer]
PublicKey = NTSzq1IHgDuStFt8LTFFfAOUGq2DXvKvPaYd
AllowedIPs = 10.20.0.3/32,172.19.0.0/24
Endpoint = 192.168.99.31:13231

启动看看

root@myserver:/etc/wireguard# wg-quick up wg0
[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip -4 address add 10.20.0.2/24 dev wg0
[#] ip link set mtu 1420 up dev wg0
[#] ip -4 route add 10.20.0.3/32 dev wg0 table 999
[#] ip -4 route add 172.19.0.0/24 dev wg0 table 999
[#] ip -4 route add 0.0.0.0/0 dev wg0 table 999

可以看到 创建的新路由表名为999,但不会设置任何路由标记,只是将相关路由都放到了999表中,此时会发现到其他peer的路由不通,原因是没有将本地路由放到999表查询,只在main表查询

查看默认的main表

root@myserver:/etc/wireguard# ip route
default via 192.168.99.1 dev ens18 proto static
10.20.0.0/24 dev wg0 proto kernel scope link src 10.20.0.2
192.168.99.0/24 dev ens18 proto kernel scope link src 192.168.99.20

查看999路由表

root@myserver:/etc/wireguard# ip route show table 999
default dev wg0 scope link
10.20.0.3 dev wg0 scope link
172.19.0.0/24 dev wg0 scope link

可以看到所有peer的路由都反正999表中,如果我希望ens18下的一个主机192.168.99.10走wg的999路由表查询,可以配置一条策略路由

ip rule add from 192.168.99.10 table 999

 

通常这种方式用于路由转发,需要开启

sysctl -w net.ipv4.ip_forward=1

永久修改可以进入/etc/sysctl.conf修改net.ipv4.ip_forward=1

涉及到nat的规则需要配置

iptables -t nat -A POSTROUTING -o wg0 -j MASQUERADE

具体细节根据管理者的需要来调整配置

在wireguard的配置参数还有使用PreUp、PostUp、PreDown、PostDown:分别是连接成功之前(执行连接指令,还未连接成功),连接成功之后,中断连接之前(执行中断指令,还未中断),中断连接之后,用于配置自定义shell,iptables防火墙规则或其他配置等,如果指定了多条命令,这些命令将按照配置顺序依次执行。

 

打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章很值,打赏犒劳作者一下