文章目录
- [不用公网 IP,把内网服务安全发布到公网:ZeroNews 快速上手](#不用公网 IP,把内网服务安全发布到公网:ZeroNews 快速上手)
-
- 1、前言
- 2、你可能也有这些痛点
- [3、三分钟讲清楚 ZeroNews 在做什么](#3、三分钟讲清楚 ZeroNews 在做什么)
-
- [3.1 三个关键概念](#3.1 三个关键概念)
- [3.2 技术特点](#3.2 技术特点)
- [3.3 与开源内网穿透(FRP)的区别](#3.3 与开源内网穿透(FRP)的区别)
- [4、上手准备:注册与 Token](#4、上手准备:注册与 Token)
-
- [4.1 注册入口](#4.1 注册入口)
- [4.2 套餐/定价怎么理解(够用就行)](#4.2 套餐/定价怎么理解(够用就行))
- 5、多平台安装
-
- [5.1 Windows](#5.1 Windows)
- [5.2 MacOS](#5.2 MacOS)
- [6、一起构建你的第一个映射(最小可复现 Demo:Flask)](#6、一起构建你的第一个映射(最小可复现 Demo:Flask))
-
- [6.1 简易代码](#6.1 简易代码)
- [6.2 内网映射](#6.2 内网映射)
- [6.3 前端界面操作](#6.3 前端界面操作)
- 7、总结
- 参考链接
🍃作者介绍:25届双非本科网络工程专业,阿里云专家博主,深耕 AI 原理 / 应用开发 / 产品设计。前几年深耕Java技术体系,现专注把 AI 能力落地到实际产品与业务场景。
🦅个人主页:@逐梦苍穹
✈ 您的一键三连,是我创作的最大动力🌹
不用公网 IP,把内网服务安全发布到公网:ZeroNews 快速上手
适用人群:开发联调、远程演示、NAS/家庭服务器远程访问、小团队临时对外开放内网服务
目标:10 分钟跑通「注册 → Agent 在线 → 创建 HTTPS 映射 → 外网访问」
1、前言
内网穿透的工具其实挺多的,但我自己的诉求一直很朴素:
- 不想为了临时联调/演示去折腾路由器端口映射
- 没公网 IP(或者公网 IP 太贵/太麻烦),但又确实需要"外网能访问"
- 不想为了一个小需求再搭一整套 VPN / 自建转发服务器
这次看 ZeroNews(零讯),我觉得比较"对胃口"的点是:上手链路很短------基本就是 Token、Agent、映射 这三件事。

内网穿透产品我个人更愿意关注两类:要么是小团队做的"体验型产品"(往往更愿意打磨上手细节、性价比也可能更友好),要么是头部大厂做的"生态型产品"(能力更全)。
2、你可能也有这些痛点
- 本地/内网服务别人访问不了:远程同事联调、客户演示、第三方回调(Webhook)一律卡住
- 家里 NAS / Mac mini 当服务器:没公网 IP,或者还在用端口映射(暴露面大、风险高)
- VPN / 自建 FRP:不是不能用,但配置/维护成本不低,而且对"临时需求"不友好
3、三分钟讲清楚 ZeroNews 在做什么
一句话理解:在内网机器上跑 Agent ,它会跟 ZeroNews 云端节点建立加密通道;你在控制台创建 映射(域名/端口 → 内网 IP:端口),外网就能访问你的内网服务了。
3.1 三个关键概念
- Token:你在控制台生成的"绑定凭证",用于把 Agent 绑定到账号
- Agent:安装在内网设备(Windows/macOS/Linux/Docker/NAS/路由器等)的客户端
- 映射(域名/端口) :把公网访问地址和内网服务地址绑定起来;常见是 HTTPS 网站映射,也可以做 TCP(SSH/RDP/MySQL 等)
协议范围(官网/文档口径):至少覆盖 HTTPS / TCP,并在官网介绍中提到 HTTP/2、WebSocket、gRPC、UDP 等能力入口。
3.2 技术特点
- 安全加密:TLS/HTTPS 保障数据传输安全。
- IP 控制:支持访问黑白名单。
- 多 Agent 多隧道:同一套餐服务支持绑定多个Agent,灵活调整设备接入
- 集中管理:平台统一远程连接,无需其它工具。
- 多协议 :支持多种协议(
HTTPS/TCP/TLS) - 无需公网 IP:适用任何公网环境,无需改动网络设置。
- 云端配置:配置云存储,自动推送。
- 一键迁移:故障时一键恢复配置。
3.3 与开源内网穿透(FRP)的区别
提到开源内网穿透,大家第一印象可能是FRP:https://github.com/fatedier/frp;
那ZeroNews和FRP的区别是什么呢:
| 特性 | ZeroNews | 开源内网穿透 (如FRP) |
|---|---|---|
| 类型 | 商业、SaaS | 完全开源 |
| 易用性 | ★★★★★ (极易) | ★★☆☆☆ (需技术) |
| 服务器 | 官方提供 | 自行搭建 (VPS) |
| 安全 | 内建多重安全策略、IP黑白名单、鉴权认证、端到端加密等 |
自行配置与管理 |
| 成本 | 有免费版, 付费升级 | 服务器成本 |
如何选择
- 选ZeroNews : 如果您是
普通用户/企业用户,不懂技术,追求快速搭建、稳定、安全、省心地访问内网资源(如NAS、家庭电脑),或者企业需要快速部署。 - 选开源 FRP: 如果您是技术爱好者、开发者,拥有自己的服务器,希望完全掌控、有深度定制需求,且不介意投入时间和精力去学习和维护。
4、上手准备:注册与 Token
4.1 注册入口
- 用户控制台:https://user.zeronews.cc/
- 官方文档:https://docs.zeronews.cc/
- 下载中心:https://www.zeronews.cc/download
注册登录后第一件事:在控制台创建 Token(后面 Agent 绑定要用)。

4.2 套餐/定价怎么理解(够用就行)
我建议先按"能不能跑通 + 是否长期用"来选:
- 免费版:先把流程跑通(做简单网站发布/日常测试/页面浏览等)
- 个人/团队版:主要差在映射/端口/Agent 数量、并发、带宽上限,以及一些治理能力(如 IP 访问控制、Basic Auth 等)是否开放
个人:

团队:

5、多平台安装
官方文档覆盖得比较全:
- Windows:https://docs.zeronews.cc/windows-guide
- macOS:https://docs.zeronews.cc/macos-guide
- Linux:https://docs.zeronews.cc/linux-guide
- Docker:https://docs.zeronews.cc/docker-guide
这里演示两个平台,Windows和macOS
5.1 Windows
先下载: https://download.zeronews.cc/windows/x64/zeronews-windows-x64-v2-3.0.2.zip

以管理员运行:

绑定token:
bash
zeronews.exe set token 「这里复制粘贴你自己的token」
启动命令:
1、只能在前台运行,当 Dos 窗口关闭时,程序会退出:
bash
zeronews.exe start
2、实现 zeronews 开机自启动,并保持程序在后台运行:
bash
zeronews.exe start -d
查看效果:

5.2 MacOS
跟着执行下面命令:
macos Intel芯片用户:
bash
mkdir -p /Applications/zeronews
cd /Applications/zeronews
curl -o zeronews.tmp https://download.zeronews.cc/macos/amd/zeronews
mv zeronews.tmp zeronews
chmod +x zeronews
./zeronews set token 「这里复制粘贴你自己的token」
macos Apple芯片用户:
bash
mkdir -p /Applications/zeronews
cd /Applications/zeronews
curl -o zeronews.tmp https://download.zeronews.cc/macos/arm/zeronews
mv zeronews.tmp zeronews
chmod +x zeronews
./zeronews set token 「这里复制粘贴你自己的token」
其实就一个区别:
本质上是芯片架构的区别。
上述完成之后,就是启动环节了:
1、只能在前台运行,当 Dos 窗口关闭时,程序会退出:
bash
./zeronews start
2、实现 zeronews 开机自启动,并保持程序在后台运行:
bash
./zeronews start -d
6、一起构建你的第一个映射(最小可复现 Demo:Flask)
目标:把你电脑上的一个本地 HTTP 服务,通过 ZeroNews 变成"外网可访问的 HTTPS 地址"。
6.1 简易代码
先看整体结构:

requirements.txt:
bash
Flask==3.0.0
templates/index.html:
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Flask测试页面</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
}
.container {
background: white;
border-radius: 12px;
padding: 40px;
box-shadow: 0 10px 40px rgba(0,0,0,0.2);
max-width: 600px;
width: 100%;
}
h1 {
color: #333;
margin-bottom: 30px;
text-align: center;
}
.info {
background: #f5f5f5;
padding: 15px;
border-radius: 8px;
margin-bottom: 20px;
}
.info p {
margin: 8px 0;
color: #666;
}
.btn {
background: #667eea;
color: white;
border: none;
padding: 12px 24px;
border-radius: 6px;
cursor: pointer;
font-size: 16px;
margin: 10px 5px;
transition: background 0.3s;
}
.btn:hover {
background: #5568d3;
}
.result {
margin-top: 20px;
padding: 15px;
border-radius: 8px;
background: #f9f9f9;
min-height: 50px;
}
.result.success {
background: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
.result.error {
background: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
}
.btn-group {
text-align: center;
}
</style>
</head>
<body>
<div class="container">
<h1>Flask 服务测试</h1>
<div class="info">
<p><strong>服务地址:</strong> http://localhost:8888</p>
<p><strong>状态:</strong> <span id="status">运行中</span></p>
</div>
<div class="btn-group">
<button class="btn" onclick="testGet()">测试GET请求</button>
<button class="btn" onclick="testPost()">测试POST请求</button>
</div>
<div id="result" class="result"></div>
</div>
<script>
function showResult(data, isError = false) {
const resultDiv = document.getElementById('result');
resultDiv.className = 'result ' + (isError ? 'error' : 'success');
resultDiv.innerHTML = '<pre>' + JSON.stringify(data, null, 2) + '</pre>';
}
async function testGet() {
try {
const response = await fetch('/api/test');
const data = await response.json();
showResult(data);
} catch (error) {
showResult({ error: error.message }, true);
}
}
async function testPost() {
try {
const response = await fetch('/api/info', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
message: '测试数据',
timestamp: new Date().toISOString()
})
});
const data = await response.json();
showResult(data);
} catch (error) {
showResult({ error: error.message }, true);
}
}
</script>
</body>
</html>
python
from flask import Flask, render_template, jsonify, request
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/api/test', methods=['GET'])
def test_api():
return jsonify({
'status': 'success',
'message': 'Flask服务运行正常',
'port': 8888
})
@app.route('/api/info', methods=['POST'])
def info_api():
data = request.get_json()
return jsonify({
'status': 'success',
'received': data,
'message': '数据接收成功'
})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8888, debug=True)
6.2 内网映射
由于程序绑定的是8888端口,这里就以8888端口为例:
先查看一下用法:
bash
./zeronews --help

映射测试端口:
bash
./zeronews add https 127.0.0.1:8888 ivtkupui0h.fy.takin.cc

然后启动一个demo示例:

此时访问https://ivtkupui0h.fy.takin.cc,如果你发现无法访问:
则可能是你没有启动,漏执行了命令。
查看设备是否启动:

如果没有启动,则需要执行:./zeronews start或者是./zeronews start -d

可以正常访问了:

然后可以在Agent当中查看自己的设备信息:

到这里,你就成功上手了ZeroNews内网穿透的基本使用。
6.3 前端界面操作
其实上述提到的命令行绑定端口的操作,在官网也可以实现操作(比如我们绑定一个本地端口678,并且把刚刚的程序改为678端口来试一下)。
1、如果域名已经用了,记得新增域名端口:

2、点击"映射"-"添加映射":

配置端口:

配置成功了:

访问:https://xzltech.dy.takin.cc

可以看到效果。
7、总结
我对 ZeroNews 的整体感受更像是:它把"内网穿透"这件事做得更像一个可控的发布入口------尤其适合"临时暴露、快速验证、可随时关掉"的场景。
- 适合:开发联调、远程演示、NAS 远程访问、小团队远程办公/运维
- 不适合:需要完全离线/自托管、对链路可控性有极致要求且不接受 SaaS 控制面的场景
下文预告: 实际应用场景当中的内网穿透(如AI应用/AI应用开发)


