用Flora_Pac.py生成自动翻墙的pac文件&让pac文件修改后立即生效

2011年12月27日 | 分类: 翻墙相关 | 标签: ,

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

源于人们对自由的向往,翻墙技术已渐趋成熟。愿意花点钱,购买海外 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'
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'
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'
    rfile    = open(pacfile, 'w')
    strLines = (
        "// Flora_Pac by @leaskh"
        "\n// www.leaskh.com, i@leaskh.com"
        "\n"
        "\nfunction FindProxyForURL(url, host)"
        "\n{"
        "\n"
        "\n    var list = ["
    )
    intLines = 0
    for ip,mask,_ in results:
        if intLines > 0:
            strLines = strLines + ','
        intLines = intLines + 1
        strLines = strLines + "\n        ['%s', '%s']"%(ip, mask)
    strLines = strLines + (
        "\n    ];"
        "\n"
        "\n    var ip = dnsResolve(host);"
        "\n"
        "\n    for (var i in list) {"
        "\n        if (isInNet(ip, list[i][0], list[i][1])) {"
        "\n            return 'DIRECT';"
        "\n        }"
        "\n    }"
        "\n"
        "\n    return '%s';"
        "\n"
        "\n}"
        "\n"%(proxy)
    )
    rfile.write(strLines)
    rfile.close()
    print ("Rules: %d items.\n"
           "Usage: Use the newly created %s as your web browser's automatic "
           "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..."
    url=r'http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest'
    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: "
                               "SOCKS 127.0.0.1:8964; "
                               "SOCKS5 127.0.0.1:8964; "
                               "PROXY 127.0.0.1:8964")

    args = parser.parse_args()

    generate_pac(args.proxy)

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

来源http://www.leaskh.com/2011/12/02/%E7%94%A8-flora_pac-py-%E7%94%9F%E6%88%90%E8%87%AA%E5%8A%A8%E7%BF%BB%E5%A2%99%E7%9A%84-pac-%E6%96%87%E4%BB%B6/

========

让 pac 文件修改后立即生效

ssh -D 和 VPN 是我认为目前最靠谱的翻墙方式了。
但是,他们都面临同一个问题,就是需要区分被墙与没有被墙的网站,以使用较快的方式访问所需要的站点。

我使用 VPN 的时候会使用 chnroutes 项目:http://code.google.com/p/chnroutes/
使用 ssh -D 的时候,我有自己的 .pac 文件,且我的 pac 文件修改很频繁。
于是怎么在不重启浏览器(或其他应用)的情况下,让新修改的 .pac 文件生效呢?
经过研究,发现只需要修改一下 .pac 文件的地址,浏览器就会重新加载代理脚本了。
但每次都在图形界面下干这活儿,实在太反人类了,于是,决定尝试写 shell:

Mac:

#!/bin/sh
pac="http://www.xxx.com/yyy.pac?time=`date +%s`";
networksetup -setautoproxyurl Wi-Fi "$pac";
# 你需要把 Wi-Fi 改为自己网络的 Service name

Linux with gnome:

#!/bin/sh
pac="http://www.xxx.com/yyy.pac?time=`date +%s`";
gconftool -s /system/proxy/autoconfig_url -t string "$pac";

Windows?

对不起,不用 Windows 好多年了。

 

来源http://www.leaskh.com/2011/11/12/%E8%AE%A9-pac-%E6%96%87%E4%BB%B6%E4%BF%AE%E6%94%B9%E5%90%8E%E7%AB%8B%E5%8D%B3%E7%94%9F%E6%95%88/

  1. mao
    2011年12月31日14:35

    博主!按你的方法。安装python-2.7文件可以运行。谢谢你!
    并祝在新的一年里。天天开心。天天发财!

  2. mao
    2011年12月30日16:34

    博主!你好。xp系统下。运行不了flora_pac。我 安装了Python 软件。盼指教。谢谢

    • iGFW
      2011年12月30日22:43

      我xp安装Python 2.7测试从https://github.com/Leask/Flora_Pac下载的文件可行,你试试

  3. 天生多疑
    2011年12月28日21:16

    太好了!一直不喜欢gfwlist,它连googe.com.hk都认为是墙内,要知道墙内google已经间歇性瘫痪,更不要说稍微有点敏感的词了,而且还不能自己修改pac文件添加条目,垃圾死了。

  4. Dunv
    2011年12月28日12:51

    运行不了呢?要报错:

    File “E:\GFW4\PythonTest2\flora_pac.py”, line 11, in
    import argparse
    ImportError: No module named argparse

    我xp系统,python是2.5版的

    • iGFW
      2011年12月28日21:05

      哥们没有测试,也不弄python代码,你看看是不是python版本问题,或者问问原文作者。

    • 天生多疑
      2011年12月28日21:18

      我是linux系统,也遇到这个问题,解决方法:
      在新力得软件包管理器里,搜索安装python-argparse,重试搞定。

  5. Ben
    2011年12月28日11:14

    原作者的最后一句话实在是太励志了