突破低性能路由器限制,大流量高并发SS透明代理实践

0. 前言 天朝的程序员,由于我国国情的特殊性,基本都需要科学上网。由于功夫网的封锁,所以都会选择当今配置简单、相对稳定的科学上网方案-“ShadowSocks”(简称ss)。而且我们还比较懒,所以希望把ss做在路由器里,成为透明代理。目前智能路由器的主流系统是OpenWRT,主流架构是MIPS,性

0. 前言

天朝的程序员,由于我国国情的特殊性,基本都需要科学上网。由于功夫网的封锁,所以都会选择当今配置简单、相对稳定的科学上网方案-“ShadowSocks”(简称ss)。而且我们还比较懒,所以希望把ss做在路由器里,成为透明代理。目前智能路由器的主流系统是OpenWRT,主流架构是MIPS,性能成为了较大瓶颈。即使是性能较强的MT7621方案,单线程也只能跑到50-70M左右,这对于大带宽宽带(比如说我的500M联通),简直是小的可怜。由于以上的原因,促成了本文。

部署了本文的方案之后,路由器的性能不再会成为瓶颈,只要拥有一个优良线路的大带宽服务器,就可以跑满带宽。(本人的500M带宽实测可以跑满)

1. 开始之前

为了部署本文的方案,你需要以下的设备及资源:

  • MT7621及以上性能的OpenWRT智能路由器(简称:路由器)
  • 一台拥有千兆网卡的电脑、平板或嵌入式设备,要求常年开机(简称:客户端,我使用的是RK3399的开发板,RockPi 4)
  • 一台线路优良、大带宽的境外服务器
  • 网线若干、千兆交换机(非必须)

注意:
本文的方案不涉及UDP转发,也无法做到UDP转发,游戏玩家请绕道。
服务器选购、TCP优化、BBR、锐速等不在本文讨论范围之内。
本文由于不可抗力原因省去ss服务器搭建部分,请大家自己寻找教程部署服务器(我想能来看这篇文章的dalao也应该会配置吧,笑)
本文所述方法同样可以适用于ssr、v2ray、trojan等。

2. 本文用到的开源项目

  • openwrt-shadowsocks (请自行解决)
  • luci-app-shadowsocks (请自行解决)
  • shadowsocks-libev (客户端使用,请自行解决)
  • https://github.com/xsm1997/KumaSocks

3. 在客户端中部署ss

请在客户端中部署ss-local,本文中,监听1080端口,如果有条件请开启--fast-open和--no-delay。部署方法由于某些原因不再赘述。

注意:由于现在封锁很严,部署ss时请采用AEAD协议(如chacha20-ietf-poly1305),如采用其他非AEAD协议导致服务器被日,本人概不负责。

本文只用ss来举例,也可使用ssr、v2ray、trojan等,注意要使用socks5(入站)协议,并监听1080端口。

4. 编译路由器可用的KumaSocks

KumaSocks为我的自用项目,现已在github上开源,是一个轻量级透明代理转socks5代理的转换器,仅适用于linux系统。

虽然Github Release界面有预编译的包,但还是推荐自行编译,因为这样才能享受到最新Golang版本(可能)带来的性能优化。

  • Golang官网下载最新的go语言安装包并且运行。Windows需要安装git for windows。以下代码以Windows为例。
  • 设置GOPATH环境变量到某目录,如D:\go
  • 打开cmd窗口,切换到你的GOPATH目录。
go get github.com/xsm1997/KumaSocks
cd src\github.com\xsm1997\KumaSocks
SET GOOS=linux
SET GOARCH=mipsle
go build

linux下的编译命令为:

go get github.com/xsm1997/KumaSocks
cd src/github.com/xsm1997/KumaSocks
GOOS=linux GOARCH=mipsle go build

若路由器的储存空间吃紧,可以用以下命令替换上述命令中的go build

go build -ldflags "-s -w"

如果体积还是大,就要祭出我们的神器upx!

upx --best KumaSocks

实测可以把KumaSocks压缩到700k左右,而且没有显著的性能问题。

  • 在目录下,找到linux可执行文件KumaSocks,上传到路由器中,本文为/root/kumasocks-mipsle,赋予可执行权限。

5. 设置路由器ss

请在路由器中按照普通方法设置ss,达到可以科学上网即可。当然防DNS污染也要做。

6. 魔改脚本

注意:本部分仅以luci-app-shadowsocks作为举例修改,目的是替换ss的执行命令为KumaSocks,同样思路可用于修改其他脚本,如luci-app-ssr-plus、luci-app-passwall等。

  • 执行/etc/init.d/shadowsocks stop停止ss。
  • 用你喜欢的编辑器修改/etc/init.d/shadowsocks
    注释掉129行的
pidof ss-redir > /dev/null || return 0

(为了停用ss启动的检测)
注释掉135-138行的ss-redir命令启动。

  • 由于luci-app-shadowsocks的更新,行号可能不对应,请根据语句内容修改。
  • 新建/etc/init.d/kumasocks文件,内容为:
#!/bin/sh /etc/rc.common
START=90
STOP=15
start() {
/root/kumasocks-mipsle 1>/dev/null 2>&1 &
}
stop() {
kill -9 $(pidof kumasocks-mipsle)
}

其中/root/kumasocks-mipsle为KumaSocks可执行文件的完整路径。

  • 赋予可执行权限。
chmod a+x /etc/init.d/kumasocks
  • 编辑或创建/etc/kumasocks.toml,内容为:
listen-addr = "0.0.0.0:1234"
proxy-addr = "socks5://192.168.1.210:1080"

这里1234为第5步ss透明转发的端口,192.168.1.210为内网中客户端的IP,1080为客户端ss的监听端口。

7. 运行!运行!

/etc/init.d/shadowsocks start
/etc/init.d/kumasocks start

添加开机自启

/etc/init.d/shadowsocks enable
/etc/init.d/kumasocks enable

当然别忘了启动服务器和客户端上的ss!

8. 出现问题怎么办

  • 首先保证在第五步时可以科学上网。
  • 其次在路由器中运行ps,查看是否有kumasocks-mipsle和ss-redir进程。正常情况下应该有kumasocks-mipsle、没有ss-redir,当然ss-local也没有。
  • 如果正常的话请在win下连接客户端的代理,查看是否可连通外网。
  • 如果还是没有问题的话,请查看iptables规则以及ipset是否正常。

9. 总结

由于客户端的性能远远强于路由器,所以这里一般不会是性能瓶颈。

众所周知,go语言的特点就是高并发性能优良,所以在MT7621的双核四线程CPU中,KumaSocks会自动负载均衡到4个线程占满CPU,性能极强。如果出了性能问题,你可以给路由器轻微超频一下,我的K2P超频到1.1Ghz跑200MCPU负载在50%左右,性能绰绰有余。

新版本的Golang编译的KumaSocks,默认启用了splice系统调用来实现零拷贝(zero copy)转发,使数据无需多次复制,效率甚至赶超C写的转发程序。但splice有时会在一些魔改系统上出问题(例如Pandorabox),这时请参照KumaSocks的Github Readme禁用这一功能。

10. 后记

作者本人已经更换软路由,目前并没有继续使用KumaSocks的需求了。但是在有需要时,还是会继续维护KumaSocks。文章中的魔改脚本方法可能已经过时,请根据实际情况进行修改。如有需要,请联系Tg @kumakitami,让我们共同进步!

Comment