Skip to content

利用FreeBSD主副路由表(FIB)在服务器使用Cloudflare Warp

cnbatch edited this page Jul 13, 2024 · 5 revisions

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)"];
Loading

或者这样用

graph LR;
    A[浏览器] <--> B[KCPTube 客户端];
    B <--> C[Internet];
    C <--> D[KCPTube 服务端];
    D <--> E["socks5 (127.0.0.1)"];
Loading

这样一来,就可以灵活使用FreeBSD的主副路由表功能。

只要确保KCPTube 服务端于socks程序都在用一台FreeBSD机器运行,那么接下来的步骤就很简单了。

步骤

1. 启用主副路由表

使用任意编辑器打开 /boot/loader.conf,插入一行

net.fibs=2

数值随意写,只要大于等于2即可。
设置为2,表示系统中会有两个路由表,分别为0号的主路由表,以及1号的副路由表。
设置为3,表示系统中会有三个路由表,分别为0号的主路由表,以及1号、2号的副路由表。

改完后请重启系统

2. shadowsocks或v2ray或者xray-core改成在 1 号路由表运行

假设用的是xray-core,那么编辑/etc/rc.conf,加入一行:

xray_fib=1

其他代理程序方法相同,都是加个后缀_fib=1

如果需要改成使用其他编号的路由表,请根据实际情况修改。

3. 配置Cloudflare Warp

配置文件的具体生成过程不在此展开,请自行使用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。

4 修改Cloudflare Warp的配置文件

这一步很重要,因为需要改成使用副路由表。

使用编辑器打开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"

5. 主路由表条目复制到副路由表

默认情况下,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"

6. 完成

重启系统,打开查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)"];
Loading

对于这种用法,可以使用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