CGNAT环境下的自托管服务
摘要
本文解释了如何在家庭环境中通过CGNAT后自托管服务,使用VPS桥接和WireGuard隧道来转发流量,克服端口转发的限制。
<p><a href="https://lobste.rs/s/sus08k/self_hosting_behind_cgnat">评论</a></p>
查看缓存全文
缓存时间: 2026/09/21 18:27
# 在CGNAT背后自托管
来源:https://david.alvarezrosa.com/posts/self-hosting-behind-cgnat/
没有什么比端到端掌控自己使用的软件和硬件更令人满足——无需依赖霸道的云服务公司。互联网本是我们,而非他们。挣脱审查枷锁,学习如何在家中自托管,实现真正的*自由*。
## 历史回顾
过去自托管更为简单。只需在路由器上开放端口并转发到家中任意设备即可。动态域名解析服务能在运营商更换公网IP时,确保你的域名始终指向正确的地址。
## 现状挑战
如今IPv4地址枯竭,导致路由器在整个社区共享同一IP地址。运营商通过**运营商级NAT(CGNAT)**——一种部署在运营商网络内部的二级NAT机制进行路由,你的路由器地址在内部转换为运营商分配的临时公网地址。由于公网地址归属于运营商,传统端口转发机制已然失效。
## 网络拓扑
(https://david.alvarezrosa.com/posts/self-hosting-behind-cgnat/#topology)
我的服务运行在西班牙北部母亲家地下室的一台中端主机上,通过法国数据中心廉价的VPS桥接服务器接入互联网。
```
+-------------------------------------+
| 公共互联网 |
+-------------------------------------+
▲ ▲
│ 入站流量 │
▼ ▼
+------------+ +------------+
| | 出站 | |
| 桥接器 |◄══════► 家实验室 |
| | | |
+------+-----+ +-----+------+
│ WireGuard隧道 │
▼ ▼
+-------------------------------------+
| 家实验室网络 |
+-------------------------------------+
```
**代码片段1:拓扑示意图。**
家实验室通过WireGuard隧道连接VPS桥接服务器暴露在互联网上。双向WireGuard隧道将桥接服务器所有端口的数据包转发至家实验室设备,反之亦然。此方案精妙之处在于隧道由家实验室主动发起,因此无需在家庭网络部署静态专用IP地址。在西班牙,向运营商购买静态IP是可行替代方案,月费约20欧元。桥接服务器带来的额外延迟约为39毫秒往返时间。
## 隧道配置
(https://david.alvarezrosa.com/posts/self-hosting-behind-cgnat/#tunnel-configuration)
**桥接服务器的`wg0.conf`配置:**
(详见"新服务器初始化指南"了解设备部署流程)
```
[Interface]
Address = 10.0.0.1/24
PrivateKey =
ListenPort = 51820
PostUp = ...
PostDown = ...
[Peer]
PublicKey =
AllowedIPs = 10.0.0.2/32
```
`PostUp`在内核层设置NAT与转发规则,`PostDown`在隧道关闭时清除规则。前两条规则排除SSH使用的2222端口和VPN隧道本身的51820端口。后三条规则将所有端口的全部流量转发至家实验室。目标地址被重写但保留源地址,因此家实验室能获取真实客户端IP。
```
iptables -t nat -A PREROUTING -i ens3 -p udp --dport 51820 -j RETURN
iptables -t nat -A PREROUTING -i ens3 -p tcp --dport 2222 -j RETURN
iptables -t nat -A PREROUTING -i ens3 -j DNAT --to-destination 10.0.0.2
iptables -A FORWARD -i wg0 -o ens3 -s 10.0.0.2 -j ACCEPT
iptables -A FORWARD -i ens3 -o wg0 -d 10.0.0.2 -j ACCEPT
```
**家实验室的`wg0.conf`配置:**
(完整配置详见我的homelab仓库)
```
[Interface]
Address = 10.0.0.2/24
PrivateKey =
Table = off
PostUp = ip route add default dev wg0 table 200
PostUp = ip rule add from 10.0.0.2 table 200
PostDown = ...
[Peer]
PublicKey =
Endpoint = 213.32.19.229:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
```
家实验室的回复必须沿隧道返回。该配置确保响应流量通过桥接服务器传输,同时保持家实验室本地流量走家庭路由器。此后,通过`ssh.alvarezrosa.com`的22端口可访问家实验室,2222端口则连接至桥接服务器。
## 故障容灾
(https://david.alvarezrosa.com/posts/self-hosting-behind-cgnat/#resilience)
存在三个潜在故障点:
- **家实验室**:通过定时任务监控SSH服务状态,异常时自动重启设备
- **桥接服务器**:建议部署Cloudflare隧道或Tailscale直连家实验室作为备用入口
- **隧道连接**:短暂中断会自动重握手,长时间中断则可通过上述备用方案解决
掌控你的服务,享受*自由*的乐趣!
相似文章
如何在客厅中通过静态IP自托管服务器
一份使用L2TP隧道和静态IP在家中自托管服务器的指南,绕过CGNAT等ISP限制。
用 SSH 和 nginx 搭建自建 HTTP 隧道
一篇博客教程,介绍如何搭建一个自建的 HTTP 隧道服务——类似于 ngrok 或 Cloudflare Quick Tunnels——只需使用 OpenSSH 反向转发配合一个 nginx 代理,再加上通配符 DNS、Let's Encrypt 证书,以及 ngx_http_secure_link_module 来生成带哈希、会过期的访问 URL。
使用 OpenBSD 搭建一个简单的自托管网页服务器
一份在 OpenBSD 上使用 httpd 和 WireGuard 通过 VPS 隧道隐藏 IP 来设置自托管网页服务器的逐步指南。
我的自托管实践 | 理想中的自托管指南
作者分享了自己的自托管经验:为何从流媒体转向 Jellyfin,如何通过 VPN/CGNAT 限制服务暴露于公网,偏好原生运行与 Podman/systemd 而非 Docker,并介绍了所用的 Beelink Mini PC 硬件配置。
@DIYgod: 博客更新《全屋隐私网关:用两台 NAS 藏起全家的 IP》 https://diygod.cc/home-gateway/
DIYgod 发布博客,详述用两台 NAS 搭建全屋隐私网关的方案:Surge 主网关与 mihomo 备用网关通过 keepalived/arping 漂移虚拟 IP 实现故障切换,并比较了 WARP、自建 VPS 出口以及 WireGuard 与 SS2022 协议的实测表现。