前言
许多家庭宽带用户都面临着没有公网 IPv4 地址的困境,这使得从外网访问家中的 NAS 或其他服务变得困难。但如果你的网络环境恰好是 NAT1 类型(Full Cone NAT),那么恭喜你,还有一种“曲线救国”的方法!
本文将详细介绍如何利用 Lucky 这款强大的网络工具的 STUN 穿透功能,获取动态变化的公网 IP 和端口。然后,通过调用 SunPanel(一个美观易用的导航面板)提供的 API 接口,自动更新导航面板中对应服务的访问地址。
最终目标是:我们只需要将 SunPanel 本身通过某种方式(例如常见的内网穿透服务)暴露到公网,就可以通过访问 SunPanel 来方便地跳转到所有通过 STUN 动态更新地址的内网服务,无需记忆或手动更新变化的 IP 和端口。
本文使用的软件版本:
Lucky: v2.16.1
SunPanel: v1.7.0
一、 Lucky 配置 STUN 穿透
Lucky 的 STUN 穿透功能是实现本次方案的核心。
1. 安装与网络环境建议
安装 Lucky: 具体安装步骤请参考 Lucky 官方文档:安装运行&升级备份 | Lucky。本文不再赘述。
网络环境: 为了最大化 STUN 穿透的成功率和后续访问的稳定性,强烈建议优化你的内网 NAT 层级。最佳实践通常是:
光猫设置为 桥接模式。
使用你的主路由器进行 PPPoE 拨号 获取宽带连接。
将 Lucky 直接安装在主路由器 上(这是本文作者采用的方式,可以减少 NAT 层级)。
其他环境: 理论上,Lucky 也可以安装在旁路网关、NAS、甚至是 Windows/Linux 虚拟机或物理机上。但这可能会增加网络配置的复杂度(例如需要处理多层 NAT 或防火墙规则),需要用户根据自身环境进行调试。
2. 理解与配置 STUN
学习资料: 在开始配置前,强烈建议先阅读或观看大佬们关于 Lucky STUN 的教程,理解其基本原理和配置流程:
教程 1:「LUCKY STUN 穿透」使用邮件通知端口变化情况 - 哔哩哔哩
教程 2:「LUCKY STUN 穿透」使用 Cloudflare 的页面规则固定和隐藏网页端口 - 哔哩哔哩
教程 3:打通大内网第一期 无公网部署 https 和反向代理 (基于 Lucky 的 STUN 穿透) - 简书
基础目标: STUN 配置成功后,你应该能在 Lucky 的 STUN 状态页面看到类似下图的状态,显示获取到的公网 IP 和公网端口,并且可以通过这个
公网IP:公网端口
地址访问到你指定的内网服务。
(图片描述:Lucky STUN 状态页面,显示成功获取公网 IP 和端口)
配置 STUN 端口映射:
登录 Lucky 后台。
导航至
网络
->STUN内网穿透
。点击
添加STUN任务
。
(图片描述:Lucky 添加 STUN 任务的基础配置部分)
公网端口: 填写一个你希望映射到公网的端口(例如图中的
45678
)。选择一个未被占用的、非周知端口即可。内网 IP 地址: 填写你要穿透访问的内网服务的实际 IP 地址(例如你的 NAS IP
192.168.1.100
)。内网端口: 填写该内网服务实际监听的端口(例如 NAS Web 服务的
5000
端口)。不使用 lucky 内置端口转发: 勾选此项。利用操作系统自身的转发机制通常性能更好,推荐勾选。
3. 配置动态域名 (DDNS)
由于 STUN 获取到的公网 IP 和端口可能会在路由器重启或网络波动后发生变化,我们需要配置动态域名解析(DDNS),将一个固定的域名指向这个动态变化的公网 IP 地址。
在 Lucky 后台,导航至
网络
->动态域名
。点击
添加动态域名任务
。
(图片描述:Lucky 添加动态域名任务的基础信息配置)
(图片描述:Lucky 动态域名任务配置获取 IP 方式)
服务商: 选择你的域名注册商提供的 DNS 服务(如 Cloudflare, DNSPod, AliDNS 等)。你需要提前准备好对应服务商的 API Key 或 Token。
类型: 选择
IPv4
。域名列表: 填写你计划用于 STUN 穿透访问的域名。强烈推荐使用通配符子域名,例如
*.stun.yourdomain.com
。这样配置后,abc.stun.yourdomain.com
、xyz.stun.yourdomain.com
等所有stun.yourdomain.com
的三级域名都会被解析到 Lucky 通过 STUN 获取到的那个动态公网 IPv4 地址。这为后续配置多个服务提供了极大的便利。获取 IP 方式: 务必选择
通过STUN服务器获取
。这样 Lucky 才会将 STUN 检测到的公网 IP 用于更新 DNS 记录。重要提示: 配置完成后,务必测试 DDNS 是否正常工作。你可以在 Lucky 的动态域名任务日志中查看更新状态,并通过
ping
或nslookup
命令检查你的域名是否已正确解析到当前的公网出口 IP。
二、 SunPanel 部署与 API 准备
SunPanel 是一个界面美观、功能实用的 NAS/服务器导航面板。我们将用它来汇集通过 STUN 穿透暴露出来的服务入口。
1. 部署 SunPanel (推荐使用 Docker)
官方文档提供了详细的 Docker 部署教程:Docker 运行 | Sun-Panel
Docker Hub 地址: Sun-Panel 项目首页
关键目录挂载说明 (v1.4.0+):
本地宿主机目录 (示例) | 容器内目录 | 说明 |
---|---|---|
~/docker_data/sun-panel/conf | /app/conf | 必需: 配置文件目录,包含所有配置数据,请务必做好持久化。 |
/var/run/docker.sock | /var/run/docker.sock | 可选: 若想在 SunPanel 面板中管理 Docker 容器,需要挂载此文件。 |
~/docker_data/sun-panel/runtime | /app/runtime | 可选: 运行日志目录(一般不需挂载)。 |
Docker Run 命令行示例 (v1.4.0+):
# 1. 拉取最新镜像
docker pull hslr/sun-panel:latest
# 2. 运行容器 (请根据实际情况修改本地挂载路径)
# 确保本地目录 ~/docker_data/sun-panel/conf 存在
mkdir -p ~/docker_data/sun-panel/conf
docker run -d \
--name sun-panel \
--restart=always \
-p 3002:3002 \
-v ~/docker_data/sun-panel/conf:/app/conf \
-v /var/run/docker.sock:/var/run/docker.sock \
hslr/sun-panel:latest
-p 3002:3002
: 将宿主机的 3002 端口映射到容器的 3002 端口 (SunPanel 默认端口)。如果 3002 端口已被占用,可以修改宿主机端口,例如-p 外部端口:3002
。-v ~/docker_data/sun-panel/conf:/app/conf
: 将配置文件挂载到宿主机,请务必确保路径正确并做好备份。-v /var/run/docker.sock:/var/run/docker.sock
: (可选)挂载 Docker Socket,允许 SunPanel 管理 Docker。--restart=always
: 容器异常退出时自动重启。-d
: 后台运行容器。
Docker Compose 示例 (v1.4.0+):
创建一个 docker-compose.yml
文件:
version: "3.2"
services:
sun-panel:
image: "hslr/sun-panel:latest"
container_name: sun-panel
volumes:
- ./conf:/app/conf # 将配置文件挂载到当前目录下的 conf 文件夹
- /var/run/docker.sock:/var/run/docker.sock # (可选) 挂载docker.sock
# - ./runtime:/app/runtime # (可选) 挂载日志目录
# - /mnt/sata1-1:/os # (可选) 硬盘挂载点示例, 根据自己需求修改
ports:
- "3002:3002" # 映射端口,格式 "宿主机端口:容器端口"
restart: always
然后在该文件所在目录运行:
docker-compose up -d
2. 准备 SunPanel API
为了让 Lucky 能够自动更新 SunPanel 中的导航项,我们需要获取 SunPanel 的 API Token 并准备好要更新的目标导航项。
查阅 API 文档: Open API V1 (开放的 API 接口) | Sun-Panel
获取 API Token:
登录 SunPanel 后台 (默认地址
http://<部署SunPanel的设备IP>:3002
)。进入
设置
->OpenAPI
页面。如果还没有 Token,点击生成一个。请妥善保管好这个 Token。
准备导航项:
在 SunPanel 中创建一个分组,例如命名为 "STUN 服务",并记下其唯一标识 (例如
stun_services
)。你可以在分组编辑页面找到或设置它。
(图片描述:SunPanel 分组设置界面,可查看或设置唯一标识)
在该分组下创建一个导航项,用于后续接收 Lucky 的更新。例如,标题为 "我的 NAS",并设置一个唯一标识 (例如
my_nas
)。初始 URL 可以随便填写一个有效的 http/https 地址,后续会被自动更新。
(图片描述:SunPanel 添加导航项界面)
(图片描述:SunPanel 编辑导航项界面,显示唯一标识字段)
测试 API (可选但强烈推荐): 为了确保 Token 和标识符都正确,可以使用
curl
或以下 Python 脚本测试 SunPanel 的item/update
API 是否工作正常。安装依赖:
pip install requests
Python 测试脚本:
import requests
import json
# --- 配置区 ---
# SunPanel 的访问地址 (确保 Lucky 所在设备能访问到这个地址)
SUNPANEL_URL = "http://<你的SunPanel内网地址:端口>" # 例如 http://192.168.1.100:3002
API_TOKEN = "<你的SunPanel_API_Token>"
# 你在 SunPanel 中准备好的导航项的唯一标识
ITEM_ONLY_NAME = "my_nas" # 请替换成你实际设置的导航项唯一标识
# 该导航项所属分组的唯一标识
GROUP_ONLY_NAME = "stun_services" # 请替换成你实际设置的分组唯一标识
# --- 配置区结束 ---
# 测试更新接口
update_url = f"{SUNPANEL_URL}/openapi/v1/item/update"
update_headers = {
"Content-Type": "application/json",
"token": API_TOKEN
}
update_data = {
"onlyName": ITEM_ONLY_NAME,
"url": "https://test-update.example.com", # 用于测试的 URL
"itemGroupOnlyName": GROUP_ONLY_NAME
}
print(f"--- 正在尝试更新导航项 '{ITEM_ONLY_NAME}' in group '{GROUP_ONLY_NAME}' ---")
print(f"目标 URL: {update_url}")
print(f"请求 Body: {json.dumps(update_data, indent=2)}")
try:
response_update = requests.post(update_url, json=update_data, headers=update_headers, timeout=10)
response_update.raise_for_status() # 如果请求失败 (非 2xx 状态码) 则抛出异常
result_update = response_update.json()
print(f"
响应状态码: {response_update.status_code}")
print(f"响应内容: {json.dumps(result_update, indent=2, ensure_ascii=False)}")
if result_update.get("code") == 0:
print("
✅ 更新测试成功!请检查 SunPanel 界面中的对应导航项 URL 是否已变为 https://test-update.example.com")
else:
print(f"
❌ 更新测试失败,错误码: {result_update.get('code')}, 错误信息: {result_update.get('msg')}")
except requests.exceptions.RequestException as e:
print(f"
⚠️ 请求异常: {str(e)}")
except ValueError as e:
print(f"
⚠️ JSON 解析异常: {str(e)}")
except Exception as e:
print(f"
⚠️ 发生未知错误: {str(e)}")
运行脚本: 将脚本中的
<...>
占位符替换为你的实际值,然后运行python3 your_script_name.py
。预期结果: 如果看到
✅ 更新测试成功!
并且 SunPanel 中对应导航项的 URL 被修改,则表示 API 配置无误。如果失败,请检查 URL、Token、唯一标识以及网络连接。
三、 连接 Lucky 与 SunPanel:配置 Webhook
现在,是时候让 Lucky 在每次 STUN 地址(IP 或端口)发生变化时,自动通知 SunPanel 更新对应的导航项了。这通过 Lucky 的 Webhook 功能实现。
回到 Lucky 后台,导航至
网络
->STUN内网穿透
。找到你之前为目标内网服务创建的 STUN 任务,点击编辑。
滚动到页面下方的
Webhook
配置部分。
(图片描述:Lucky STUN 任务编辑页面中的 Webhook 配置区域)
配置 Webhook 参数:
接口地址: 填写 SunPanel 的更新 API 地址。注意: 这个地址必须是 Lucky 能够访问到的地址。通常填写 SunPanel 的内网 IP 和端口。
http://<你的SunPanel内网地址:端口>/openapi/v1/item/update
例如:http://192.168.1.100:3002/openapi/v1/item/update
请求方法: 选择
POST
。请求头: 点击“添加”,添加两个必要的请求头:
Key:
Content-Type
, Value:application/json
Key:
token
, Value:<你的SunPanel_API_Token>
(将<你的SunPanel_API_Token>
替换为真实的 Token 字符串)
(图片描述:配置 Content-Type 和 token 请求头)
请求 Body:
选择 Body 类型为
JSON
。在下方的文本框中输入以下 JSON 内容。请务必将
my_nas
和stun_services
替换为你之前在 SunPanel 中设置的导航项唯一标识和分组唯一标识。
(图片描述:配置 JSON 格式的请求 Body)
{
"onlyName": "my_nas",
"url": "http://#{ipAddr}",
"itemGroupOnlyName": "stun_services"
}
onlyName
: 替换为你 SunPanel 中目标导航项的唯一标识 (例如my_nas
)。itemGroupOnlyName
: 替换为该导航项所属分组的唯一标识 (例如stun_services
)。url
: 这里是关键。#{ipAddr}
是 Lucky 提供的一个内置变量,当 Webhook 被触发时,Lucky 会自动将其替换为当前通过 STUN 获取到的公网IP:公网端口
字符串。我们暂时先使用http://
前缀,后面会优化为 HTTPS。
测试 Webhook:
点击 Webhook 配置区域下方的“测试”按钮。
Lucky 会模拟一次 STUN 地址获取成功并调用你配置的 Webhook。
观察测试按钮下方的“请求结果”。如果显示成功 (通常 SunPanel API 成功会返回
{"code":0,"msg":"ok",...}
类似的内容),并且你登录 SunPanel 查看到对应导航项的 URL 已经被更新为http://<你的公网IP>:<STUN端口>
的格式,则表示 Webhook 配置成功!
四、 配置 HTTPS 访问 (推荐)
直接通过 http://公网IP:端口
访问服务存在安全风险(数据未加密)。我们可以利用 Lucky 内置的 ACME 功能免费申请 HTTPS 证书,并通过 Lucky 的 Web 服务功能为这个 STUN 穿透出来的端口提供 HTTPS 反向代理。
1. 申请 HTTPS 证书
在 Lucky 后台,导航至
安全
->ACME证书管理
。点击
添加证书申请任务
。
(图片描述:Lucky ACME 证书申请任务配置界面)
验证方式: 选择
DNS验证
(通常最方便)。DNS 服务商: 选择与你之前配置 DDNS 时相同的服务商,并填入对应的 API 密钥/Token。
域名列表: 填写你打算用来访问这个特定服务的具体域名。例如,如果你想通过
nas.stun.yourdomain.com
访问你的 NAS,就在这里填写nas.stun.yourdomain.com
。注意:这里不能使用通配符*
,ACME 需要具体的域名来申请证书。这个域名必须是你之前配置的 DDNS 域名(或其子域名,例如*.stun.yourdomain.com
中的一个)。填写其他必要信息(如邮箱),然后点击“申请”。等待 Lucky 完成 DNS 验证并成功签发证书。
2. 配置 Lucky Web 服务 (反向代理)
在 Lucky 后台,导航至
网络
->Web服务
。点击
添加Web规则
。
(图片描述:Lucky Web 服务规则基本信息配置)
(图片描述:Lucky Web 服务规则后端地址、HTTPS 及证书配置)
规则名称: 自定义一个描述性的名称,例如
NAS HTTPS Proxy
。监听 IPv4 端口: 填写你之前在 STUN 任务中设置的那个“公网端口” (例如
45678
)。Lucky 将监听这个通过 STUN 映射出来的公网端口。启用 HTTPS/TLS: 勾选此项。
证书来源: 选择
ACME证书管理
。选择证书: 从下拉列表中选择你刚刚为这个服务申请到的具体域名证书 (例如
nas.stun.yourdomain.com
)。前端地址: 填写你申请证书时使用的具体域名 (例如
nas.stun.yourdomain.com
)。这个域名将用于后续访问。后端地址: 填写 STUN 任务实际穿透的目标内网服务地址 (包括协议、IP 和端口),例如
http://192.168.1.100:5000
。保存配置。
3. 更新 Webhook Body (使用 HTTPS 域名)
现在,由于我们已经通过 Lucky Web 服务为 STUN 端口配置了 HTTPS 代理和固定域名,SunPanel 中的导航项 URL 应该直接指向这个 HTTPS 域名,而不是动态的 http://IP:端口
。因此,我们需要再次修改 STUN 任务的 Webhook Body。
回到
网络
->STUN内网穿透
,编辑对应的 STUN 任务。找到 Webhook 配置部分的 请求 Body。
修改 JSON 内容如下:
{
"onlyName": "my_nas",
"url": "https://nas.stun.yourdomain.com:#{port}",
"itemGroupOnlyName": "stun_services"
}
将
url
的值修改为https://<你的具体域名>:#{port}
格式。使用
https://
协议。将
nas.stun.yourdomain.com
替换为你申请证书并配置在 Web 服务前端地址中的那个具体域名。#{port}
是 Lucky 的另一个内置变量,它会被替换为 STUN 获取到的公网端口号。这样,即使端口变化,域名部分仍然固定,只有端口号动态更新。
再次测试 Webhook: 点击“测试”按钮。确认 SunPanel 中的 URL 被正确更新为
https://nas.stun.yourdomain.com:<stun端口号>
的格式。
现在,你应该可以通过 https://nas.stun.yourdomain.com:<stun端口号>
这个地址,以 HTTPS 加密的方式访问你的内网服务了!
4. 如何更新多个内网服务?
如果你有多个内网服务需要通过 STUN + SunPanel 的方式访问,可以采用以下两种方法:
方法 1: 每个服务一个 STUN 规则
为每个内网服务(例如 NAS、Jellyfin、Home Assistant)分别创建一个 STUN 任务。
为每个 STUN 任务配置对应的 Webhook,更新 SunPanel 中不同的导航项(需要提前在 SunPanel 中为每个服务创建好导航项并记下唯一标识)。
为每个服务申请独立的 HTTPS 证书(使用不同的子域名,如
jellyfin.stun.yourdomain.com
)并配置独立的 Web 服务规则。优点: 配置隔离,互不影响。
缺点: 配置步骤重复较多。
方法 2: 使用 Lucky 计划任务 + Call Web 任务 (推荐)
创建一个 STUN 任务,只用于获取公网 IP 和端口,但不配置 Webhook。
在 Lucky 后台,导航至
计划任务
->添加计划任务
。设置一个执行计划(例如,每 5 分钟执行一次,或者选择“当lucky启动/重启时”以及“当网络接口配置发生变化时”触发)。
在该计划任务下,添加多个
Call Web
类型的子任务。每个
Call Web
子任务配置与之前 Webhook 类似:接口地址: SunPanel 的
item/update
API 地址。请求方法:
POST
。请求头:
Content-Type: application/json
和token: <你的 Token>
。请求 Body (JSON): 针对不同的服务,填写不同的
onlyName
、itemGroupOnlyName
和url
(使用https://<对应服务域名>:#{port}
格式)。注意:计划任务中的Call Web
同样支持#{ipAddr}
和#{port}
变量,但这些变量的值来源于触发计划任务的那个 STUN 任务(或者系统默认的网络状态,取决于计划任务的触发条件和 Lucky 的全局设置,建议仍然依赖一个专门的 STUN 任务来稳定获取)。 (如果使用计划任务,建议在计划任务的设置中关联一个 STUN 任务来确保变量来源)为每个服务申请 HTTPS 证书并配置 Web 服务规则(监听同一个 STUN 端口,但使用不同的前端域名)。
(图片描述:Lucky 计划任务配置界面,可添加多个 Call Web 子任务)
优点: 集中管理更新逻辑,STUN 探测只需一次。
缺点: 配置稍复杂,需要理解计划任务和 Call Web 的工作方式。
五、 暴露 SunPanel 访问入口
至此,我们已经实现了通过 Lucky STUN 动态更新 SunPanel 中内网服务的访问地址(域名+动态端口)。但要真正实现从外网访问这些服务,还需要让 SunPanel 本身能够从外网访问到。
以下是几种常见的方法:
使用成熟的内网穿透服务 (推荐):
利用 FRP (例如 Sakura Frp、自建 FRP 服务端)、Ngrok、Zerotier、Tailscale 等工具或服务。
将你的 SunPanel 服务(例如内网地址
http://192.168.1.100:3002
)穿透到公网,获取一个固定的、易于记忆的公网访问地址(例如https://mysunpanel.mydomain.com
或服务商提供的域名)。优点: 通常更稳定,访问地址固定,配置相对简单。
缺点: 可能需要付费或依赖第三方服务。
为 SunPanel 单独配置 STUN 穿透:
像为其他内网服务一样,为 SunPanel 服务本身也配置一个 STUN 任务、DDNS(例如
sunpanel.stun.yourdomain.com
)、ACME 证书和 Web 服务规则。这样,SunPanel 的访问地址就会变成
https://sunpanel.stun.yourdomain.com:<SunPanel的STUN端口>
。挑战: 这个
<SunPanel的STUN端口>
也是动态变化的。你需要一种方式来获取这个变化的端口:配置 Lucky 的通知功能(如邮件、钉钉、微信 Server 酱等),在 STUN 端口变化时发送通知给你。
手动登录 Lucky 查看最新的端口。
优点: 无需额外服务费用。
缺点: SunPanel 入口地址的端口会变,访问便利性打折扣,除非你只在需要时查询端口。
总结
通过巧妙地结合 Lucky 的 STUN 穿透、动态域名 (DDNS)、Webhook (或计划任务) 功能,以及 SunPanel 的 API 接口和 Lucky 的 ACME、Web 反向代理,我们成功地为 NAT1 网络环境下、没有固定公网 IPv4 的内网服务创建了一个动态更新、支持 HTTPS 的公网访问入口聚合点。
虽然初始配置步骤稍显复杂,但一旦设置完成,就可以通过一个相对固定的 SunPanel 入口,方便地访问家中部署的各种服务了,极大地提升了在外访问内网资源的便利性和体验。
请务必根据你自己的网络环境、域名、内网服务地址和端口、以及 SunPanel 的配置,仔细替换掉本文示例中的各项参数。祝你配置成功!
推荐本站淘宝优惠价购买喜欢的宝贝:
本文链接:https://www.hqyman.cn/post/11106.html 非本站原创文章欢迎转载,原创文章需保留本站地址!
休息一下~~