在 UBNT ERX 上搭建 GOST 隧道
前段时间有个需求,需要在一个有公网 IP 的环境下放一个 GOST 隧道入口(或者称为「中转」),对于这种需求一般来说想到的方式是在内网下开一个 GOST 隧道,然后通过路由器做一个端口映射给内网下的那台机器,但是由于功耗考虑对方不希望这么做,加之买的树莓派 4 还没到(为啥不早点买…),于是开始调研一下如何合理利用一下唯一的那个路由器来完成这个需求。
UBNT ERX
网上有很多类似的说明,这里也就不额外展开了,官方的介绍是:
The EdgeRouter™X delivers cost-effective routing performance in an ultra‑compact form factor.
对于我们而言,我们一般关注以下特性:
OS
UBNT ERX 默认使用的 EdgeOS 是一个魔改版的 Debian,如果你使用了 v2.0.x 的固件,那么就是 Debian 9,不然是 Debian 7,目前手上这个路由器运行着 v2.0.8,也就是 Debian 9。
- EdgeOS v2.0.0 Release Uses Debian 9 (Stretch).
- Older EdgeOS Releases Uses Debian 7 (Wheezy).
要升级固件的话看官网:Ubiquiti - Download,注意 UBNT 给 ER-X 同时提供了两个版本的固件,一个是 v1.10.x,一个是 v2.0.x,都是可用的,不过有说法是 v2.0.x 相比较之前的 bug 会变多,转发性能下降。
在升级系统这块,如果系统中有多于两个镜像的话,几乎约等于重启后无法起来(由于存储空间实在太小了,只有 256 MB),所以升级系统前建议先 SSH 到路由器上 show system image
一下看看有没有多余的系统,例如本例中只有一个 image:
ubnt@ubnt:~$ show system image
The system currently has the following image(s) installed:
v2.0.8-hotfix.1.5278088.200305.1641 (running image) (default boot)
如果有多的话,使用 delete system image
,删掉多余的,或者如果 default boot 不是最新系统的话使用 set system image default-boot
切换一下默认开机系统,重启后删除另一个多余的系统。
Hardware
在硬件方面我们需要关注的是:
- Max. Power Consumption: 5W(功耗很小)
- Processor: Dual-Core 880 MHz, MIPS1004Kc
- System Memory: 256 MB DDR3 RAM
- Code Storage: 256 MB NAND(存储空间很小,别瞎装不需要的包)
对于 CPU 来说,SSH 进入路由器后通过 lscpu
可以看到如下输出:
Architecture: mips
Byte Order: Little Endian
CPU(s): 4
On-line CPU(s) list: 0-3
Thread(s) per core: 2
Core(s) per socket: 2
Socket(s): 1
BogoMIPS: 581.63
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
用的是小端法(Little Endian),所以后文中下载的包一律找包含关键词 mipsle 的(le -> little endian)。
Configuration
有了以上预备知识之后就可以开始配置路由器了,在本文中,路由器的配置模式为「光猫桥接,路由器 eth0 口 PPPoE 拨号,eth1~eth4 配置在 switch0 接口上并开启了 DHCP」
Add Debian repo
SSH 到路由器上后使用:
configure
set system package repository stretch components 'main contrib non-free'
set system package repository stretch distribution stretch
set system package repository stretch url http://mirrors.tuna.tsinghua.edu.cn/debian
commit ; save
配置 Debian 的源,这里使用了清华的源,如果有别的需求的话可以上 Debian worldwide mirror sites 找一下对于你来说速度比较快的源,记得看后面的注释是需要包含 mipsel 的,比如下图中的 163 的源这种就不要选了:
配置好后 apt update
一波(但别 apt upgrade
,不然要炸),然后安装用来临时保持的 screen,和用来传包的 rsync: apt install screen rsync -y
。
Download GOST
在自己电脑上下载 GOST,在写本文时 GOST 版本为 v2.11.1,所以用的是 https://github.com/ginuerzh/gost/releases 的 https://github.com/ginuerzh/gost/releases/download/v2.11.1/gost-linux-mips64le-2.11.1.gz
在本地解压之后把 GOST 的可执行文件传上路由器,然后在路由器上开 screen 后启动 GOST,这里假设你使用的是如下指令启动的 GOST(监听本地 3306 端口,并使用 WebSocket 隧道转发到远程 12.34.56.78
的 995 端口):
./gost -L=tcp://:3306 -L=udp://:3306 -F=forward+ws://12.34.56.78:995
Configure Firewall
由于这个程序是直接开在路由器上的,UBNT ERX 默认有防火墙挡住了这个请求,所以需要在防火墙上开个口子放行 3306 端口的流量到路由器上,在 「Firewall/NAT」 那一栏找到 WAN_LOCAL
:
并加入一条目的地址为 3306 的放行规则即可:
Performance
在测试的情况下,用 wss
Forward 方式,跑到 45 Mbps 左右的时候路由器的 CPU 接近 100%。
Misc
POC
以上只能算是个 POC 了,证明路由器可以这么用,但是从转发(以及加解密)性能来看,跑 GOST 的确吃力,通过这个实验也算是慢慢理解为啥之前某著名代理工具的某些加密算法会强调在弱算力设备上的运行速度。
DDNS
UBNT ERX 没有自带 DDNS 功能,不过既然路由器上有 Linux 环境,我们可以自己搓一个出来,可以参考我的笔记本: 用 cURL 自動更新 Cloudflare IP 地址實現 DDNS,配合 crontab 使用。
HWNAT
许多人拿到路由器后可能会习惯性地打开 Hardware Offloading,虽然这个特性有一些好处,比如:
Without offloading enabled, IPv4 traffic will be routed via the CPU and will be limited to around 300Mbps on the EdgeRouter Lite (ERLite-3). With offloading enabled, the throughput will be about 950Mbps.
但是在文末 Reference 3 链接中有一些说明:
You should only need to enable offloading for these features if you are using them in your environment. However, enabling offloading for all features will not cause a negative impact if those features are not being used.
开启前建议仔细阅读一下。