Added support for custom gTLDs; Updated gfwlist and CNIP to the latest.
This commit is contained in:
14
README.md
14
README.md
@@ -2,11 +2,10 @@
|
||||
|
||||
通过 gfwlist 和中国 IP 地址生成 PAC(Proxy auto-config) 文件。对存在于 gfwlist 的域名和解析出的 IP 在国外的域名使用代理。
|
||||
|
||||
基于 [GFWList2PAC](https://github.com/clowwindy/gfwlist2pac) 和 [Flora PAC](https://github.com/Leask/Flora_Pac)
|
||||
|
||||
## 特性
|
||||
* 速度快,优先按域名匹配,再按 IP 匹配
|
||||
* 可自定义需要代理的域名
|
||||
* 可自定义本地开发 TLD 域名,例如 .test
|
||||
* 可自定义不需要代理的域名
|
||||
* 如果访问的域名不在列表里,但是 IP 在国外,也返回代理服务器
|
||||
|
||||
@@ -16,17 +15,21 @@
|
||||
|
||||
## gfw-pac.py 使用说明
|
||||
|
||||
usage: gfw-pac.py [-h] [-i GFWLIST] -f PAC -p PROXY [--user-rule USER_RULE]
|
||||
[--direct-rule DIRECT_RULE] [--ip-file IP_FILE]
|
||||
usage: gfw-pac.py -f PAC -p PROXY [-h] [-i GFWLIST_FILE]
|
||||
[--user-rule USER_RULE_FILE]
|
||||
[--direct-rule DIRECT_RULE_FILE]
|
||||
[--localtld-rule LOCAL_TLD_RULE_FILE]
|
||||
[--ip-file IP_FILE]
|
||||
|
||||
参数说明:
|
||||
|
||||
-h 显示帮助
|
||||
-i 指定本地 gfwlist 文件,若不指定则自动从 googlecode 下载
|
||||
-i 指定本地 gfwlist 文件,若不指定则自动下载
|
||||
-f (必须)输出的 pac 文件
|
||||
-p (必须)指定代理服务器
|
||||
--user-rule 自定义使用代理的域名文件,文件里每行一个域名
|
||||
--direct-rule 自定义不使用代理的域名文件,文件里每行一个域名
|
||||
--localtld-rule 自定义不使用代理的顶级域,文件里每行一个域名,必须带前导圆点(例如 .test)
|
||||
--ip-file 指定本地的从 apnic 下载的 IP 分配文件。若不指定则自动从 apnic 下载
|
||||
|
||||
举例:
|
||||
@@ -36,6 +39,7 @@
|
||||
-p "PROXY 192.168.1.200:3128; DIRECT" \
|
||||
--user-rule=custom-domains.txt \
|
||||
--direct-rule=direct-domains.txt \
|
||||
--localtld-rule=local-tlds.txt \
|
||||
--ip-file=delegated-apnic-latest.txt
|
||||
|
||||
[一路凯歌 技术博客](http://zhiyi.us)
|
||||
@@ -11,9 +11,6 @@ wikipedia.org
|
||||
stackoverflow.com
|
||||
sstatic.net
|
||||
imgur.com
|
||||
github.com
|
||||
githubusercontent.com
|
||||
github.io
|
||||
googlecode.com
|
||||
docker.io
|
||||
docker.com
|
||||
@@ -44,12 +41,3 @@ last.fm
|
||||
scdn.co
|
||||
spotify.com
|
||||
spotilocal.com
|
||||
music.126.net
|
||||
laravel.com
|
||||
youbma.com
|
||||
youb99.com
|
||||
youb88.com
|
||||
youb77.com
|
||||
youb66.com
|
||||
youb11.com
|
||||
qiporn.com
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -366,3 +366,6 @@ zhihu.com
|
||||
zhimg.com
|
||||
zhubajie.com
|
||||
zongheng.com
|
||||
github.com
|
||||
githubusercontent.com
|
||||
github.io
|
||||
29
gfw-pac.py
29
gfw-pac.py
@@ -30,6 +30,8 @@ def parse_args():
|
||||
' gfwlist')
|
||||
parser.add_argument('--direct-rule', dest='direct_rule',
|
||||
help='user rule file, contains domains not bypass proxy')
|
||||
parser.add_argument('--localtld-rule', dest='localtld_rule',
|
||||
help='local TLD rule file, contains TLDs with a leading dot not bypass proxy')
|
||||
parser.add_argument('--ip-file', dest='ip_file',
|
||||
help='delegated-apnic-latest from apnic.net')
|
||||
return parser.parse_args()
|
||||
@@ -192,7 +194,7 @@ def reduce_domains(domains):
|
||||
return uni_domains
|
||||
|
||||
|
||||
def generate_pac_fast(domains, proxy, direct_domains, cnips):
|
||||
def generate_pac_fast(domains, proxy, direct_domains, cnips, local_tlds):
|
||||
# render the pac file
|
||||
with open('./pac-template', 'rb') as f:
|
||||
proxy_content = f.read()
|
||||
@@ -218,6 +220,14 @@ def generate_pac_fast(domains, proxy, direct_domains, cnips):
|
||||
json.dumps(cnips, indent=2, sort_keys=False)
|
||||
)
|
||||
|
||||
tlds_dict = {}
|
||||
for domain in local_tlds:
|
||||
tlds_dict[domain] = 1
|
||||
proxy_content = proxy_content.replace(
|
||||
'__LOCAL_TLDS__',
|
||||
json.dumps(tlds_dict, indent=2, sort_keys=True)
|
||||
)
|
||||
|
||||
return proxy_content
|
||||
|
||||
|
||||
@@ -243,6 +253,7 @@ def main():
|
||||
args = parse_args()
|
||||
user_rule = None
|
||||
direct_rule = None
|
||||
localtld_rule = None
|
||||
if (args.input):
|
||||
with open(args.input, 'rb') as f:
|
||||
content = f.read()
|
||||
@@ -274,6 +285,20 @@ def main():
|
||||
else:
|
||||
direct_rule = []
|
||||
|
||||
if args.localtld_rule:
|
||||
tldrule_parts = urlparse.urlsplit(args.localtld_rule)
|
||||
if not tldrule_parts.scheme or not tldrule_parts.netloc:
|
||||
# It's not an URL, deal it as local file
|
||||
with open(args.localtld_rule, 'rb') as f:
|
||||
localtld_rule = f.read()
|
||||
else:
|
||||
# Yeah, it's an URL, try to download it
|
||||
print 'Downloading local tlds rules file from %s' % args.user_rule
|
||||
localtld_rule = urllib2.urlopen(args.localtld_rule, timeout=10).read()
|
||||
localtld_rule = localtld_rule.splitlines(False)
|
||||
else:
|
||||
localtld_rule = []
|
||||
|
||||
cnips = fetch_ip_data()
|
||||
|
||||
content = decode_gfwlist(content)
|
||||
@@ -281,7 +306,7 @@ def main():
|
||||
|
||||
domains = parse_gfwlist(gfwlist)
|
||||
domains = reduce_domains(domains)
|
||||
pac_content = generate_pac_fast(domains, args.proxy, direct_rule, cnips)
|
||||
pac_content = generate_pac_fast(domains, args.proxy, direct_rule, cnips, localtld_rule)
|
||||
|
||||
with open(args.output, 'wb') as f:
|
||||
f.write(pac_content)
|
||||
|
||||
4439
gfwlist.txt
4439
gfwlist.txt
File diff suppressed because it is too large
Load Diff
2
local-tlds.txt
Normal file
2
local-tlds.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
.test
|
||||
.localhost
|
||||
36
pac-template
36
pac-template
@@ -1,13 +1,14 @@
|
||||
var proxy = __PROXY__;
|
||||
|
||||
var direct = 'DIRECT;';
|
||||
|
||||
var cnips = __CN_IPS__;
|
||||
|
||||
var directDomains = __DIRECT_DOMAINS__;
|
||||
|
||||
var domains = __DOMAINS__;
|
||||
var domainsUsingProxy = __DOMAINS__;
|
||||
|
||||
var proxy = __PROXY__;
|
||||
|
||||
var direct = 'DIRECT;';
|
||||
var localTlds = __LOCAL_TLDS__;
|
||||
|
||||
var hasOwnProperty = Object.hasOwnProperty;
|
||||
|
||||
@@ -63,9 +64,32 @@ function testDomain(target, domains, cnRootIncluded) {
|
||||
}
|
||||
}
|
||||
|
||||
function isLocalTestDomain(domain) {
|
||||
// Chrome uses .test as testing gTLD.
|
||||
var tld = domain.substring(domain.lastIndexOf('.'));
|
||||
if (tld === domain) {
|
||||
return false;
|
||||
}
|
||||
return Object.hasOwnProperty.call(localTlds, tld);
|
||||
}
|
||||
|
||||
/* https://github.com/frenchbread/private-ip */
|
||||
function isPrivateIp(ip) {
|
||||
return /^(::f{4}:)?10\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(ip) ||
|
||||
/^(::f{4}:)?192\.168\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(ip) ||
|
||||
/^(::f{4}:)?172\.(1[6-9]|2\d|30|31)\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(ip) ||
|
||||
/^(::f{4}:)?127\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(ip) ||
|
||||
/^(::f{4}:)?169\.254\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(ip) ||
|
||||
/^f[cd][0-9a-f]{2}:/i.test(ip) ||
|
||||
/^fe80:/i.test(ip) ||
|
||||
/^::1$/.test(ip) ||
|
||||
/^::$/.test(ip);
|
||||
}
|
||||
|
||||
function FindProxyForURL(url, host) {
|
||||
if (isPlainHostName(host)
|
||||
|| host === '127.0.0.1'
|
||||
|| isPrivateIp(host)
|
||||
|| isLocalTestDomain(host)
|
||||
|| host === 'localhost') {
|
||||
return direct;
|
||||
}
|
||||
@@ -75,7 +99,7 @@ function FindProxyForURL(url, host) {
|
||||
return direct
|
||||
}
|
||||
|
||||
if (testDomain(host, domains)) {
|
||||
if (testDomain(host, domainsUsingProxy)) {
|
||||
return proxy;
|
||||
}
|
||||
strIp = dnsResolve(host);
|
||||
|
||||
Reference in New Issue
Block a user