Shadowsocks + GfwList 实现 OpenWRT / LEDE 路由器自动科学上网

本站发布的三种 shadowsocks 在 openwrt 上的自动科学上网方案:

1、Shadowsocks + ChnRoute 实现 OpenWRT / LEDE 路由器自动科学上网
2、Shadowsocks + Redsocks 实现 OpenWRT 路由器自动科学上网 (停止更新)
3、Shadowsocks + GfwList 实现 OpenWRT / LEDE 路由器自动科学上网

本方案依靠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,只有这样,第三方的包才能通过签名验证。执行:

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

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

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


方法二: 手动下载软件包,上传至路由器后安装

依赖列表

右边注释为该包在官方软件源目录下划分到了哪一类 方便查找

LEDE 安装步骤

写在前面:由于LEDE官方软件源包含最新版本shadowsocks-libev软件包,但是官方包和本文使用的aa65535的包不同,并且不兼容,因此请一定要手动下载安装aa65535的软件包,避免装成LEDE官方软件源中的包。

首次安装的话,先确保路由器联网,并更新软件包列表:

注:部分ISP访问LEDE官方站点可能会非常缓慢甚至下载失败,此时需要自行在PC上下载上面的依赖包以后自行上传至路由器目录手动安装。

首先,需要手动安装部分依赖包(并不是所有的依赖包,部分依赖包会自动从软件仓库安装)

接下来下载软件,注意需要根据自己的CPU型号来进行选择。

下载地址: http://openwrt-dist.sourceforge.net/packages/base/

需要下载的文件:

将下载的包通过WinSCP之类的工具上传至路由器的/tmp目录。

然后卸载dnsmasq并安装dnsmasq-full以及剩下的包:

注意不要装成LEDE官方源里的shadowsocks-libev包!

二、配置shadowsocks

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

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

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

修改文件权限:

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

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

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

额外的优化:

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

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

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

执行如下命令使之生效:

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

最后重启一下shadowsocks即可:

 

2、配置dnsmasq和ipset

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

如果你需要

2.2. 修改dnsmasq配置:

OPENWRT:

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

LEDE:

执行:

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

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

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

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

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

三、配置防污染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 :

最后重启路由器即可。

方案三:使用dns-forwarder将DNS转成TCP后走ss代理解析:

dns-forwarder的安装可参考:《Shadowsocks + ChnRoute 实现 OpenWRT / LEDE 路由器自动科学上网》一文中的安装部分,到文中提到的地址,下载安装dnsforwarder_x.x.xx_xxxx.ipk,luciappdnsforwarder_x.x.xx_all.ipk即可。

配置也很简单,luci界面,“服务”→”DNS 转发”(英文界面是DNS Forwarder),如图配置:

最后需要在自定义防火墙规则里再增加一句,来确保8.8.8.8是走代理的:

其他TCP查询方式可以参考:

TCP 方式查询解决 DNS 污染问题


2. 步骤二

在WAN口配置中如图所示,将DNS手动指定为127.0.0.1:

ss222

最后在DHCP/DNS设置中将你的ISP的DNS填入(或者使用114DNS等公共DNS)

dnsmasq_localdns

 

最后你可能需要重启一下路由器,以及清空一下你的PC/PED设备的DNS缓存。


PS1:发现有不少人之前用过chnroute方案,然后改成gfwlist方案,此时记得把忽略解析文件的勾选去掉并把原来的设置填回去:

problem1

 

四、其他

一些强烈推荐的额外设置项(涉及到更新、维护)可以参考:《Shadowsocks for OpenWRT / LEDE 拾遗》

需要自己搭建服务器的,可以参考:shadowsocks – libev 服务端的部署

推荐的VPS商家见:https://cokebar.info/about

本博客有关 shadowsocks 文章合集目录

五、写在最后

本人作为一名普通使用者,水平有限,且文章也缺乏校审,肯定有错误存在,也有很多能改进的地方,如有意见或建议,请留言指出,万分感谢! 如果使用时遇到问题也欢迎留言,本人如果有空都会回复,不过请一定要将出错信息贴出来,有些错误信息需要到系统日志中查看。

 


参考文章:https//kyonli.com/p/18

617 条评论

  1. dover 回复

    博主,你好,我使用的你介绍的这个配置:
    1. 进入 Luci 界面 -> 访问控制 -> 外网区域
    「被忽略IP列表」 选择留空(/dev/null)
    「额外被忽略IP」 设置为 0.0.0.0/1 和 128.0.0.0/1
    2.对于 GfwList 中的 IP 地址, 可以直接添加到「强制走代理IP」里
    也可以保存为一个 IP 列表文件后将列表文件路径填到「走代理IP列表」里
    对于 GfwList 中的域名, 新建一个 dnsmasq 的配置文件, 里面写入类似如下的内容
    # 使用不受污染干扰的 DNS 解析该域名
    server=/google.com/127.0.0.1#5353
    # 将解析出来的结果保存到名为 gfwlist 的 ipset 表中
    ipset=/google.com/ss_spec_dst_fw

    对于gfwlist中的域名能正常通过SS访问,gfwlist以外的是直接访问

    以我的理解,如果设成“全局代理”的时候,是所有域名都通过SS访问,包括墙与没墙。
    但是,在设成“全局代理”后,没墙的是通过SS能正常访问,但墙了的域名就只有gfwlist中的能访问,没有的就不能访问。

    请问这个情况,是我对“全局代理”理解有误,还是哪里设置没正确?

    1. starlight 回复

      应该是ChinaDNS的域名解析的问题。以前GFW对被墙的域名返回一个错误的国外地址,这成为ChinaDNS判断的重要依据。现在貌似GFW变换了策略,对被墙的域名既有可能返回错误的国外地址,也有可能返回国内地址,就是随机化了。这样ChinaDNS已经不能保证正确解析域名了。这是我的推测,欢迎指正。

    2. starlight 回复

      如果没用ChinaDNS,那就更不可能正确解析。被墙的网站只能放在list中,去墙外解析。

  2. dover 回复

    但我是使用ss-tunnel转发UDP的DNS请求

    1. starlight 回复

      ss-tunnel是UDP转发,非加密,有人说会受到GFW干扰,我猜想你也可能是这个情况。可以试一下DNS-forwarder用TCP方式查询DNS.

    2. starlight 回复

      我又想了一下,刚才说的可能不正确。按照你的方案,只有gfwlist中的域名是走ss-tunnel的,其它的都是直接在本地查询,如果被墙,自然不能得到正确结果。
      正如你写的
      # 使用不受污染干扰的 DNS 解析该域名
      server=/google.com/127.0.0.1#5353 (这个是将google.com转到ss-tunnel去查询)
      # 将解析出来的结果保存到名为 gfwlist 的 ipset 表中
      ipset=/google.com/ss_spec_dst_fw (这个是将查询到的ip保存到列表中,让透明代理走ss去访问。如果你用了全局代理,这一句就可以不要,因为统统都走代理了)

      1. dover 回复

        如果设成“全局模式”的话,应该都走SS吧?

        1. starlight

          “全局模式”指所有的ip地址都通过代理访问。但为了正常上网,你还需要保证能获得正确的ip地址,这是DNS解析的工作。路由器是不认识域名的,它只认识ip地址,你需要DNS服务器来进行解析。

        2. starlight

          现在你的上网情况分为三类
          (1)未被墙网站:通过本地查询获得正确ip,通过ss代理访问,正常上网
          (2)己墙,在gfwlist中:通过ss-tunel(即127.0.0.1#5353)获得正确ip,通过ss代理访问,正常上网
          (3)己墙,不在gfwlist中:通过本地查询获得错误ip,通过ss代理访问,不能上网

          如果你想让所有访问都用ss-tunel查询ip,可以将WAN口的DNS直接设置成127.0.0.1#5353。这样再加上全局代理,下面的两句话都不需要了

          # 使用不受污染干扰的 DNS 解析该域名
          server=/google.com/127.0.0.1#5353 (这个是将google.com转到ss-tunnel去查询)
          # 将解析出来的结果保存到名为 gfwlist 的 ipset 表中
          ipset=/google.com/ss_spec_dst_fw (这个是将查询到的ip保存到列表中,让透明代理走ss去访问。如果你用了全局代理,这一句就可以不要,因为统统都走代理了)

          但是,这样的坏处是:所有的DNS查询都是ss-tunnel的结果。如果你输入新浪,可能直接转到北美新浪(如果ss服务器在美国)等等。

        3. dover

          多谢指点

  3. Kingbeyondwall 回复

    博主你好,谢谢你的教程让我一直稳定的使用SS。但是我最近通过IPV6访问instagram时候打不开,显示“ERR_CONNECTION_RESET”。我确认服务端是支持IPV6的,利用PC端也能打开,所以想是不是这套方案里面是不是ipv6不支持走SS通道的?

    1. Kingbeyondwall 回复

      更新,目前在电脑上使用SS客户端可以正常打开INS和FB。但是通过路由器则需要看人品,偶尔运气好才能刷新出来,鉴于之前Telegram直接使用IP而不需要域名解析的经验,可能现在的INS和FB也需要直接添加IP到GFWlist吗?

  4. dover 回复

    如果设成“全局模式”的话,应该都走SS吧?

  5. Samuel 回复

    Hey guys, a Chinese laowai here! Thanks for the detailed how-to, it is great and I just got it working =D. But there’s a but. Telegram app doesn’t work while connected to this router.

    I checked the gfwlist that I’m using and sure enough telegram.org is in it, so why it doesn’t work? Anyone here faced and solved this already?

    1. Starlight 回复

      Can you open the website with a browser such as safari or chrome? Maybe the app uses a different domain name.

  6. Samuel 回复

    Yes, I can open all of Telegram’s sites such as telegram.org, t.me etc.

    If it’s a special domain that the app is using I wonder if there’s a way to find out what that domain is. Would dnsmasq log show it? Could it also be a hard coded IP in the app?

    Does anyone ever compare gfwlist to the domains in greatfire.org’s list? Would be an interesting thing to do given that gfwlist has some missing domains, I even found some on my own. I might do it myself if I can manage to find greatfire’s full list.

    1. Starlight 回复

      I have a similar problem. I can open wsj.com, but the wsj app doesn’t work. I can’t find out the domain name used by app yet. Currently, I have to use a vpn client such as Wingy to force all IP going through the VPS when I use that app. I will appreciate it if anyone can give a better solution.

  7. Samuel 回复

    So there are several apps with this issue. You’re using iPhone too? I wonder if Android apps also suffer from this.

    I tried enabling dnsmasq’s log and hunting for the mysterious domain that would still be blocked. I also downloaded the WSJ app and checked for the same thing. In both cases as I watched the dns queries I didn’t see any domain related to the apps.

    What I saw was queries for several different CDN’s. So I thought the CDN’s might be blocked or they might be doing the blocking themselves. So I added them to the gfwlist to test that hypothesis. If I was right the apps would now work but they still didn’t. Nothing had changed.

    So now I’m thinking this issue may be caused by hard coded IP’s on these apps. Maybe we could compile a list of blocked IP’s and re-route them. Again such an IP list is already available on sites like greatfire.org. I will try that if I have time.

    This link shows how to watch the dns queries in real time in case you want to give this a try:

    https://superuser.com/questions/632898/how-to-log-all-dns-requests-made-through-openwrt-router

    1. Starlight 回复

      The WSJ app doesn’t work on some Android devices, such as my Amazon Fire HD Tablet and Huawei P10 mobile phone. I don’t try the app through a global proxy because I don’t have the android VPN client. I believe it will work, just like the iphone case.

      Thank you for the detailed information. I will visit greatfire.org to see whether I can find the IP list I need and report the result later.

    2. Starlight 回复

      It seems I can’t find any useful information in greatfire.org, which contains much political content and little technical information. I will try to find the so called “hard coded IPs” when I have time. Now I will still use the global proxy solution.

    3. Starlight 回复

      I have tried the way you mentioned above to track the DNS queries and finally solve the problem of WSJ app. Just put “dowjones.com” into gfwlist, then it will work fine. There is also another APP named “Economist” who has the same problem. And I find out that put “pugpig.com” into the list will make it work. Thanks for your advice!

  8. Samuel 回复

    I don’t know if greatfire.org is still actively updating their database, but this is the link of the their roughly 3000 blocked IP’s: https://en.greatfire.org/search/ip-addresses

    If there was a Chinese site with such a list I think that would be better, I’m not aware of any.

  9. Samuel 回复

    I was checking out the gfwlist today and I just realized it contains quite a few IP addresses already. The gfwlist to dnsmasq tool filters them out?

    1. Starlight 回复

      I have no idea how gfwlist2dnsmasq works. Hope Cokebar can answer your question.

    2. cokebar 文章作者 回复

      dnsmasq is a DNS resolver. The ipset rule for dnsmasq works like this:
      When dnsmasq try to resolve a domain, and the domain match an ipset rule, when dnsmasq get the IP address for this domain, dnsmasq will automatically add the IP address to the ipset. This rule works for domain but not for IP address.
      When you need to add an IP address to the ipset, use the command:
      ipset add IPSET_NAME IP_CIDR

  10. liangchaoxiong 回复

    我是小白,按照方法二成功了。想问下的是如果偶然想走全局代理的话应该怎样改?多谢先

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

请输入验证码 *