Skip to content

Instantly share code, notes, and snippets.

@lanceliao
Last active August 18, 2023 11:26
  • Star 77 You must be signed in to star a gist
  • Fork 49 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save lanceliao/85cd3fcf1303dba2498c to your computer and use it in GitHub Desktop.
将gfwlist转换成带ipset的dnsmasq规则,适用于OpenWrt智能上网
#!/usr/bin/env python
#coding=utf-8
#
# Generate a list of dnsmasq rules with ipset for gfwlist
#
# Copyright (C) 2014 http://www.shuyz.com
# Ref https://code.google.com/p/autoproxy-gfwlist/wiki/Rules
import urllib2
import re
import os
import datetime
import base64
import shutil
mydnsip = '127.0.0.1'
mydnsport = '1053'
# the url of gfwlist
baseurl = 'https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt'
# match comments/title/whitelist/ip address
comment_pattern = '^\!|\[|^@@|^\d+\.\d+\.\d+\.\d+'
domain_pattern = '([\w\-\_]+\.[\w\.\-\_]+)[\/\*]*'
tmpfile = '/tmp/gfwlisttmp'
# do not write to router internal flash directly
outfile = '/tmp/gfwlist.conf'
rulesfile = '/etc/dnsmasq.d/gfwlist.conf'
fs = file(outfile, 'w')
fs.write('# gfw list ipset rules for dnsmasq\n')
fs.write('# updated on ' + datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + '\n')
fs.write('#\n')
print 'fetching list...'
content = urllib2.urlopen(baseurl, timeout=15).read().decode('base64')
# write the decoded content to file then read line by line
tfs = open(tmpfile, 'w')
tfs.write(content)
tfs.close()
tfs = open(tmpfile, 'r')
print 'page content fetched, analysis...'
# remember all blocked domains, in case of duplicate records
domainlist = []
for line in tfs.readlines():
if re.findall(comment_pattern, line):
print 'this is a comment line: ' + line
#fs.write('#' + line)
else:
domain = re.findall(domain_pattern, line)
if domain:
try:
found = domainlist.index(domain[0])
print domain[0] + ' exists.'
except ValueError:
print 'saving ' + domain[0]
domainlist.append(domain[0])
fs.write('server=/.%s/%s#%s\n'%(domain[0],mydnsip,mydnsport))
fs.write('ipset=/.%s/gfwlist\n'%domain[0])
else:
print 'no valid domain in this line: ' + line
tfs.close()
fs.close();
print 'moving generated file to dnsmasg directory'
shutil.move(outfile, rulesfile)
print 'restart dnsmasq...'
print os.popen('/etc/init.d/dnsmasq restart').read()
print 'done!'
#!/bin/sh /etc/rc.common
# Copyright (C) 2006-2011 OpenWrt.org
# ref http://ipset.netfilter.org/ipset.man.html
START=95
SERVICE_USE_PID=1
SERVICE_WRITE_PID=1
SERVICE_DAEMONIZE=1
start() {
echo starting ss-redir...
service_start /opt/bin/ss-redir -c /etc/shadowsocks.json
echo loading firewall rules...
ipset create gfwlist hash:ip counters timeout 1200
iptables -t nat -A zone_lan_prerouting -p tcp -m set --match-set gfwlist dst -j REDIRECT --to-port 1081
echo done.
}
stop() {
echo stopping ss-redir...
service_stop /opt/bin/ss-redir
echo restarting firewall...
/etc/init.d/firewall restart
echo done.
}
@HugoPresents
Copy link

本来想在 openwrt 上做个 cron 自动更新的,但是下不动 gfwlist 怎么破~

@lanceliao
Copy link
Author

我的就是在路由器上更新的,使用http获取gfwlist失败,换成https就没问题。网上有gfwlist的镜像也可以用。

@tanyewei
Copy link

tanyewei commented Dec 27, 2014

!/usr/bin/env python

-- coding: utf-8 --

tanyewei@gmail.com

import re

domain_regex = re.compile(r'[a-zA-Z\d-]{,63}(.[a-zA-Z\d-]{,63})*')

with open('gfwlist', 'r') as f:
data = f.read()

domain_list = []

for i in data.decode('base64').splitlines():
m = re.search(domain_regex, i)
if m and len(m.group()):
if m.group().startswith('.'):
domain_list.append('ipset=/{0}/setmefree'.format(m.group()))
else:
domain_list.append('ipset=/.{0}/setmefree'.format(m.group()))

domain_list = list(set(domain_list))

with open('gfw.conf', 'w') as f:
f.write('\n'.join(domain_list))

@HugoPresents
Copy link

楼主,最新的 gfwlist 文件换了 https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt 可以改一发

@lanceliao
Copy link
Author

楼主,最新的 gfwlist 文件换了 https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt 可以改一发

@Rabbit52 谢谢提醒!已更改。

@lsylsy2
Copy link

lsylsy2 commented Jan 12, 2017

楼主,这个好像不能匹配
/^https?://([^\/]+.)google.(ac|ad|ae|al|am|as|at|az|ba|be|bf|bg|bi|bj|bs|bt|by|ca|cat|cd|cf|cg|ch|ci|cl|cm|co.ao|co.bw|co.ck|co.cr|co.id|co.il|co.in|co.jp|co.ke|co.kr|co.ls|co.ma|com|com.af|com.ag|com.ai|com.ar|com.au|com.bd|com.bh|com.bn|com.bo|com.br|com.bz|com.co|com.cu|com.cy|com.do|com.ec|com.eg|com.et|com.fj|com.gh|com.gi|com.gt|com.hk|com.jm|com.kh|com.kw|com.lb|com.ly|com.mm|com.mt|com.mx|com.my|com.na|com.nf|com.ng|com.ni|com.np|com.om|com.pa|com.pe|com.pg|com.ph|com.pk|com.pr|com.py|com.qa|com.sa|com.sb|com.sg|com.sl|com.sv|com.tj|com.tr|com.tw|com.ua|com.uy|com.vc|com.vn|co.mz|co.nz|co.th|co.tz|co.ug|co.uk|co.uz|co.ve|co.vi|co.za|co.zm|co.zw|cv|cz|de|dj|dk|dm|dz|ee|es|fi|fm|fr|ga|ge|gg|gl|gm|gp|gr|gy|hk|hn|hr|ht|hu|ie|im|iq|is|it|je|jo|kg|ki|kz|la|li|lk|lt|lu|lv|md|me|mg|mk|ml|mn|ms|mu|mv|mw|mx|ne|nl|no|nr|nu|org|pl|pn|ps|pt|ro|rs|ru|rw|sc|se|sh|si|sk|sm|sn|so|sr|st|td|tg|tk|tl|tm|tn|to|tt|us|vg|vn|vu|ws)/./

这一行,于是google.com.hk就用不了?

@masktao
Copy link

masktao commented Oct 29, 2017

请问DD WRT可以用码?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment