记wireguard的ip Rule配置问题
文章目录
虽然学过计算机网络, 但是实践却并不多, 这里以wireguard建立的连接为例, 实践了一下路由配置, 更详细的了解了linux系统下路由的体系.
几个概念
多路由表
linux系统在2.1、 2.2 版本内核就支持了多路由表。简单来说,就是系统中同时存在多个路由表 (这个解释贼6)。不同的路由表同时存在,通过ip rule来进行配置,决定某个包由哪个路由表来 进行路由。
ip-rule
这是linux下iproute2工具中的一个,用以配置决定多路由表情况下的包路由。
格式
ip rule add SELECTOR ACTION
SELECTOR是用来匹配的条件, ACTION是匹配之后的动作。初始情况下系统有local、main、default
三个路由表,其中local具备优先级0,一般不能更改,main具有priority:32766,除了
一个空的default路由表之外是最低优先级的路由表了。路由表匹配规则是0->32767这个顺序一路
匹配过来,如果包匹配到了SELECTOR,就执行后面的ACTION, 但是如果这个包没有在这个ACTION
中匹配到路由规则的话,则会继续在ip-rule的table列中继续匹配下去,知道找到他的路由规则。
从这个路由查找过程我们可以知道,在最低优先级的路由表中有兜底的路由很重要,也就是我们常见
的default via xxx这条规则。这样即使在高优先级的路由表中没有匹配路由规则,最后也会有其
适用的规则,而不是不知道该怎么发包。
一个常见的场景是,多网卡情况下,
比如两个网卡eth0, 192.168.0.3, eth1, 10.0.0.8, 路由情况为
default via 192.168.0.1 dev eth0
192.168.0.1/24 dev eth0
10.0.0.8/24 dev eth1
在这种情况下,如果eth1上收到来自某处的包,比如111.11.1.1发来一个请求,通过eth1到达
系统,在进行回复时,由于默认路由的配置,会自动走eth0。但是这往往不是我们想要的结果。Yeah!
这个时后我们的ip rule要发挥作用了!!!
ip rule add iif eth1 table 111
ip route add default via 10.0.0.1 dev eth1 table 111
第一条命令,所有从eth1进来的连接都采用table 111这个路由表进行路由。
第二条命令,添加路由规则到table 111中,这个表某人所有的包都从eth1发出。
在这样之后,所有从eth1来的访问,回复的包也会从eth1发出。
问题来了
对的,那么问题来了,这些和wireguard由哪几毛钱的关系?由于众所周知的原因,我们这里称呼 wireguard为‘虚拟连接工具’,是众多‘虚拟连接’实现方式的一种。最近发现的wireguard,发现 这个家伙配置起来十分的简单方便,相比其他的各种虚拟连接工具,比如l2tp、IPSec容易太多。 所以实践了一下,很容易的达到了连接的目的。并且,这个工具最诱人的一点是,建立虚拟连接的 两点只需要一方具备WAN IP地址,这对于目前国内几大ISP很难获取到公网IP的情况十分适用。
简单配置
wireguard用类似RSA的一组key来定义一个peer, 一个private key以及其一个public key,
pubkey给别人用来建立和自身的连接,而prikey则可以判定只有确实发送目标是本peer的包才接受
和处理。根据作者的介绍,在安全方面做了很多的考量,而且由于代码量很少,引入不可预计的bug
的可能性也相对较小,因此这是一个很不错的虚拟连接工具。简单举个例子:
# server端
[Interface]
Address = 10.0.0.1 # 可以有多个,指定不同的地址
PrivateKey = aaaaaaaaaaaa # 唯一identify本peer的key
ListenPort = 1032 # 监听端口
[peer]
PublicKey = dddddddddddddd # 所要连接的对方peer的公共key
AllowedIPs = 10.0.0.1/24 # 从该peer发来的包所被允许的IP地址
# 对应的client端的配置
[Interface]
Address = 10.0.0.2 # 可以有多个,指定不同的地址
PrivateKey = ccccccccccc # 唯一identify本peer的key
ListenPort = 1111 # 监听端口
[peer]
PublicKey = bbbbbbbbbbbbbb
# 所要连接的对方peer(这里指server)的公共key
AllowedIPs = 0.0.0.0/0
# 这里不做任何限定,这样可以在server端作NAT,可以
# 有来自任一IP地址的包从server peer发送过来
Endpoint = server_ip:1032
# 这里server peer必须具备公网IP,这样才可以让连接
# 建立,而对于server端,在收到client的包时会自动配置
# 直接实现了UDP puchhole
在server端做好iptables nat配置,很容易就可以实现客户端数据以server作为出口。
遇到的问题
到这里遇到了一个很缺乏常识造成的问题。请注意,这里的虚拟连接建立之后在两边虽然都多出来
一个网卡,但是他们只是虚拟网卡,所有的数据仍然都是从实际的网卡发出去的,如果按照把虚拟网卡
当真的情况,就会出现包发布出去的现象。如果是采用wg-quick作为工具,它在发现client端的
AllowedIPs = 0.0.0.0/0的情况下,会判断本虚拟连接的用途为以server作为数据出入口。因此
会自动进行一下配置,避免我后面将要遇到的情况
wg set wg0 fwmark 5324
ip rule add not fwmark 5324 table 5324
ip route add default dev wg0 table 5324
第一,将所有由虚拟连接万口wg0发出的数据添加一个fwmark标签。
第二,所有没有该标签的数据走路由表5324, 很关键的一步,因为wg0的数据实际还是要用本机的
实际网口将数据发出,如果不添加wg0网口发出的数据为例外直接将wg0设为默认出口,会导致数据
无法发出。
剩下的部分将在下一篇“linux下让某程序的所有数据包通过指定网口发出”中介绍。
文章作者 thinkeryu
上次更新 2017-10-28