OpenWRT上从2.66版开始的Dnsmasq已经支持IPSET,但是默认的版本不支持ipset,需要dnsmasq-full.
查看dnsmasq是否支持ipset
[root@PandoraBox:/root]# dnsmasq -v
Dnsmasq version 2.72 Copyright (c) 2000-2014 Simon Kelley
Compile time options: IPv6 GNU-getopt no-DBus no-i18n no-IDN DHCP DHCPv6 no-Lua TFTP no-conntrack ipset auth DNSSEC loop-detect
如果 Compile time options显示ipset就是支持的.no-ipset就是不支持.
但是PandoraBox默认源里面没有dnsmasq-full,在网上找到了aa65535编译的版本,已经加上了chinadns,非常给力.使用ipset的主要优势在于直接将所有被污染的域名解析结果交给ipset,不需要动态维护IP列表,在路由上更智能.
以下是设置步骤
1.卸载默认的dnsmasq
opkg remove dnsmasq
2.安装dnsmasq-full
opkg install http://sourceforge.net/projects/openwrt-dist/files/depends-libs/ramips/libnettle_2.7.1-1_ramips_24kec.ipk
opkg install http://sourceforge.net/projects/openwrt-dist/files/depends-libs/ramips/libgmp_6.0.0-1_ramips_24kec.ipk
opkg install http://sourceforge.net/projects/openwrt-dist/files/dnsmasq/2.72-8372a82/ramips/dnsmasq-full_2.72-6_ramips_24kec.ipk
3.安装ipset
opkg update //安装前必须更新包数据库缓存。
opkg install ipset iptables-mod-nat-extra
安装的时候会报错,需要重启一次路由才可以正常使用.
4.安装配置shadowsocks就不细说了,参考这里
5.用ipset创建一个set,这里我创建的set名字为fuckgfw,然后将这个set中所有IP均转发到shadowsocks(这里本机的shadowsocks监听的是默认的1080端口)。建议将下面的命令写入 /etc/rc.local 。每次开机自动运行。
ipset -N gfwlist iphash
iptables -t nat -A PREROUTING -p tcp -m set --match-set gfwlist dst -j REDIRECT --to-port 1080
设置 dnsmasq 对某些域名使用pdnsd进行解析并且加入fuckgfw这个set:
为了保持配置文件整洁,建议在 /etc/dnsmasq.conf 最后加入:
conf-dir=/etc/dnsmasq.d
然后新建目录 /etc/dnsmasq.d,自定义的配置文件就放这里面.在这里我们使用一个python脚本转换gfwlist里面的网址为符合dnsmasq格式要求的配置文件.
脚本内容为如下
#!/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://www.vpnhot.com/gfwlist.txt'
# match comments/title/whitelist/ip address
comment_pattern = '^\!|\[|^@@|^\d+\.\d+\.\d+\.\d+'
domain_pattern = '([\w\-\_]+\.[\w\.\-\_]+)[\/\*]*'
tmpfile = 'gfwlisttmp'
# do not write to router internal flash directly
outfile = 'gfwlist.conf'
rulesfile = '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!'
gfwlist的地址默认是访问不了的,我们替换为镜像地址.生成的配置文件很长,有伍仟多行,这里就不放上来了.用ftp工具穿到/etc/dnsmasq.d里面.
然后重启dnsmasq
/etc/init.d/dnsmasq restart
6.通过下面的命令查看set中的IP,这样可以确定解析是否正常,并且查看某网站是否正确的被加到了ipset:
ipset list gfwlist
7.通过下面的命令可以清理掉set中所有ip。更多的ipset用法请查看ipset help
ipset flush gfwlist
8.本文参考了北落师门的教程
更新:我目前是配合shadowvpn+pdnsd tcp解析使用的,但是现在dns解析似乎也不太稳定了,直接让Google Dns 走VPN吧
[root@PandoraBox:/etc/dnsmasq.d]#route add -host 8.8.8.8 dev tun0
[root@PandoraBox:/etc/dnsmasq.d]#route add -host 8.8.4.4 dev tun0
http://dl.aenes.com/gfwlist.txt
这个稳定吗?
一定要用python?用shell解析有没有办法?
1.每隔12小时同步一次。
2.https://code.google.com/p/autovpn-for-openwrt/wiki/Dnsmasq_Patched
喂喂喂我不叫北落师兄好吧!!!!
我看到了两个从gfwlist生成dnsmasq conf的方案。感觉这个生成的列表应该要小一些
问题是2000多域名应该有很多都是无效的吧- -
蛋疼啊
我看看性能什么的吧
PS 你贴的这个脚本是自动把生成文件移动到dnsmasq目录并且重启dnsmasq的。。。你就不能悄悄的删掉么。。。。
我粗枝大叶了没注意看,抱歉了,我给注释掉。
你ipset里写的是fuchgfw
但是python脚本里写的是gfwlist
是写错了还是故意的?
我按照博主的文章配了路由。现在http的请求可以正常自动分流到1080端口走vpn,但是https的网页都打不开。比如我打开http://www.facebook.com,会自动302到https://www.facebook.com,然后就打不开了。手动设置代理到路由的1080端口就没问题,是iptable的设置问题吗?
我不信你这句话能执行成功:
ipset -N gfwlist iphash
ipset不支持-N参数不说,iphash是什么东西? ipset支持这种类型? ipset help看看吧。
我猜的没错应该是hash:ip