最近入了一台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
简要参考如下:
SOCKSListenAddress 192.168.1.1:9150
Bridge meek 0.0.2.0:2 url=URL front=FRONT
ClientTransportPlugin meek exec /jffs/usr/bin/meek-client
UseBridges 1
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程序。我没有尝试,也不确定可行,有兴趣的可以试一试
2
xfspace 2015-03-21 20:56:51 +08:00
TL;DR
|
3
yuhaaitao 2015-03-21 22:29:23 +08:00 via Android
好东西,可是好复杂
|
4
zx9597446 2015-03-23 09:24:05 +08:00
go编译到mips很坑的
|
5
xrjr2015 2015-04-20 01:21:45 +08:00
上个网,搞的像科研一样,失去了意义!而且赛风和tor都慢的要死,直接一包烟钱买ss账号比啥都简单!
|
6
southwolf 2015-05-06 07:13:12 +08:00
gcc-go 是能编译……但是非常讨厌地不能strip, 导致编译出来的文件大了一倍不止……
|