-
Notifications
You must be signed in to change notification settings - Fork 16
利用FreeBSD主副路由表(FIB)在服务器使用Cloudflare Warp
FreeBSD有一项独特、方便的特性:FIB。不少人直译为“多路由表”,我个人更倾向于使用简单直白的意译,称之为“主副路由表”。
FIB的特性是,0号路由表是系统的默认表、主表,往后编号的都是副表。所有程序都使用0号路由表,除非明确指定使用其他编号的路由表。
如何明确指定使用其他编号的路由表?做法有两个:
第一个做法:使用setfib
命令,例如
setfib 1 xray run -c ./config.json
这样xray-core就会改成使用1号路由表。
第二个做法:调用setsockopt设置SO_SETFIB
选项
int fib = 1;
setsockopt(s, SOL_SOCKET, SO_SETFIB, (void *)&fib, sizeof(fib));
nginx就是这样做的。
第一种做法更加通用,本文就是基于第一种做法。
在 常规配置模式:客户端 ↔ 服务端 的流程图已经提到过,kcptube是用作管道的。
某些情况下,kcptube会这样用:
graph LR;
A[shadowsocks] <--> B[KCPTube 客户端];
B <--> C[Internet];
C <--> D[KCPTube 服务端];
D <--> E["shadowsocks (127.0.0.1)"];
或者这样用
graph LR;
A[浏览器] <--> B[KCPTube 客户端];
B <--> C[Internet];
C <--> D[KCPTube 服务端];
D <--> E["socks5 (127.0.0.1)"];
这样一来,就可以灵活使用FreeBSD的主副路由表功能。
只要确保KCPTube 服务端于socks程序都在用一台FreeBSD机器运行,那么接下来的步骤就很简单了。
使用任意编辑器打开 /boot/loader.conf,插入一行
net.fibs=2
数值随意写,只要大于等于2即可。
设置为2,表示系统中会有两个路由表,分别为0号的主路由表,以及1号的副路由表。
设置为3,表示系统中会有三个路由表,分别为0号的主路由表,以及1号、2号的副路由表。
改完后请重启系统。
假设用的是xray-core,那么编辑/etc/rc.conf,加入一行:
xray_fib=1
其他代理程序方法相同,都是加个后缀_fib=1
如果需要改成使用其他编号的路由表,请根据实际情况修改。
配置文件的具体生成过程不在此展开,请自行使用wgcf工具生成配置文件。
在继续之前,请确保FreeBSD已经安装了wireguard-tools。若未安装wireguard-tools,请使用pkg安装好再继续。
把生成的配置文件复制到 /usr/local/etc/wireguard
,并命名为 wg1.conf
cp wgcf-profile.conf /usr/local/etc/wireguard/wg1.conf
当然啦,名称改为wg0.conf或者wg2.conf之类的都可以。这里假设已经存在wg0配置文件,所以新文件命名为wg1。
这一步很重要,因为需要改成使用副路由表。
使用编辑器打开wg1.conf,向[Interface]
新增Table = 1
条目,就像这样:
[Interface]
PrivateKey = xxxxxxxxxx
Address = xxx.xx.xx.xx/32
Address = xx:xx::xx:xx/128
DNS = 1.1.1.1, 1.0.0.1, 2606:4700:4700::1111, 2606:4700:4700::1001
MTU = 1280
Table = 1
[Peer]
的AllowedIPs
建议从
AllowedIPs = 0.0.0.0/0
AllowedIPs = ::/0
改成
AllowedIPs = 0.0.0.0/1, 128.0.0.0/1
AllowedIPs = ::/1, 8000::/1
保存后,修改/etc/rc.conf,向wireguard_interfaces=""
加入相应接口名称
wireguard_interfaces="wg0 wg1"
默认情况下,FreeBSD并不会把主路由表的条目全部复制到副路由表,所以需要手动复制。
FreeBSD目前并没有专门的复制工具,我做了个临时程序fibmgr暂时用用。
首先,运行以下命令,解压并复制到 /usr/local/sbin/
tar xf fibmgr-static.tar.xz
cp fibmgr /usr/local/sbin/
接着,运行以下命令创建RC启动脚本
touch /usr/local/etc/rc.d/fibmgr
chmod +x /usr/local/etc/rc.d/fibmgr
然后使用任意工具编辑该文件,例如ee
ee /usr/local/etc/rc.d/fibmgr
把以下文件内容复制粘贴进去:
#!/bin/sh
#
# $FreeBSD$
#
# PROVIDE: fibmgr
# REQUIRE: NETWORKING
# BEFORE: wireguard
# KEYWORD: shutdown
# Add these lines to /etc/rc.conf.local or /etc/rc.conf to enable `fibmgr':
#
# fibmgr_enable (bool): Set to "NO" by default.
# Set it to "YES" to enable fibmgr
# fibmgr_config (path): Set to "/usr/local/etc/fibmgr/config.conf" by default
# Set it to the fibmgr server config
. /etc/rc.subr
name="fibmgr"
rcvar="${name}_enable"
eval ": \${${name}_enable:=\"NO\"}"
procname="/usr/local/sbin/fibmgr"
start_cmd=fibmgr_start
fibmgr_start()
{
${procname} copy 0 to all > /dev/null 2>&1
}
load_rc_config "$name"
run_rc_command "$1"
保存后,往/etc/rc.conf新增一行:
fibmgr_enable="YES"
重启系统,打开查IP的网站,如无意外应该已经从Cloudflare Warp连出去了。
如果系统中已经存在其他wireguard连接,并且需要使用主路由表(0号表),建议在这些连接的配置文件当中的[Interface]
新增Table = 0
条目,以免路由条目自动出现在其它路由表。
有些时候,可能会使用这样的连接方式:
graph TD;
A["shadowsocks (client)"] <--> B[KCPTube 客户端];
B <--> C[Internet];
C <--> D["FIB1\nKCPTube 服务端\nFIB2"];
D <--> E["Internet"];
E <--> F["shadowsocks (server)"];
对于这种用法,可以使用fib_ingress
以及fib_egress
选项指定出入口,就像这样:
mode=server
kcp=regular3
inbound_bandwidth=1G
outbound_bandwidth=1G
listen_port=3000-4000
destination_port=6000
destination_address=::1
encryption_password=qwerty1234
encryption_algorithm=AES-GCM
fib_ingress=1
fib_ingress=2