Wireguard网关服务器上的路由设置
背景
我在学校日常使用wireguard连回家里的局域网,众所周知wireguard是个vpn软件,但是苦于不会配置,只能让他默认走eth0转发出去,蛋疼地再挂多一个梯子,手动设置代理,非常不舒服。间断肝了两三天,终于搞定这个问题(我菜
更新:发现新版(至少1.17版本)的mihomo客户端的tun模式的auto-route选项能够自动设置好路由,没必要这么麻烦了...
尝试过程
直接iptables(失败)
eth0的转发我也是直接设置iptables,最朴素的想法(无脑),就改了eth0为meta,结果当然不行。
iptables -t nat -A POSTROUTING -s 21.9.2.0/24 -o meta -j MASQUERADE
后来网上查了一圈,大部分都集中于snat和masquerade的配置,都不行。
透明代理tproxy或者redirect?(也许可以,有问题未解决)
这个方案看上去似乎可行,简单设置转发之后数据包也确实走到了clash,但是clash总是循环路由,日志中显示出口地址永远是本地地址(127.0.0.1或者服务器地址21.9.2.1这样的)而不是实际想要访问的地址
网上很多的办法都是为clash的流量打上标记,让他自身绕过代理,然后再设置路由表,有点复杂就没折腾了(其实后面的办法也差不多,都需要打标记...)
内核问题
有一部分iptables需要设置mangle,但是我的老提示不存在,刚开始作罢(以为这玩意没和内核一起编译),后来突然搜到这玩意原来可以以内核模块的形式加载
使用tcpdump抓包发现问题
v2ex有高人建议用tcpdump上抓包来分析,我觉得也有道理,刚开始不会用tcpdump(菜),没用这玩意,就盲人摸象,很难排查问题。
后来在gpt的指点下,快速入门了一下。
解决这个问题的关键也就是依靠这个发现的。
我尝试直接iptables NAT直接设置POSTROUTING时转发到指定网卡,可是我发现这不起作用,用tcpdump -i eth0
一查,发现来自wg的数据包,这时候意识到是路由表的问题。
后来又求助于gpt,他说POSTROUTING
是数据包离开系统之后的阶段,也就是说数据包已经选好路了...而PREROUTING
是不能指定出口网卡的(iptables搞了半天也不是特别理解,人菜
设置路由表
看了网上有一部分透明代理的设置,都需要设置路由表,为数据包打上mark标记。
又问了问gpt,他说,iptables 的 mangle 表用于修改数据包的头部信息,通常用于实施高级的网络策略和质量服务(QoS)操作,特别是他举例的时候特别提到在MANGLE 的 PREROUTING 链中标记数据包,并将标记设置为 42。这种标记通常用于实现高级路由策略的时候,意识到这也许是我要的答案,就在gpt的手把手指导下,终于解决了这个问题
配置例子
我的服务器安装的是proxmox 6(debian 10),内核5.18,使用1.16版本的clash meta
tun网卡的名字是meta,wireguard网卡是wg0,网段21.9.2.0/24
proxmox的内核似乎很多模块默认没有加载,要使用iptables的mangle及其MARK功能,需要加载xt_mark
和iptable_mangle
两个内核模块
以下为符合条件数据包设定标记233,创建了一个id=100的路由表,设置路由表默认出口是meta,并设置标记233的数据包走id=100的路由表进行路由选择
ip route add 21.9.2.0/24 dev wg1 table 100
ip route add default dev meta table 100
iptables -t mangle -A PREROUTING -i wg1 -s 21.9.2.0/24 -j MARK --set-mark 233
ip rule add fwmark 233 lookup 100
后记
(图文无关警告!)
感觉计算机网络学的还是有点用,设置iptables总是想起了寄网课玩cisco路由设置nat和路由表的那些命令和学到的nat和路由表的原理。但是遇到iptables这个庞然大物,不知从哪入手,感觉太复杂了,得花些时间学习一下才行。
后来觉得一方面这也是我目前学习的现状吧,也许很多时候看书也只是囫囵吞枣图一乐,并没有真正融合进所谓“元认知”,因为很明显最后这就是设置路由表的问题,而我却兜兜转转整半天
另一方面要动脑子去分析问题,要善于用工具(比如tcpdump之类,去分析当前的状况,结合原理去思考哪里出现了问题)