ngrok技术指南:本地服务的公网映射与隧道技术详解
1. 简介
1.1 ngrok 是什么?
ngrok 是一个强大的反向代理工具,它可以将你的本地开发环境暴露在公网上。通过创建一个安全的隧道,ngrok 能够将公网的请求转发到你本地机器上运行的服务。这使得在开发和测试阶段与外部服务(如 Webhooks、APIs)集成变得异常简单。
1.2 工作原理
ngrok 的工作原理可以概括为以下几个步骤:
- 启动 ngrok 客户端:你在本地机器上运行 ngrok 客户端,并指定要暴露的本地端口。
- 建立安全隧道:ngrok 客户端连接到 ngrok 云服务,并建立一个安全的加密隧道。
- 分配公网地址:ngrok 云服务会为你分配一个唯一的公网 URL(例如
https://random-string.ngrok.io)。 - 请求转发:当有请求发送到这个公网 URL 时,ngrok 云服务会通过隧道将请求转发到你本地的 ngrok 客户端。
- 访问本地服务:ngrok 客户端再将请求转发到你指定的本地端口上运行的服务。
sequenceDiagram
participant User as 用户/外部服务
participant NgrokCloud as ngrok 云服务
participant NgrokClient as 本地 ngrok 客户端
participant LocalServer as 本地 Web 服务
User->>NgrokCloud: 请求 https://<subdomain>.ngrok.io
NgrokCloud->>NgrokClient: 通过安全隧道转发请求
NgrokClient->>LocalServer: 请求 http://localhost:<port>
LocalServer-->>NgrokClient: 返回响应
NgrokClient-->>NgrokCloud: 通过安全隧道返回响应
NgrokCloud-->>User: 返回最终响应
1.3 为什么使用 ngrok?
- Webhook 开发:在本地开发和测试需要接收 Webhook 的应用(如 GitHub、Stripe、Twilio)。
- API 测试:让移动应用或其他外部服务可以访问你本地正在开发的 API。
- 项目演示:向客户或同事快速演示一个正在开发中的网站或应用,而无需部署到服务器。
- 调试:捕获和检查所有通过隧道的 HTTP 请求和响应,方便调试。
2. 快速入门
2.1 下载和安装
- 访问官网:前往 ngrok 官网。
- 下载客户端:根据你的操作系统(Windows、macOS、Linux)下载对应的 ngrok 客户端。
- 解压文件:下载完成后,解压压缩包。你会得到一个名为
ngrok的可执行文件。
2.2 账户和 Authtoken
注册账户:在 ngrok 官网 注册一个免费账户。
获取 Authtoken:登录后,在你的 dashboard 页面找到你的 Authtoken。
配置 Authtoken:打开终端,进入 ngrok 可执行文件所在的目录,运行以下命令将 Authtoken 添加到默认的配置文件
ngrok.yml中:./ngrok config add-authtoken <YOUR_AUTHTOKEN>配置 Authtoken 后,你将能够使用更多的功能,如自定义子域名、更长的会话时间等。
2.3 建立你的第一个隧道
假设你本地有一个在 8000 端口上运行的 Web 服务,你可以使用以下命令来为它创建一个公网隧道:
./ngrok http 8000
命令执行后,你会在终端看到类似下面的输出:
ngrok by @inconshreveable (Ctrl+C to quit)
Session Status online
Account Your Name (Plan: Free)
Version 3.x.x
Region United States (us)
Web Interface http://127.0.0.1:4040
Forwarding https://9a1b-2c3d-4e5f-6a7b-8c9d.ngrok.io -> http://localhost:8000
Connections ttl opn rt1 rt5 p50 p90
0 0 0.00 0.00 0.00 0.00
现在,你就可以通过 https://9a1b-2c3d-4e5f-6a7b-8c9d.ngrok.io 这个公网地址访问你本地 8000 端口的服务了。
同时,你也可以通过浏览器访问 http://127.0.0.1:4040 来打开 ngrok 的 Web 界面,在这里你可以查看所有通过隧道的请求和响应详情。
3. 核心概念
3.1 隧道协议
ngrok 支持多种协议来创建隧道:
HTTP/HTTPS:最常用的协议,用于暴露 Web 服务。
# 暴露本地 80 端口的 HTTP 服务 ngrok http 80 # 暴露本地 3000 端口的 HTTPS 服务 ngrok http https://localhost:3000TCP:用于暴露非 HTTP 的服务,如 SSH、数据库连接、游戏服务器等。
# 暴露本地 22 端口的 SSH 服务 ngrok tcp 22TLS:用于暴露需要端到端 TLS 加密的 TCP 服务。
ngrok tls --domain=your-domain.com 443
3.2 自定义域名
对于付费用户,ngrok 允许你使用自定义的子域名或完全自定义的域名。
自定义子域名:
ngrok http --subdomain=my-awesome-app 8080这会将你的服务暴露在
https://my-awesome-app.ngrok.io。自定义域名 (需要付费计划和 CNAME 配置):
ngrok http --hostname=dev.example.com 80
4. 高级用法
4.1 配置文件
除了在命令行中指定参数,你还可以通过 ngrok.yml 配置文件来定义隧道。这对于管理多个隧道和复杂的配置非常有用。
默认情况下,配置文件位于:
- macOS:
~/Library/Application Support/ngrok/ngrok.yml - Linux:
~/.config/ngrok/ngrok.yml - Windows:
C:\Users\YourUser\AppData\Local\ngrok\ngrok.yml
一个配置文件的示例:
version: "2"
authtoken: <YOUR_AUTHTOKEN>
tunnels:
my-api:
proto: http
addr: 8080
subdomain: my-cool-api
ssh:
proto: tcp
addr: 22
配置好后,你可以通过名称来启动隧道:
ngrok start my-api
ngrok start ssh
ngrok start --all # 启动所有定义的隧道
4.2 安全选项
ngrok 提供了多种安全功能来保护你的隧道:
HTTP 基本认证:为你的隧道添加用户名和密码保护。
ngrok http --basic-auth="username:password" 8000OAuth 2.0 (付费功能): 与 Google, GitHub, Microsoft 等 OAuth 提供商集成,只有通过身份验证的用户才能访问你的隧道。
ngrok http --oauth=google --oauth-allow-emails=user@example.com 8000IP 限制 (付费功能): 只允许或拒绝特定 IP 地址或 CIDR 范围的访问。
ngrok http --ip-restriction-allow-cidrs=203.0.113.0/24 8000
4.3 Webhook 验证 (付费功能)
ngrok 可以自动验证来自某些服务(如 Twilio, Stripe)的 Webhook 请求的签名,增加安全性。
ngrok http --verify-webhook=twilio --verify-webhook-secret=<YOUR_SECRET> 8000
5. API 和集成
ngrok 提供了官方的客户端库,可以让你以编程方式控制隧道。@ngrok/ngrok 是官方的 Node.js 库。
5.1 安装
npm install @ngrok/ngrok
5.2 示例:在 Node.js 应用中启动隧道
const ngrok = require("@ngrok/ngrok");
// 设置 Express 应用
const express = require('express');
const app = express();
const port = 8080;
app.get('/', (req, res) => {
res.send('Hello from local server!');
});
app.listen(port, async () => {
console.log(`Local server listening at http://localhost:${port}`);
// 启动 ngrok 隧道
try {
const listener = await ngrok.forward({
addr: port,
authtoken_from_env: true, // 从 NGROK_AUTHTOKEN 环境变量读取
});
console.log(`Ingress established at: ${listener.url()}`);
} catch (error) {
console.error("Error establishing ngrok tunnel:", error);
}
});
6. 常见问题解答 (FAQ)
Q: ngrok 隧道的地址是固定的吗? A: 在免费计划中,每次重启 ngrok 客户端,你都会得到一个新的随机 URL。付费计划的用户可以使用固定的子域名或自定义域名。
Q: 如何在后台运行 ngrok?
A: 在 Linux 或 macOS 上,你可以使用 & 将其置于后台:./ngrok http 8000 &。对于更稳定的方案,建议使用 systemd 或 supervisor 等工具来管理 ngrok 进程。
Q: 免费版和付费版有什么主要区别? A: 付费版提供更多高级功能,包括:
- 自定义/固定子域名
- 自定义域名
- 更多的并发隧道
- IP 白名单/黑名单
- OAuth 集成
- 更长的会v话超时时间
Q: 我可以同时运行多个隧道吗?
A: 可以。你可以在配置文件中定义多个隧道并使用 ngrok start --all 启动,或者打开多个终端窗口分别运行 ngrok 命令。免费版对并发隧道的数量有限制。