redsocks on android指南
redsocks的作用
redsocks是一个通用的proxy redirector,能实现系统级别的全局代理(HTTP或者socks),从而可以实现HTTP代理或者SSH翻墙。
大概的原理是用iptables把外向的包重定向到本地redsocks开的端口,然后redsocks可以从tcp/ip头里得到包的目标ip的端口,然后就通过代理建立连接。
由于iptables的语法非常灵活,可以非常有效地控制哪些包走代理(国内国外,端口,进程,甚至是Level7的协议种类),但是这个方案也有一个比较致命的缺点。
由于redsocks并非针对http协议,所以只能得到目标地址的ip而不是域名,这样的话在建立连接之前需要有一次dns询问。 这个问题在ssh的情况下是不存在的,因为ssh采用的socks5提供了dns的代理,同时redsocks也支持udp,在config文件里多加一个udp就可以了。 但是在使用http代理的情况下,这个问题必须通过一个干净无污染的dns解决,而且显然,这个dns服务器必须在国内。否则就必须手工维护一个很大的hosts文件了。
cross compile ARM下的redsocks
先下载codesourcery.com提供的gcc arm toolchain,不嫌麻烦也可以自己做一个
$ wget http://www.codesourcery.com/sgpp/lite/arm/portal/package7851/public/arm-none-linux-gnueabi/arm-2010.09-50-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 $ md5sum arm-2010.09-50-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 f9dbd7a2daf20724e013cc4b5b64d62f arm-2010.09-50-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 $ tar jxf arm-2010.09-50-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 $ export PATH=$PATH:`pwd`/arm-2010.09/bin
下载并交叉编译libevent2
$ wget http://monkey.org/~provos/libevent-2.0.10-stable.tar.gz $ md5sum libevent-2.0.10-stable.tar.gz a37401d26cbbf28185211d582741a3d4 libevent-2.0.10-stable.tar.gz $ tar zxf libevent-2.0.10-stable.tar.gz $ cd libevent-2.0.10-stable $ ./configure --host=arm-none-linux-gnueabi $ make $ cp .libs/libevent.a .. $ DESTDIR=/tmp make install $ cd ..
用生成的libevent.a编译redsocks
$ git clone -b libevent2-fix https://github.com/bjin/redsocks $ cd redsocks $ sed -i 's/-levent/..\/libevent.a -lrt/g' Makefile $ CC=arm-none-linux-gnueabi-gcc CFLAGS="-O4 -static -I /tmp/usr/local/include" make $ file redsocks redsocks: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, for GNU/Linux 2.6.16, not stripped
手机端的配置
先说下手机端的要求,必须有iptables,这个在CyanogenMod里是自带的,否则可以从网上下一个。另外显然需要有root权限,最好配合SuperUser这个app。
下面的例子是以比较简单的http代理为例,ssh的情况复杂些,需要额外用openssh建立隧道
$ cat redsocks.conf # redsocks的配置文件
base {
log_debug = on;
log_info = on;
log = "file:/data/redsocks/redsocks.log";
daemon = on; // 在后台运行
redirector = iptables;
}
redsocks {
local_ip = 127.0.0.1;
local_port = 12345;
ip = <PROXY IP>;
port = <PROXY PORT>;
type = http-connect; // HTTP CONNECT,一般用于HTTPS
login = "<PROXY USER>"; // 可选
password = "<PROXY PASS>"; // 可选
}
redsocks {
local_ip = 127.0.0.1;
local_port = 54321;
ip = <PROXY IP>;
port = <PROXY PORT>;
type = http-relay; // 一般的HTTP 代理
login = "<PROXY USER>"; // 可选
password = "<PROXY PASS>"; // 可选
}
$ cat start_re.sh # 启动iptables重定向的脚本
/system/bin/iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to 54321
/system/bin/iptables -t nat -A OUTPUT -p tcp --dport 443 -j REDIRECT --to 12345
/system/bin/iptables -t nat -A OUTPUT -p udp --dport 53 -j DNAT --to-destination x.x.x.x:53 #用iptables重定向dns包,x.x.x.x必须是国内干净的dns服务器
$ cat start.sh # 启动redsocks的脚本
cd /data/redsocks
if [ -e redsocks.log ] ; then
rm redsocks.log
fi
./redsocks -p /data/redsocks/redsocks.pid
$ cat stop_re.sh # 关闭iptables重定向的脚本
/system/bin/iptables -t nat -F OUTPUT
$ cat stop.sh # 关闭redsocks的脚本
cd /data/redsocks
if [ -e redsocks.pid ]; then
kill `cat redsocks.pid`
rm redsocks.pid
else
echo already killed, anyway, I will try killall
killall -9 redsocks
fi
$ adb shell mkdir /data/redsocks
$ for file in `ls *.sh` redsocks redsocks.conf; do adb push $file /data/redsocks/; done最后建议采用Scripter运行脚本,直接调用/data/redsocks/xxx.sh就可以了,全局建议开着redsocks,想翻墙就start_re.sh,想关闭就stop_re.sh。