Skip to content

Lucky内网穿透实践

约 11097 字大约 37 分钟

lucky

2025-05-22

前言

根据 RFC1918RFC4193 规范,IPv4 有 3 段保留地址段,不能在公网中路由传播,只用于局域网通信。

地址段掩码地址范围典型用途
10.0.0.0/8255.0.0.010.0.0.0 ~ 10.255.255.255企业内部大型网络
172.16.0.0/12255.240.0.0172.16.0.0 ~ 172.31.255.255云服务默认网段(如:AWS)
192.168.0.0/16255.255.0.0192.168.0.0 ~ 192.168.255.255家庭/小型办公局域网最常用✅

家庭路由器常见的地址:192.168.1.1, 而局域网中的设备 IP 通常是 192.168.1.x。我们知道,在脱离了自家局域网环境,就无法访问自家 192.168.1.x 的任何地址了。
能不能做到离开家呢,我还能访问到自家 192.168.1.x 的任何地址呢?当然可以,VPN(Virtual Private Network,虚拟专用网络) 就是用来做这个的,它是一种通过公用网络(如互联网)安全地连接到另一个网络的技术,核心就是:让你像在一个远程局域网/蜂窝数据网中一样访问资源,同时保证通信加密、安全
通过 VPN 我们可以连通家庭内部服务,如:Nas、Docker、GitLab、数据库、打印机、远程桌面,还支持虚拟局域网,让多个异地设备在一个虚拟局域网中相互访问。

不过,我们今天的目的是做内网穿透,虚拟局域网不在我们的需求范围中。我的做法总结起来就是在 OpenWrt 中搭建 Shadowsocks➕Shadow-TLS 服务,来实现需求。

1. 内网穿透

这一部分利用 Lucky 实现非常简单,只需要略微配置就开始了,只不过新手会比较懵逼,不知道怎么配置,这里我就将自己摸索出来的经验分享出来。
关于 Lucky 是什么,我就不多说了,官网上有介绍,接下来我们按步骤操作,安装 Lucky 并设置好内网穿透。

1.1 Lucky 安装

Lucky 适配多种平台:绿联NAS、宝塔、群晖矿神源、iStoreOS、飞牛NAS、CasaOS,在这些平台下你可以通过软件商店直接安装,也可以用 Docker 方式安装。而我使用的是 OpenWrt 系统,需要手动安装,接下来说安装步骤:

  1. 查看 CPU 核心架构,可以使用命令:uname -mcat /proc/cpuinfogrep "model name" /proc/cpuinfogrep "Processor" /proc/cpuinfo
  2. 打开GitHub release,下载对应 CPU 架构的核心包。比如,我的 CPU 架构是aarch64/armv8/arm64,名称中带wanji的是万吉版本,否则就是lucky。考虑到 R2S 的硬件资源有限,且万吉多出来的功能我也用不上,因此就下载了 Lucky 版本。
  3. 再下载luci-app-lucky_XXX_all.ipkluci-i18n-lucky-zh-cn_XXX_all.ipk,按照下载顺序依次安装。

安装完成后,我们在后台页面启动它,并访问http://192.168.0.1:16601PixPin_2025-05-22_16-51-26

1.2 STUN内网穿透

1.2.1 STUN穿透原理

先说说STUN内网穿透是个什么原理,而在讲它之前,我们还需要了解下常见的网络 NAT 类型(从最开放到最严格):

NAT编号NAT类型说明是否易穿透示例
NAT0无 NAT(Public IP)设备本身有公网 IP,无需转换✅ 不用穿透VPS、光猫桥接模式
NAT1全锥形 NAT(Full Cone NAT)所有外部主机都可以通过固定端口访问你,只要你先发过一次数据✅ 最容易穿透家用公网宽带
NAT2受限锥形 NAT(Restricted Cone NAT)外部主机必须是你发过数据的 IP,端口无关✅ 可穿透一些家庭宽带
NAT3端口受限锥形 NAT(Port Restricted Cone NAT)外部主机必须是你发过数据的 IP+端口⚠️ 较难穿透大多数运营商 NAT
NAT4对称 NAT(Symmetric NAT)每次连接不同目标,映射的端口不同,无法打洞,只能用中继❌ 难穿透(打洞基本无效)手机热点、校园网、企业网

我们可以通过NatTypeTester工具来查看自己的网络处于哪种 NAT 类型。

PixPin_2025-05-22_17-16-11

可以看到,我的网络类型是 NAT1,是最容易穿透的。
再多说一点,Full Cone NAT的网络类型需要运营商和路由器同时支持才行,在 OpenWrt 后台中要启用FullCone NAT相关的设置,如果启用了设置,测试出的结果依然不是Full Cone NAT,那就说明是运行商给你的网络就不是Full Cone NAT

PixPin_2025-05-22_17-20-51

而 Lucky 支持穿透的网络类型为NAT1,如果不是 NAT1,就不用继续操作了。不过可以试试Tailscale,它不挑网络。

通过上面可以了解 STUN 穿透的原理就是:通过请求 STUN 服务器,然后 STUN 服务会告诉我们,它看到我的 ip 和 port 是多少,外部网络通过这个 ip:port 就可以访问到我们的拨号设备了

1.2.2 STUN穿透设置

在 Lucky 后台的STUN内网穿透->设置下,启用Stun穿透模块,然后点击查看最新可用STUN服务器列表,全选复制到全局Stun服务器列表,保存修改。

PixPin_2025-05-22_17-32-16

然后,添加穿透规则,这里穿透通道本地端口443就表示将外部流量转发到了 WAN 网卡的 443 端口,你也可以指定其他任意端口。
这里勾选了不使用Lucky内置端口转发,而是在软路由的防火墙配置端口转发,因为软路由上是内核级转发,性能会好一些。

另外,可以看到我启用了Webhook,它支持标准的 HTTP 请求,当公网的 IP 和 PORT 发生变化时,会触发这个 Webhook ,也就会发起我们配置的 HTTP 请求。这个请求可以随意发挥,比如可以是执行本地脚本(后面会给出)、通知推送到手机。

PixPin_2025-05-22_17-35-47

至此,内网穿透就配置好了,是不是超级简单!下图表示,当外网访问 ip:5243 端口,流量就会被转发到我们拨号设备的 WAN 网卡的 443 端口。

PixPin_2025-05-24_11-52-46

1.2.3 防火墙配置

内网穿透可以让我们从外网访问到内网,可是互联网毕竟是公开的,其他人也能访问。并且,对于在内网中的一些服务,我们多数设置的都是弱密码,自己使用很方便,可是其他人恶意访问,攻破弱密码也很方便。所以,就需要配置防火墙,阻止外网直接访问到内网。那我们自己访问怎么?没关系,配置端口转发就好了。

PixPin_2025-05-24_12-04-23

1.3 动态域名

动态域名,也就是 DDNS(Dynamic DNS,动态域名系统),是一种将动态 IP 地址自动绑定到一个固定域名的服务。

如果没有域名,可以去dynv6申请一个,纯免费。如果已有域名,那就直接用,不过最好是能托管到Cloudflare上,或者直接在Cloudflare申请一个(付费的)。

在 Lucky 后台的动态域名菜单下,点击添加任务
选择托管服务商,你的域名托管在哪就选哪个,然后根据提示去获取一个 Token 填在这里。实际上就是托管服务商开放了接口,允许外部修改 DNS 记录,Token 是接口鉴权用的。

PixPin_2025-05-24_12-08-43

上一部完成后,点击添加记录,例如我们申请的域名是lucky.dynv6.net,那么添加的解析记录如下。
至少需要添加两条解析记录,主域名:lucky.dynv6.net、泛域名:*.lucky.dynv6.net。这表示会将你的公网 IP 解析到lucky.dynv6.net*.lucky.dynv6.net下面,也就是说你可以是使用lucky.dynv6.net*.lucky.dynv6.net来访问,*表示任意值,如abc.lucky.dynv6.net123.lucky.dynv6.netabc-123.lucky.dynv6.net等,可以任意创建。如果你不想使用泛域名,那就不要用*,改成一个固定的值即可。
还要注意的是记录类型,这里我们是将 IPv6 地址记录到了我们的域名,你也可以更改/新增一个记录,记录类型选择为A(IPv4),这样就可以将 IPv4 的地址记录到域名了。
如果你只是把 IPv6 的地址记录到了域名,那么访问时需要客户端也具有 IPv6 的地址才行,否则无法访问。一般使用蜂窝网络(数据流量)都是有 IPv6 地址的。如果你介意这一点,那就配置把 IPv4 的地址一同记录到你的域名即可。
访问的时候要注意,由于运营商给的 IPv6 地址通常是公网 IP,哪怕它是动态的也是公网 IP,通过这个 IPv6 是可以直接放访问到你的设备,没有经过 NAT 转换,流量就到达了你的 WAN 网卡,这意味着你开放一个固定的端口就可以了,访问时可以通过域名:固定端口
但是通过 IPv4 访问就不一样了,由于 IPv4 地址不是公网 IP,它是一个经过了 NAT 转换的运营商局域网 IP,IP 和端口都是会随机变化的。所以,即使你把 IPv4 记录到了域名,访问的时候也需要使用域名:动态端口才可以。在我的使用场景下,我认为把 IPv4 记录到域名是没必要的,所以只记录了 IPv6 地址。

PixPin_2025-05-24_12-15-07

注意:我发现通过 IPv6 访问会被严重限速,但是使用 IPv4 可以跑满上行。这个跟运营商策略有关,可能你的 IPv6 不会限速。不过也有说可以打电话投诉,但不一定有用。在我的使用方式中,只要 IPv6 能通就行,这点限速不影响,因为我主要使用 IPv4 访问内网服务。

1.4 Web服务

其实就是反向代理,跟你起一个 Nginx 做是一个意思,只是 Lucky 提供给你更便捷的操作。我们在Web服务下点击添加Web服务规则

这里监听端口 443,表示监听 WAN 网卡的 443 端口,并且启用了防火墙自动放行,会自动放行 WAN 网卡的 443 端口。

PixPin_2025-05-24_13-17-07

接着选择标记默认规则,服务类型选择关闭连接,这一点很重要。它表示当未匹配到Web服务中任一条规则时的行为,我们让他关闭连接,防止别人恶意试探,导致内网服务意暴露,非常危险

PixPin_2025-05-24_13-26-50

至此,我们的网络设置部分就完成了,接下来开始搭建服务器节点。

2. 服务节点

我们通过搭建一个Shadowsocks服务器节点,让客户端通过Shadowsocks加密协议连接到服务器(即软路由),后续与内网的通信都将这条加密隧道中往来,保证通信安全。

有多种节点搭建方式,主要是这么多种方式我都尝试过了,记下来只是证明我曾经做过。

只是跟着实操的话,推荐选择shadowsocks-rust-ssserver或者sing-box。这俩区别在于,前者只能用来搭建shadowsocks节点,如果需要伪装/混淆还需要额外安装其他软件包;后者是一个大而全的包,除shadowsocks外还可以搭建其他协议的节点,如TUICVLESSHysteria2AnyTLS等。
实际运行起来,sing-box的内存占用可能稍大一点点,但我感觉是没多大区别,所以更推荐使用sing-box

当然,如果不想自己搭建,还有更简单的方式,ImmortalWrt的作者开发了HomeProxy,它底层其实就是用的sing-box,可以在ImmortalWrt源中直接下载。如果不想用HomeProxy也可以使用passwall2,用起来都差不多。

HomeProxy 软件包含了客户端和服务端,客户端就是让设备实现科学强国的,服务端就是提供出来让其他设备连接,让其他设备实现科学强国。它支持多种协议,包含shadowsocks,我们可以直接用这个服务端实现就好了。
要注意的是,它的服务端仅仅是一个桥接功能,需要客户端保持启用状态,并且客户端有能够连通的节点,否则服务端就不能正常提供服务。这种方式是能用,但是我个人不推荐使用,因为过于依赖客户端,一旦客户端的节点不通了,那从外网穿透回内网就也不通了,不稳定的方式我不用。

2.1 Shadowsocks-libev

这是一个用 C 语言开发的软件包,软件包说明,软件包下载地址,选择对应的 CPU 架构下载即可。 可以看到有两个下载选项shadowsocks-libevshadowsocks-libev-sever,前者是包含服务端与客户端,后者只有服务端,所以按需下载即可。
另外,它还可以与luci-app-shadowsocks配套使用,提供控制界面,方便操作。不过要使用它你必须安装shadowsocks-libev。我个人感觉是没必要,只安装shadowsocks-libev-sever即可,最小化配置提供服务,配置好后开机自启就好了,又不会经常动它。

不过这软件包最近一次发布版本在 2020 年了,作者应该都不维护了,这个我就没做过多尝试。再加上我发现ImmortalWrt源中提供了shadowsocks-rust-ssserver软件包,它是用 Rust 语言实现的 Shadowsocks 服务端,性能更高、资源占用更低,所以我安装并尝试了这个。

2.2 shadowsocks-rust-ssserver(推荐)

2.2.1 shadowsocks 节点配置

因为我的软路由安装的是ImmortalWrt系统,所以直接在系统->软件包下搜索并安装shadowsocks-rust-ssserver
软件包的安装位置在/usr/bin/ssserver,接着我们创建配置文件/etc/ss-rust/config.json,内容如下:

config.json
{
    "server": "192.168.0.1",
    "server_port": 5505,
    "password": "ltx0Rml9z91CmLX8Ff7KZCggiYQcTnhxNzHM4Lm0B8w=",
    "timeout": 300,
    "method": "aes-256-gcm",
    "fast_open": true,
    "no_delay": true,
    "reuse_port": true,
    "mode": "tcp_and_udp",
    "ipv6_first": false
}

系统自启配置,创建文件/etc/init.d/ss-rust(文件名随意):

ss-rust
#!/bin/sh /etc/rc.common

START=99
USE_PROCD=1
LOGFILE="/var/log/ss-rust.log"

start_service() {
    # 启动 shadowsocks 基础服务
    procd_open_instance
    procd_set_param command /usr/bin/ssserver --config /etc/ss-rust/config.json
    procd_set_param stdout "$LOGFILE"
    procd_set_param stderr "$LOGFILE"
    procd_set_param respawn
    procd_close_instance
}

参考如下命令,赋予执行权限、允许开机自启,然后启动服务。

chmod +x /etc/init.d/ss-rust # 赋予执行权限
service /etc/init.d/ss-rust enable # 允许开机自启
service /etc/init.d/ss-rust start # 启动服务
service /etc/init.d/ss-rust status # 查看服务状态
service /etc/init.d/ss-rust stop # 停止服务

此时,就可以在客户端通过config.json中配置的值,通过内网来连接了。如果测试能连通,说明服务没问题,那就可以配置外网连接,否则需要检查服务端运行问题。
假定通过内网可以连通,接下来就配置通过外网来访问。

由于我们前面在STUN内网穿透中指定将外网流量穿透到本地 443 端口,所以这里设置端口转发,将 443 端口转发到 LAN 网卡的 5055 端口。然后在客户端将地址和端口都修改为STUN内网穿透那显示的地址和端口,再次测试连接。能连通那就没问题了,此时已经可以从外网穿透回内网了,不通的话再检查防火墙配置。

PixPin_2025-05-24_14-45-30

2.2.2 obfs 混淆(不推荐)

经过前面的配置,已经有一个shadowsocks协议的节点可以通过公网连接了,但这还没结束。虽然shadowsocks是加密连接协议,可直接在公网中连接无异于是在裸奔。因为在shadowsocks连接中传输的数据是安全的,可这个协议本身的特征非常明显:没有 TLS 握手(流量不像 HTTPS,容易被 DPI 识别)、可被主动探测(审查方主动连接验证为代理)、SNI 为空(一看就不是浏览器发起的 TLS 请求),容易被GFW识别为代理协议流量,审查系统可以用 DPI(深度包检测)识别这些特征,从而可能降速甚至是阻断网络连接。因此需要做一些额外的安全处理,较为简单的做法是利用obfs混淆,它的主要作用是让代理流量“看起来不像代理”,从而躲避 DPI(深度包检测)或主动探测,但它并不是shadowsocks的一部分,而是作为独立插件的形式存在,流量会->obfs->shadowsocks
目前主流的代理软件:ShadowrocketSurgeLoonQuantumult XStashEgernMihomo(Clash.Meta)均支持 obfs。

直接在系统->软件包下搜索并安装simple-obfs-server,然后编写如下启动文件/etc/init.d/obfs

obfs
#!/bin/sh /etc/rc.common

START=99
USE_PROCD=1
LOGFILE="/var/log/obfs.log"

start_service() {

    # 启动 obfs-server 混淆服务
    procd_open_instance
    procd_set_param command /usr/bin/obfs-server -s 192.168.0.1 -p 8675 -r 127.0.0.1:5505 -t 300 --obfs tls --fast-open
    procd_set_param stdout "$LOGFILE"
    procd_set_param stderr "$LOGFILE"
    procd_set_param respawn
    procd_close_instance
}

然后参考之前的做法,赋予执行权限和开机自启。接着可以改防火墙端口转发到 lan 的8675端口,不出意外的话是可以通的,出意外就自行排查。
用 Quantumult X 连接 obfs 混淆的节点,疑似遇到了阻断问题,节点无法连接,即使换其他软件连 Shadow-TLS 伪装节点也不通,重启软路由后 IP 和端口变化了,此时又都能通了,所以最好还是不要用 obfs 混淆。

2.2.3 shadow-tls 伪装(推荐)

你不会以为到上面就安全了吧?还没有,obfs 是轻度混淆,它只是让代理流量看起来像是 tls 流量而已,但它没有三次握手行为,如果 DPI 主动探测还是会露馅的,只是比裸奔强一点,算不上安全。如果要对安全更上一层楼的话,就得上shadow-tls

shadow-tlsihciah开发的一款中间层协议,它通过模拟真实的 TLS 握手过程,将代理流量隐藏在 TLS 握手中,使代理流量看起来像是访问正常的 HTTPS 网站,从而可以抵御主动探测、DPI 深度检测,增强shadowsocks流量的隐蔽性。它依靠密钥机制,未知密钥的连接会被丢弃,单向握手伪装,不需要真实证书。
流量会->shadow-tls->shadowsocks,客户端发起一段看起来像真实网站握手(包含SNI)的请求,审查系统看到的是标准的 TLS 连接,实际数据在 shadow-tls 之下传输 shadowsocks 流量,shadow-tls 服务端识别并解封装,还原流量为 shadowsocks 并转发。

下载对应 CPU 架构的安装包,上传到/ust/bin,并重命名为shadow-tls赋予执行权限。接着编写如下启动文件/etc/init.d/shadow-tls

shadow-tls
#!/bin/sh /etc/rc.common

START=99
USE_PROCD=1
LOGFILE="/var/log/shadow-tls.log"

start_service() {
    # shadow-tls 伪装 tls 握手服务
    procd_open_instance
    procd_set_param command sh -c "MONOIO_FORCE_LEGACY_DRIVER=1 RUST_LOG=error /usr/bin/shadow-tls --fastopen --v3 --strict server --server 127.0.0.1:5505 --tls 'toutiao.com;coding.net;mp.weixin.qq.com;cdn.bootcdn.net;feishu.cn;cloud.tencent.com' --password he4IM5QvPR1wiAZ0RL5HCA== --listen 192.168.0.1:55345"
    procd_set_param stdout "$LOGFILE"
    procd_set_param stderr "$LOGFILE"
    procd_set_param respawn
    procd_close_instance
}

然后参考之前的做法,赋予执行权限和开机自启。接着可以改防火墙端口转发到 lan 的55345端口,不出意外的话是可以通的,出意外就自行排查。
客户端可以配置多个节点,每个节点的 SNI 不同,然后轮询使用。目前主流的代理软件就Quantumult X不支持它。

2.3 sing-box(推荐)

2.3.1 服务配置

sing-box是一个全能选手,原生支持shadow-tls无需额外插件,但不支持obfs因为旧技术效果不太好。
安装简单,直接在系统->软件包下搜索并安装sing-box,然后编写如下配置文件/etc/sing-box/config.json

config.json

接着编写如下启动文件/etc/init.d/sing-box

sing-box
#!/bin/sh /etc/rc.common

START=99
USE_PROCD=1
LOGFILE="/var/log/ss-box.log"

start_service() {
    # 启动 shadowsocks 基础服务
    procd_open_instance
    procd_set_param command /usr/bin/sing-box run -c /etc/sing-box/config.json
    procd_set_param stdout "$LOGFILE"
    procd_set_param stderr "$LOGFILE"
    procd_set_param respawn
    procd_close_instance
}

然后参考之前的做法,赋予执行权限和开机自启。接着,,,,接着怎么办呢?内网访问还好,客户端配置不同的端口连接即可,但通过外网访问就不行了,外网流量只转发到了一个端口,如何对应到 5 个不同端口的 shadow-tls。此时就需要一个反向代理的服务,根据不同 sni 将流量转发到不同端口。

2.3.2 HAProxy 分流

NginxHAProxy是两种广泛使用的高性能反向代理服务器和负载均衡器,它们在功能上有重叠,但各自有明显的优势和适用场景。

  • Nginx: Web 服务器出身,擅长静态内容、反向代理、HTTPS、应用层代理等,功能全面。
  • HAProxy: 专注于负载均衡和高可用,性能极致,适合做 TCP/HTTP 层的高并发负载均衡。

实际使用中可以选择任一个,或者将二者结合:流量 -> HAProxy -> Nginx。

安装简单,直接在系统->软件包下搜索并安装haproxy,然后编写如下配置文件/etc/haproxy.cfg

haproxy.cfg

然后参考之前的做法,赋予执行权限和开机自启。这里我同时兼容了shadow-tlsobfs两种入口方式:

只要把防火墙的端口转发至55305即可。

3. 节点订阅

前面做了这么多,还是得手动去配置多麻烦,偶然间看到 GitHub 上一个项目GoHomeEasy,受到了启发,于是有了我的做法,订阅更安全、客户端适应性更强。

3.1 WebHook

前面说了在 STUN内网穿透可以配置 WebHook,可以触发一个标准的 HTTP 请求。我的做法是启动一个本地 HTTP 服务,当公网的 IP 或端口变更则触发,然后生成节点订阅。外网通过域名(IPv6)请求来获取订阅,虽然 IPv6 限速了,不过我们的文本很小,这点限速基本没影响。

编写如下脚本/usr/local/bin/homelan.py

homelan.py

POST请求触发功能后会生成如下格式的节点文件:

Node.yaml
proxies:
  - {"name":"MC之家1","type":"ss","server":"110.110.1.1","port":9527,"cipher":"2022-blake3-aes-128-gcm","password":"ZO0zrrHOaS8P4zQsV46EPg==","fast-open":true,"client-fingerprint":"chrome","plugin":"shadow-tls","plugin-opts":{"host":"toutiao.com","password":"he1IM5QvPR1wiAZ0RL5HCA==","version":3,"padding":true}}
  - {"name":"MC之家2","type":"ss","server":"110.110.1.1","port":9527,"cipher":"2022-blake3-aes-128-gcm","password":"ZO0zrrHOaS8P4zQsV46EPg==","fast-open":true,"client-fingerprint":"chrome","plugin":"shadow-tls","plugin-opts":{"host":"coding.net","password":"he2IM5QvPR1wiAZ0RL5HCA==","version":3,"padding":true}}
  - {"name":"MC之家3","type":"ss","server":"110.110.1.1","port":9527,"cipher":"2022-blake3-aes-128-gcm","password":"ZO0zrrHOaS8P4zQsV46EPg==","fast-open":true,"client-fingerprint":"chrome","plugin":"shadow-tls","plugin-opts":{"host":"mp.weixin.qq.com","password":"he3IM5QvPR1wiAZ0RL5HCA==","version":3,"padding":true}}
  - {"name":"MC之家4","type":"ss","server":"110.110.1.1","port":9527,"cipher":"2022-blake3-aes-128-gcm","password":"ZO0zrrHOaS8P4zQsV46EPg==","fast-open":true,"client-fingerprint":"chrome","plugin":"shadow-tls","plugin-opts":{"host":"cdn.bootcdn.net","password":"he4IM5QvPR1wiAZ0RL5HCA==","version":3,"padding":true}}
  - {"name":"MC之家5","type":"ss","server":"110.110.1.1","port":9527,"cipher":"2022-blake3-aes-128-gcm","password":"ZO0zrrHOaS8P4zQsV46EPg==","fast-open":true,"client-fingerprint":"chrome","plugin":"shadow-tls","plugin-opts":{"host":"feishu.cn","password":"he5IM5QvPR1wiAZ0RL5HCA==","version":3,"padding":true}}

这里实现了两个功能:POST(生成订阅)、GET(获取订阅)。客户端mihomo(Clash.Meta)的配置(yaml格式)原生可以配置如obfsshadow-tls,所以就生成了这种配置,这也是Sub-Store支持的输入。另外,Sub-Store 还支持脚本操作
如果生成的是 ss 标准格式的链接,则需要在Sub-Store中使用 JS 脚本处理,加上插件信息:

// Sub-Store 订阅处理, 为每个节点加上客户端参数
function operator(proxies) {
    const sni = ['toutiao.com','coding.net','mp.weixin.qq.com','cdn.bootcdn.net','feishu.cn'];
    proxies.forEach(proxy => {
        proxy['plugin'] = 'shadow-tls'
        proxy['plugin-opts'] = {'host': sni.pop(), 'password': 'xxx123', 'version': 3}
        // 或
        proxy['shadow-tls-sni'] = sni.pop()
        proxy['shadow-tls-password'] = 'xxx123'
        proxy['shadow-tls-version'] = 3
    })
}

如果订阅只有一个节点的话,无需写operator函数:

// 直接使用 $server 变量即表示当前的输入的节点信息
$server['plugin'] = 'shadow-tls'
$server['plugin-opts'] = {'host': sni.pop(), 'password': 'xxx123', 'version': 3}

Sub-Store 的后端我们自己使用 Docker 搭建后端路径一定要设置的复杂些,这是后端唯一的保护方式,目前还没有鉴权。
Sub-Store 的前端我们可以使用公用的地址,配置的后端信息保存在浏览器的 cookie 中,所以要保护好 cookie。另外,一定要记得通过 Sub-Store 的分享功能,这样分享出去的链接中才不会有后端路径,避免隐私泄露,同时还能灵活的设置分享有效期,并随时撤销分享。
如果想自建前端,建议 Fork 项目,然后通过 Vercel 部署即可。

3.2 Web服务

在 Lucky后台的Web服务下点击添加子规则,其中http://127.0.0.1:3001是 Sub-Store 的后端地址:

PixPin_2025-05-25_18-52-46

3.3 SSL/TLS证书

在 Lucky后台的SSL/TLS证书下点击添加证书

PixPin_2025-05-25_18-58-21

之后就可以在 Sub-Store 的前端设置中配置后端地址https://sub.lucky.dynv6.net:443/<后端路径>,然后从 Sub-Store 分享的订阅来更新获获取节点了。
当公网 IP 或端口发生变化时,要先在 Sub-Store 更新下,以拉取最新节点信息,再到代理软件中更新,将 Sub-Store 中的最新节点信息拉取到软件中。

3.4 分流规则

在代理软件中新增一条分流规则ip-cidr, 192.168.1.0/24, homelan

  • 其中ip-cidr表示规则类型。
  • 192.168.1.0/24是一种简写,表示网络为192.168.1.0子网掩码为255.255.255.0,因为在 IP 段中,1通常为网关地址,255为广播地址,0表示这个网络,而/24是因为子网掩码255.255.255.0为十进制表示,对应二进制是11111111.11111111.11111111.00000000,掩码掩住的位(用 1 表示掩盖了)是不能变的,一共 4 段,每一段是 8 位,有 3 个 8,所以是 24。
  • homelan 就是你的策略组名,策略组中应包含你订阅的内网节点。

附加

我们前面在homelan.py中生成了mihomo格式化的客户端节点配置,托管在了Sub-store上,其实,,,我们还可以更进一步。
目前Windows/Macos/Linux/Android/IOS/OpenWrt等各端免费的代理软件客户端,通常Clash核心的比较流行。既然如此,我们完全可以通过维护一套配置托管在Sub-store上,实现一处维护,处处开箱即用。

贴上一套简单的配置模板:

Meta.yaml

参考配置文件语法,参考配置示例,参考贡献者博客,参考综合教程,快速生成配置

这套配置示例可以任意增减机场数量,自定义嵌套策略组,自定义增减规则。将这套配置文件托管在Sub-Store然后分享,其他客户端直接订阅分享链接即可实现开箱即用。

各端代理软件推荐: