在路由器上部署 shadowsocks

在路由器上部署 shadowsocks

本文主要介绍在路由器上部署 shadowsocks 的方法与流程。通过在路由器上部署 shadowsocks 服务,可以为整个局域网内设备提供透明代理,而无需在每台设备上做相应设置,也可以让一些不方便设置代理的设备能够通过代理访问网站。

此处的路由器指安装了 OpenWrt, dd-wrt, Tomato 等固件,或者其他提供了 shell 接入、并可安装 .ipk 格式的软件包的路由器。

本文主要以安装了 padavan/rt-n56u 固件的华硕 rt-n56u 路由器为例。

安装 shadowsocks

首先通过包管理工具来安装 shadowsocks。

  • 如果路由器使用 Optware 进行软件分发,则使用 ipkg 命令,由于 Optware 包仓库中并没有 shadowsocks 的软件包,需自行网上下载,或动手编译,才能安装;

    # 更新软件列表  ipkg update  # 安装 shadowsocks  ipkg install <文件名>  
  • 如果路由器使用 Entware 进行软件分发,则使用 opkg 命令;

    # 更新软件列表  opkg update  # 安装 shadowsocks  opkg install shadowsocks-libev  

    安装 shadowsocks-libev

  • 如果路由器不使用任何包管理工具,需自行从网上下载可执行文件以及相应依赖,并放至路由器相应目录。

安装完成后,将会有 ss-local, ss-redir, ss-tunnel 等命令可用,本文中主要用到 ss-redir

安装完成后,可以运行以上命令来验证安装正确完成。

错误解决

  • opkg update 报错

    在配置完成 shadowsocks 代理前,路由器可能还无法直接访问到软件仓库,导致出现如下图所示错误:

    opkg update 错误

    此时,可以先在电脑端等能访问下载地址的机器上下载完软件包后,再上传至路由器安装。大部分路由器是基于 mips 平台的,可以使用如下地址下载 shadowsocks 。

    http://pkg.entware.net/binaries/mipsel/shadowsocks-libev_2.4.5-1_mipselsf.ipk

    由于在电脑端直接下载的 shadowsocks 包可能与路由器上所包含的元信息不一致,安装时可能需要指定 --force-checksum 选项。

    opkg install --force-checksum <文件名>  
  • 运行 ss-redir 等报 libsodium 相关错

    由于 shadowsocks 依赖 libsodium 库,因此如果该库未安装或者安装版本与所需版本不一致就会报错。解决办法则是安装所需版本的库。可以运行以下命令来安装:

    如果无法在路由器直接下载安装,则可以在以下地址下载后上传至路由器后安装。

    http://pkg.entware.net/binaries/mipsel/libsodium_1.0.8-1_mipselsf.ipk

    安装所用命令:

    opkg install --force-checksum <文件名>  

配置 shadowsocks 客户端

配置客户端可以有两种方式:

  • 使用配置文件 shadowsocks.json

    {      "server": "服务器地址",      "server_port": 服务器端口,      "local_address": "0.0.0.0",      "local_port": 本地端口,      "password": "密码",      "method": "加密方式"  }  

    配置文件所支持的所有参数可参见其源代码

    随后,在启动 shadowsocks 时,使用 -c 选项指定配置文件的位置。例如如下所示:

    ss-redir -c /etc/shadowsocks.json  
  • 命令行参数

    此外,也可以在命令行上直接指定所需的相关参数,例如:

    ss-redir -u -s "服务器地址" -p 服务器端口 -b 0.0.0.0 -l 本地端口 -k "密码" -m "加密方式"  

配置服务文件

通过服务启动 shadowsocks 时,shadowsocks 所用的参数来自于服务文件,需要在服务文件中进行配置。

安装 shadowsocks 后,会在系统中安装一个 shadowsocks 的服务文件,取决于系统与具体所安装的版本,服务文件可能位于以下位置中:

  • /etc/init.d/shadowsocks
  • /opt/etc/init.d/shadowsocks
  • /etc/init.d/S22shadowsocks
  • /opt/etc/init.d/S22shadowsocks

Shadowsocks 服务文件示例:

#!/bin/sh    ENABLED=yes  PROCS=ss-redir  ARGS="-c /opt/etc/shadowsocks.json"  PREARGS=""  DESC=$PROCS  PATH=/opt/sbin:/opt/bin:/opt/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin    . /opt/etc/init.d/rc.func  

其中:

  • ENABLED 行表明了是否在开机时自动启动服务;
  • PROCS 行指定了所运行的主程序;
  • ARGS 行指定了 shadowsocks 启动时的参数。

-c 后跟的是配置文件的位置,需将填写好的配置文件保存至该位置。

该配置文件具体位置取决于所安装版本和服务配置,一般为 /etc/shadowsocks.json/opt/etc/shadowsocks.json,也可自行指定为其他位置。

注意事项

  • 以上例子中的 ss-redir 也可以换为其他 shadowsocks 命令,他们使用相同的配置参数。
  • 配置 shadowsocks 时,可以同时使用配置文件和命令行参数。其中,在命令行上提供的参数将覆盖配置文件中的设置。如:

    ss-redir -c /etc/shadowsocks.json -b 0.0.0.0  

启动 shadowsocks 服务

命令行启动

ss-redir -u -c /etc/shadowsocks.json -f /var/run/ss-redir.pid -b 0.0.0.0  

其中,

  • -u 选项启用UDP转发(需要TPROXY模块支持);
  • -c 选项指定配置文件;
  • -f 选项指定pid文件的位置,同时让进程进入后台运行;
  • -b 选项指定 shadowsocks 服务绑定的本地地址,默认绑定在 127.0.0.1

    • 要想使局域网内机器能够访问到部署在路由器上的 shadowsocks 服务,需要将该地址指定为路由器的IP地址(如 192.168.1.1,具体值取决于所配置的路由器的IP地址);
    • 要想使路由器自身的流量能够经过 shadowsocks 服务,需要将该地址指定为 127.0.0.1
    • 若想使路由器自身和局域网内的机器都能够使用到 shadowsocks 服务,则需将该地址指定为 0.0.0.0

启动服务

使用命令 /etc/init.d/shadowsocks start 启动服务;

使用命令 /etc/init.d/shadowsocks enable 设置开机自动启动。

注意上面命令中的 /etc/init.d/shadowsocks 需换为上文中提到的 shadowsocks 服务文件在系统中的实际位置。

配置自动转发流量至 shadowsocks 服务器

配置自动流量转发主要通过 iptables 相关命令完成, iptables 相关的命令执行后立即生效。如果配置错误导致无法上网,可以重启路由器,原先输入的命令会被自动撤销;如果配置完成后,并没有起到效果,可能是配置有问题,也有可能配置正确,但所访问的网站不但需要通过代理访问,对其域名进行的 DNS 解析也应通过代理完成,详见后文转发 DNS 请求

转发局域网内 TCP 流量

转发局域网内 TCP 流量的 iptables 规则参照了 shadowsocks-libev 的官方文档

# 创建 iptables 链  iptables -t nat -N SHADOWSOCKS    # 忽略自己服务器的 IP 地址  # !!重要!! 忽略此步将无法代理流量至 shadowsocks 服务器  iptables -t nat -A SHADOWSOCKS -d "服务器IP地址" -j RETURN    # 忽略局域网中的 IP 和其他想忽略的 IP 地址  # 可参照 ashi009/bestroutetb 来生成忽略所有中国地址的列表  iptables -t nat -A SHADOWSOCKS -d 0.0.0.0/8 -j RETURN  iptables -t nat -A SHADOWSOCKS -d 10.0.0.0/8 -j RETURN  iptables -t nat -A SHADOWSOCKS -d 127.0.0.0/8 -j RETURN  iptables -t nat -A SHADOWSOCKS -d 169.254.0.0/16 -j RETURN  iptables -t nat -A SHADOWSOCKS -d 172.16.0.0/12 -j RETURN  iptables -t nat -A SHADOWSOCKS -d 192.168.0.0/16 -j RETURN  iptables -t nat -A SHADOWSOCKS -d 224.0.0.0/4 -j RETURN  iptables -t nat -A SHADOWSOCKS -d 240.0.0.0/4 -j RETURN    # 其他所有未被忽略的 TCP 流量将被转发至 shadowsocks 的本地端口(即之前配置配置文件中配置的本地端口)  iptables -t nat -A SHADOWSOCKS -p tcp -j REDIRECT --to-ports "本地端口"    # 应用 shadowsocks 规则  iptables -t nat -A PREROUTING -p tcp -j SHADOWSOCKS  

转发路由器自身 TCP 流量

要让路由器自身的流量也能够经过 shadowsocks 代理服务器的话,还需要运行如下 iptables 规则:

iptables -t nat -A OUTPUT -p tcp -j SHADOWSOCKS  

使用 bestroutetb 生成忽略列表

按照上文的配置可以将所有通向外网的流量转发至 shadowsocks 服务器,但实际上,更多时候我们只想将通向国外的流量转发至 shadowsocks 服务器,而国内的流量则依然直接连接。那么我们可以使用 bestroutetb 来智能地生成 iptables 规则,具体详见该项目主页。

也可以使用生成好的规则列表:下载规则脚本

脚本中的命令类似如下所示:

# 忽略中国IP,不经过shadowsocks代理  iptables -t nat -A SHADOWSOCKS -d 0.0.0.0/7 -j RETURN  iptables -t nat -A SHADOWSOCKS -d 10.0.0.0/8 -j RETURN  iptables -t nat -A SHADOWSOCKS -d 14.0.0.0/8 -j RETURN  iptables -t nat -A SHADOWSOCKS -d 14.0.0.0/21 -j RETURN  iptables -t nat -A SHADOWSOCKS -d 14.0.12.0/22 -j RETURN  iptables -t nat -A SHADOWSOCKS -d 14.1.0.0/22 -j RETURN  ...  

转发 DNS 请求

配置完 TCP 流量转发后,还需要配置 DNS 请求的转发,以避免 DNS 污染造成的无法访问。

转发 DNS 请求可以通过添加 iptables 规则来转发所有 DNS 请求至 shadowsocks 服务器;也可以配置 ChinaDNS ,只将国外域名的 DNS 请求转发。两者选其一即可。

使用 iptables 规则转发所有 DNS 请求

DNS 请求默认走的是 UDP 协议,而 iptables 转发 UDP 请求需要 TPROXY 模块支持。因此,如果以下命令执行出现错误,说明相关模块没有在路由器上安装,可以考虑手动安装,或者配置 ChinaDNS

# 创建 iptables 链  iptables -t mangle -N SHADOWSOCKS    # 添加 UDP 规则  ip rule add fwmark 0x01/0x01 table 100  ip route add local 0.0.0.0/0 dev lo table 100  iptables -t mangle -A SHADOWSOCKS -p udp --dport 53 -j TPROXY --on-port "本地端口" --tproxy-mark 0x01/0x01    # 应用 shadowsocks 规则  iptables -t mangle -A PREROUTING -j SHADOWSOCKS  

配置 ChinaDNS 转发国外域名的 DNS 请求

参考:ChinaDNS

安装

# 更新软件列表  opkg update  # 安装 ChinaDNS  opkg install chinadns  

启动 ChinaDNS

# 启动 ChinaDNS  /etc/init.d/chinadns start  # 配置开机自动启动(有些系统无需执行以下命令,安装后默认配置为开机自启)  /etc/init.d/chinadns enable  

ChinaDNS 默认监听5353端口,因此在之后的配置中使用5353端口。

配置 /etc/dnsmasq.conf

添加或修改相应行:

no-resolv  server=127.0.0.1#5353  

修改完成后,重启 dnsmasq 服务:

/etc/init.d/dnsmasq restart  

或配置 /etc/resolve.conf

修改为以下内容:

nameserver 127.0.0.1  nameserver 127.0.0.1#5353  

修改完成后,重启 dnsmasq 服务:

/etc/init.d/dnsmasq restart  

自启动 shadowsocks 及 ChinaDNS

自启动 shadowsocks 服务及 ChinaDNS 服务可按上文所述的如下命令完成:

/etc/init.d/shadowsocks enable  /etc/init.d/chinadns enable  

其中的 /etc/init.d/ 需换为服务所安装的实际位置。

此外,有些系统无需执行以上命令,安装后默认配置为开机自启。

除了启动服务外,还需要在开机启动时再次自动执行之前配置的 iptables 命令。配置开机启动的命令一般在路由器的网页管理界面中都有配置,也可在命令行下配置,不再详述。