有时候想把家里的电脑、树莓派或者一台内网服务器挂到公网,但没有公网 IP,路由器也不好折腾。

这时候 Cloudflare Tunnel 就挺适合。它的逻辑很简单:本地机器主动连到 Cloudflare,然后外面的人通过你的域名访问这个隧道。你不用暴露端口,也不用管运营商给不给公网 IP。

适用场景

  • 家里跑了一个网站,想临时给外网访问。
  • NAS、面板、测试服务想绑个域名。
  • 不想在路由器上开一堆端口。
  • 没有公网 IP,但又想有 HTTPS。

别拿它当万能反代。要是你跑的是高并发、大流量服务,还是老老实实上服务器。Tunnel 更适合个人服务、测试环境和低频访问。

前置条件

先确认这几件事:

项目 说明
Cloudflare 账号 域名需要已经托管到 Cloudflare
一台本地机器 Linux 最省事,Windows 也能跑,但这里按 Linux 写
一个本地服务 比如 http://127.0.0.1:80http://127.0.0.1:8080
一个域名 比如 app.example.com

先测一下你的本地服务是不是活的:

1
curl -I http://127.0.0.1:80

能看到 200301302 这类正常响应就行。要是本地都打不开,先别折腾 Tunnel,不然排错会很抽象。

最终效果

做完以后,外网访问的是你的域名:

1
https://app.example.com

请求会从 Cloudflare 进入,再通过本机主动建立的 Tunnel 转到内网服务。你不用在路由器上做端口映射,也不用要求家里有公网 IP。

安装 cloudflared

cloudflared 是 Cloudflare Tunnel 的客户端。

macOS 可以直接用 Homebrew:

1
brew install cloudflared

Linux 下载二进制文件就行:

1
2
3
curl -L 'https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64' -o ./cloudflared
chmod +x ./cloudflared
sudo mv ./cloudflared /usr/local/bin/cloudflared

看一下有没有装好:

1
cloudflared --version

有版本号就行。

登录 Cloudflare

让本机的 cloudflared 拿到 Cloudflare 账号授权:

1
cloudflared tunnel login

命令会给一个链接。复制到浏览器打开,登录 Cloudflare,选择你要用的域名,然后授权。

授权成功后,本机会生成一个证书文件。这个文件别乱删,后面创建隧道要用。

创建隧道

给隧道起个名字,比如 home-web

1
cloudflared tunnel create home-web

输出里会有两个关键信息:

1
2
Created tunnel home-web with id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Tunnel credentials written to /root/.cloudflared/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.json

记住这两个:

  • 隧道 ID
  • credentials 文件路径

后面配置文件要填。

写配置文件

创建配置目录:

1
2
sudo mkdir -p /etc/cloudflared
sudo nano /etc/cloudflared/config.yml

示例配置:

1
2
3
4
5
6
7
8
9
10
11
tunnel: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
credentials-file: /root/.cloudflared/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.json

ingress:
- hostname: app.example.com
service: http://127.0.0.1:80

- hostname: admin.example.com
service: http://127.0.0.1:8080

- service: http_status:404

这里别照抄域名。换成你自己的。

ingress 是按顺序匹配的,最后那个 404 建议留着。不然没匹配到的请求怎么处理会比较乱。

配置写完先检查:

1
cloudflared tunnel ingress validate

能过再继续。

绑定域名

把域名指到这个 Tunnel:

1
2
cloudflared tunnel route dns home-web app.example.com
cloudflared tunnel route dns home-web admin.example.com

如果提示 DNS 记录冲突,去 Cloudflare 面板把旧的 AAAAACNAME 记录删掉,再执行一次。

先手动跑一下

别急着装服务,先跑起来看看:

1
cloudflared tunnel run home-web

然后访问你的域名:

1
https://app.example.com

能打开就说明主流程没问题。

如果打不开,优先看这几个点:

  • 本地服务是不是还活着。
  • hostname 有没有写错。
  • Cloudflare DNS 有没有指到 Tunnel。
  • 服务器时间是不是离谱。
  • 配置文件路径是不是对的。

设置开机启动

确认手动运行没问题后,再装成 systemd 服务:

1
2
sudo cloudflared service install
sudo systemctl enable --now cloudflared

看状态:

1
sudo systemctl status cloudflared

看实时日志:

1
journalctl -u cloudflared -f

日志里能看到连接成功,域名也能访问,就差不多了。

常用命令

功能 命令
登录账号 cloudflared tunnel login
创建隧道 cloudflared tunnel create <name>
查看隧道 cloudflared tunnel list
删除隧道 cloudflared tunnel delete <name>
绑定域名 cloudflared tunnel route dns <name> <domain>
校验配置 cloudflared tunnel ingress validate
前台运行 cloudflared tunnel run <name>
查看服务 sudo systemctl status cloudflared
看日志 journalctl -u cloudflared -f

一点安全建议

Tunnel 不等于你可以什么都裸奔。

如果是管理面板,最好再加一层登录,或者用 Cloudflare Access 限制访问。不然只是端口没暴露,服务本身该被扫还是可能被扫。

简单说:公网能访问的东西,就按公网服务来处理。别侥幸。