家庭网络架构实战:软路由、DDNS、域名与备案路径

2024 年 4 月 18 日 星期四(已编辑)
/ , , , , ,
5
摘要
服务器服务要从外网访问后,网络问题会从 Docker 延伸到软路由、DDNS、端口转发、Cloudflare Tunnel、Zero Trust、NPM 和备案域名。记录 R5C/OpenWRT 初始化、动态公网 IP 绑定、80/443 受限后的取舍,以及境内外域名分层。

阅读此文章之前,你可能需要首先阅读以下的文章才能更好的理解上下文。

家庭网络架构实战:软路由、DDNS、域名与备案路径

编写时间:2024-04-18

服务器底座跑起来以后,我遇到的第一个大问题是:这些服务到底怎么从外面访问?如果只是局域网里打开 Docker 页面,事情很简单;但一旦要做博客、媒体库、文件入口和远程管理,就会立刻碰到软路由、DDNS、备案、证书、80/443 端口限制和反向代理。

这一阶段要把“家用动态公网 IP + 软路由 + DDNS + 境内外域名分流”一步步接起来。下面的域名、IP、端口和账号都只写示例值。

总体拓扑

我最后把软路由放在光猫和局域网之间,让它承担拨号、DHCP、端口转发和部分管理入口。服务器只做服务承载,不直接负责家庭网关。这样出问题时也更容易定位:网络问题先看软路由,服务问题再看服务器。

软路由初始化

以 OpenWRT 类软路由为例,建议先单独接电脑完成基础配置:

  1. 电脑直连软路由 LAN 口;
  2. 进入默认管理地址,例如 192.168.6.1 或固件文档里给出的 LAN 地址;
  3. 配置 WAN 口 PPPoE 拨号;
  4. 确认 LAN 口 DHCP 范围;
  5. 再把光猫出线接到软路由 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]:443HTTPS 服务入口
[公网 IP]:8880[服务器 LAN IP]:80HTTP 服务入口
[公网 IP]:51820/udp[服务器 LAN IP]:51820/udpWireGuard 虚拟局域网

如果 URL 必须不带端口,就需要固定 IP 机器或云服务器做前置反代;否则带端口是成本最低、链路最短的方案。

端口转发和 DNS 可以这样组合:

@.example.cn          A      [fixed-public-ip]
ddns.example.cn       A      [dynamic-public-ip]
*.home.example.cn     CNAME  ddns.example.cn
WAN 8443 -> server-lan-ip:443
WAN 8880 -> server-lan-ip:80
WAN 51820/udp -> server-lan-ip:51820/udp

NPM 再根据 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后端 APICloudflare Tunnel 或反代
ddns.example.cn动态公网 IP 记录DDNS 客户端更新

我的拆法是:境外域名更适合交给 Cloudflare,处理 Tunnel、Zero Trust 和免公网 IP 入口;境内域名更适合保留备案身份、固定 IP 展示页和 DDNS 直连入口。必要时可以在前端或网关层把境内访问导向 example.cn,把境外访问留在 example.net

Cloudflare Tunnel 更像一条入口隧道。它适合把 blog.example.netapi.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 入口。它不应该存放业务数据,只负责:

  1. 按域名反代到容器服务;
  2. 管理 Let's Encrypt 证书;
  3. 统一 WebSocket、缓存、SSL 相关配置;
  4. 和 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 规则”。

使用社交账号登录

  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...