Dnsmasq+ipset+iptables基于域名的流量管理
iptables只能根据ip地址进行转发,不能识别域名,而dnsmasq-full不仅可以实现域名-IP的映射,还可以把这个映射关系存储在ipset中,所以使用dnsmasq+ipset就可以实现iptables对域名的转发,可以实现很多功能,比如:
禁止浏览某些网站,如taobao.com
对国内和国外的流量进行不同路径的转发或者代理,可以应用在ss或者SSH这样的代理中,加速某些网站访问速度。
原理很简单,就是Dnsmasq接收到一个DNS查询请求,首先匹配配置文件中的域名列表,如果匹配成功某域名,就把IP的查询结果存储在一个或几个ipset集合中,然后使用iptables对这个ipset中的全部ip进行匹配并做相应的处理,如DROP或者REDIRECT。
下面来看一下Dnsmasq+ipset的工作过程
首先Ubuntu16.04自带dnsmasq-full,Openwrt 15.05等较新的版本的dnsmasq也支持ipset,并将本机的dns服务器设置为dnsmasq(/etc/resolv.conf中将域名服务器设置为127.0.0.1遍指向了本地的dnsmasq服务)。
其中ipset默认没有被安装,Ubuntu和Openwrt均可使用自带的软件包安装源进行安装,具体步骤这里就不细说了,就像安装普通的包一样。
我们可以通过dnsmasq -v来查看当前主机的dnsmasq是否添加了ipset支持
首先我们编辑dnsmasq的配置文件,Ubuntu和Openwrt的目标均为/etc/dnsmasq.conf
添加如下黄线中的几句
前两句的意思是将所有.com和.hk结尾的域名请求都发往OpenDNS的服务器,端口5353,这样可以防止ISP和GFW的一些域名污染,防止请求的页面被误导或者页面上出现莫名其妙的广告
最后一行是指将yahoo.com和google.com的域名解析IP结果存储到vpn和search的ipset结果中,准备交给iptables识别和转发。
而且在此之前我们需要建立v*n和search两个ipset表,可以使用如下语句
sudo ipset create 列表名 hash:ip
然后我们建立完成之后可以列出这个表的所有ip记录,目前当然是空的了
sudo ipset list 列表名
然后我们可以使用nslookup命令查询我们上面规定好的yahoo.com和google.com,然后dnsmasq就会自动的将这两个域名的解析结果存放到我们刚刚建立的ipset中去,该过程如下图
如上图,在查询玩yahoo之后,雅虎的两个IP就被存放到了我们设置的ip集合中去了
同样我们可以再查询一下google.com的域名并把这个域名放到ip集合中
看,这么多的ip都被放到vpn这个ip集合中了。
然后我么再使用iptables做相应的规则转发即可,比如我们把目标地址为这两个域名的流量转发到1080端口进行SSH或者SS代理
sudo iptables -t nat -I PREROUTING -m set --match-set 列表名 dst -j REDIRECT --to-ports 1080
当然,如果你是黑名单可以做DROP或者RETURN处理
sudo iptables -t nat -I PREROUTING -m set --match-set 列表名 dst -j RETURN
如果IP集合不是目标地址而是原地址,可以把dst换成src
如果你要处理的域名很多,那么写在/etc/dnsmasq.conf会显得凌乱不堪,所以我们不妨另起一个或多个文件存放这些域名配置
首先我们可以找个目录随便起名建立一个文件,目录我们就选/home/alex/config/dnsmasq.d好了,其中alex是我Ubuntu系统的用户名
然后再这个目录下建立一个文件,比如ip_filter.conf
然后把上面黄线的内容写入进去,比如我要建立一个国内常用网址的就可以像下面这么写
然后再/etc/dnsmasq.conf中添加如下
这样就可以可以实现和直接写在配置文件中相同的效果
参考文章:https://hong.im/2014/07/08/use-ipset-with-shadowsock-s-on-openwrt/