Nep

纯粹是个人兴趣的表达

突破低性能路由器限制,大流量高并发ss透明代理实践(0619更新)

0.前言

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

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

1.开始之前

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

  • MT7621及以上性能的OpenWRT智能路由器(简称 路由器)
  • 一台拥有千兆网卡的电脑、平板或嵌入式设备,要求常年开机(简称 客户端,我用的是一个Z8300的平板电脑,USB3.0外接千兆网卡)(0619更新:现在已经替换为NanoPi Neo 2,这是一个全志H5芯片具有板载千兆网卡的嵌入式设备)
  • 一台线路优良、大带宽的境外服务器
  • 网线若干、千兆交换机(非必须)

注意:
若你有斐*讯K3那样性能怪兽级别的ARM路由器,可以直接无视本文,因为默认方案性能就足够(0619更新:实测K3也不能跑满百兆带宽的ss)
本文的方案不涉及UDP转发,也无法做到UDP转发,游戏玩家请绕道(0619更新:现在无法做到UDP转发,但是可能更新加入)
服务器选购、TCP优化、BBR、锐速等不在本文讨论范围之内
本文由于不可抗力原因省去ss服务器搭建部分,请大家自己寻找教程部署服务器(我想能来看这篇文章的dalao也应该会配置吧,笑)

2.本文用到的开源项目

  • openwrt-shadowsocks (请自行寻找)
  • luci-app-shadowsocks (请自行寻找)
  • shadowsocks-libev (客户端使用,请自行查找)
  • https://github.com/cybozu-go/transocks
  • (0619更新)https://github.com/xsm1997/KumaSocks

3.在客户端中部署ss

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

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

4.编译路由器可用的KumaSocks

(0619更新:此部分已经替换为更轻量级的KumaSocks,KumaSocks为我的自用项目,现已在github上开源)

golang官网下载最新的go语言安装包并且运行。Windows需要安装git for windows。以下代码以Windows为例。

首先设置GOPATH环境变量。

打开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

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

go build -ldflags "-s -w"

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

upx --best KumaSocks

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

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

5.设置路由器ss

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

6.魔改脚本

执行/etc/init.d/shadowsocks stop

停止ss。

用你喜欢的编辑器修改/etc/init.d/shadowsocks,
注释掉129行的pidof ss-redir > /dev/null || return 0
注释掉135-138行的ss-redir命令启动。
(0619更新)由于luci-app-shadowsocks的更新,行号可能不对应,请根据语句内容修改。
新建/etc/init.d/kumasocks文件,内容为:

#!/bin/sh /etc/rc.common
START=90
STOP=15
start() {
/root/kumasocks-mipsle 1> /dev/null 2> /dev/null &
}
stop() {
kill -9 $(pidof kumasocks-mipsle)
}

其中/root/kumasocks-mipsle为KumaSocks可执行文件的完整路径。请自行把>替换为>,&替换为&。(markdown出bug了,不是

赋予可执行权限。

chmod a+x /root/kumasocks-mipsle

编辑或创建/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的监听端口。

(0619更新)
注意:原有方案transocks在一些小内存路由器上(如128M内存的K2P)可能会因为内存不足而崩溃,这也是我自己写KumaSocks的重要契机。如果你还是遇到了不定期的崩溃,推荐自己写一个守护脚本。

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中,transocks会自动负载均衡到4个线程占满CPU,200M远远不是问题!如果出了性能问题,你可以给路由器轻微超频一下,我的K2P超频到1.1Ghz跑200MCPU负载在50%左右,性能绰绰有余。本文可以运用在酸酸乳环境中,实现方法同理,只需要在客户端中把ss替换为酸酸乳即可。

点赞
  1. vancy说道:

    留个即时通讯的方式?有点问题请教一下

    1. 熊本熊说道:

      请联系telegram @kumakitami

  2. 噜噜说道:

    mips按文章步骤编译出来的KumaSocks执行会报错Illegal Instruction,重新编译时增加GOMIPS=softfloat解决,可能是golang版本的问题?跑起来实际效果不错,原来ss-redir跑在wndr3800上CPU满载也就十多兆带宽,现在满速50M,瓶颈变成了路由器的百兆LAN口,离探到校园网IPv6的带宽上限还远得很。目前问题是改成这样配置后PS4连不上网,一开始怀疑是不支持UDP的问题,可是把电脑当作二级路由给PS4开热点又能联网了,还没想清楚原因。

    1. 熊本熊说道:

      感觉是你配置的问题,因为我这里的PS4是可以正常联网的,或者你查看一下PS4中有线连接有没有设置代理,或者改一下DNS试试看?

    2. 熊本熊说道:

      运行错误是因为你路由CPU本身没有MIPS的硬件浮点指令集,所以需要手动指定软浮点。新一点的CPU比如说MT7620/7621都是有硬件浮点的。

    3. 陌陌说道:

      请联系telegram @kumakitami

  3. 三月三说道:

    非常谢谢你的文章,我的路由是k3,用了你的程序,性能提高了很多。

  4. rampageX说道:

    没搞懂为什么要再用一个 Socks5 中转。

    如果在中间机器跑 SS ,那么路由器 iptables 规则直接转发到那台中间机器不就可以了?

    1. 熊本熊说道:

      实际上透明代理会读取iptables转发流量的原始目的IP,而这部分是Linux内核存储的。TCP协议并不包含这部分信息。所以脱离了iptables做转发的主机,透明代理都是无法使用的。
      你可以自行测试用DNAT和SNAT的方式做转发,ss-libev是否能接受并正常连接。

  5. Joe说道:

    博主是否可以提供一下7620A的预编译版本,直接下载的不兼容呀。

    1. 熊本熊说道:

      请联系Telegram,@kumakitami

  6. wwbfred说道:

    在op上运行产生了超大的内存占用,648m 539%,这是怎么回事?

    1. 熊本熊说道:

      那个内存占用是虚拟内存,实际上物理内存只占用几M。

发表评论

电子邮件地址不会被公开。 必填项已用*标注