Added support for custom gTLDs; Updated gfwlist and CNIP to the latest.

This commit is contained in:
zhiyi
2018-09-28 13:22:48 +08:00
parent 81740011f8
commit 0d9103804b
9 changed files with 26923 additions and 4114 deletions

View File

@@ -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)

View File

@@ -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

View File

File diff suppressed because it is too large Load Diff

View File

@@ -366,3 +366,6 @@ zhihu.com
zhimg.com
zhubajie.com
zongheng.com
github.com
githubusercontent.com
github.io

View File

@@ -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)

4379
gfw.pac
View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

2
local-tlds.txt Normal file
View File

@@ -0,0 +1,2 @@
.test
.localhost

View File

@@ -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);