家里有一些连接外面世界的需求,一般的设备如电脑、手机,都各自安装了相关软件,所以访问没有什么问题。但有些设备如 Nintendo Switch 并不能设置代理(据说现在可以设置代理了,但考虑到外出时连接其他网络还需要关闭代理,十分麻烦)。所以决定在家中搭建一个二级网络,凡是在这个二级网络中的设备,都可以无感上网。

之前我曾经使用树莓派搭建过一个透明代理,一个第三方制作的树莓派版本的 Openwrt ,使用树莓派的有线网口作为 WAN,Wifi 作为 LAN,代理使用了 Shadowsocks。具体配置方法这里就不细讲了,支持 luci 可视化配置,过程并不复杂。但是问题有三个,第一个问题是树莓派的 Wifi 信号不是很好,稍微远点信号就会变得很差;第二个问题是我已经全面升级到了 V2Ray,Shadowsocks 对我来说有些过时了;第三个问题是我想拯救这台树莓派,让它拜托成为路由器的宿命,让它能在其他方面发光发热。

前段时间家里升级了网络设备,淘汰下来一台 Netgear WNDR3700 路由器,这台路由器在很早之前就已经刷上了 Openwrt,于是我就计划着用这个无线路由器来做二级网络的网关。但也有两个问题,第一个问题是 Openwrt 下 V2Ray 的尺寸太大了,这台路由器没有足够的空间可以安装;第二个问题是就算我想办法扩展了路由器的容量,并且自己编译一个V2Ray安装进去,以这款路由器的 CPU 性能估计也没办法提供很好的体验。

所以我考虑着另辟蹊径,例如将比较需要 CPU 性能的工作交给其他设备,二级网关只负责转发流量。因为很早之前在家里的群晖上就部署过一个 V2Ray 代理服务,分别提供了 socks5 代理和 http 代理,所以只需要将二级网络的流量转发到群晖的代理上不就实现了吗。这样不仅可以依靠群晖相对比较强大的x86处理器来负责流量数据的加密和压缩,而且通过这个统一的代理点,就不需要在各个设备上分别配置代理了,想改参数到一个地方就行了。

接下来就开始配置的过程:

一、安装redsocks

通过 ssh 连接至二级网关

安装 redsocks

opkg update
opkg install redsocks

修改 redsocks 的配置文件 /etc/redsocks.conf

redsocks {
    /* `local_ip' defaults to 127.0.0.1 for security reasons,
     * use 0.0.0.0 if you want to listen on every interface.
     * `local_*' are used as port to redirect to.
     */
    local_ip = 0.0.0.0;
    local_port = 12345;

    // `ip' and `port' are IP and tcp-port of proxy-server
    // You can also use hostname instead of IP, only one (random)
    // address of multihomed host will be used.
    ip = 192.168.1.XX;
    port = XXXXX;

    // known types: socks4, socks5, http-connect, http-relay  
    type = socks5;
}

重启 redsocks 服务

/etc/init.d/redsocks restart

安装 redsocks 之后,它提供了一个转发到代理服务器的通道,这个通道可以将 TCP/IP 的网络请求转化为 socks5 的代理请求。根据上面的配置来看,redsocks 的进入端口是 12345 ,出口是 192.168.1.XX:XXXXX (即 V2Ray 代理的 IP 地址和端口,根据自己的实际情况进行修改)。

二、配置iptables

接下来需要实现的是将所有经过这个二级网关的网络请求全部转发到它自身的12345端口。

新建脚本文件 redirect ,用于编写 iptables 的命令,编写 iptables 命令。

# create a new chain named REDSOCKS
iptables -t nat -N REDSOCKS

# Ignore LANs IP address
iptables -t nat -A REDSOCKS -d 0.0.0.0/8 -j RETURN
iptables -t nat -A REDSOCKS -d 10.0.0.0/8 -j RETURN
iptables -t nat -A REDSOCKS -d 127.0.0.0/8 -j RETURN
iptables -t nat -A REDSOCKS -d 169.254.0.0/16 -j RETURN
iptables -t nat -A REDSOCKS -d 172.16.0.0/12 -j RETURN
iptables -t nat -A REDSOCKS -d 192.168.0.0/16 -j RETURN
iptables -t nat -A REDSOCKS -d 224.0.0.0/4 -j RETURN
iptables -t nat -A REDSOCKS -d 240.0.0.0/4 -j RETURN

# Anything else should be redirected to redsocks's local port
iptables -t nat -A REDSOCKS -p tcp -j REDIRECT --to-port=12345

# Apply the rules
iptables -t nat -A PREROUTING -j REDSOCKS

然后需要赋予该脚本运行权限,之后就可以通过运行这个脚本让其中的 iptables 命令生效了。

chmod +x ./redirect

三、配置开机自动执行

iptables 的命令在每次重启路由器之后都会重置,所以还需要在每次路由器重启之后重新运行上面的脚本。

要实现路由器重启后自动执行某个脚本,可以将执行脚本的命令写在文件 /etc/rc.local 中。在其内容的 exit 0 这行之前添加执行命令即可。例如:

# Put your custom commands here that should be executed once
# the system init finished. By default this file does nothing.
~/redirect
exit 0

连上这个二级网关的Wifi试一下吧。