我花了好几个小时在谷歌上搜索端口转发。然后我找到了 Cloudflare Tunnel
Source: Dev.to

我在 NAT 后面的服务器上运行着一个内部服务。私有 IP,无法公开访问。典型的噩梦。
我的 ISP 不提供静态 IP。我的路由器的端口转发 UI 看起来像是 2003 年设计的。每次我终于把它弄好,IP 又变了,所有东西都坏掉。
后来我发现了 Cloudflare Tunnel。只用了 10 分钟,我就用自定义域名把服务暴露到互联网。无需端口转发。无需静态 IP。免费。
下面就是我的完整操作步骤。
问题
我有一个服务运行在 192.168.39.231:8088。使用自签名证书的 HTTPS。我需要从任何地方访问它,最好有一个像 myapp.mydomain.com 这样好看的域名。
传统做法:
- 获取静态 IP(需要花钱)
- 在路由器上转发端口(麻烦)
- 设置动态 DNS(又要维护)
- 处理 SSL 证书(Let’s Encrypt 可用,但仍然麻烦)
或者直接使用 Cloudflare Tunnel。
快速隧道(快速方式)
如果你只想快速测试一下,有一个零配置的选项:
cloudflared tunnel --url https://192.168.39.231:8088 --no-tls-verify
Cloudflared 会为你生成一个随机 URL,例如 alice-ion-married-knights.trycloudflare.com。你的服务现在已经公开。
如果你的源站使用自签名证书,--no-tls-verify 参数非常重要。没有它,cloudflared 会因为无法验证证书而拒绝连接。
随机 URL 并不理想,所以我们来设置一个正式的自定义域名。
Source: …
命名隧道(正确方式)
您需要一个 Cloudflare 账户并将您的域名添加到 Cloudflare。
第 1 步:登录
cloudflared tunnel login
会打开浏览器窗口;完成身份验证。Cloudflared 会将证书下载到 ~/.cloudflared/cert.pem。
第 2 步:创建隧道
cloudflared tunnel create my-app
示例输出:
Tunnel credentials written to /root/.cloudflared/8a0b7c44-4677-421e-810b-f5e6de9d0555.json
Created tunnel my-app with id 8a0b7c44-4677-421e-810b-f5e6de9d0555
保存该隧道 ID,稍后会用到。
第 3 步:为域名路由
cloudflared tunnel route dns my-app app.yourdomain.com
此操作会在 Cloudflare 中创建一个 CNAME 记录,将您的子域指向该隧道。
第 4 步:创建配置文件
在 ~/.cloudflared/config.yml 中写入:
tunnel: my-app
credentials-file: /root/.cloudflared/8a0b7c44-4677-421e-810b-f5e6de9d0555.json
ingress:
- hostname: app.yourdomain.com
service: https://192.168.39.231:8088
originRequest:
noTLSVerify: true
- service: http_status:404
将隧道 ID 和主机名替换为您自己的值。noTLSVerify: true 行相当于配置文件中的 --no-tls-verify,在使用自签名证书时是必需的。最后的 ingress 规则用于捕获所有其他请求并返回 404,这是强制性的。
第 5 步:运行隧道
cloudflared tunnel run my-app
您的服务现在可以通过 https://app.yourdomain.com 访问。
常见问题
“无法访问源服务”
您的服务未运行,或 cloudflared 无法访问它。请在本地进行测试:
curl -k https://192.168.39.231:8088
如果 curl 无法访问,则 cloudflared 也无法访问。
“tls: failed to verify certificate”
您的源使用了自签名证书。可在快速隧道中添加 --no-tls-verify,或在命名隧道的配置中使用 noTLSVerify: true。
“credentials file doesn’t exist”
您可能忘记在 config.yml 中将占位路径替换为步骤 2 中创建的实际凭证文件路径。请确保路径完全匹配。
作为服务运行
您可能不想一直保持终端打开。将 cloudflared 安装为系统服务:
cloudflared service install
systemctl start cloudflared
systemctl enable cloudflared
现在它会在启动时运行,并在崩溃时自动重启。
为什么这样更好
- 无需端口转发的麻烦
- 不需要静态 IP
- 不需要动态 DNS 维护
- 免费的 Cloudflare SSL
- 在严格的 NAT 和防火墙后仍可工作
- 隧道是主动向外连接的,即使入站端口被阻塞也能工作
我早该发现这个了。
结论
如果你仍在用传统方式将内部服务暴露到互联网,请停止。Cloudflare Tunnel 只需约 10 分钟即可完成设置,而且直接可用。
快速隧道非常适合测试。对于任何生产级别的需求,你需要使用带自定义域名的命名隧道。
你正在暴露哪些内部服务?欢迎分享——我很好奇其他人是通过隧道运行了哪些服务。