文章 /

Cloudflare Tunnel + Zero Trust 稳定接入 Netcup VPS SSH

“出站建隧道 + 边缘鉴权”的接入方式处理 `sshd` 正常而跨境链路不稳问题

德国 VPS 的 sshd 正常但跨境链路抖动,直连 22 端口无响应,排查过程:

  • VNC 能进,说明机器没有失联
  • SSH 服务 active 且 22 端口监听正常,说明服务本身没挂
  • UFW 未拦截但仍频繁断开,说明问题不在主机防火墙
  • preauth reset 反复出现,说明连接在认证前阶段就被链路重置

最后采用的方案是:当无可用稳定优质节点时,在服务器部署 cloudflared,把 ssh-de.condevtools.com 通过 Tunnel 映射到 localhost:22,本地再使用 cloudflared access ssh 连接。这样 SSH 不再依赖直连 22 端口,稳定性和可控性都更好。

一、现状确认

服务器厂商 VNC 可进入,SSH 服务 active,22 端口监听正常,日志中有 Connection reset by peer [preauth]

systemctl status ssh
ss -tlnp | grep sshd
ufw status    # 或 iptables -S / nft list ruleset
journalctl -u ssh -n 100 --no-pager

检查要点:

  • systemctl status ssh 确认 SSH 服务是否在运行,Active: active (running)
  • ss -tlnp | grep sshd 确认 SSH 监听端口,有输出则监听正常
  • ufw status 确认系统防火墙是否拦截 SSH,inactive未拦截
  • journalctl -u ssh -n 100 --no-pager 查看认证和连接日志,Connection reset by peer [preauth]:连接到达服务器,但认证前就被重置,常见于链路问题

结论:服务正常、端口正常、防火墙未拦,但日志持续出现 preauth reset,应优先判断为网络路径问题,而不是 SSH 配置故障。

二、可选接入方案

1) 买机中转

先 SSH 到香港机,再从香港机连接德国机;或者在香港机上搭 WebSSH。这个方案能绕开部分跨境问题,但会引入额外机器成本和运维点。

# ~/.ssh/config
Host hk
  HostName 香港机IP
  User your_user
  Port 22
  IdentityFile ~/.ssh/id_rsa

Host de-via-hk
  HostName 德国机IP
  User your_user
  Port 22
  ProxyJump hk
  IdentityFile ~/.ssh/id_rsa
ssh de-via-hk

也可以参考这个教程:买机做中转

2) sshx 作为应急网页终端

可以通过 VNC 在服务器上安装并运行 sshx,再从本地浏览器打开生成的链接。

curl -sSf https://sshx.io/get | sh
sshx

sshx

实测使用中出现断流,往往还要重新打开 VNC 才能恢复,不适合作为长期入口。

3) Cloudflare Tunnel + Zero Trust

Cloudflare Tunnel 是“由源站主动发起”的反向隧道:服务器运行 cloudflared 后,会主动连接 Cloudflare 边缘,再把指定域名的流量转发到本机服务。

通常解决三类问题:

  • 跨境直连不稳定
  • 端口被运营商或网络策略干扰
  • 公网暴露 SSH 端口的安全风险

可以概括为“出站建隧道 + 边缘鉴权 + 回源转发”。Cloudflare Tunnel 是服务本身,cloudflared 是官方客户端;前者定义能力,后者负责建隧道、发起接入并转发流量。

三、服务器侧 Tunnel

1) 安装 cloudflared

sudo apt-get update
sudo apt-get install -y cloudflared
cloudflared --version

2) 登录 Cloudflare 并生成 cert.pem

cloudflared tunnel login
ls -l /root/.cloudflared/cert.pem

3) 创建 Tunnel 并绑定 SSH 子域名

cloudflared tunnel create de-ssh
cloudflared tunnel list
cloudflared tunnel route dns de-ssh ssh-de.condevtools.com

4) 生成配置文件

TUNNEL_ID=$(cloudflared tunnel list | awk '$2=="de-ssh"{print $1}')

cat >/root/.cloudflared/config.yml <<EOF
tunnel: ${TUNNEL_ID}
credentials-file: /root/.cloudflared/${TUNNEL_ID}.json
ingress:
  - hostname: ssh-de.condevtools.com
    service: ssh://localhost:22
  - service: http_status:404
EOF

cat /root/.cloudflared/config.yml
cloudflared tunnel ingress validate

5) 前台验证

cloudflared tunnel run de-ssh

前台验证通过后再安装为系统服务,可以避免把错误直接带入开机自启。

6) 安装为 systemd 服务并开机自启

cloudflared service install
systemctl daemon-reload
systemctl enable --now cloudflared
systemctl status cloudflared --no-pager -l

四、Zero Trust Access

cloudflared tunnel 负责把 SSH 服务接到 Cloudflare 边缘,Zero Trust Access 负责鉴权。没有 Access,公网 hostname 依然可能被任何人尝试连接。

工作流程如下:

  1. 执行 ssh,其中 ProxyCommand 调用本地 cloudflared access ssh --hostname ...
  2. 本地 cloudflared 拉起浏览器完成登录
  3. Cloudflare Access 按策略判断是否放行
  4. 只有命中 Allow 的用户才会拿到访问令牌
  5. 放行后流量进入 Tunnel,再转发到源站 localhost:22

配置步骤:

  1. Zero Trust -> Access -> Applications -> Add application -> Self-hosted
  2. Domainssh-de.condevtools.com
  3. Policy 只允许你自己的邮箱或账号,建议开启 MFA

这套方法更适合长期运维和跨境不稳定场景。

五、本地接入

1) 安装客户端

brew install cloudflared
cloudflared --version

2) 直接连接测试

ssh -o "ProxyCommand=$(which cloudflared) access ssh --hostname %h" [email protected]

3) 可选:写入 ~/.ssh/config

Host de-cf
  HostName ssh-de.condevtools.com
  User root
  ProxyCommand /opt/homebrew/bin/cloudflared access ssh --hostname %h
ssh de-cf

链路不稳时,先改接入方式,通常比反复重启 sshd 更有效。