$ view ~/notes/Tailscale 零公网暴露方案.md
Tailscale 零公网暴露方案
$ tree --toc
Tailscale 零公网暴露方案
方案目标
- 不开放任何公网端口(0 暴露)
- 禁用公网 SSH
- 使用 Tailscale 进行私网访问
- 自动适配:
- UDP P2P 打洞(优先)
- DERP 中继(兜底)
📌 快速使用:如果你只想快速部署 Tailscale,直接跳到 安装与部署。 后续章节是 P2P/DERP 全链路的技术解析,供深入了解时阅读。
相关文档:
- 基础安全加固参见 个人服务器安全加固方案
- 多机集群架构参见 Oracle 多机集群零公网架构方案(Oracle 免费层专用)
- 对外服务发布参见 Cloudflare Tunnel 完整方案
整体架构
🌍 互联网
│
┌─────────────┴─────────────┐
│ │
🖥 你的电脑 🧠 服务器
Tailscale Client Tailscale Client
│ │
└─────── 控制面协调 ────────┘
│
┌─────────────┴─────────────┐
│ │
🚀 P2P UDP直连(优先) 🐢 DERP中继(兜底)
安装与部署
curl -fsSL https://tailscale.com/install.sh | sh
启动并加入网络
tailscale up
💡 这里不加
--ssh。--ssh会启用 Tailscale 内置的 SSH 服务(替代 sshd),而我们的场景是继续使用服务器自身的 sshd 管理 SSH 连接,Tailscale 仅用于虚拟组网实现零公网暴露。
查看分配 IP
tailscale ip -4
示例输出:
100.101.23.5
SSH 登录(核心方式)
ssh root@100.x.x.x
持久化配置(防止密钥过期)
登录 Tailscale Admin Console,找到该机器 → Edit machine settings → 勾选 Disable key expiry。
P2P UDP 打洞全链路(核心)
流程图
你电脑 服务器
│ │
│ 1️⃣ 登录控制服务器 │
├──────────────► │
│ │
│ 2️⃣ 获取对方公网IP + 端口 │
│◄──────────────┤ │
│ │
│ 3️⃣ UDP 打洞(同时发包) │
├──────────────► │
│◄──────────────┤ │
│ │
│ 4️⃣ 建立 P2P 通道 │
│◄══════════════►│
│ │
│ 5️⃣ SSH 流量(加密) │
│◄══════════════►│
实际数据路径
SSH
↓
Tailscale 虚拟网卡(tun)
↓
WireGuard 加密
↓
UDP → 对端公网IP
↓
对端解密
↓
sshd(22端口)
特点
| 项目 | 值 |
|---|---|
| 连接方式 | UDP直连 |
| 是否依赖入站 | ❌ 不需要 |
| 延迟 | 🚀 低(10~50ms) |
| 带宽 | 高 |
| 稳定性 | 受 NAT 类型影响 |
DERP 中继全链路(兜底机制)
当 P2P 打洞失败时(对称型 NAT),流量自动切换到 DERP 中继。
流程图
你电脑 DERP服务器 服务器
│ │ │
│ 1️⃣ 出站连接 │ │
├──────────────► │ │
│ │ │
│ │◄──────────────┤
│ │ 2️⃣ 出站连接 │
│ │ │
│ 3️⃣ SSH数据 │ │
├──────────────► │ │
│ │ 4️⃣ 转发 │
│ ├──────────────► │
│ │ │
│ │ 5️⃣ 返回 │
│◄──────────────┤ │ │
SSH 数据流详解
当使用 DERP 中继时,SSH 连接的实际路径:
1️⃣ 服务器 → DERP(TCP 443,出站连接)
2️⃣ 你电脑 → DERP(TCP 443,出站连接)
3️⃣ 你执行:ssh root@100.x.x.x
4️⃣ SSH数据:
↓
Tailscale 虚拟网卡(tun)
↓
WireGuard 加密
↓
发送给 DERP(通过你已有连接)
5️⃣ DERP:
↓
把数据写入"服务器那条已建立连接"
6️⃣ 服务器:
↓
从该连接读取数据
↓
Tailscale 解密
↓
送入本地 22 端口(sshd)
特点
| 项目 | 值 |
|---|---|
| 连接方式 | TCP中继 |
| 是否依赖入站 | ❌ 不需要 |
| 延迟 | 🐢 较高(100ms+) |
| 带宽 | 较低 |
| 稳定性 | 稳定,不受 NAT 影响 |
P2P vs DERP 对比
| 项目 | P2P | DERP |
|---|---|---|
| 连接方式 | UDP直连 | TCP中继 |
| 是否依赖入站 | ❌ | ❌ |
| 延迟 | 🚀低 | 🐢高 |
| 带宽 | 高 | 较低 |
| 稳定性 | 受 NAT 影响 | 稳定 |
如何判断当前连接类型
方法一:tailscale status
tailscale status
输出 active; direct → ✅ P2P
输出 active; relay → 🐢 DERP
方法二:tailscale ping(推荐)
tailscale ping 服务器IP
输出 via 1.2.3.4:41641 → ✅ P2P
输出 via DERP(lax) → 🐢 DERP
方法三:抓包
tcpdump -i any udp or port 443
| 结果 | 类型 |
|---|---|
| UDP公网IP | P2P |
| TCP 443 | DERP |
为什么可以"0公网暴露"?
核心原因
所有连接都是:服务器主动发起(出站)
防火墙行为(关键)
主流云平台的防火墙都具有**有状态(stateful)**特性:
允许出站 → 自动允许回流
适用于 Oracle Cloud、AWS、GCP、腾讯云、阿里云等所有主流平台。
因此:
- ❌ 不需要开放 22
- ❌ 不需要开放任何端口
最终架构总结
SSH:
你 → Tailscale →(P2P UDP 或 DERP TCP)→ 服务器
特点:
✔ 端口不暴露
✔ 自动切换链路
✔ 端到端加密
✔ 零信任访问
常见问题与排查
| 问题 | 排查命令 | 解决方案 |
|---|---|---|
| 无法连接 | tailscale status |
检查 Tailscale 是否在线 |
| 强制 DERP | iptables -A OUTPUT -p udp -j DROP |
测试 DERP 兜底是否正常 |
| 查看网络类型 | tailscale netcheck |
确认当前连接模式 |
一句话总结
使用 Tailscale 可以在不开放任何公网端口的前提下,通过 UDP 打洞实现 P2P 直连,并在失败时自动切换到 DERP 中继,实现稳定、安全的零暴露服务器访问架构。