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

本站发布的三种使用 shadowsocks 在 OpenWrt / LEDE 上的自动科学上网方案:

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

这篇文章介绍的方法基于aa65535的luci-app-shadowsocks/openwrt-shadowsocks,介绍了如何在OpenWRT / LEDE下配置自动科学上网,新版本支持在Luci下图形化配置,大大简化了配置过程。配置完成后,路由器本身获得自动科学上网能力,所有连入该路由的设备都可无障碍访问被墙的站点。是运行于路由器的透明代理。

方案简介
本文changelog

注:本文不再提供OpenWrt 15.05及以下版本的说明;仅支持LEDE 17.01, OpenWrt 18.06及后续版本

一、安装

适用于 openwrt-shadowsocks 3.0.1及以上版本,搭配 luci-app-shadowsocks 1.6.0及后续版本。

所需软件列表

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

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

前提是所用网络环境直连sourceforge.net和downloads.openwrt.org没有问题。

接下来可以直接使用作者的一键脚本,执行:

此方法手动的步骤

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

如果直连遇到困难(无法连接或者过程中下载总是中断),请继续下面的步骤来安装。实测国内许多ISP,执行 opkg update 和 opkg install 下载安装的时候都可能会遇到卡住、中断的情况,请多试几次。如果尝试多次仍然失败,请参考下面的依赖列表,手动至官方下载站点手工下载。

详细步骤点击展开
二、shadowsocks 配置

登录Luci,指向“服务”,此时应该能够看到shadowsocks(中文界面下显示“影梭”)了。接下来进行shadowsocks的配置。

I. 添加服务器
II. 设置代理方案
III. 开启代理服务
IV. 额外的优化
三、DNS配置

到此虽然shadowsocks配置完成,不过还没有进行DNS部分的配置,只有完成了DNS的配置才能解决DNS污染并优化DNS解析,接下来的部分来对DNS的配置进行说明。

PS:DNS的调试可以使用dig

I. DNS转发链图示
II. DNS转发链的基本配置
III. DNS转发链的优化配置
四、按域名指定是否走代理(可选)

这一部分的配置用于替代 “三.III.2. 添加gfwlist和China-List配置文件”中的步骤。请在完成“三.III.2. 添加gfwlist和China-List配置文件”前面的配置后进行这一部分的配置。

下面的步骤会使用我编写的脚本来自动生成配置文件,脚本放在github维护,可能随时更新,可到gfwlist2dnsmasq, openwrt-scripts查看最近更新的动态。

先使用dnsmasq-full替换掉原有的dnsmasq,由于先卸载dnsmasq后很可能会导致后面下载dnsmasq-full包的时候无法域名解析,从而导致下载失败,因此这里使用一个取巧的办法,先尝试安装dnsmasq-full:

然后会收到错误信息(原因是文件冲突),dnsmasq-full也不会成功安装;但是不用管,因为此时dnsmasq-full的依赖包应该已经装好了。接下来到openwrt官网下载dnsmasq-full的包,举例:https://downloads.openwrt.org/releases/packages-18.06/arm_cortex-a9_vfpv3/base/dnsmasq-full_2.80-1_arm_cortex-a9_vfpv3.ipk

然后将ipk包上传到路由器/tmp目录,并执行如下命令:

I. China-List强制直连 自定义域名强制直连
II. GFWList强制走代理 自定义域名强制走代理
四、其他

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

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

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

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

五、写在最后

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

2,087 条评论

  1. 头像qwerty 回复

    无论是LUCI SS控制界面的“DNS转发”又或者是DNS转发插件,对于8888和8844似乎都不稳定,速度奇慢且行为不稳定,有时候地址解析完了,OpenWRT路由器在一系列内部转发之后只把IPv6地址返回给网内客户端,导致不少无辜网站完全连不上。
    不过有个方法可以彻底避免这种现象,那就是使用Open DNS+443+强制代理:
    1、Shadowsocks设置界面内,访问控制 > 外网区域 > 强制走代理IP,填入208.67.222.222
    2、ChinaDNS设置界面,“上游服务器”填入,;例如:119.29.29.29,208.67.222.222#443
    Open DNS的好处就是使用443端口来做DNS解析,SS可以完美地代理,就算不用SS来转发,443也能保证不受DNS污染。
    3、ChinaDNS设置界面,勾选“双向过滤”。
    4(可选)、“网络”-“DHCP/DNS” > “HOSTS和解析文件”选项卡,恢复“忽略解析文件”原有设置。

    3+4同时设置可以避免只返回IPv6的怪事。

    使用以上方法就不需要麻烦且不稳定的DNS forward功能了,更不需要安装DNS forward相关的ipk。
    当然这还是比不上梅林版shadowsocks控制功能,梅林的可以使用“cdns”,不需要填DNS地址,cdns是直接在ss服务器上面做DNS解析,用的DNS就是ss服务器所在运营商DNS,对网速友好。切换服务器能够自动更换DNS。

    1. cokebarcokebar 文章作者 回复

      1. 这是你的个例,请根据自己的vps选用合适的DNS服务器。大部分VPS访问google dns效果都是不错的。如果感觉用了dns forwarder有问题,可以再试试ss-tunel走udp,如果还是慢,就根据vps的默认dns填。

      2. 你说的第4点是有问题的,这里一定要勾选忽略。有以下两种情况:
      ① WAN口没手工指定127.0.0.1为DNS而是用的自动,此时如果不勾选忽略解析文件,就会将WAN口自动获取的ISP的DNS引入dnsmasq中,可能造成DNS污染;你可以尝试将/etc/dnsmasq.d/dnsmasq_gfwlist.conf文件移走(因为如果有这个设置文件,gfwlist中的网址会强制走防污染DNS,这里去掉这个配置,模拟访问一个未在gfwlist中,但被dns污染了的网站的情况)并重启dnsmasq,然后在客户机上用dig命令测试你会发现有dns污染;
      ② WAN口手工指定了127.0.0.1为DNS,那么不勾选忽略解析文件,会将127.0.0.1这个上游DNS引入dnsmasq中,也就是,dnsmasq的上游dns是他自己,这就意味着,dnsmasq转发客户机的dns请求时,会同时发给chinadns和他自己,而后者是一个死循环;虽然dnsmasq应是有措施避免死循环的,不过假设dnsmasq自己没防死循环措施的话,这个查询死循环会一直进行下去,直到收到chinadns来的解析结果后才会停止。

      3. cdns通过带edns的dns请求,并且加delay来防污染,根据我在koolshare中看的帖子,dns方案应该是多选一,没有做多级dns转发,因此cdns应该是将本地ip作为edns subnet ip传送给上游dns了(上游dns是那些支持edns subnet的公共dns,一般来说都是用的还是google dns),以此来抗污染,但是得到的解析结果是根据你的本地ip优化的,并不是你的ss服务器的ip;如果想要试用EDNS subnet来优化解析,可以尝试aa65535编写的带EDNS subnet的ChinaDNS 2.0版本(https://github.com/aa65535/ChinaDNS)。不过 edns subnet方案还是不皮实,不但需要DNS resolver支持,还需要权威DNS也支持才行,如果某个网站的权威DNS不支持EDNS subnet,那么这方案就对这个网站就没用了,而且google dns的edns subnet也不是很皮实,详见这个issue的讨论:https://github.com/aa65535/ChinaDNS/issues/1

      4. 经过openwrt里的转发器转发后只有ipv6了是不可能的,请检查是否被DNS污染。另外,目前的方案中,透明代理并不支持ipv6,也就是,请将LAN口ipv6改为禁用避免客户机获取到公网ipv6地址导致引入ipv6的污染ip

      5. 出问题请用dig命令仔细排查
      https://cokebar.info/archives/402

    2. cokebarcokebar 文章作者 回复

      如果哪里我理解有误请指正

    3. cokebarcokebar 文章作者 回复

      DNS只有iPv6解析结果的话,请考虑禁用ipv6,应该是路由获取了Ipv6的dns服务器,这个服务器先返回了污染的结果

  2. 头像GD 回复

    “这一部分的配置用于替代 “二.III.2. 添加gfwlist和China-List配置文件”中的步骤。请在完成“二.III.2. 添加gfwlist和China-List配置文件”前面的配置后进行这一部分的配置。”

    这段话是什么意思呢,看了 半天搞不明白是”添加gfwlist和China-List配置文件”前,先这样设置,还是“添加gfwlist和China-List配置文件”之后,再按照下面的 步骤生成文件。

    1. cokebarcokebar 文章作者 回复

      用 第III大节的内容 替换掉 二.III.2.小节的内容

      1. 头像Tyleo 回复

        按照上面的步骤设置之后是可以连上SS了,但是有一个无比蛋疼的问题,我试过了各种办法都无法避免。症状如下:1.家里的谷歌音箱连不上SS了,但能在内网投射音频;2.Chromecast再也无法投射YouTube的视频了。
        3、在Shadowsocks控制界面里,如果选择“代理自身”是“直接连接”的话,那么所有被墙的网站统统都上不了。
        4、我尝试关闭了路由器的防火墙,结果就是无论国内国外,任何网站都上不了了。5、想让一个域名直连,已经按照规则添加到直连的名单里,死活都是走代理,名单貌似没有生效。

        以上问题折腾了好几天都没办法搞定,不知道是哪里出了问题。可惜博主写的教程,只是记录了步骤,并没有过多的解释原理。因为不懂得原理,出了问题也是束手无策啊。希望博主以后写教程,原理也讲一下,这样出了问题,也知道如何自行解决。谢谢

        1. cokebarcokebar 文章作者

          1、2. 没有相关设备 但估计是谷歌的设备自己强制走google dns解析不走路由器dns导致的,这种情况需要在路由器上打开udp透明代理(udp服务器选上)是的google设备解析dns时候走代理
          3. 这一点仔细想了一下 是我的方案的问题,如果没有代理自身,dns解析会有问题,回头我会修改一下方案
          4. 你是怎么关闭防火墙的? openwrt上的防火墙不能关的,LAN到WAN的NAT都是他来管否则不能上网

        2. cokebarcokebar 文章作者

          linux里的防火墙netfilter 不仅仅是限制程序联网的安全程序;netfileter是在Linux内核中的一个软件框架,用于管理网络数据包。不仅具有网络地址转换(NAT)的功能,也具备数据包内容修改、以及数据包过滤等防火墙功能。QoS、upnp、vpn等很多网络功能的实现都要依赖于它

      2. 头像tyleo 回复

        非常感谢,勾选上udp之后,谷歌音箱和Chromecast可以正常投射了。

        还有一个问题没解决的是,我想让ip.cip.cc这个域名直连,并没有成功。因为这个是查询本机IP的域名,走代理的话会查到是Shadowsocks服务器的IP,而不是我目前的电信IP。

        因我有个在Godaddy上买的域名,想用来做动态DNS解析。Godaddy开放了API,有个老外写的脚本可以放路由上去,设置每隔10分钟查询一下本地的IP地址,如果IP改变,则马上更改Godaddy域名绑定的IP,如本地IP没有改变,则保持现状。从而实现动态DDNS解析。这样就可以远程访问家里的路由了。

        我关闭路由防火墙是在wiki上看到的。具体是:

        先运行停止命令:/etc/init.d/firewall stop
        再运行禁止命令: /etc/init.d/firewall disable
        这样就禁用了防火墙

        激活防火墙:/etc/init.d/firewall enable

        1. cokebarcokebar 文章作者

          ip.cip.cc这个域名在chinalist里本身就是有的,如果你配置正确就应该是直连过去的才对。在路由器上直接运行 curl ip.cip.cc 就能看结果。可以按如下步骤排查:
          1. 关闭那个脚本的自动运行,重启路由器,一切置于初始状态;切记禁用IPv6,并且WAN口配置自定义DNS为127.0.0.1,否则路由器自身解析DNS时不走dnsmasq导致无法触发chinalist规则
          2. 在电脑上执行一次dns查询:dig ip.cip.cc,记下解析结果: 139.180.221.217
          3. 路由器上运行 ipset list ss_spec_dst_bp | grep ‘139.180.221.217’
          4. 命令运行返回结果为空则配置有问题 chinalist未生效,如果有,证明生效,应该能直连了
          5. 运行 curl ip.cip.cc看看是否返回WAN口地址

        2. cokebarcokebar 文章作者

          /etc/init.d/firewall这个自启脚本的作用时读取一下两个配置文件,设置netfilter:
          /etc/firewall.user
          /etc/config/firewall

          禁用后,luci里设置的防火墙配置全部失效,影响NAT从而影响上网,并且shadowsocks的透明代理也依赖这个,会往firewall配置文件里写配置进去,这东西不要禁用

      3. 头像Tyleo 回复

        按照你的方法试了一下,问题应该是chinalist规则未生效。不知如何解决,需要重新安装一遍Shadowsocks?

  3. 引用: shadowsocks客户端配置 – Liu Wei's Blog

  4. 头像anthony 回复

    cokebar博主,感觉https://github.com/pymumu/smartdns 这个dns方案不错,能不能结合smartdns出个教程,谢谢!

  5. 头像register 回复

    dns-forwarder 一直可以,国内外解析都OK
    昨天想使用ss-tunnel转发,却总是不成功,调试到半夜都没弄明白

    楼主能针对ss-tunnel的配置做下说明吗,包括对vps的要求

    1. cokebarcokebar 文章作者 回复

      一、 udp方式
      1. ss服务端支持UDP转发
      2. ss-tunnel代替dns-forwarder的位置即可。先把dns-forwarder关了,然后ss的端口转发里填本地端口5311(也就是之前dns-forwarder的地址),远程目标是8.8.8.8:53即可
      3. 最后用dig命令调试一下
      二、tcp方式
      如果仍想要使用TCP转发但不想让路由器自身走代理,可以将dns-forwarder与ss-tunel联合使用,上级dns发到dns-forwarder后,dns-forwarder再转发给ss-tunel。
      dns-forwarder仍然使用5311端口,上级的chinadns和dnsamsq会把dns请求发给dns-forwarder,dns-forwarder的下一级填ss-tunnel的地址,也就是127.0.0.1:端口号

      1. 头像Tyleo 回复

        按照你的办法:“先把dns-forwarder关了,然后ss的端口转发里填本地端口5311(也就是之前dns-forwarder的地址),远程目标是8.8.8.8:53 “

        发现还不行,需要加多一个步骤:还要去“网络”——“接口”——wan ——高级选项,这里,把“使用对端通告的 DNS 服务器” 这个勾打上,然后 /etc/init.d/firewall restart 重启防火墙,就搞定了。

        谢谢!

      2. 头像tyleo 回复

        测试了一会,有个奇怪的问题是,它一会又打回原型了。不知怎么回事,一会可以正常解析本机IP,一会又解析到了搬瓦工的IP。。。

  6. 头像anthony 回复

    强烈建议博主建个telegram群,方便大陆翻墙者学习

  7. 头像Ten 回复

    飞羽有空的话更新一下changelog吧,谢谢

  8. 头像unfly 回复

    博主你好,我的一台740n在lede-17.01.6是能完美运行的,但在openwrt-18.06.2就是不知道为啥dhcp不起作用了,只有先前有记录的设备能再次连接上路由器,我完全安装教程来的,试了好几次了。

  9. 头像unfly 回复

    不好意思我搞错了,openwrt18也是可以的,但我在lede和openwrt都遇到了设置完成后无法上网(表现为可ping通网站ip,无法ping通网站),最后我先把所有翻墙设置取消,再在dhcp/dns里的dns转发改成114.114.114.114才能上网,再打开翻墙设置就成功了

    1. cokebarcokebar 文章作者 回复

      应该是lede里的dns转发有问题,用dig命令层层排查一下是哪一层出问题了

  10. 头像Chris 回复

    一个建议:
    我自己试过,只要先更新软件包列表,之后卸载dnsmasq再安装dnsmasq-full是没问题的
    命令行下面应该先opkg update之后同理

    1. cokebarcokebar 文章作者 回复

      文中是保险的做法,毕竟前面将WAN口DNS设置成了127.0.0.1,卸载了dnsmasq后路由自身无法解析域名,另外也可能有其他杂七杂八的原因影响解析,我按照你的建议写肯定有人会遇到这种问题,索性不如直接按照保险的方法来写,适用于所有情况

发表评论

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

请输入验证码 * 请输入正确的验证码