本方案依靠GFWList,List中的域名站点走代理,不在List中的域名不走代理,根据域名判断。然而其实本质上依然是根据IP判断是否代理IP走代理,dnsmasq-full可以将解析域名得到的IP加到一个ipset中,利用这个ipset来判断走不走代理。实际是完成了gfwlist(域名列表)到dnsmasq的ipset规则再到IP地址的转换。同样,本方案依然可以搭配ChinaDNS搭配使用,也可以使用ss-tunnel,或者是自己的DNS服务器。

本方案的优点明确,只有被墙的站点才走代理,但是gfwlist并不能100%涵盖被墙站点,而且有些国外站点直连速度远不如走代理,特别是你代理服务器速度较快,希望通过代理加速国外访问时,此方案就不是那么好用了。请酌情选择你所使用的方案。

注:由于近期OPENWRT/LEDE的一系列变化,以及作者aa65535的一系列更改,本文需要更新,下面的步骤仅供参考!本人应该会在近期休假期间更新本文。不排除鸽的可能:)

一、安装

方法一: 添加作者的软件源,直接利用opkg命令安装 (此方式快捷方便,推荐!)

软件源位置:http://openwrt-dist.sourceforge.net/packages/

前提是所用网络环境直连sourceforge.net和downloads.lede-project.org没有问题。此处仅提供LEDE 17.X 的步骤。

首先添加 a65535 的 gpg key,只有这样,第三方的包才能通过签名验证。执行:

1
2
wget http://openwrtdist.sourceforge.net/packages/openwrtdist.pubO /tmp/openwrtdist.pub
opkgkey add /tmp/openwrtdist.pub

打开Luci,定位到“系统”-“软件包”-“配置”选项卡,在“自定义feeds”末尾加入两行并点击“提交”:

1
2
src/gz openwrt_dist http://openwrt-dist.sourceforge.net/packages/base/mipsel_24kc
src/gz openwrt_dist_luci http://openwrt-dist.sourceforge.net/packages/luci

请根据自己的CPU架构(可以执行 opkg printarchitecture 查看,或者参考“发行版软件源”里的URL里的文本),将mipsel_24kc替换成相应的文本,最后点击提交。

然后执行命令 opkg update 更新软件列表,然后执行下列命令安装依赖包以及shadowsocks相关的软件:

1
2
3
4
opkg install ipset libpthread
opkg install shadowsockslibev
# 如果下面的DNS防污染解析方案选择方案三,那么你还需要安装dns-forwarder:
opkg install dnsforwarder luciappdnsforwarder
二、配置shadowsocks

1、配置 /etc/shadowsocks.json ,格式如下:

1
2
3
4
5
6
7
{
      “server”: “X.X.X.X”,
      “server_port”: “443”,
      “password”: “password”,
      “local_port”: “1080”,
      “method”: “aes-128-gcm”
}

请自行修改好服务器IP、端口号、密码、加密方式。

新建文件: /etc/init.d/shadowsocks

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/sh /etc/rc.common
START=95
SERVICE_USE_PID=1
SERVICE_WRITE_PID=1
SERVICE_DAEMONIZE=1
SERVICE_PID_FILE=/var/run/shadowsocks.pid
CONFIG=/etc/shadowsocks.json
start() {
# Proxy Mode
service_start /usr/bin/ssredirc $CONFIGb 0.0.0.0f $SERVICE_PID_FILE
}
stop() {
# Proxy Mode
service_stop /usr/bin/ssredir
}

修改文件权限:

1
chmod +x /etc/init.d/shadowsocks

然后启动shadowsocks,并设置开机运行:

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

最后检查一下是否正常启动了:

1
netstatlnp | grep ssredir

如果未能正确启动,尝试手动执行,看看报什么错:

1
ssredirc /etc/shadowsocks.jsonb 0.0.0.0v

额外的优化:

开启 TCP Fast Open (TCP快速打开,缩略为TFO)

需求: 系统内核版本≥3.7,shadowsocks-libev≥3.0.4,shadowsocks服务端开启tcp fast open。

修改 /etc/sysctl.conf ,加入如下一行:

1
net.ipv4.tcp_fastopen = 3

执行如下命令使之生效:

1
sysctlp

配置文件 /etc/shadowsocks.json 增加一行:

1
2
3
4
5
6
7
8
{
      “server”: “X.X.X.X”,
      “server_port”: “443”,
      “password”: “password”,
      “local_port”: “1080”,
      “method”: “aes-128-gcm”,
      “fast_open”: true
}

最后重启一下shadowsocks即可:

1
/etc/init.d/shadowsocks restart

2、配置dnsmasq和ipset

2.1. 将如下规则加入到“网络→防火墙→自定义规则”中(最后的1080是shadowsocks的本地端口 酌情修改):

1
2
3
ipsetN gfwlist iphash
iptablest natA PREROUTINGp tcpm setmatchset gfwlist dstj REDIRECTtoport 1080
iptablest natA OUTPUTp tcpm setmatchset gfwlist dstj REDIRECTtoport 1080

如果你需要

2.2. 修改dnsmasq配置:

OPENWRT:

修改 /etc/dnsmasq.conf,在最后加入 confdir=/etc/dnsmasq.d

LEDE:

执行:

1
uci get dhcp.@dnsmasq[0].confdir

如果返回值为 uci: Entry not found 或者其他非  /etc/dnsmasq.d 的值,则执行:

1
2
uci add_list dhcp.@dnsmasq[0].confdir=/etc/dnsmasq.d
uci commit dhcp

2.3 添加gfwlist和China-List配置文件:

新建并进入目录  /etc/dnsmasq.d ,下载 dnsmasq_gfwlist_ipset.conf 后放入该目录。

自动生成配置文件的脚本,本人放在这里:https://github.com/cokebar/gfwlist2dnsmasq

你可能需要自行修改这个文件,格式如下:

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

1. 步骤一,有三个方案:

方案一 (由于不加密 所以有风险 不推荐):

在代理服务器上搭建DNS服务来解析国外网站,可用dnsmasq或者pdnsd,监听非53端口。

比如说DNS服务器IP是:3.4.5.6,端口是5050,那么使用替换功能将 /etc/dnsmasq.d/dnsmasq_list.conf 里面的 127.0.0.1#5353 全部替换成 3.4.5.6#5050 即可。

最后重启路由器即可。

方案二 (如果此方案较稳定那么推荐这个方案 不过不少ISP会出现UDP方式不稳定的情况,如果遇到请用方案三):

使用ss-tunnel转发UDP的DNS请求,修改 /etc/init.d/shadowsocks 文件,如需修改上游DNS,请修改 DNS=8.8.8.8:53 字段,本地端口修改 TUNNEL_PORT=5353

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/bin/sh /etc/rc.common
START=95
SERVICE_DAEMONIZE=1
CONFIG=/etc/shadowsocks.json
DNS=8.8.8.8:53
TUNNEL_PORT=5353
start() {
# Proxy Mode
service_start /usr/bin/ssredirc $CONFIGb 0.0.0.0
# Tunnel
service_start /usr/bin/sstunnelc $CONFIGb 0.0.0.0ul $TUNNEL_PORTL $DNS
}
stop() {
# Proxy Mode
service_stop /usr/bin/ssredir
# Tunnel
service_stop /usr/bin/sstunnel
}

最后重启路由器即可。

01-07 13:20