OpenWrt 上的 ke 学软件还真有好几个:

  • ShadowsocksR Plus+
  • OpenClash
  • PassWall
  • ShellClash

之前我喜欢用 PassWall,也用过一段时间 OpenClash,但是现在喜欢上了 ShadowsocksR Plus+,后面将简称为 ssrplus+,ShellClash 暂时没用过,不过都是基于 Clash 的 core 封装的程序,我在 armbian 机器上单独部署过 clash core 的透明代理,这个应该也差不太多,就是封装了一下用户需要手动操作的地方可能更少了。本文我们来着重看看 ssrplus+ 的服务端部署。

人不在家中,你想要访问家中的路由器管理页面?访问 qBittorrent 进行远程下载?访问其他各种内网服务?

实际上能实现这个需求方案真的太多了,我简单列举几个,虽然有一些我没用过

  1. frp,这个非常有名了,简单易用高效,我就在用
  2. ngrok,同楼上,但是传播广度和用户应该没有 frp 多
  3. 花生壳一类
  4. 如果你的家宽有动态 public IP,那可以配置 ddns 实现需求
  5. public IP + OpenWrt + firewall port forwarding + nginx proxy_pass
  6. OpenVPN 等 VPN 方案(还有 PPTP L2TP 等)
  7. WireGuard,同楼上,属于 VPN 方案,但是协议更新,更适合使用
  8. tailscale zerotier 等组网方案
  9. todesk,向日葵等方案
  10. other...

ssrplus+ 的基础使用我就不赘述了,网络上大把的教程,本文只是我使用其中的 ssr-server 的一些分享。现在我开始在我的 OpenWrt 上部署 ssr-server,可以看到其二进制文件位于 /var/etc/ssrplus/bin/ssr-server

服务端1.jpg

ssr-server 主要需要下面这些配置(和你在 vps 上配置 ss-server 之类的差不多)

  • 监听的 server 地址,luci 页面中没有,默认监听所有 ipv4 和 ipv6 来源地址
  • 监听端口,这个重要,建议设置非常规端口、高位端口,至少 10000 以上,我更习惯于使用 20000-50000 之间的端口
  • 密码,非常重要,建议使用 bitwarden/vaultwarden 等密码生成工具生成复杂随机密码,至少 10 位,包含数字、大小写英文字母、特殊符号。密码强度更高,使用起来更安心
  • 超时,比如 60s
  • 加密方式,我的软路由是 2018 年自组的,CPU 是 N3150,其支持 AES 指令,于是选择 aes-256-cfb 这个折衷的加密方法,其他还有更多,可以多学习一下看看哪个更适合自己的 cpu
  • tcp fast open,我一般都打开
  • 混淆和插件就保持默认

最终 OpenWrt 生成了这一份文件 /var/etc/ssrplus/ssr-server1.json

{
  "server": "0.0.0.0",
  "server_ipv6": "::",
  "server_port": 1234,
  "mode": "tcp_and_udp",
  "password": "123456",
  "timeout": 60,
  "method": "aes-256-cfb",
  "protocol": "origin",
  "protocol_param": "",
  "obfs": "plain",
  "obfs_param": "",
  "fast_open": true
}

这里我发现,在页面上填好了相关配置,点击 保存并应用 实际上 ssr-server 并没有启动,并没有直接 working,然后我直接重启 ssrplus+ 主程序解决。

在 openwrt 终端执行以下命令重启主程序

/bin/sh /etc/rc.common /etc/init.d/shadowsocksr restart

可以看到状态正常了

ssrplus2.jpg

也有相关日志信息

ssrplus3.jpg

此时我打开 iPhone,切换到手机流量,然后打开 Shadowrocket 或者 Quantumult X,我各添加了一份配置文件。

由于我这具备 public IP,于是我可以直接使用这个 ssr server,添加好配置之后,挂上 proxy,打开浏览器,访问 google,成功生效。

google首页1.jpg


正文其实在这里结束了,但是下文是记叙我当时使用小火箭和 quanx 添加这个配置进行“远程回家”的一个问题。该问题简单描述就是我能通过 http://home.to:88/ 访问到路由器管理页面但是不能通过 ip+port 访问的问题 http://10.10.10.1:88/ ,就是记录解决这个问题的过程。

期间我遇到这个问题,本文重点记录一下,没有兴趣的读者可以直接跳过关闭浏览器当前 tab。当时我还询问了 ChatGPT,我把问答贴上来


来自你的消息:

我在手机上建立 shadowsocksr 全局代理到家中服务器,能通过域名访问家中的一些服务,但是为什么无法通过 ip 和端口号访问呢?通过 ip+端口访问就会报错,err_connection_timed_out,比如我人在家中时我通过 http://10.10.10.1:88 或者 http://home.to:88 都可以访问,但是现在人不在家中(使用手机流量模拟这个场景),手机连了全局代理之后只能通过 http://home.to:88 访问,用 http://10.10.10.1:88 访问就会报 err_connection_timed_out 的错误。请帮我分析一下为什么?

来自 ChatGPT 的消息:

这种情况可能是由于你的路由器没有开启 NAT 反向代理功能所导致的。当你通过 http://home.to:88 访问时,请求首先会被发送到家中服务器,然后服务器会将请求转发到路由器的 10.10.10.1:88 端口。这个过程中,服务器会将请求的源 IP 地址替换为自己的 IP 地址,这样路由器就可以正确地将响应返回给你的手机。

但是,当你直接通过 http://10.10.10.1:88 访问时,请求会直接发送到路由器的 10.10.10.1:88 端口,由于这个请求的源 IP 地址是你手机的 IP 地址,而不是家中服务器的 IP 地址,所以路由器无法正确地将响应返回给你的手机,从而导致连接超时的错误。

要解决这个问题,你可以在家中服务器上安装 NAT 反向代理软件,例如 Nginx,然后将请求转发到路由器的 10.10.10.1:88 端口。这样,无论你是通过 http://home.to:88 还是 http://10.10.10.1:88 访问,请求都会被正确地转发到路由器,并且路由器也可以正确地将响应返回给你的手机。

来自你的消息:

我已经在路由器上安装了 nginx 了,但是需要怎么操作呢?另外我想到,这个是不是 NAT 环回问题?

来自 ChatGPT 的消息:

如果你已经在路由器上安装了 Nginx,那么你需要进行以下操作:

  1. 配置 Nginx 反向代理:在 Nginx 的配置文件中添加反向代理规则,将请求转发到家中服务器的端口上。例如,如果你想将请求转发到家中服务器的 80 端口上,可以在 Nginx 的配置文件中添加以下规则:
location / {
    proxy_pass http://家中服务器IP:80;
}
  1. 配置路由器端口转发:在路由器的管理界面中开启端口转发功能,将请求转发到 Nginx 的端口上。例如,如果你将 Nginx 配置在了路由器的 8080 端口上,那么你需要将路由器的 80 端口转发到 8080 端口上。

至于 NAT 环回问题,它通常是指在同一个局域网内通过公网 IP 访问本地服务时出现的问题。在这种情况下,你可以尝试通过修改路由器的 NAT 反向代理设置来解决问题。但是,如果你是通过 shadowsocksr 全局代理来访问家中服务的话,那么这个问题可能不太适用。

来自你的消息:

好的,我现在大概明白应该可以添加 nginx 配置来解决了,那么你帮我生成这个 nginx 配置吧。我简要说一下需求

  • 程序使用 http 访问资源
  • 监听端口 88
  • 路由器 web 界面是在 http://10.10.10.1:88 监听并提供 web 服务
  • 其他默认设置你帮我添加

来自 ChatGPT 的消息:

好的,根据你的需求,以下是一个简单的 Nginx 配置,你可以将其添加到 Nginx 的配置文件中:

server {
    listen 88;
    server_name localhost;

    location / {
        proxy_pass http://10.10.10.1:88;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

这个配置将会监听 88 端口,并将所有请求转发到 http://10.10.10.1:88 上。其中,proxy_set_header 用于设置请求头,以便正确地传递客户端的 IP 地址和 Host 头信息。

请注意,如果你的路由器 web 界面是通过 HTTPS 访问的话,你需要将 proxy_pass 改为 https://10.10.10.1:443,并且在 Nginx 中添加 SSL 配置。


最终我再三思考,觉得问题没有出在路由器以及 ssr-server 服务端这边,应该是手机这边 shadowrocket 客户端配置上。我又使用 Quanx 添加了同样的配置,然后我看这边默认是走的策略路由,于是我想到,应该使用 IP CIDR 规则添加一条 10.10.10.0/24,让来自这个目标网络的请求也走 proxy 就行了,之前域名能成功是因为全局代理可以将 dns 请求放在我 OpenWrt 的 dnsmasq 上进行。

于是

分流规则1.jpg

添加了这条分流规则后 成功在外网通过 ip+port 访问到家中设备

在外访问到软路由管理页面通过ip形式.jpg

然后我又回到 shadowrocket,添加了同样的 cidr proxy 规则,但是没有生效。

最终发现默认的 default.conf 中的一条通用规则首先就将来自 10.10.10.1 的请求 跳过代理 了,这条 ip cidr 写的是 10.0.0.0/810.10.10.0/24 是被包含的关系,所以直接跳过了代理,我后面新添加的已经不会生效了。

default conf1.jpg

这里很关键,原本有一条 10.0.0.0/8 我给删掉后面再单独添加 10.10.10.0/24 走代理就也解决了 shadowrocket 上遇到的问题。

跳过代理1.jpg

至此,我的需求都完美实现。