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. thesun 回复

    我想请教一下,我按照教程安装好了,开始速度很快,但是过段时间境外网站就会变的很慢,甚至打不开,为什么呢?同一个SS服务器,我如果用windows版本ss代理连接就很快,说明不是服务器的问题,请问为什么?

    1. cokebar 文章作者 回复

      1. 路由的系统日志里看看有无大量ss的报警日志;
      2. 检查路由器当前连接数,以及路由器的负载,是否开了过多的连接导致路由器吃不消了,如果网络内有在使用P2P类软件更要注意路由器的性能问题;低端路由CPU性能比较弱,国内一些比较无耻的软件,比如说某雷影音,会打开成百上千个连接搞P2P传输,OpenWrt本身就不支持硬件NAT加速,此种情况会很快耗尽CPU的计算资源,这时候如果还要计算ss的加解密(特别是aes-xxx-xxx这种计算量比较大的算法),直接结果就是慢的要死。
      3. ss是否设置过长的超时时间,过长的超时时间也可能造成ss有过多的连接数
      4. 可以通过/etc/sysctl.conf优化一下

  2. mlm 回复

    飞羽老师,承接上次的问题,我按照你的方法更改了list,当时是可以翻墙的,但是隔一段时间又不行了,直接无法连接,我是自己用pdnsd架的dns服务器在我的vps上,需要把我的vps的ip设为强制翻墙么?

    1. mlm 回复

      今天的使用情况来看,时好时坏,有时候会自己恢复,能够正常翻墙,然后过一会又不行了。。

    2. cokebar 文章作者 回复

      这个回复你看了没:
      “我二了 SS_SPEC_WAN_FW是iptables链,这里应该对应ipset名,应该是:
      server=/google.com/127.0.0.1#5353
      ipset=/google.com/ss_spec_dst_fw
      注意,如果你的防污染DNS用的国外DNS是8.8.8.8,且走了shadowsocks了,那么要把8.8.8.8填到强制走代理IP里面”
      如果照做了,那么继续排查:
      检查一下dnsmasq对于GFWLIST上的DNS解析是否有异常,并且ipset是否正常添加了,可以按照下面的步骤:
      1. PC上退出所有浏览器等可能连接被墙站点的程序,并且 ipconfig /flushdns 清缓存
      2. SSH连接路由器,重启shadowsocks和dnsmasq( /etc/init.d/shadowsocks restart/etc/init.d/dnsmasq restart
      3. SSH中ipset list ss_spec_dst_fw,应该是空的,看不到任何IP
      4. PC上使用dig或者nslookup,尝试解析被墙域名,如:
      dig @192.168.1.1 -p 53 www.google.com
      如果DNS设置没有问题,那么应该返回无污染的解析结果,记下结果的IP
      5. SSH中ipset list ss_spec_dst_fw,此时ipset中应该已经有IP了,应该正好是上一步骤的解析结果

    3. cokebar 文章作者 回复

      注意我这个方式,如果重启shadowsocks(此时ipset被清空),则必须同时重启dnsmasq(否则直接走缓存,dnsmasq不会向ipset中添加IP),客户机也必须清除DNS缓存(否则客户机直接使用本地缓存,不通过dnsmasq,则也不会向ipset中添加IP)

      1. mlm 回复

        感谢飞羽老师详细的解答,我周末是看了你的回复马上改了试的,一开始确实是各种不稳定,看到你的排查方式,我猜是不是我修改shadowsocks之后,它自动重启了ss,但是dnsmasq并没有重启,那么造成dns解析错误,很有可能是这个原因。我觉得你的这些回复可以作为我刷路由器的标准教程了,赞一个。我用的是自己的vps做的dns服务器,就像:server=/.lsxszzg.com/104.194.72.179#5656这种,之前用你的第三种方法,这种写法完全没问题,所以我想还是你说的这个dns缓存没有清空的问题。目前使用一切正常,有问题会按照你的方式进行排查,再次感谢!

  3. 喵喵银 回复

    为什么chnroute那篇有luci下的配置教程,这篇就全是命令行……

    1. cokebar 文章作者 回复

      chnroute那篇的luci-app-shadowsocks最初是专为chnroute绕行模式设计的,后来虽说加入了不少功能,可以通过一些步骤实现gfwlist模式,但是还是有点小问题没解决;如果解决了可能会补充通过luci-app-shadowsocks实现gfwlist方案的步骤

  4. mlm 回复

    求教老师,路由器在修改了一下shadowsocks设置后就又翻不了了。按照你的方法,现重启dnsmasq和ss,然后dig google, 返回ip是172.217.5.196, 查询路由器ipset list ss_spec_dst_fw 也是这个ip。但是依然无法翻墙,不光是电脑,手机都不行,一经清空dns了。求解啊,感觉这个luci的版本用gfwlist还是不太稳定,有时候修改ss设置就没问题,有时候就不行了。

    1. mlm 回复

      74.125.204.113
      216.58.216.10
      172.217.11.74
      74.125.204.100
      216.58.217.202
      172.217.11.78
      216.58.219.10
      54.215.170.9
      173.194.203.188
      172.217.4.138
      172.217.4.163
      74.125.199.125
      172.217.11.170
      216.58.193.202
      74.125.204.138
      172.217.5.202
      74.125.204.139
      74.125.204.102
      172.217.5.206
      172.217.5.74
      216.58.219.14
      74.125.204.101
      用网页尝试登陆youtube google ipset里面就多了很多ip。

  5. devjia 回复

    你好,
    LEDE17.01.2 替换 dnsmasq 为 dnsmasq-full 后重启 dnsmasq log:
    udhcpc: started, v1.25.1
    udhcpc: sending discover
    udhcpc: no lease, failing

    按照 gfwlist 的 wiki 配置完成后,ipset里gfwlist正常有 ip,ss_spec_dst_fw没 IP
    nslookup google.com
    Server: 127.0.0.1
    Address: 127.0.0.1#53

    Name: google.com
    Address 1: 216.58.221.14
    Address 2: 2404:6800:4004:807::200e
    然后表现就是 google 打不开,请问可能是哪块有问题?

    1. cokebar 文章作者 回复

      1. 建议禁用wan、lan的ipv6,重启时候的udhcpc的消息可消除。
      2. aa65535的wiki里面就是将IP添加到gfwlist的ipset里的。然后gfwlist里的ip会转发数据包到SS_SPEC_WAN_FW的链中,从而转发到ss-redir
      3. 重启/启动shadowsocks时候,SS_SPEC_WAN_FW链中规则会先被清空,因此需要重新执行那条iptables命令添加转发规则

      1. devjia 回复

        感谢回复。

        个人觉得可能是 iptables 的转发链(iptables -t nat -I SS_SPEC_WAN_AC 1 -m set –match-set gfwlist dst -j SS_SPEC_WAN_FW)没有生效。
        暂时通过配置 dnsmsaq gfwlist.conf 为
        server=/google.com/127.0.0.1#5300
        ipset=/google.com/ss_spec_dst_fw
        直接把 gfwlist 域名对应 ip 解析到 ss-redir 强制走代理集合(ss_spec_dst_fw)中 , 省去了 iptables 的转发 gfwlist -> SS_SPEC_WAN_FW 操作。

        这样做有没有问题?
        之前 dnsmasq 重启的时候 udhcpc 的消息是警告还是错误?能否忽略?

  6. niphor 回复

    楼主 最后我采用了 luci-app-shadowsocks/wiki/GfwList-Support 的方案,但是遇到个问题
    我已经 在 透明代理->UDP代理 设置为与主服务器相同,并且把8.8.8.8加入到强制走代理IP
    并且开启dns-forwarder,路由器上解析是正常的,gfwlist也能正常走代理

    但是 如果我在局域网内客户机上 设置DNS为8.8.8.8 原则上应该走UDP代理 然后有返回值才对,现在一直是 timeout

    如果nslookup 用 dns-forwarder 的端口 则 能正常有返回


    root:~# nc -vuz 8.8.8.8 53
    Connection to 8.8.8.8 53 port [udp/domain] succeeded!
    root:~# nslookup
    > server 8.8.8.8
    Default server: 8.8.8.8
    Address: 8.8.8.8#53
    > www.baidu.com
    ;; connection timed out; no servers could be reached

    现在想不出原因来 求指导

  7. niphor 回复

    我 顺手做了个简单的测试

    root:~# nslookup

    8.8.8.8加入到 强制走代理IP

    > server 8.8.8.8
    Default server: 8.8.8.8
    Address: 8.8.8.8#53
    > http://www.baidu.com
    ;; connection timed out; no servers could be reached

    正常不走代理的 非标端口DNS
    > set port=54
    > server 185.37.37.37
    Default server: 185.37.37.37
    Address: 185.37.37.37#54
    > wwww.google.com
    ** server can’t find wwww.google.com: NXDOMAIN

    加入到 强制走代理IP
    > http://www.google.com
    Server: 185.37.39.39
    Address: 185.37.39.39#54

    Non-authoritative answer:
    Name: http://www.google.com
    Address: google ip

  8. 引用: WNBR4300安装LEDE – Liu Xinyun's Kulakism

  9. 王万荣 回复

    将直接所有流量都经过$$转发和使用ipset分流进行对比一下,访问那些gflist里的站点的速度是不是有差别?意思是,利用iptables加ipset对流量进行筛选的时候会不会拖慢数据包的传输过程?(类似于游戏中ping有多少毫秒),毕竟list里有几千个域名需要对照!

    1. cokebar 文章作者 回复

      只有首次传输时候会稍慢,因为首次时候dnsmasq解析域名,和list中对照,发现在list中后,将DNS请求转给配置好的防污染DNS,收到解析结果后会将返回的IP地址添加到ipset中,然后只要以后访问这个IP就会走代理。
      分析一下性能开销:
      延迟方面:
      1. dnsmasq对照list的开销,这个确实不小,一些路由性能弱的如果规则条数过多可能首次查找时候会卡,但是如果只是gfwlist,只有几千条而已,性能不会有差;dnsmasq在几万条以上的时候才会初步展现性能差距(用china-domain-list时候需要稍注意一下性能问题),不过有人针对这个做出了改进版:https://github.com/infinet/dnsmasq/tree/fastlookup-v2.77test4,从文本匹配改成了hash表,这样就无视规则数量了。影响指数,毫秒级以下。这个只在首次连接时候存在,因为DNS有缓存,不用每次都查询。
      2. DNS查询速度由于走了国外DNS,这个大部分情况下肯定是比直接查询国内DNS来得慢。不过由于DNS缓存的存在,因此也就影响首次访问而已。影响指数,百毫秒级
      3. ipset查表,判断是否走代理;由于建立的ipset是hash表,因此也是一个无视列表大小的查询巨快的存在,影响指数毫秒级以下。
      4. TCP建立连接时间额外开销。由于TCP连接需要三次握手,如果是连美国,这三次可能半秒都过去了,然后才开始传数据。而如果走了代理,就多了一次TCP建立过程,首先$$客户端和$$服务端建立TCP连接,然后$$服务器和目标远程服务器建立TCP连接,延迟大的可能一秒以上了。影响指数,百毫秒级到秒级。改善这个的方法是开启tcp fast open(TFO)。TFO可以在握手过程中传输数据,从而减少建立连接的开销。
      5. UDP延迟比TCP低

      传输速率方面:
      1. ss加密方式:;路由器cpu通常性能不强,不支持硬件加密指令集,所以aes一类的加密方式计算开销最大,chacha20中等,rc4一类的较小。我尝试过WNDR4300(单核MIPS),aes下的表现就比较差,而WRT1900ACS(双核ARM)则轻松跑满带宽。
      2. NAT性能,同样和CPU性能直接相关,由于openwrt/lede不支持硬件NAT所以大流量时候的软NAT还是会消耗一些CPU计算能力的
      3. TCP流控措施,服务端使用bbr/锐速一类可以增加带宽利用率加快传输速率,然而可能会增加延迟。

  10. Passenger 回复

    继续请教出现的问题:
    这次用的是华为的HG255D,系统17.01.4
    发现ss不运行,根据上面所说输入ss-redir -c /etc/shadowsocks.json -b 0.0.0.0 -v命令后出现类似下面这种提示:
    INFO: initializing ciphers… chacha20
    INFO: This system doesn’t provide enough entropy to quickly generate high-quality random numbers
    Installing the rng-utils/rng-tools or haveged packages may help.
    On virtualized Linux environments, also consider using virtio-rng.
    The service will not start until enough entropy has been collected.
    INFO: listening at 0.0.0.0:1080
    INFO: running from root user
    然后就停止在那里需要ctrl+c终止。
    实际上,前几次运行ss-redir -c /etc/shadowsocks.json -b 0.0.0.0 -v命令后出现的提示不包含
    INFO: This system doesn’t provide enough entropy to quickly generate high-quality random numbers
    Installing the rng-utils/rng-tools or haveged packages may help.
    On virtualized Linux environments, also consider using virtio-rng.
    The service will not start until enough entropy has been collected.
    这句,只是其他几句然后就无响应,连续中断并重新输入运行这个命令后才多出这一句提示,请问应该如何处理,谢谢!

    1. cokebar 文章作者 回复

      安装rng-tools可以消除这个错误 然而这个错误应该不会影响正常使用(只是会慢一些才可用)

      1. Passenger 回复

        非常感谢,刚刚搞定了,装了rng-tools和haveged两个东西。不过不知道是不是这个的问题,因为我刚才又重新把你上面贴的shadowsocks文件内容复制一遍到路由内重启的。重新改shadowsocks文件试手系统日志的启发,刚才看到一个/init.d/shadowsocks 错误。想想之前因为看网上资料说这个HG255D配置比较差,所以我之前写这个文件内容的时候为了省空间就把你上面带#号注释的内容都去掉了。现在没敢动,原样粘贴,终于好了。所以这个问题不一定和上面两个组件有关,不过现在组件正常了,我也懒得去卸载这两个东西了。现在说明白一点,供后来人参考吧。也非常感谢博主的热心,顺带说一下,服务器端的那个问题我也解决了,之前用的是普通源,后来按照官方说明用了那个什么stretch-backports源的安装默认就带ietf加密了,一切正常。
        谢谢!不过这个HG255D真的不好折腾,到现在无线都开不开,开启后信号总显示0%,也搜索不到,希望慢慢能找到资料吧。

发表回复

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

请输入验证码 *