利用ipset进行选择性的翻墙

一般而言想要实现透明的自动翻墙路由器有两种策略:

  1. 利用IP地址段国家区分的方式,国外的统统走翻墙,国内的统统直连,我的Blog中之前介绍的大体上都是这种,这种方式的优点是适应性高,对于自己以前没有注意过的网站也可以很好的流畅的体验,缺点也很明显——就是带宽利用不高,因为对于不需要翻墙的网站而言,大部分时候直连的速度还是要优于翻墙的。
  2. 利用squid缓存劫持配合polipo做二级代理,利用squid强大的代理策略做域名区分的代理,这个的有点是因为是以域名区分的代理,所以相对而言某些本身没有被屏蔽的网站访问要快一些,同时翻墙用的VPS主机的负载也要小一点,缺点是需要维护相对较为庞大的squid的配置列表同时squid的缓存劫持还比较麻烦,需要linux系统支持,我没有在我的Tomato和OpenWRT上实现过,而且Squid的体积相对非常庞大,对于路由器的小体积而言是个大负担

于是广大淫民不断的探索,终于基于ipset第三种翻墙策略也孕育诞生了。

其基本原理是在访问网站解析域名的同时,将设置为需要翻墙的域名解析到的ip地址存入ipset的对应set中,然后在iptables中对于这些存入特定的set的ip地址的网络连接自动走s绕行。

要完成这个,需要三个必要条件,一是路由器支持ipset,二是dnsmasq支持ipset,三是iptables支持ipset包

我是在tomato的shibby版的mod上做的,因为下载的是all in one版本,所以所有的软件都自带了

首先运行一下ipset
如果不是报告-bash: ipset: command not found,那就是支持ipset了

然后运行一下iptables -m set -h
如果最后有set match options:等等字样,就说明你的iptables是支持set option了

最后运行一下dnsmasq --help|grep ipset
如果能看到ipset的相关说明就说明dnsmasq是支持的了(这货如果不支持也可以有其他的办法绕过,可以去搜索一下ipset-dns这个包)

相比用ip地址段翻墙,这个的配置很简单,核心是dnsmasq的配置文件,因为tomato的dnsmasq.conf 不可以太长(更加重要的是这个文件是每次重启dnsmasq自己生成的),所以一般都是放在/etc/dnsmasq.custom中

写法一般是
server=/instagram.com/127.0.0.1#5353
ipset=/instagram.com/setmefree

第一行代表所有的instagram.com及其子域名均使用本地的DNS解析(本地建立纯净的DNS的方法请参考之前的帖子)
第二行表示所有解析到的IP地址自动进入ipset的setmefree set中

然后在firewall.user或者tomato在administration - Scripts - Firewall中写上

iptables -t nat -A PREROUTING -p tcp -m set --set setmefree dst -j REDIRECT --to-port 6666

其中的6666是你的本地的ss-redir的端口,注意,是ss-redir,不是ss-local,新版的shadowsocks libenv都是带了这个的,用它可以省去redsocks(tomato版本的可以到这里下载到)

这就完成了,就是这么简单

debug的方法:

检查ipset有没有正确的捕捉到ip,方法是运行 ipset -L setmefree
如果里面有ip地址的话,那就是正确的了
你也可以手动用ipset命令将一些需要翻墙的ip添加进入这个set

检查ss-redir有没有启动起来:
运行ps、netstat命令查看是否有程序运行,端口连接,检查加密方式、密码是否正确

附注:
当ipset升级到 4.5或者更高的版本的时候你可能需要手动的添加ipset的set,因为它多了一个settype需要指定

只需要手动运行一次ipset -N setmefree iphash就可以了

参考帖子:
http://hong.im/2014/07/08/use-ipset-with-shadowsocks-on-openwrt/

评论

此博客中的热门博文

远程记录OpenWRT日志

用OpenWRT打造自动翻墙路由器(详解篇)

Python中为什么要用is None来代替== None?