Permalink: 2014-07-10 09:41:04 by ning in misc tags: all

1   分析

抓包, 发现 23.239.5.211 这个host:

ning@ning-laptop ~/test$ host 23.239.5.211
211.5.239.23.in-addr.arpa domain name pointer li699-211.members.linode.com.

访问 https://23.239.5.211/ 发现是一个https服务.

也就是说, honx 架设了一个https代理服务器,

但是, 据我所知, client 和proxy 之间的协议, 只支持 socks, socks5, http, 并不支持https. 目前PAC文件也是只支持这三种协议,

因为g-f-w会根据内容过滤, 所以代理必须使用一种加密的通道, 而不能是socks, http, 这也就是自己之前一直用ssh隧道的原因.

2   chrome支持https proxy

看了一下 chrome 扩展中 允许的 proxy 类型:

https://developer.chrome.com/extensions/proxy

发现有https协议:

Scheme      Port
http        80
https       443
socks4      1080
socks5      1080

原来, chrome 是支持 https 代理的:

http://www.chromium.org/developers/design-documents/secure-web-proxy http://www.chromium.org/spdy/spdy-proxy

可以直接在porxy.pac里面返回HTTPS xxx就行:

function FindProxyForURL(url, host) { return "HTTPS secure-proxy.example.com:443"; }
  • 其实这里也可以是SPDY
  • HTTPS proxy 的支持是chrome特有的, 目前还没发现其它浏览器或者ssh客户端之类支持(因为代码相对复杂)

3   尝试破解

既然如此, 我们写这样一个pac文件:

function FindProxyForURL(url, host) {
    return 'HTTPS 23.239.5.211:443;';
}

似乎就ok, 但是测试发现不行, 原因是 https 有域名校验, 这里chrome可能使用强制校验, 必须通过匹配的域名访问 23.239.5.211 才行.

再查了一些chrome的资料, 其实通过 chrome://xxx-internals/ 很容易发现, honx其实也是写了这样的一个pac文件. 可以清楚的看到:

PAC script: data:application/x-ns-proxy-autoconfig...

它的内容是:

function FindProxyForURL(url, host) {

var D = "DIRECT";
var p='HTTPS xxxxx.com:443;';

var node = {"net":{"akamaihd":1,"facebook":1,"fbcdn":1,"cloudfront":1,"sstatic":1,"doubleclick":1,"2mdn":1},"com":{"facebook":1,"twitter":1,"twimg":1,"google":1,"googleusercontent":1,"googleapis":1,"gstatic":1,"gmail":1,"tumblr":1,"appspot":1,"amazonaws":{"s3":1},"blogspot":1,"blogger":1,"mediafire":1,"ytimg":1,"youtube":1,"googlevideo":1,"youtube-nocookie":1,"wordpress":1,"vimeo":1,"googlesyndication":1,"ggpht":1,"imgur":1,"googleadservices":1,"cloudflare":1,"chrome":1,"symantec":1},"co":{"t":1},"hk":{"com":{"google":1}},"ly":{"bit":1},"be":{"youtu":1},"wpad":1,"org":{"chromium":1}};

var hostParts = host.toLowerCase().split('.');
for (var i=hostParts.length - 1; i >= 0; i --) {
    var part = hostParts[i];
    node = node[part];
    if (node == undefined || node == 1) break;
}
if (node == 1)
    return p;

return D;
}

我们发现这个脚本里面清楚的写着xxxx.com 这个域名, 把自己的pac换成这个域名:

function FindProxyForURL(url, host) {
    return 'HTTPS xxxxx.com:443;';
}

ok, 发现我们已经顺利使用这个https 代理了.

这里为了防止大家瞎搞, 域名我已经隐去了.

这段js里面居然用了一个 trie-tree , 好赞, 不像我写的土鳖js:

var hosts = [
    "google.com",
    "google.co.jp",
    "blogspot.com",
];

function FindProxyForURL(url, host) {
    for (var i in hosts){
        pattern = '.*' + hosts[i] + '.*';
        if (regExpMatch(host, pattern)){
            return proxy;
        }
    }
    return "DIRECT";
}

4   这个方法对自己有啥用

  • 既然知道了chrome 可以用https 的proxy, 那我就可以在自己的linode上搭了.
  • 搭了这样一个https代理, 会不会被大家乱用呢.. 还得想办法.
  • 如果能让ssh客户端等支持https 代理就好了.

4.1   架设https 代理服务器的方法

Running a Secure Web Proxy

  1. While all the details of running a secure web proxy are out of scope for this document, here are two suggestions. If you are already running a web proxy, you use stunnel to convert it into a secure web proxy. For example:

    stunnel -f -d 443 -r localhost:8080 -p cert.pem
    

This would cause stunnel to listen for SSL connections on port 443 and send any HTTP requests to the web proxy running on port 8080.

  1. Squid appears to offer support for running as a secure web proxy via the https_port directive.
  2. nginx+SPDY?
  3. https://github.com/igrigorik/node-spdyproxy

5   给honx的建议

  • 增加某种验证机制,
    • 使用http/https的 proxy验证机制
      • 都比较弱, 而且需要用户介入手动填一次密码, 会频繁打断用户.
    • 比如在代理服务器上同时开一个注册服务, 当honx启动后, 每x秒会向这个接口注册一次, 说这个clientip是合法的, 这个接口可以加入复杂的验证, 这样就比较优雅.
      • 不过引入这种机制会导致一些ip会变(公司多出口之类)的用户可能不能正常使用. 比较烦恼
    • 再者, 一个honx用户估计是可以在多处登录, 这样就可以多人共享proxy, 所以, 加认证等等, 终归是防君子不防小人.

  • 建议针对学生降价.

6   ps

  • honx 在产品设计上非常傻瓜, 0配置, 一键加入代理也很方便.
  • 好服务, 要呵护, 希望大家没功夫折腾的同学, 多多支持honx(我也买了)

Comments