Openwrt上使用dnsmasq和ipset实现域名分流

目标

部署一台自动代理路由器,实现根据域名来自动设定直连或者代理,而我要做的只是设置PC的默认网关为主路由器(192.168.0.1)还是自动代理路由器(192.168.0.254)。

创建Openwrt虚拟机

系统版本

  • 主路由器 (ip: 192.168.0.1)
  • ESXI 6.0U2
  • Openwrt 15.05.1 (ip: 192.168.0.254,gateway: 192.168.0.1)

Openwrt虚拟机的配置教程有很多,这里只针对ESXI版Openwrt可能会遇到的问题说明下:

  • 在ESXI6上,openwrt_x86每次启动时会大概率的出现卡死现象,表现为Kernel panic - not syncing: Attempted to kill init
    • 解决办法:改用openwrt_x64后正常。原因未知。
  • 在ESXI6上,在openwrt上执行某些命令时,会被强制关机,表现为

    1
    来自 promote 的消息: The operation on the file "/vmfs/devices/deltadisks/17ad1ab5-openwrt-15. 05.1-x86-64-combined-ext4-s001.vmdk" failed (Bad address). The file system where disk "/vmfs /devices/deltadisks/17ad1ab5-openwrt-15.05.1-- x86-64-combined-ext4-s001.vmdk" resides is full. Select _Retry to attempt the operation again. Select Cancel to end the session.
    • 解决办法:在Vmware Fusion中新建openwrt虚拟机(other/other linux 64, 256MB,虚拟机版本为11),第一次启动后,关机导出为ova,然后再导入到ESXI6中。具体原因未知。

安装软件

1
2
3
4
5
6
7
opkg update
opkg remove dnsmasq
opkg install dnsmasq-full
opkg install ipset iptables-mod-nat-extra
 
wget http://x.x.x.x/s-libev_2.4.6-1_x86_64.ipk
opkg install s-libev_2.4.6-1_x86_64.ipk

PS
在这里,安装官方版的s,而不是openwrt spec版, 下载地址在这里。

PPS
在这里,如果安装的顺序不同,可能会导致lib的依赖错误(至少在15.05.1上是这样)。使用ldd命令,检查一下s的依赖包是否正常。

1
ldd /usr/bin/ss-redir

 

配置

配置s

配置/etc/s.json,格式如下:

1
2
3
4
5
6
7
{
"server": "X.X.X.X",
"server_port": "443",
"password": "password",
"local_port": "1080",
"method": "aes-256-cfb"
}

 

修改/etc/init.d/s,设置s以Proxy Mode模式启动,同时开启转发DNS请求功能,上游DNS为8.8.8.8

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/bin/sh /etc/rc.common
 
START=95
 
SERVICE_USE_PID=1
SERVICE_WRITE_PID=1
SERVICE_DAEMONIZE=1
 
CONFIG=/etc/s.json
 
start() {
#service_start /usr/bin/ss-local -c $CONFIG -b 0.0.0.0
service_start /usr/bin/ss-redir -c $CONFIG -b 0.0.0.0
service_start /usr/bin/ss-tunnel -c $CONFIG -b 0.0.0.0 -l 5353 -L 8.8.8.8:53 -u
}
 
stop() {
#service_stop /usr/bin/ss-local
service_stop /usr/bin/ss-redir
service_stop /usr/bin/ss-tunnel
}

设置s开机启动,并手动运行:

1
2
/etc/init.d/s enable
/etc/init.d/s start

 

到目前为止,你已经有了一个监听在1080端口的socks代理,和监听在5353端口的不受污染的DNS服务器

配置ipset

进入Luci界面-网络-防火墙-自定义规则,加入以下规则(最后的1080是s的本地端口,请酌情修改):

1
2
3
4
5
6
#创建名为gfwlist,格式为iphash的集合
ipset -N gfwlist iphash
#匹配gfwlist中ip的nat流量均被转发到s端口
iptables -t nat -A PREROUTING -p tcp -m set --match-set gfwlist dst -j REDIRECT --to-port 1080
#匹配gfwlist中ip的本机流量均被转发到s端口
iptables -t nat -A OUTPUT -p tcp -m set --match-set gfwlist dst -j REDIRECT --to-port 1080

 

配置dnsmasq-full

修改/etc/dnsmasq.conf,在文末加入conf-dir=/etc/dnsmasq.d

1
echo 'conf-dir=/etc/dnsmasq.d' >> /etc/dnsmasq.conf

 

新建目录/etc/dnsmasq.d,生成dnsmasq_list.conf 到该目录:

1
2
3
4
5
6
git clone https://github.com/cokebar/gfwlist2dnsmasq.git
cd gfwlist2dnsmasq
python2 gfwlist2dnsmasq.py
 
mkdir /etc/dnsmasq.d
cp dnsmasq_list.conf /etc/dnsmasq.d

 

其中,dnsmasq_list.conf的格式为:

1
2
3
4
#使用不受污染的DNS解析该域名,可以将此IP改为自己使用的DNS服务器
server=/google.com/127.0.0.1#5353
#将解析出来的IP保存到名为gfwlist的ipset表中
ipset=/google.com/gfwlist

 

你可以手动修改这个文件,你也可以使用gfwlist2dnsmasq.py自动生成dnsmasq_list版的gfwlist列表。

重新运行dnsmasq,它将监听在本机53端口上。

1
/etc/init.d/dnsmasq restart

 

测试

场景一

  • PC端的默认网关设置为192.168.0.1, DNS设置为192.168.0.1
    • 国内网站访问正常
    • Google无法访问

场景二

    • PC端的默认网关设置为192.168.0.254, DNS设置为192.168.0.254
      • 访问国内网站
        • dnsmasq解析该域名,发现该域名不在dnsmasq_list中,使用默认DNS服务器进行解析,正常访问。
      • 访问Google
        • dnsmasq解析该域名,发现该域名在dnsmasq_list中,使用设置的安全DNS服务器进行解析,并将该IP加至gfwlist集合中,iptables匹配到规则,将流量转发到s监听的端口,进行代理访问。

你可能感兴趣的:(Openwrt上使用dnsmasq和ipset实现域名分流)