配置 ShadowsocksR Plus+ 的服务端,在外访问家中服务
OpenWrt 上的 ke 学软件还真有好几个:
- ShadowsocksR Plus+
- OpenClash
- PassWall
- ShellClash
之前我喜欢用 PassWall,也用过一段时间 OpenClash,但是现在喜欢上了 ShadowsocksR Plus+,后面将简称为 ssrplus+
,ShellClash 暂时没用过,不过都是基于 Clash 的 core 封装的程序,我在 armbian 机器上单独部署过 clash core 的透明代理,这个应该也差不太多,就是封装了一下用户需要手动操作的地方可能更少了。本文我们来着重看看 ssrplus+ 的服务端部署。
人不在家中,你想要访问家中的路由器管理页面?访问 qBittorrent 进行远程下载?访问其他各种内网服务?
实际上能实现这个需求方案真的太多了,我简单列举几个,虽然有一些我没用过
- frp,这个非常有名了,简单易用高效,我就在用
- ngrok,同楼上,但是传播广度和用户应该没有 frp 多
- 花生壳一类
- 如果你的家宽有动态 public IP,那可以配置 ddns 实现需求
- public IP + OpenWrt + firewall port forwarding + nginx proxy_pass
- OpenVPN 等 VPN 方案(还有 PPTP L2TP 等)
- WireGuard,同楼上,属于 VPN 方案,但是协议更新,更适合使用
- tailscale zerotier 等组网方案
- todesk,向日葵等方案
- other...
ssrplus+ 的基础使用我就不赘述了,网络上大把的教程,本文只是我使用其中的 ssr-server 的一些分享。现在我开始在我的 OpenWrt 上部署 ssr-server,可以看到其二进制文件位于 /var/etc/ssrplus/bin/ssr-server
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
可以看到状态正常了
也有相关日志信息
此时我打开 iPhone,切换到手机流量,然后打开 Shadowrocket 或者 Quantumult X,我各添加了一份配置文件。
由于我这具备 public IP,于是我可以直接使用这个 ssr server,添加好配置之后,挂上 proxy,打开浏览器,访问 google,成功生效。
正文其实在这里结束了,但是下文是记叙我当时使用小火箭和 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,那么你需要进行以下操作:
- 配置 Nginx 反向代理:在 Nginx 的配置文件中添加反向代理规则,将请求转发到家中服务器的端口上。例如,如果你想将请求转发到家中服务器的 80 端口上,可以在 Nginx 的配置文件中添加以下规则:
location / {
proxy_pass http://家中服务器IP:80;
}
- 配置路由器端口转发:在路由器的管理界面中开启端口转发功能,将请求转发到 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 上进行。
于是
添加了这条分流规则后 成功在外网通过 ip+port
访问到家中设备
然后我又回到 shadowrocket,添加了同样的 cidr proxy 规则,但是没有生效。
最终发现默认的 default.conf
中的一条通用规则首先就将来自 10.10.10.1
的请求 跳过代理
了,这条 ip cidr 写的是 10.0.0.0/8
,10.10.10.0/24
是被包含的关系,所以直接跳过了代理,我后面新添加的已经不会生效了。
这里很关键,原本有一条 10.0.0.0/8
我给删掉后面再单独添加 10.10.10.0/24
走代理就也解决了 shadowrocket 上遇到的问题。
至此,我的需求都完美实现。
从一几年一直都用的openvpn,因为一直很稳定好用就没换过,不过这几年看到组网大多是tailscale、zerotier、frp比较多,想请教一下,这种和openvpn有什么明显优势吗
openvpn最大的优势就是工作在更低层网络层,一般是建立系统上的虚拟网卡,但是连接建立后一般会接管系统上所有流量。tailscale 这些程序,一般工作在应用层,更加灵活,但是需要用户自己配置,可以让单独的程序走指定的通道,系统默认的流量还是走正常的 wifi 网卡或者有线网卡。
我是这么理解的。