在使用 OpenWrt 配合 Docker 版 Nginx Proxy Manager (NPM) 做反向代理时,经常遇到一个经典痛点:外网访问域名一切正常,但在内网使用域名却无法访问,或者提示“意外终止连接”。
这种情况通常是由 NAT 回流 或 IPv6 优先级 导致的。特别是当 NPM 使用 Macvlan 模式拥有独立 IP 时,我们需要在路由器层面进行“内外网分流解析 (Split DNS)”配置。
本文将介绍如何通过 OpenWrt 的 DNS 设置,三步完美解决此问题。
环境前提
- 路由器系统: OpenWrt
- 反代服务: Nginx Proxy Manager (Docker, Macvlan 模式)
- 现象: 外网访问正常,内网 Ping 域名显示公网 IP 或 IPv6 地址,浏览器无法打开网页。
第一步:确认 NPM 容器的独立 IP
由于使用了 Macvlan 模式,NPM 容器拥有一个独立的局域网 IP(与宿主机/NAS 的 IP 不同)。
- 登录 NPM 后台或查看 Docker 设置,确认 NPM 容器的 独立 IPv4 地址。
- 假设 NPM 容器 IP 为:
192.168.1.10
- 假设 NPM 容器 IP 为:
- 关键点: 确保 NPM 内部的反代配置中,转发目标的 IP 填写的是后端服务的真实 IP(如果是同网段容器,建议直接使用容器 IP),尽量避免填写宿主机 IP,以规避 Macvlan 的通信限制(Host 访问黑洞)。
第二步:配置 OpenWrt 实现“域名劫持”
我们需要强制让内网设备在解析该域名时,直接获取 NPM 的内网 IP,并屏蔽公网 IPv6 解析(防止 Windows/浏览器优先尝试 IPv6 导致连接失败)。
- 登录 OpenWrt 后台,进入 网络 (Network) -> DHCP/DNS。
- 在 常规设置 (General Settings) 底部,找到 “自定义挟持域名” (Addresses) 或 “地址” 列表。
- 添加以下两类规则(假设您的域名为
yourdomain.com):- 规则 A(强制 IPv4 走内网):
- 格式:
/yourdomain.com/192.168.1.10 - 作用:将域名及其所有子域名解析强制指向 NPM 的内网 IP。
- 格式:
- 规则 B(屏蔽 IPv6 解析):
- 格式:
/yourdomain.com/:: - 作用:
::代表 IPv6 空地址。强制告诉客户端“该域名没有 IPv6”,迫使客户端仅使用 IPv4 通道连接内网服务。
- 格式:
- 规则 A(强制 IPv4 走内网):
- 点击页面底部的 保存并应用。
提示: 如果您的 OpenWrt 开启了 “重绑定保护 (Rebind Protection)”,建议在同页面的 “域名白名单 (Domain whitelist)” 中填入你的域名
yourdomain.com,防止路由器拦截内网 IP 的解析结果。
第三步:刷新缓存并验证
配置完成后,电脑或手机可能会缓存之前的 DNS 结果,需要刷新一下。
- 刷新 DNS 缓存:
- Windows: 打开 CMD 运行
ipconfig /flushdns - Mac: 打开终端运行
sudo killall -HUP mDNSResponder
- Windows: 打开 CMD 运行
- 验证测试:
- 在电脑上 Ping 您的域名:
ping yourdomain.com - 成功标准: 返回的 IP 地址必须是
192.168.1.10(NPM 的内网 IP),且不能出现 IPv6 地址。
- 在电脑上 Ping 您的域名:
只要 Ping 出的结果是内网 IP,浏览器即可流畅访问内网服务,且支持 HTTPS!