这台 2 核 2G 的阿里云 ECS 只对公网开放了一个 SSH 端口。网站却能通过 https://suxiangyu.top 正常访问,靠的是 Cloudflare Tunnel。
链路长什么样
请求先到 Cloudflare 边缘节点,再通过 cloudflared 建立的反向隧道回到源站的 localhost:80:
浏览器
│ HTTPS 443
▼
Cloudflare Edge
│ 隧道(出站长连接)
▼
cloudflared ──> localhost:80 ──> Nginx ──> /var/www/site服务器不需要公网入站端口,也不需要单独申请证书。TLS 在 Cloudflare 边缘终止,源站只处理明文 HTTP。
一次性配置
在 Cloudflare Zero Trust 控制台创建 Tunnel,选择 Linux 安装方式,会得到一段带 token 的安装命令。执行后 cloudflared 注册为 systemd 服务:
systemctl status cloudflared --no-pager
systemctl enable --now cloudflared然后在 Tunnel 的 Public Hostname 里添加:
| 字段 | 值 |
|---|---|
| 子域名 | suxiangyu |
| 域名 | top |
| 服务类型 | HTTP |
| URL | localhost:80 |
保存后配置会推送到服务器,日志里能看到新的 ingress 规则:
Updated to new configuration
config={"ingress":[{"hostname":"suxiangyu.top","service":"http://localhost:80"}]}踩过的坑
源站自己访问不了自己的域名
在 ECS 内部执行 curl https://suxiangyu.top 可能失败,因为公网 IP 的回程流量不经过本机。判断站点是否正常,应该在服务器上直接访问 http://127.0.0.1/,公网可用性则从外部或边缘节点验证。
安全组不要顺手放开 80
既然流量走隧道,安全组只保留 SSH 端口即可。多开一个入站端口,就多一份被扫描和攻击的面积。Nginx 仍然监听 80,但只绑定在本机回环链路上,由 cloudflared 访问。
日志里看不到真实客户端 IP
默认 Nginx 访问日志记录的是 127.0.0.1。需要真实 IP 时,配置 Cloudflare 的 CF-Connecting-IP 头,或在边缘开启日志分析。对个人站点来说,先用 Cloudflare 的统计就够了。
这套方案适合谁
- 域名已按所在地要求完成备案,且希望隐藏源站 IP
- 源站资源有限,只想跑 Nginx + 少量学习服务
- 能接受流量经过 Cloudflare,换取零入站端口和自动 HTTPS
合规提醒:在中国大陆服务器上绑定域名通常需要完成 ICP 备案。Cloudflare Tunnel 只改变流量路径、隐藏源站,不替代备案义务。
代价是依赖 Cloudflare 的可用性。对个人博客而言,这是可以接受的取舍。