家庭网络架构实战:软路由、DDNS、域名与备案路径
编写时间:2024-04-18
服务器底座跑起来以后,我遇到的第一个大问题是:这些服务到底怎么从外面访问?如果只是局域网里打开 Docker 页面,事情很简单;但一旦要做博客、媒体库、文件入口和远程管理,就会立刻碰到软路由、DDNS、备案、证书、80/443 端口限制和反向代理。
这一阶段要把“家用动态公网 IP + 软路由 + DDNS + 境内外域名分流”一步步接起来。下面的域名、IP、端口和账号都只写示例值。
总体拓扑
我最后把软路由放在光猫和局域网之间,让它承担拨号、DHCP、端口转发和部分管理入口。服务器只做服务承载,不直接负责家庭网关。这样出问题时也更容易定位:网络问题先看软路由,服务问题再看服务器。
软路由初始化
以 OpenWRT 类软路由为例,建议先单独接电脑完成基础配置:
- 电脑直连软路由 LAN 口;
- 进入默认管理地址,例如
192.168.6.1或固件文档里给出的 LAN 地址; - 配置 WAN 口 PPPoE 拨号;
- 确认 LAN 口 DHCP 范围;
- 再把光猫出线接到软路由 WAN 口。
这套环境里软路由用的是 R5C,购买时已经刷好 OpenWRT 和 GUI。最稳的流程是:先不要接光猫,只让电脑和 R5C 单独成网;进入后台后把上网方式改成拨号;确认可以作为网关之后,再把光猫出来的线接到 R5C 的 WAN 口。
服务器如果换了上游网关,重新获取 DHCP 即可:
nmcli device status
nmcli device show "[interface]"
sudo nmcli device disconnect "[interface]"
sudo nmcli device connect "[interface]"静态 IP 不一定要写在服务器系统里。更推荐在软路由上做 DHCP 绑定,让服务器继续用 DHCP 自动联网:
[server-mac-address] -> 192.168.10.10这样服务器重装系统后也能拿到同一个内网地址,NPM、端口转发和 WireGuard 配置都不需要跟着改。
DNS 与管理入口
DNS 可以在路由器侧统一设置。例如境外解析用 1.1.1.1,境内解析用运营商或公共 DNS。服务器侧通常不需要手动写死 /etc/resolv.conf,因为 NetworkManager 会跟随 DHCP 下发的 DNS。
内网设备访问自托管服务时,最好不要绕到公网再回来。可以在软路由上做 Host override、内网 DNS 或 split-horizon DNS,让 service.example.net 在家里解析到服务器 LAN IP,在外面再解析到公网入口。这一步不是必需,但会明显减少内网访问延迟,也能避免部分运营商环境下的 NAT 回环问题。
管理页面不要直接裸露到公网。我的处理方式基本是放到 Cloudflare Application / Zero Trust 后面:
| 入口 | 使用场景 |
|---|---|
| Cloudflare Zero Trust | 浏览器访问管理后台、SSH Web、OpenWRT / NPM / Cockpit |
| 端口转发 | 仅开放必要公网服务 |
| WireGuard | 伪局域网联机、异地设备互通、远控实验 |
软路由后台、NPM 管理页、Portainer、Cockpit 这类入口优先放在 Zero Trust 后面。WireGuard 不是这里的主方案,它更多是后面用来组虚拟局域网。
如果要把 OpenWRT 管理页挂到 Cloudflare Zero Trust,可以在软路由上跑 cloudflared。OpenWRT 上直接安装不顺时,也可以用 Docker 跑,但要注意网络位置:Cloudflare 面板里如果指向软路由本机的 localhost,容器要使用 host network;否则就直接把 Public Hostname 指到软路由的 LAN IP 和管理端口。
docker run -d \
--network host \
--name cloudflared \
--restart always \
cloudflare/cloudflared:latest \
tunnel --no-autoupdate run --token [cloudflare-tunnel-token]DDNS 的位置
家用公网 IP 是动态的,DDNS 的作用是把变化的公网 IP 更新到固定域名。可以让软路由或服务器运行 DDNS 客户端,例如 ddns-go。DNS 服务商的 API 凭据只填在 DDNS 客户端里,不进入文章、仓库或长期公开笔记。
建议使用子域名承接动态 IP:
ddns.example.cn A [当前动态公网 IP]
*.home.example.cn CNAME ddns.example.cn根域名不要直接交给 DDNS,尤其是需要备案或固定展示页的场景。根域名承担身份和备案,子域名承担动态服务入口,职责更清楚。
验证链路可以分三步:
| 步骤 | 期望结果 |
|---|---|
| DNS 控制台 | ddns.example.cn 被 ddns-go 更新为当前公网 IP |
| 直接访问 | ddns.example.cn:[port] 和 [public-ip]:[port] 等效 |
| 端口转发 | service.example.cn:[port] 能进入服务器上的 NPM |
如果第一步成功而第三步失败,问题通常在软路由端口转发或服务器防火墙;如果第一步就失败,再看 DDNS 客户端、API 权限和公网 IP 获取方式。
端口转发与 80/443 限制
很多家用宽带会限制 80 和 443。可选方案大概有三类:
| 方案 | 优点 | 代价 |
|---|---|---|
| 带端口访问 | 最简单、链路短、成本低 | URL 不够漂亮 |
| 云服务器反代 | 可以使用标准 80/443 | 带宽和转发速度受云服务器限制 |
| Cloudflare Tunnel | 不需要公网 IP,配置方便 | 国内访问可能绕路 |
| 隐性 URL / iframe | 配置门槛低 | 协议、SEO、体验和跨站限制都不理想 |
实际使用里,带端口访问是最直接的起步方案:
| 外部入口 | 转发目标 | 用途 |
|---|---|---|
[公网 IP]:8443 | [服务器 LAN IP]:443 | HTTPS 服务入口 |
[公网 IP]:8880 | [服务器 LAN IP]:80 | HTTP 服务入口 |
[公网 IP]:51820/udp | [服务器 LAN IP]:51820/udp | WireGuard 虚拟局域网 |
如果 URL 必须不带端口,就需要固定 IP 机器或云服务器做前置反代;否则带端口是成本最低、链路最短的方案。
端口转发和 DNS 可以这样组合:
@.example.cn A [fixed-public-ip]
ddns.example.cn A [dynamic-public-ip]
*.home.example.cn CNAME ddns.example.cnWAN 8443 -> server-lan-ip:443
WAN 8880 -> server-lan-ip:80
WAN 51820/udp -> server-lan-ip:51820/udpNPM 再根据 Host 分发:
app.home.example.cn -> app-container:2333
blog.home.example.cn -> shiro:2323
api.home.example.cn -> mx-server:2333域名分层
实践里可以把域名分成两类:
| 域名 | 角色 | 流量路径 |
|---|---|---|
home.example.net | 境外/免备案入口 | Cloudflare Tunnel 回源 |
home.example.cn | 境内/备案入口 | DDNS 或固定 IP 前端 |
api.example.net | 后端 API | Cloudflare Tunnel 或反代 |
ddns.example.cn | 动态公网 IP 记录 | DDNS 客户端更新 |
我的拆法是:境外域名更适合交给 Cloudflare,处理 Tunnel、Zero Trust 和免公网 IP 入口;境内域名更适合保留备案身份、固定 IP 展示页和 DDNS 直连入口。必要时可以在前端或网关层把境内访问导向 example.cn,把境外访问留在 example.net。
Cloudflare Tunnel 更像一条入口隧道。它适合把 blog.example.net、api.example.net 这类 Host 打到服务器的 NPM,再由 NPM 按域名分发。不要期待 cloudflared 自己完成复杂的路径分流,例如把 /socket.io 或 /proxy/admin 单独映射到不同后端;这类规则交给 Nginx 或应用层更清晰。
备案理解
这里是 2024-05 搭建时形成的工程理解,具体规则仍应以接入商和最新监管要求为准。备案关注的是“域名解析到境内公网 IP”这件事。一个实用策略是:根域名绑定固定 IP 完成备案,实际高流量服务通过子域名和 DDNS 指回家用宽带。
这个判断来自几个前提:
| 前提 | 对架构的影响 |
|---|---|
| 家用宽带通常是动态公网 IP | 需要 DDNS 或 Tunnel |
| 固定公网 IP 稀缺且专线昂贵 | 不适合把所有服务都压到固定 IP |
| 国内云服务器带宽和流量成本高 | 只适合做轻量入口或备案展示 |
| 家庭服务器在境内网络里访问更快 | 高流量内容更适合走家宽直连 |
这不是为了绕开规则,而是为了把身份确认和流量承载拆开:
| 部分 | 作用 |
|---|---|
| 固定 IP 机器 | 备案展示、标准 80/443、轻量前端 |
| 家庭服务器 | 真正承载后端、媒体、文件和容器 |
| DDNS | 动态公网 IP 跟踪 |
| NPM | 按 Host 分发到具体服务 |
如果没有动态公网 IP,可以选择 Cloudflare Tunnel 或自建内网穿透。前者配置简单,后者可控性更高,但都要接受链路绕行带来的延迟。
Nginx Proxy Manager 的位置
NPM 是这套家庭网络里的 Web 入口。它不应该存放业务数据,只负责:
- 按域名反代到容器服务;
- 管理 Let's Encrypt 证书;
- 统一 WebSocket、缓存、SSL 相关配置;
- 和 Docker 共享网络,用容器名做 upstream。
Domain Names = app.example.net
Scheme = http
Forward Host = service-container
Forward Port = 2333
WebSocket = enabled对于 Cloudflare Tunnel 入口,外部 HTTPS 可以由 Cloudflare 终结,NPM 内部走 HTTP 即可。对于固定 IP 入口,NPM 负责 Let's Encrypt 证书签发和续期。
这套记录沿用当时的 NPM 方案,因为面板上手快;如果已经熟悉 Nginx,直接写配置会更自由,复杂路径分流和 header 处理也更可控。
小结
家庭网络的核心是把几条入口拆清楚:
| 入口 | 适合场景 |
|---|---|
| DDNS + 端口转发 | 高流量、低成本、能接受端口 |
| Cloudflare Tunnel | 管理后台、境外入口、无公网 IP |
| 固定 IP 前端 | 备案域名、标准 HTTPS、轻量展示 |
| WireGuard | 伪局域网、异地设备互通 |
只要 DNS、端口转发、反向代理和服务容器各守各的边界,后面新增服务基本就是“加 Compose + 加 NPM 规则”。