跳到正文
从「开端口放行」到「主动出站」:我换用 Cloudflare Tunnel 之后多想了什么
从「开端口放行」到「主动出站」:我换用 Cloudflare Tunnel 之后多想了什么

从「开端口放行」到「主动出站」:我换用 Cloudflare Tunnel 之后多想了什么

把域名接进 Cloudflare、用 Tunnel 做零端口发布。重点不是怎么配,而是我当初怎么理解可达、后来哪里想偏了,以及「主动出站」之后我对整套工作流怎么重新分了面。

速读#

这篇讲的不是 Tunnel 配置步骤,而是“公网可达”从入站开门转成主动出站后的认知变化。DNS 代理只是藏 IP,端口还在;Tunnel 改的是连接发起方向。读这篇要顺手记住:token 是密钥,WordPress 反代要处理 HTTPS 协议头。

入站思维:开一道缝就多一份攻击面#

最早「让外面访问到服务」只有一个动作:在防火墙开端口放行。公网 IP + ufw allow 80,443 + Nginx,这就叫上线了。

能用,但是入站思维:外面来敲门,我把门开一道缝。隐含代价当时没察觉——开了多少缝,就暴露多少攻击面。fail2ban 日志里每天几百条扫描,本质就是缝在招事。

DNS 代理只是藏,门缝还在#

Cloudflare DNS 接管:NS 改过去,A 记录橙云开启,外面 ping 到的是 CF IP,不是真实 IP。顺手 CDN、SSL、基础 WAF,扫描日志肉眼清净了。

但这只是。回源时 CF 仍要从公网打你的 80/443——IP 藏了,端口还在。IP 一旦泄露(邮件头、历史 DNS),照样被打。

当时未解决的问题:能不能连这道缝都不开?

Tunnel:根本不要入站#

我以为「更安全」等于「更严的入站规则」。Tunnel 给的答案是:根本不要入站。

cloudflared 在机器上主动向 Cloudflare 建出站连接,访客请求沿隧道进来。服务器可以对公网零入站端口,服务仍用 HTTPS 域名访问。

可达拆成两层:

  1. 谁发起连接(入站 / 出站)
  2. 真实入口暴露在哪

Tunnel 把发起方向改成出站,真实入口归零。家宽、NAT、没有公网 IP 的机器,在出站模型下也能挂服务——出站本来就不依赖公网入站能力。

四种方案对照#

方案发起方向真实 IP我为何没长期停在这
端口转发 / 直挂入站暴露攻击面摊开
frp 等自建中转源站出站连中转,公网入站落在中转机源站可藏,中转暴露暴露面只是挪到了中转机,还多一台要守
CF DNS 代理入站(回源)藏了但端口在IP 一泄露就破功
CF Tunnel出站全程可不暴露真正零入站

frp 那行值得多看一眼:它其实已经把源站翻成出站了,思路和 Tunnel 同源。差别在承接入站的那台中转机归谁守——自建中转,暴露面和运维负担都是自己的;Tunnel 等于把这台「中转机」外包给了 Cloudflare 的边缘网络。

选 Tunnel 不是因为它完美:流量经 CF 中转,多一层依赖,出站断了服务就断。在「几台机器、要省心、要少暴露」这个场景下,这个取舍我认。

出站想通后:部署按面拆#

不再把部署看成一串配置步骤,而按系统生命周期分成一个个独立的面:

我现在怎么做状态
可达Tunnel 出站,零入站在用
守护systemd 崩溃自拉在用;更底层 watchdog 评估中
防护ufw 只放 SSH + fail2ban在用
可观测哪吒 + 告警在用
配置密钥Tunnel token 进 .env + gitignore在用

每面独立问「缺了会怎样」。例如守护:systemd 能拉「进程崩了」,拉不起「更彻底的挂」——watchdog 是那一层,没上就照实写评估中

三个和 Tunnel 强相关的点#

1. token 是密钥,不是配置 能让隧道连上 CF,等于一把钥匙。差点写进 compose.yml,后来进 .env 并 gitignore。和 SSH 私钥同待遇。

2. cloudflared 与 app 同 Compose 网络 用服务名 app:8080 直连,不必走宿主机端口。app 用 expose 而不是 ports——只在 Docker 内网开,不绑宿主机。零暴露落到编排层的动作。

3. WordPress + 反代 / 隧道:HTTPS 死循环几乎必踩 外层 HTTPS、内部 HTTP,WP 会无限重定向。让它信任转发协议头:

if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])
&& $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
$_SERVER['HTTPS'] = 'on';
}

和 Nginx 反代漏传 X-Forwarded-Proto 是同一类「内外协议不一致」问题:外层终止了 HTTPS,内层应用只看见 HTTP,就会执着地往 HTTPS 跳,形成死循环。

如果重新来一次#

  • 可达面一开始就选 Tunnel,不必先入站再迁移
  • SSH 不进 Tunnel——Web 与管理通道分开,隧道自己出故障时,还得有一条不依赖它的路进去修;SSH 靠密钥 + 改端口 + fail2ban 自守
  • 守护面更早分层想:「进程崩」和「更彻底的挂」是两级

工具会换,分面的习惯不换。从入站开门,到出站不打门——改变的不是某个配置,是「可达还可以这样理解」。

版权许可

CC BY-NC-SA 4.0 本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

相关文章

s1oopX

登录 s1oopX