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

618 条评论

  1. TheFirstCurse 回复

    你好,博主,用你的方案成功使用好一段时间,但是从aa的openwrt-SS-libev-spec2.4.3开始(就是目前的2.4.5还是一样)就不能正常运行了,后来看了下/etc/init.d/下的SS执行脚本,发现他重写了获取参数的方法,所以就怀疑是否脚本有问题而造成不能正常启动,但本人shell不是很熟练,看不出到底哪里有问题,所以请博主有时间看一下是否是他的脚本有问题,谢谢。

    1. cokebar 文章作者 回复

      gfwlist方案请勿使用spec版本

      1. TheFirstCurse 回复

        我是使用第一种方案的,然后我回去安装了Luci使用(之前一直是使用vi直接编辑+shell命令运行),发现option global_server这个原来是启动的选项,之前直接看config目录下的配置时还以为是全局代理配置参数,现在可以运行了,但是还是不能正确解析外IP,诶,真的,现在ss改动很大,配置不能跟以前作类比来改就可以的,希望博主有空更新一下配置教程吧。感谢博主的回复,继续折腾。PS:我使用第一种方案的,是不是应该发到第一种方案的评论下呢?

      1. TheFirstCurse 回复

        很感谢博主的回复,但是到作者那里看的就只是一个默认配置,根本没有什么用,配置项的意思和使用说明都没有,就像option global_server应该怎么填,看他的模板都不知道是怎么回事。

      2. TheFirstCurse 回复

        还是说让我去看源代码吗?

    2. TheFirstCurse 回复

      我现在就是安装了Luci,所以解决了没有运行起来的问题,但是配置不正确上不了墙外网,国内的可以。

    3. TheFirstCurse 回复

      config global
      option global_server ‘nil’ #此处值不知如何获取
      option udp_relay_server ” #这个值使用Luci后会出来,怎样使用不知道

      config servers
      option auth_enable ‘0’ #授权验证不知道用来做什么
      option server ‘127.0.0.1’ #不说也知道是什么
      option server_port ‘8388’ #不说也知道是什么
      option local_port ‘1080’ #不说也知道是什么
      option password ‘barfoo!’ #不说也知道是什么
      option timeout ’60’ #不说也知道是什么
      option encrypt_method ‘rc4-md5’ #不说也知道是什么

      config udp_forward
      option tunnel_enable ‘0’ #应该要使用1吧如果使用udp查询dns
      option tunnel_port ‘5300’ #不说也知道是什么
      option tunnel_forward ” #不说也知道是什么

      config access_control
      option lan_ac_mode ‘0’ #不要改
      option wan_bp_list ‘/dev/null’ #就是iglist

    4. TheFirstCurse 回复

      另外我看了init.d/ss文件,有如下内容,这样不是写死用5300端口吗?

      start_tunnel() {
      /usr/bin/ss-tunnel \
      -c $CONFIG_FILE $ARG_OTA ${ARG_UDP:=”-u”} \
      -l $(uci_get_by_type udp_forward tunnel_port 5300) \
      -L $(uci_get_by_type udp_forward tunnel_forward 8.8.4.4:53) \
      -f /var/run/ss-tunnel.pid
      return $?
      }

      1. TheFirstCurse 回复

        不好意思看错了,仔细看了uci_get_by_type()函数,是在没有设置时就会用5300端口。

      2. cokebar 文章作者 回复

        改成新版结构后用luci配置即可 参考https://cokebar.info/archives/664

        1. TheFirstCurse

          感谢博主的博文更新,回去要试一下,希望博主能给更多好的方案,然后然后可以考虑一下写一篇使用strong——swan的文章,官方也有很多支持,前景应该很好。

  2. River 回复

    如果使用GFWlist的方案,可以让ipv6直连、GFWlist里的ipv4走ss代理吗?
    还有,防污染我试来试去就发现dnscrypt是最稳定的,当然不要用opendns

      1. River 回复

        谢谢回复,刚刚查了一下,openwrt里的shadowsocks本身没法代理ipv6?

        1. cokebar 文章作者

          可以 但是没见有人做现成的包

      2. River 回复

        对那个dnsmasq_list.conf里面的写法不是很理解
        比方说第一条
        server=/.85.17.73.31/127.0.0.1#5353
        ipset=/.85.17.73.31/gfwlist
        这样写这个IP好像没有走代理

        1. cokebar 文章作者

          gfwlist里面带的 就他是IP 自动脚本生成出来的只认域名 对这种ip地址的有点问题
          dnsmasq里面这样直接写IP是无效的 删掉此行即可 留着也不影响 属于无效行

      3. River 回复

        ipset -A gfwlist 85.17.73.31
        这种IP直接写入防火墙规则好了

    1. ifreeswan 回复

      你好,我用的是默认的opendns,你用的什么dns呢?

      1. River 回复

        去下载最新的dnscrypt resolve文件,里面有好多可选,然后就要根据自己的环境试了、去掉那些老是获取不到证书的,我这里当然是用ipv6的DNS又快又可靠

        1. ifreeswan

          ipv6 从没试过,cisco 查询时间在300ms左右,其他没试过了,shell编程不会,不然用个程序来测试。

      2. River 回复

        Cisco 是最快的、可是我这用一会就获取不到证书了?

  3. 春夏秋冬 回复

    我用用tcp方法来防DNS污染,将dnsmasq_list.conf里面的127.0.0.1#5353改成pdnsd的端口号127.0.0.1#25252,
    用dig查询好像也没污染,tcping也可以通,为什么所有被墙的都打不开, etc/init.d/shadowsock这个文件还需要改端口吗?
    root@OpenWrt:~# dig http://www.youtube.com

    ; <> DiG 9.9.4 <> http://www.youtube.com
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 18784
    ;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1

    ;; OPT PSEUDOSECTION:
    ; EDNS: version: 0, flags:; udp: 1024
    ;; QUESTION SECTION:
    ;www.youtube.com. IN A

    ;; ANSWER SECTION:
    http://www.youtube.com. 663 IN CNAME youtube-ui.l.google.com.
    youtube-ui.l.google.com. 900 IN CNAME youtube-ui-china.l.google.com.
    youtube-ui-china.l.google.com. 1184 IN A 37.61.54.158

    ;; Query time: 42 msec
    ;; SERVER: 127.0.0.1#53(127.0.0.1)
    ;; WHEN: Tue Apr 12 15:05:41 GMT 2016
    ;; MSG SIZE rcvd: 125

  4. 春夏秋冬 回复

    补充一下,没有安装chinadns,

  5. ifreeswan 回复

    你好,我现在用的 gfwlist 方式,以前用过 ChnRoute 方式,gfwlist 需要自己输入 ipset iptable 命令,而 shadowsocks-libev-spec 包含了 ipset iptables 命令,能不能把 shadowsocks-libev-spec 包含的命令贴出来学习下。
    谢谢!

    1. cokebar 文章作者 回复

      view it on github

  6. bing 回复

    你好,我的路由器自带的是这样的,看你的教程没有讲到这个忽略列表,我发现不光gfwlist的列表会走ss,所有的国外网站都会走ss,但是把这个忽略列表留空的话,就会变成全局代理,该怎么办才能,只有gfwlist列表里面的走ss呢???

    透明代理
    使用ss-redir,iptables以及ipset进行全局代理

    启用
    端口
    1080
    忽略列表
    /etc/chinadns_chnroute.txt

    帮助 如果希望使用全局代理模式,请留空.

    1. cokebar 文章作者 回复

      你是用的是chnroute方案 ,spec版本,请换用此文章gfwlist方案即可。卸载原有所有的ss相关的包并还原系统配置,最后按照此篇文章重新配置即可

  7. bing 回复

    谢谢你的解答,我搞定了,我在别的地方看到spec版本就是比原版多了个ss_rules,然后我进去那个配置文件里面把start_rules这一段删除了,关于rules这个词的段都删除了,然后就好了

    1. jk 回复

      请问删除了哪里呢,我试着找不到头绪,可以具体指点一下吗,谢谢。

      1. bing 回复

        etc/init.d/shadowsocks这个是配置文件,把里面关于ss-rules的内容全部删除,貌似spec版就是比普通版多个ss-rules这个东西,把配置文件里面关于它的字段删除后,系统就不会启动他了,或者直接把那个ss-rules文件删除了

        1. cokebar 文章作者

          请勿如此操作 请卸载spec版本后使用非spec版本 本篇方案不可以使用spec版本

  8. kodango 回复

    好奇怪,我安装楼主的方法配置(方案二),启动shadowsocks后,长城外的网站打开很快说明代理是工作了。但是访问国内网站感觉慢,v2ex 打不开,youku 打开很慢视频显示非中国不能观看类似的提醒。

  9. 那只猫 回复

    我一个问题,我使用第二种方案和第三种方案,国内网站可以正常访问,但是gfwlist里面的域名,连域名解析都出不来。

    1. jk 回复

      同问这个问题,国内是好的,但是list里面国外域名解析不了。

  10. jk 回复

    问题解决,可能是ss-redir没启动,另外参考https://github.com/shadowsocks/openwrt-shadowsocks/issues/81 修改了启动,ps |grep 看看进程有没有,如果没有,就手动启动,现在可以使用了。

发表回复

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

请输入验证码 *