Leask

用 Flora_Pac.py 生成自动翻墙的 pac 文件

Leask

源于人们对自由的向往,翻墙技术已渐趋成熟。愿意花点钱,购买海外 VPN 和 ssh 主机用于自由获取信息是目前比较有效的手段。如我之前文章中提及,这两种方式都有需要筛选出那些网站在墙外,那些网站在墙内,以较节约、高速的方式访问网络。八仙过海,各显神通,不少帮助人们解决这一问题,降低翻墙门槛的小项目出现了。较具代表性的有 chnroutes(http://code.google.com/p/chnroutes/) 项目和 autoproxy-gfwlist(http://code.google.com/p/autoproxy-gfwlist/) 项目。前者修改路由表,配合各种 VPN 使用,后者可以配合 AutoProxy for Firefox(https://addons.mozilla.org/firefox/addon/11009) 或导出(https://autoproxy2pac.appspot.com/)为 pac 文件,配合各种代理服务器,包括 ssh -D 使用。他们的原理稍有差异,chnroutes 只区分国内外 IP 段,让国外地址全部走翻墙路线,autoproxy-gfwlist 项目则精确记录着那些网站被墙。

我以往喜欢 ssh -D 生成 SOCKS 代理后,搭配自己的 pac 文件翻墙。最近由于各种原因转到了 VPN 阵营。感觉 VPN 搭配 chnroutes 的确很舒服,不用再关心那些网站被墙,不会因为 gfwlist 更新延迟而影响访问。于是我在想,有没有办法让使用 ssh -D 或者其他翻墙代理的用户能和使用 VPN 的用户那样省心呢?于是我站在巨人的肩膀上,基于 chnroutes 项目,结合 pac 文件的 dnsResolve() 和 isInNet() 函数,开发了 Flora_Pac 这个小项目。

Flora_Pac 使用 Python 开发,能自动抓取 apnic.net 的 IP 数据,找出所有国内的 IP 地址段,生成能让浏览器自动判断国内外 IP 地址的 pac 文件,让代理用户有等价于 VPN + chnroutes 的翻墙体验。Flora_Pac 使用十分简单,兼容各种平台:

####### 获得帮助:
$ python flora_pac.py -h
usage: flora_pac.py [-h] [-x [PROXY]]
Generate proxy auto-config rules.
optional arguments:
  -h, --help            show this help message and exit
  -x [PROXY], --proxy [PROXY]
                        Proxy Server, examples:
                            SOCKS 127.0.0.1:8964;
                            SOCKS5 127.0.0.1:8964;
                            PROXY 127.0.0.1:8964
####### 生成 pac 文件,国外 IP 通过代理 SOCKS 代理 127.0.0.1:8964 访问:
$ python flora_pac.py -x 'SOCKS 127.0.0.1:8964'<br />
Fetching data from apnic.net, it might take a few minutes, please wait...
Rules: 3460 items.
Usage: Use the newly created flora_pac.pac as your web browser's automatic proxy configuration (.pac) file.
####### 生成 pac 文件,国外 IP 通过代理 HTTP 代理 127.0.0.1:8964 访问:
$ python flora_pac.py -x 'PROXY 127.0.0.1:8964'<br />
Fetching data from apnic.net, it might take a few minutes, please wait...
Rules: 3460 items.
Usage: Use the newly created flora_pac.pac as your web browser's automatic proxy configuration (.pac) file.

程序跑完后,就会在当前目录产生 flora_pac.pac 文件,把它设为浏览器或系统代理设置的 pac 文件即可。

项目代码我放在 github 上开源了:https://github.com/Leask/Flora_Pac,其中 fetch_ip_data 函数 fork 自 chnroutes 项目。

不方便上 github 的朋友,直接复制以下代码保存为 flora_pac.py 就可以跑了:

#!/usr/bin/env python
#
# Flora_Pac by @leaskh
# www.leaskh.com, i@leaskh.com
#
# based on chnroutes project (by Numb.Majority@gmail.com)
#
import re
import urllib2
import argparse
import math
def generate_pac(proxy):
    results  = fetch_ip_data()
    pacfile  = 'flora_pac.pac'<br />
    rfile    = open(pacfile, 'w')
    strLines = (
        "// Flora_Pac by @leaskh"<br />
        "\n// www.leaskh.com, i@leaskh.com"<br />
        "\n"<br />
        "\nfunction FindProxyForURL(url, host)"<br />
        "\n{"<br />
        "\n"<br />
        "\n    var list = ["<br />
    )
    intLines = 0
    for ip,mask,_ in results:
        if intLines > 0:
            strLines = strLines + ','<br />
        intLines = intLines + 1
        strLines = strLines + "\n        ['%s', '%s']"%(ip, mask)
    strLines = strLines + (
        "\n    ];"<br />
        "\n"<br />
        "\n    var ip = dnsResolve(host);"<br />
        "\n"<br />
        "\n    for (var i in list) {"<br />
        "\n        if (isInNet(ip, list[i][0], list[i][1])) {"<br />
        "\n            return 'DIRECT';"<br />
        "\n        }"<br />
        "\n    }"<br />
        "\n"<br />
        "\n    return '%s';"<br />
        "\n"<br />
        "\n}"<br />
        "\n"%(proxy)
    )
    rfile.write(strLines)
    rfile.close()
    print ("Rules: %d items.\n"<br />
           "Usage: Use the newly created %s as your web browser's automatic "<br />
           "proxy configuration (.pac) file."%(intLines, pacfile))
def fetch_ip_data():
    #fetch data from apnic
    print "Fetching data from apnic.net, it might take a few minutes, please wait..."<br />
    url=r'http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest'<br />
    data=urllib2.urlopen(url).read()
    cnregex=re.compile(r'apnic\|cn\|ipv4\|[0-9\.]+\|[0-9]+\|[0-9]+\|a.*',re.IGNORECASE)
    cndata=cnregex.findall(data)
    results=[]
    for item in cndata:
        unit_items=item.split('|')
        starting_ip=unit_items[3]
        num_ip=int(unit_items[4])
        imask=0xffffffff^(num_ip-1)
        #convert to string
        imask=hex(imask)[2:]
        mask=[0]*4
        mask[0]=imask[0:2]
        mask[1]=imask[2:4]
        mask[2]=imask[4:6]
        mask[3]=imask[6:8]
        #convert str to int
        mask=[ int(i,16 ) for i in mask]
        mask="%d.%d.%d.%d"%tuple(mask)
        #mask in *nix format
        mask2=32-int(math.log(num_ip,2))
        results.append((starting_ip,mask,mask2))
    return results
if __name__=='__main__':
    parser=argparse.ArgumentParser(description="Generate proxy auto-config rules.")
    parser.add_argument('-x', '--proxy',
                        dest = 'proxy',
                        default = 'SOCKS 127.0.0.1:8964',
                        nargs = '?',
                        help = "Proxy Server, examples: "<br />
                               "SOCKS 127.0.0.1:8964; "<br />
                               "SOCKS5 127.0.0.1:8964; "<br />
                               "PROXY 127.0.0.1:8964")
    args = parser.parse_args()
    generate_pac(args.proxy)

我想,应该过不了多久就要解放了。期待着有那么一天:我们能一起呼吸自由的空气,我们不再需要折腾各种翻墙玩意。那时,生活应该会更美好一些吧。

Comments

  1. 用 Flora_Pac.py 生成自动翻墙的 pac 文件 « 细节的力量

    […] 原文:https://leaskh.com/2011/12/02/用-Flora_Pac.py-生成自动翻墙的-pac-文件/ […]

  2. 用 Flora_Pac.py 生成自动翻墙的 pac 文件 « 细节的力量

    […] 原文:https://leaskh.com/2011/12/02/用-Flora_Pac.py-生成自动翻墙的-pac-文件/ […]

  3. yeahsky

    感谢楼主,果然是好东西。非常好用。

  4. 智能翻墙Pac文件 – Flora_Pac | Stephen King 的博客

    […] 想了解Flora_Pac文件原理的,请看《Flora_Pac.py 生成自动翻墙的 pac 文件》。 […]

  5. 智能翻墙Pac文件- Flora_Pac « Qiantongshun's Blog

    […] 想了解Flora_Pac文件原理的,请看《Flora_Pac.py 生成自动翻墙的 pac 文件》。 […]

  6. 智能翻墙Pac文件- Flora_Pac « 细节的力量

    […] 想了解Flora_Pac文件原理的,请看《Flora_Pac.py 生成自动翻墙的 pac 文件》。 […]

  7. fhxu

    好东西,感谢分享!

  8. 乂按

    博主你好,请问如何解决内网问题?似乎路由的192.168.1.1也被列入了国外ip!!肿么改才好!!?因为这样的话就不能打开路由的管理界面!!呃

  9. dongxi8

    想要在flora_pac.pac里屏蔽掉路由器的ip地址192.168.x.x,该怎么修改pac文件啊

  10. Leask

    代码已经更新了,去 github 更新一份就好了。

  11. Leask

    代码已经更新了,去 github 更新一份就好了。 :)

  12. any

    纯小白来求助: win8系统 已经安装了Python3.3 已在github上下载到 flora_pac,并重命名为 flora_pac.py 双击flora_pac.py后,命令行窗口一闪而过,什么都没有留下 请问还缺少了什么,或者是哪里错了?

  13. any

    原来是不支持3.X的。。。

  14. goomoon

    楼主,现在碰到一个问题;在公司有很多应用是内部应用,一访问就会报如下异常 Python Urlfetch Error: ‘GET’ DNSLookupFailedError(‘DNS lookup failed for URL: http://xxx.xxx-inc.com/’,), deadline=60

    这个问题如何解决。

    另外,10...网段和172.16..–172.31..*网段都是局域网网段,应该加入到国内列表里面

  15. kumkee

    支持https路由吗?如goagent

  16. Leask

    Sorry 还不支持python3

  17. adolink

    内网ip段不全啊 A类的10.0.0.0到10.255.255.255 B类的172.16.0.0到172.31.255.255,还有224之后的广播段

  18. 苦咖啡 » 用 Flora_Pac.py 生成自动翻墙的 pac 文件

    […] 官方博客:点击进入 […]

  19. Leask

    将会逐渐完善。不好意思啊,业余项目,平日要工作,维护时间不多。谢谢您的宝贵意见。

  20. Leask

    支持。

  21. Leask

    哈哈,最近有时间会迁移到 py 3 上的。

  22. Leask

    下一个版本会支持python3,支持更完善的内网段,并且支持例外域名作为生成参数。

    谢谢支持。

  23. scara

    谢谢博主,这个挺直接的,干净利落。

  24. wenlong1423

    呃。。。。。https://zh.greatfire.org/ 打不开,chrome表示DNS解析失败,dnsResolve函数是不是运行失败还是什么呢?联通的DNS没返回结果,所以浏览器不知道怎么办了么?

  25. wenlong1423

    var strIp = dnsResolve(host); if (!strIp) { return PROXY; } DNS无法解析时用直链? 用意何在?不理解? 希望博主指教

  26. ask

    好像还是不行,能打开twitter 但是facebook和youtube打不开,是不是dns污染 呢? 我用的socks加密后中转的http代理

  27. EdiTurn

    博主你好,很抱歉作为一个伸手党来索取功能。 能否考虑实现将其转换成一个在线规则列表,以便实现在 Chrome 的 Proxy SwitchySharp 中自动更新规则并能够更方便的切换所需的代理。即类似于 gfwlist。

  28. Leask

    什么平台?上游是什么代理?

  29. Leask

    有相关计划,谢谢你的意见。:)

  30. ask

    对squid提供了一个加密的dns查询后,问题解决了。 估计原因是squid查询到错误的ip。感谢楼主的分享

  31. Leask

    今天实现了一下类似的功能,不知道是否如你所愿,详情可参见: https://leaskh.com/2013/10/30/测试为-Flora_Pac-提供-HTTP-host/

  32. dgiraffe

    博主你好,我是一個普通用戶,對技術方面並不了解,可能問題會比較小白了點,見笑了。 用了你的 flora_pac 後確實是相當的舒服,但是有個問題,在之前的版本中,生成的 pac 文件會出現打開台灣 IP 沒有走代理的情況,顯示鏈接被重置。然後今天在你的 GitHub 主頁下載的新的 flora_pac 文件,生成後的 pac 文件卻會導致全局走代理,沒有區分國外國內 IP。我的使用環境是 Firefox+FoxyProxy

  33. Leask

    前几天有个朋友贡献了一段优化代码,我没有完全测试就合并了,导致全局走代理了。对不起大家。问题已经修正了。台湾站点的问题我可以再调试一下,请列出有问题的站点的网址,谢谢你!

  34. dgiraffe

    你好,比如這個網址 http://www.pixnet.net/ 就沒有走代理

  35. benosn

    用vpn怎么翻墙,加设了,但还是上不了www.youtube.com的。

  36. Leask

    什么意思?你用什么VPN?

  37. Leask

    VPN 不需要 Flora Pac 的,Flora Pac 一般和代理一起工作。VPN 找专用的路由表才行。

  38. hnboy2005

    你好, 这个pac挺好的,我想咨询个问题,不知道可否解答一下: DnsResolve(host) 这个方法dns解析时, 走的是本地解析还是远程解析? 我知道浏览器如果设置了HTTP代理的话都是走远程解析的. 但是在PAC文件里的DnsResolve就不太清楚是本地还是远程解析了. 谢谢!