ARM 路由器的独占优势

2015-03-21 18:27:50 +08:00
 comicfans44

最近入了一台R6300v2,ARM双核,被很多人吐槽发热量大(再配上R6300的电磁炉造型),

可用软件包少(大部分可用的软件都是mips架构的),但ARM有一个优势,就是go语言原生

支持! 折腾了一阵,终于在R6300v2上成功运行了tor和psiphon3, 在这里简单分享下

希望给那些买了ARM cpu路由器的机友们一点折腾的新思路。涉及的方面比较多,也无法

面面俱到,有具体的问题欢迎后续交流。

R6300v2刷的系统是kong大的dd-wrt k3 arm ac 25100M,需开启jffs

tor 主程序并不是go语言编写的,这个编译教程估计也不少,就不废话了。tor在我朝不能
直接运行,还需要配合go语言编写的meek插件

go语言运行环境的准备和根证书拷贝:

需要最新的1.4,下载安装后修改go的源代码src/crypto/x509/root_unix.go

这里面硬编码了系统的根证书路径,ddwrt默认没有对应的证书,meek插件默认无法运行。
请参考原源代码里面certFiles位置拷贝一份主机linux版自带的证书文件到到ddwrt上,

再将这个证书路径加在certFiles变量列表里面

设置GOROOT,GOPATH,PATH变量以便后续执行go命令,可参考一些golang的教程

meek插件的编译(meek的git仓库在tor网站上,请先自行翻墙获取):

meek源码路径下有很多目录,但只有meek-client是终端运行所需的。在目录下执行

GOOS=linux GOARCH=arm GOARM=5 go build

将生成meek-client可执行程序

将交叉编译好的tor主程序和meek-client拷贝到dd-wrt上面,准备tor所需的配置文件

torrc

简要参考如下:

socks5代理ip和端口,替换成你自己的路由器地址和相应端口

SOCKSListenAddress 192.168.1.1:9150

下面会具体说明

Bridge meek 0.0.2.0:2 url=URL front=FRONT

meek-client的路径

ClientTransportPlugin meek exec /jffs/usr/bin/meek-client

UseBridges 1

tor支持透明代理,配合iptabes可实现透明代理,替换成你自己的路由器地址和相应端口

TransPort 192.168.1.1:9040

URL和FRONT是meek插件依赖的云服务器地址,为减少被墙的可能,我就不贴出来了,

可以按照如下步骤来获取:

安装windows版的torbrowser运行,在配置里面选择meek并成功连接一次tor网络

在tor\Browser\TorBrowser\Data\Tor目录下找到torrc文件打开,即可找到

Bridge meek xxxx xxxx xxxx的这一行,copy到dd-wrt的torrc的对应位置里面即可

tor的启动命令

tor -f torrc路径

接下来你就可以测试一下tor是否运行正常,再配合iptables搞一搞透明代理

psiphon3的交叉编译

原有的psiphon3在linux下是python编写,但是在路由器上运行需要交叉编译python不说,
还需要交叉编译改版的ssh,比较麻烦。好在后来又开发了go语言版本,相对来说轻量级一点
(但源码还不太完善,编译过程很麻烦)。

大致的流程如下(可能比较笨吧,总之可行):

1下载psiphon3源码

2.1修改源码去除server_list校验并编译主机版

2.2运行主机版生成连接数据库

3.1修改源码更新sqlite部分并编译ARM版本

3.2将ARM版本和主机版生成的连接数据库拷贝到dd-wrt上运行

psiphon3的go语言版本在github上可找到psiphon-tunnel-core

psiphon3启动过程要通过一个server_list来生成连接数据库,

但我没有搞定如何正确设定public key让正常的server_list通过校验,只好

曲线救国,先去除源码中的校验代码

psiphon/remoteServerList.go 79行左右

去除

err = validateRemoteServerList(config, remoteServerList)

if err != nil {

return ContextError(err)

}

部分

然后编译主机版:

在ConsoleClient目录中执行

CGO_ENABLED=1 go build

编译主机版(需要系统中有gcc编译器)

再编写一个config.json放在编译出的可执行文件同目录内容如下:

{

"PropagationChannelId" : "FFFFFFFFFFFFFFFF",

"SponsorId" : "FFFFFFFFFFFFFFFF",

"RemoteServerListUrl" : "server_list地址",

"RemoteServerListSignaturePublicKey" : "胡乱写",

"DataStoreDirectory" : "",

"DataStoreTempDirectory" : "",

"LogFilename" : "",

"LocalHttpProxyPort" : 8080,

"LocalSocksProxyPort" : 1080,

"EgressRegion" : "",

"TunnelProtocol" : "",

"ConnectionWorkerPoolSize" : 10,

"TunnelPoolSize" : 1,

"PortForwardFailureThreshold" : 10,

}

server_list的地址可使用https://psiphon.ca/server_list

不过这种配置要先能够透明翻墙。可以先把这个文件下载下来,再

架个简单的本地http服务,将server_list指向你本地的这个地址

接下来即可运行主机版

psiphon3 -config config.json

没有问题的话可以看到一大堆的输出,同目录下会生成psiphon.db,

中断psiphon3进程,用sqlite打开psiphon.db看看serverEntry表,如果有几十条记录,

那就是生成成功了。

(同目录下会有psiphon.db-joural psiphon.db-wal几个sqlite运行时所需的临时文件,

用sqlite打开数据库查询一次,并正常退出的话就会消失。推荐执行这个过程,不然

后续拷贝到dd-wrt上时候还要将这几个临时文件一并上传)

接下来修改让arm正常运行的源码:

找到GOPATH路径下

(注意是GOPATH路径下,虽然psiphon3的源代码路径下也有同名目录,但那并不是编译时所使用的!)
src/github.com/Psiphon-Inc/go-sqlite3

将sqlite3.c替换为最新的3.8.8.2版本(sqlite官网有下载),默认的3.8.5编译后ARM上运行非法指令,
原因不明。(编译主机版本时不修改并不影响)

交叉编译ARM版本:

注意,此过程需要ARM的gcc交叉编译器,这个需要和dd-wrt所用的兼容。

kong大25100M的版本使用的是musl c库,因此交叉编译器要选musl c库版本。

CC=arm-musl-gcc(你使用的交叉编译器) CGO_ENABLED=1 GOOS=linux GOARCH=arm GOARM=5 go build
将最终编译为ARM版psiphon3,将config.json和psiphon.db一并上传dd-wrt

接下来还有最关键的一步:必须要拷贝到 /tmp目录下执行!

sqlite3(或者是psiphon3使用sqlite3的方式)与dd-wrt中的jffs2文件格式存在兼容问题,
无法正常读写数据库,但/tmp挂载为ramfs,可以正常运行

执行过程同样是

psiphn3 -config config.json

psiphon3默认在127.0.0.1上监听,可使用iptables将代理暴露到路由器局域网ip上

也可以修改psiphon3源代码中socksProxy.go中的内容,把127.0.0.1改成路由器的局域网ip

附录:

GOARM环境变量的简要说明:R6300v2的cpu是cortex-a9,体系上隶属于armv7l

但是没有vfp和neon,在go语言里面这样的硬件被归类到GOARM=5里面,

请不要尝试GOARM=6或者GOARM=7,运行时会提示不支持。

tor meek的配置参考了

http://www.scutlaoyi.tk/wpeiebTool003-how-to-use-tor-with-meek.html

如果tor运行不正常,可尝试配置

ClientTransportPlugin meek exec /tmp/meek-client --log /tmp/meek-client.log

看看/tmp/meek-client.log里面输出了什么。如果是提示

x509 can not load system root

那就是go源码修改和根证书拷贝的环节出错

哪里获取musl版交叉编译器?google,或者buildroot

我用的是buildroot 2015.2 ,里面已经可选musl c库了

psiphon3还有一个命令参数

-serverList=

也许可以直接指定android版psiphon3中的serverList的文本内容,不过我没有确认,

有兴趣的去看源代码吧

如果读者有兴趣读一下psiphon3源代码,那么配合windows版的psiphon3注册表和sqlite3
其实也完全可以手动生成可用的连接数据库的,但是我放弃了,因为psiphon3的连接数据库
格式真的是...匪夷所思,自定义字符串格式嵌入到json中再当成二进制(可能还转换成了
hex)放在sqlite里面...难道是为了防止被扫描出来?

dd-wrt 25100M的说明

自带的模块不支持ipset,需要手动编译模块xt_set

自带的dnsmasq不支持ipset,需要手动编译...

自带的iptables不支持ipset,需要手动编译...(iptables与musl库兼容性不好,需要改动一些头文件,好在不是很多)

不知道是我执行命令有误,还是内核配置有问题,iptables REDIRECT 做透明代理就是不行,
但DNAT到本机ip是可以的

buildroot编译的musl版本是1.16,但dd-wrt里面的版本比较低,导致某些软件交叉编译

可以通过但运行时找不到符号,需要改动些源代码

mips的路由器怎么办?gcc 5.0 支持go 1.4标准,可以自己编译支持go语言的gcc编译器,
再用gcc go来交叉编译mips版本的go程序。我没有尝试,也不确定可行,有兴趣的可以试一试

1776 次点击
所在节点    路由器
6 条回复
fclql
2015-03-21 20:12:18 +08:00
路由干路由的事,集成那么多没实际意义的东西只会带来bug
xfspace
2015-03-21 20:56:51 +08:00
TL;DR
yuhaaitao
2015-03-21 22:29:23 +08:00
好东西,可是好复杂
zx9597446
2015-03-23 09:24:05 +08:00
go编译到mips很坑的
xrjr2015
2015-04-20 01:21:45 +08:00
上个网,搞的像科研一样,失去了意义!而且赛风和tor都慢的要死,直接一包烟钱买ss账号比啥都简单!
southwolf
2015-05-06 07:13:12 +08:00
gcc-go 是能编译……但是非常讨厌地不能strip, 导致编译出来的文件大了一倍不止……

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/178482

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX