07
2025
05
10:51:20

无公网 IPv4?利用 Lucky (STUN) + SunPanel API 动态更新内网服务地址

前言

许多家庭宽带用户都面临着没有公网 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 端口映射:

  1. 登录 Lucky 后台。

  2. 导航至 网络 -> STUN内网穿透

  3. 点击 添加STUN任务

(图片描述:Lucky 添加 STUN 任务的基础配置部分)

    • 公网端口: 填写一个你希望映射到公网的端口(例如图中的 45678)。选择一个未被占用的、非周知端口即可。

    • 内网 IP 地址: 填写你要穿透访问的内网服务的实际 IP 地址(例如你的 NAS IP 192.168.1.100)。

    • 内网端口: 填写该内网服务实际监听的端口(例如 NAS Web 服务的 5000 端口)。

    • 不使用 lucky 内置端口转发: 勾选此项。利用操作系统自身的转发机制通常性能更好,推荐勾选。

3. 配置动态域名 (DDNS)

由于 STUN 获取到的公网 IP 和端口可能会在路由器重启或网络波动后发生变化,我们需要配置动态域名解析(DDNS),将一个固定的域名指向这个动态变化的公网 IP 地址。

  1. 在 Lucky 后台,导航至 网络 -> 动态域名

  2. 点击 添加动态域名任务

(图片描述:Lucky 添加动态域名任务的基础信息配置)

(图片描述:Lucky 动态域名任务配置获取 IP 方式)

    • 服务商: 选择你的域名注册商提供的 DNS 服务(如 Cloudflare, DNSPod, AliDNS 等)。你需要提前准备好对应服务商的 API Key 或 Token。

    • 类型: 选择 IPv4

    • 域名列表: 填写你计划用于 STUN 穿透访问的域名。强烈推荐使用通配符子域名,例如 *.stun.yourdomain.com。这样配置后,abc.stun.yourdomain.comxyz.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:

  1. 登录 SunPanel 后台 (默认地址 http://<部署SunPanel的设备IP>:3002)。

  2. 进入 设置 -> OpenAPI 页面。

  3. 如果还没有 Token,点击生成一个。请妥善保管好这个 Token

  • 准备导航项:

  1. 在 SunPanel 中创建一个分组,例如命名为 "STUN 服务",并记下其唯一标识 (例如 stun_services)。你可以在分组编辑页面找到或设置它。

(图片描述:SunPanel 分组设置界面,可查看或设置唯一标识)

    1. 在该分组下创建一个导航项,用于后续接收 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 功能实现。

  1. 回到 Lucky 后台,导航至 网络 -> STUN内网穿透

  2. 找到你之前为目标内网服务创建的 STUN 任务,点击编辑。

  3. 滚动到页面下方的 Webhook 配置部分。

(图片描述:Lucky STUN 任务编辑页面中的 Webhook 配置区域)

  1. 配置 Webhook 参数:

  • 接口地址: 填写 SunPanel 的更新 API 地址。注意: 这个地址必须是 Lucky 能够访问到的地址。通常填写 SunPanel 的内网 IP 和端口。
    http://<你的SunPanel内网地址:端口>/openapi/v1/item/update

    例如:http://192.168.1.100:3002/openapi/v1/item/update

  • 请求方法: 选择 POST

  • 请求头: 点击“添加”,添加两个必要的请求头:

  1. Key: Content-Type, Value: application/json

  2. 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。

  1. 测试 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 证书

  1. 在 Lucky 后台,导航至 安全 -> ACME证书管理

  2. 点击 添加证书申请任务

(图片描述: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 服务 (反向代理)

  1. 在 Lucky 后台,导航至 网络 -> Web服务

  2. 点击 添加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。

  1. 回到 网络 -> STUN内网穿透,编辑对应的 STUN 任务。

  2. 找到 Webhook 配置部分的 请求 Body

  3. 修改 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 获取到的公网端口号。这样,即使端口变化,域名部分仍然固定,只有端口号动态更新。

  1. 再次测试 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): 针对不同的服务,填写不同的 onlyNameitemGroupOnlyName 和 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 本身能够从外网访问到。

以下是几种常见的方法:

  1. 使用成熟的内网穿透服务 (推荐):

  • 利用 FRP (例如 Sakura Frp、自建 FRP 服务端)、Ngrok、Zerotier、Tailscale 等工具或服务。

  • 将你的 SunPanel 服务(例如内网地址 http://192.168.1.100:3002)穿透到公网,获取一个固定的、易于记忆的公网访问地址(例如 https://mysunpanel.mydomain.com 或服务商提供的域名)。

  • 优点: 通常更稳定,访问地址固定,配置相对简单。

  • 缺点: 可能需要付费或依赖第三方服务。

  1. 为 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 的配置,仔细替换掉本文示例中的各项参数。祝你配置成功!




推荐本站淘宝优惠价购买喜欢的宝贝:

image.png

本文链接:https://www.hqyman.cn/post/11106.html 非本站原创文章欢迎转载,原创文章需保留本站地址!

分享到:
打赏





休息一下~~


« 上一篇 下一篇 »

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

请先 登录 再评论,若不是会员请先 注册

您的IP地址是: