Pages

Friday, 31 July 2015

在Android上走出"天朝局域网"

买了Android手机以后,一直在考虑如何访问这些网站。经过一番苦战,终于搞定,把相关经验写下来分享。
文章比较长,比较有价值的内容包括:
  • 第二部分介绍Opera mini,除了能实现访问抽疯的国外网站外,还能提高访问速度。
  • 第三部分主要介绍SSH Tunnel,能解决DNS污染的问题,并可实现浏览器以及其他非浏览器应用的翻墙访问。
我的手机是Huawei C8500, firmware:2.1-update1, kernel: 2.6.29-perf。

第一阶段:不给力的http_proxy和VPN

最早,我尝试用Android自身的HTTP代理方式。网上有不少帖子读在讨论给Android的一个系统设置表增加http_proxy记录来实 现http代理,主要方式包括通过手动使用sqlite3修改data/data /com.google.android.providers.settings/databases/settings.db表,增加 http_proxy代理记录(详细参考此文:Tips: Howto Connect Android Emulator behind proxy),如下所示:
./adb shell sqlite3 /DATA/DATA/com.google.android.providers.settings/DATABASES/settings.db
 “\”INSERT INTO system VALUES(99,’http_proxy’,[host_or_IP]:[port]);\”"
但经过验证,至少在我的机器上是不行的。
然后又照着这篇文章([Android] How to set proxy for android browser),写了一个插件直接设置浏览器代理。这个方法试了试,偶尔能行,偶尔不能行。
后来再尝试VPN,试验了几个VPN供应商提供的试用账户,都没有成功。

第二阶段:翻墙麻利、访问提速的Opera mini

Opera mini 是 老资历的翻墙工具了,但自从前段时间出了Opera中国版的事情以后,官方版本不支持翻墙了,必须自己破解,并搭建一个IP位于国外的中转服务器。中转服 务器其实很简单,只是接收请求,然后用CURL去Opera官方服务器去获取实际内容,再将内容发回。虽然弄一个使用自己的中转服务器的破解版Opera mini比较麻烦,但是搭建起来以后觉得速度相当快。尤其是访问国外几个大站如Google, facebook 和 twitter的移动版,那是相当流畅,远比 Andriod 自带的浏览器流畅。从服务器端Squid代理的日志来看,使用Opera mini访问同一个网页,貌似最终只有一个HTTP请求,图片和JS,CSS等都不用再单独请求了。从日志看,请求数明显减少,网页体积也缩小很多,流量 也省不少。
详细参考:
搭建php版的中转服务器十分简单,就一个PHP文件,内容如下(文件内容参考自opera mini 翻墙大法提供的文件):
if ($_SERVER['REQUEST_METHOD'] == 'GET') {
       //......
} else {
        $curlInterface = curl_init();
        $headers[] = 'Connection: Keep-Alive';
        $headers[] = 'content-type: application/xml';
        $headers[] = 'User-Agent: Java0';
        curl_setopt_array($curlInterface, array(
                CURLOPT_URL => 'http://server4.operamini.com',
                CURLOPT_HTTPHEADER => $headers,
                CURLOPT_POST => 1,
                CURLOPT_POSTFIELDS => @file_get_contents('php://input'))
    );
        $result = curl_exec($curlInterface);
        curl_close($curlInterface);
        header('Content-Type: application/octet-stream');
        header('Cache-Control: priavte, no-cache');
        echo $result;
}
顺带提一句,在你翻墙以后(前提是使用第三部分介绍的方式或者其他方式实现443/80端口翻墙以后),你可以使用最新的Opera Mobile 10翻 墙。Opera Mobile 10支持手动设置代理,可直接使用国外IP的代理服务器。 Opera Mobile 10 有Android的原生版本,并且不经过Opera的中间服务器代理,你不需要担心安全问题。不过相比较经过中间服务器的Opera mini版本而言,速度慢了不少,且体积庞大,安装完成后有二十几兆大。
有关Opera Mobile 10的代理设置参考这里

第三阶段:使用SSH Tunnel为所有80/443端口的访问翻墙

但还有一个问题,就是GMS里的一部分应用被墙了,如Gmail,这必须使用能全局代理的代理软件才行。在桌面系统上,有很多工具实现全局代理。其中让系 统以socks5代理协议通过SSH隧道就是一种常用方式。SSH隧道在本地服务器与SSH服务器之间建立起一个加密信道,本地系统数据经过这条隧道传递 给目标服务器。 这种代理方式所有的内容都经过了加密,并会对流量进行适度压缩。其需要的资源也比较少,只要拥有一个ssh账户就可以实现。这篇文章 (A short guide to SSH port forwarding) 对通过SSH做端口转发做了详细介绍。
不过在Android系统上,因为系统本身不支持代理设置,尤其像Huawei C8500这样的手机,在Wifi/3G网络的设置中都不能设置代理,必须要有一种方式将本地数据包转发到SSH隧道的本地端口。因为Android是基 于Linux的,通常我们可以用iptables来实现数据包的转发。有关iptables的内容,可以参阅一下这篇中文指南,了解一些基本知识。
除此以外,使用端口转发的方式,还需要在服务器端建立一个http代理服务器监听SSH隧道的另一端,接收请求并将请求转给目标服务器,并将处理结果再通过隧道传回给手机。常用的http代理服务器有 squid, nigix 等。
一开始我找到的是TransparentProxy, 但这个软件需要手机除了需要支持 iptables外, 内核还需支持 iptables 的 REDIRECT 表。我的手机不支持 redirect,只好作罢。
然后试了试 SSHTunnel,结果没报告错误,但就是访问不了。 因为这个项目是开源的,翻开代码一看,跟TransparentProxy一样,需要 iptables 的 redirect 支持。
尝试了用 connectBot 做动态代理,然后再写了个软件将所有端口的内容转发到这个connectBot。转发通过 iptables 的 DNAT 来实现。不过这样操作起来还是比较麻烦,要开启这两个软件,而且 connectbot 耗电太厉害了,开了一段时间以后,手机发热。
最后,签出 SSHTunnel 的代码,修改成在内核不支持 redirect 的手机上,自动使用 DNAT 实现转发。问题终于搞定。
完成后,向该项目提交了这个patch,该项目已经接受此patch,现在SSHTunnel支持更多的与华为C8500的固件类似的手机了。
SSH Tunnel 项目主页: 详细使用介绍请去该项目的帮助页面

from http://blog.xiping.me/2011/03/break-gfw-on-android.html