怎么设置局域网和公网的域名解析。比如我想同一个域名,比如host1.example.com, 在局域网指向192.168.0.1 ,在公网指向202.96.199.133
AI的回答:
这是个挺实际的问题,尤其是在需要同时管理局域网和公网访问的场景。你可以通过结合DNS配置和本地hosts文件,实现“同一个域名在不同环境指向不同IP”的目标。
下面我详细讲一下方案:
方案一:利用DNS服务器,实现“多环境域名解析”
1. 在公网DNS管理平台添加记录
- 在你的域名(比如
example.com
)的公共DNS(通常在域名注册商提供的控制台):- 添加 A 记录:
host1.example.com
指向 公网IP:202.96.199.133
- 添加 A 记录:
2. 在局域网内搭建DNS解析服务(可选)
- 如果局域网内有自己的DNS服务器(比如dnsmasq、bind等),可以配置局域网DNS:
- 添加 A 记录:
host1.example.com
指向 局域网IP:192.168.0.1
- 添加 A 记录:
- 然后在局域网内的所有设备的DNS设置中,指向你局域网的DNS服务器。
3. 客户端配置
- 在局域网内部:设备解析
host1.example.com
时,会使用局域网DNS,指向192.168.0.1
- 在公网环境:访问时,会用到公共DNS,指向公网IP
202.96.199.133
总结:如果你控制DNS服务器(比如公司内部网络的DNS),可以实现一切自动切换。
方案二:单一且简单 — 使用hosts文件(适合少数几台设备)
- 局域网设备:编辑
/etc/hosts
(Linux、macOS)或C:\Windows\System32\drivers\etc\hosts
(Windows):
192.168.0.1 host1.example.com
- 公网设备(或自己用的服务器):不要改hosts(否则会锁死),或者在对应设备的hosts中加:
202.96.199.133 host1.example.com
- 限制:这种方式只适合管理少数设备,不适合大规模。
方案三:利用动态DNS(DDNS)和分级解析
- 你可以使用支持动态DNS的服务(比如
Cloudflare
、DuckDNS
等):- 公网:通过动态DNS解析到你的公网IP
- 局域网:自己搭建DNS解析或内部hosts
核心:“智能切换” 核心点在于 DNS
- 最专业方案:在公司/个人的网络中部署自己的分级DNS:
- 内部解析
host1.example.com
指向内网IP - 公共解析指向公网IP
- 内部解析
- 这样,所有设备都会根据自身网络环境,得到对应的正确IP。
小结
场景 | 方法 | 关键操作 |
---|---|---|
企业或有自己DNS | 搭建局域网DNS,内部解析不同IP | 配置局域网DNS,指向不同目标 |
只修改设备hosts | 在局域网设备配置hosts | 只适合少数设备,手动维护 |
使用公共DNS+内部DNS结合 | 在域名管理平台上设置公网记录,局域网中用内部DNS解析 | 这是最优方案 |
如果需要,我可以帮你写一份更具体的配置方案,或者推荐用什么软件搭建局域网DNS服务器。
在公司/个人的网络中部署自己的分级DNS
在公司/个人网络里部署 分级(Split‑Horizon) DNS
目标:同一个域名在内网解析到内网 IP(192.168.0.1),在公网解析到公网 IP(202.96.199.133),而且外部用户只看到公网记录,内部用户可以看到内网记录。
下面提供 两套实现方案
1️⃣ BIND9(最通用、功能最完整) – 通过 views 实现真正的分级 DNS。
2️⃣ dnsmasq(轻量、适合小型/家庭网络) – 只需要一份配置文件,功能也足够。
后面会给出 完整的安装、配置、验证、常见问题,以及 安全/运维要点,帮助你一步步把它搭建起来。
目录
章节 | 内容 |
---|---|
1️⃣ 前置准备 | 了解需求、准备域名、决定 DNS 架构 |
2️⃣ BIND9 方案 | 安装、ACL/View 配置、内外区文件、测试 |
3️⃣ dnsmasq 方案 | 安装、简单配置、测试 |
4️⃣ 客户端配置 | DHCP 推送、手动配置、分辨内外网 |
5️⃣ 监控 & 日志 | 常用检查、日志分析 |
6️⃣ 常见故障排查 | “外部仍返回内网 IP”等典型问题 |
7️⃣ 安全 & 运维建议 | 防止缓存投毒、DNSSEC、备份、更新 |
8️⃣ 小结 & 关键命令 | 快速回顾 |
1️⃣ 前置准备
项目 | 说明 |
---|---|
域名 | 必须拥有 example.com (或你自己的顶级域)并能在注册商处添加/编辑 DNS 记录。 |
公网 DNS | 建议把 外部 区域交给公网 DNS(如 Cloudflare、阿里云 DNS、腾讯 DNS)进行托管,只在内部 部署权威 DNS。 |
内部网络 | 假设内部网段为 192.168.0.0/16 (或其他) |
服务器 | 至少一台 Linux(推荐 Ubuntu 20.04+、CentOS 8+)作为内部 DNS;如果担心单点,可采用主从结构。 |
防火墙 | 只放通 53/tcp、53/udp 给内部网络;外部不允许直接访问内部 DNS,防止信息泄露。 |
注:如果你只想在 本地(单机或几个设备)使用分级 DNS,也可以直接在该机器上跑 dnsmasq 而不必装 BIND。
2️⃣ BIND9 方案(推荐)
2.1 安装 BIND
Ubuntu / Debian
sudo apt update
sudo apt install bind9 bind9utils bind9-doc
CentOS / RHEL
sudo yum install bind bind-utils
安装后默认会启动
named
(BIND 服务器),监听127.0.0.1
与本机所有网卡的53
端口。
2.2 定义内部网络 ACL
编辑 /etc/bind/named.conf.local
(或 /etc/named.conf
视发行版而定),加入:
acl "internal_clients" {
192.168.0.0/16; // 你的内部网络
localhost; // 本机
};
2.3 配置 View(视图)
View 1 – internal(内部视图)
view "internal" {
match-clients { internal_clients; };
recursion yes; // 允许内部递归查询
zone "example.com" IN {
type master;
file "/etc/bind/db.example.com.internal";
};
// 如果需要反向解析也可以加
zone "0.168.192.in-addr.arpa" IN {
type master;
file "/etc/bind/db.192.168.rev";
};
};
View 2 – external(外部视图)
view "external" {
match-clients { any; }; // 所有非 internal 的客户端
recursion no; // 只做权威答复
zone "example.com" IN {
type master;
file "/etc/bind/db.example.com.external";
};
};
关键点
match-clients
必须放在view
最前面,BIND 会先匹配内部视图,再匹配外部视图。recursion yes
仅给内部客户端,防止外部使用你的内部 DNS 进行缓存投毒。
2.4 创建区文件(Zone Files)
2.4.1 内部区:/etc/bind/db.example.com.internal
$TTL 300
@ IN SOA ns1.example.com. admin.example.com. (
2024090101 ; Serial(每次改动记得递增)
7200 ; Refresh
1800 ; Retry
1209600 ; Expire
300 ) ; Minimum TTL
IN NS ns1.example.com.
ns1 IN A 192.168.0.1 ; 内部 DNS 本机 IP(可选)
host1 IN A 192.168.0.1 ; 内网 IP
www IN CNAME host1
2.4.2 外部区:/etc/bind/db.example.com.external
$TTL 300
@ IN SOA ns1.example.com. admin.example.com. (
2024090101 ; Serial(与内部同步递增)
7200
1800
1209600
300 )
IN NS ns1.example.com.
ns1 IN A 202.96.199.133 ; 公开的 DNS 服务器 IP(如果是同一台机器,填公网 IP)
host1 IN A 202.96.199.133 ; 公网 IP
www IN CNAME host1
提示:如果你希望外部 DNS 托管在 Cloudflare 等云平台,只需要在该平台上创建相同的 A 记录即可;BIND 只保留内部视图即可。
2.5 检查语法并重启 BIND
# 检查配置文件语法
sudo named-checkconf
# 检查每个 zone 文件
sudo named-checkzone example.com /etc/bind/db.example.com.internal
sudo named-checkzone example.com /etc/bind/db.example.com.external
# 重载(不掉线)
sudo systemctl reload bind9 # Ubuntu/Debian
# 或者
sudo systemctl reload named # CentOS/RHEL
如果一切正常,systemctl status bind9
会显示 active (running)。
2.6 用 dig
验证
在内部网络(如 192.168.0.10)
dig @192.168.0.1 host1.example.com +short
# 预期输出:192.168.0.1
dig @192.168.0.1 example.com NS +short
# 预期输出:ns1.example.com.
在外部(或用公网 IP 访问)
dig @202.96.199.133 host1.example.com +short
# 预期输出:202.96.199.133
dig @8.8.8.8 host1.example.com +short
# 如果你把外部 A 记录放在 Cloudflare,输出应为 202.96.199.133
如果外部仍返回 192.168…,说明外部客户端根本没有走外部视图(可能 DNS 缓存或客户端仍使用内部 DNS)。请检查 客户端 DNS 配置 与 防火墙。
3️⃣ dnsmasq 方案(轻量级)
3.1 安装
sudo apt install dnsmasq # Debian/Ubuntu
# 或
sudo yum install dnsmasq # CentOS/RHEL
dnsmasq
默认会监听本机 127.0.0.1
,我们把它配置为 内部 DNS(仅内部网络使用)。
3.2 配置文件
编辑 /etc/dnsmasq.conf
(或新建 /etc/dnsmasq.d/custom.conf
):
# 只接受内部网段请求
listen-address=127.0.0.1,192.168.0.1
bind-interfaces
interface=eth0 # 替换为你的网卡名
# 返回内部 IP 的记录(优先级最高)
address=/host1.example.com/192.168.0.1
address=/www.example.com/192.168.0.1
# 若要让外部查询仍走公网 DNS(如上游 8.8.8.8),配置上游 DNS
server=8.8.8.8
server=8.8.4.4
3.3 启动 & 测试
sudo systemctl restart dnsmasq
dig @192.168.0.1 host1.example.com +short
# 应输出 192.168.0.1
- 外部用户不使用
dnsmasq
,只会查询公网 DNS(在 Cloudflare/阿里云等平台上已经配置了host1.example.com -> 202.96.199.133
),因此不需要额外的外部视图。
适用场景:家庭/小型办公室、没有专门 DNS 服务器的情况下,只需要让内部设备通过 DHCP 拉取
192.168.0.1
作为首选 DNS。
4️⃣ 客户端(终端、电脑、手机)如何获取正确的 DNS
方法 | 说明 |
---|---|
DHCP 推送 | 在路由器或 DHCP 服务器中,把 dns-server = 192.168.0.1 (内部 DNS)作为 首选,第二 DNS 指向公共 DNS(8.8.8.8)。内网设备默认走内部解析,外网则回退到公网 DNS。 |
手动配置 | 对于不支持 DHCP(如某些服务器),在 /etc/resolv.conf (Linux)或网络设置里手动写 nameserver 192.168.0.1 . |
VPN 场景 | 若用户使用 VPN 访问内网,在 VPN 服务器端配置“推送 DNS”或 push "dhcp-option DNS 192.168.0.1" ,确保 VPN 期间走内部 DNS。 |
移动端 | iOS/Android 如使用 Wi‑Fi,系统会自动读取 DHCP 提供的 DNS;离开 Wi‑Fi 切换到移动网络后会使用运营商 DNS,解析为公网 IP。 |
小技巧:在防火墙上把 外部用户只能访问 53/udp/tcp 为 8.8.8.8、1.1.1.1 等公共 DNS,阻止外部直接访问内部 DNS(
192.168.0.1
),防止信息泄露。
5️⃣ 监控 & 日志
组件 | 常用命令 | 说明 |
---|---|---|
BIND | sudo journalctl -u bind9 -f | 实时查看 named 日志 |
rndc stats + dig @127.0.0.1 bind/stats | 查询查询统计 | |
dnsmasq | sudo journalctl -u dnsmasq -f | 查看 DNS 请求记录 |
sudo tcpdump -n -i eth0 port 53 | 捕获 DNS 包,确认请求来源 | |
外部 DNS | 使用外部监控平台(UptimeRobot、Pingdom)定时 dig @202.96.199.133 host1.example.com | 检查公网解析是否保持正常 |
提醒:生产环境建议开启 DNSSEC(如果上游/云平台支持),并在 named.conf 中添加
dnssec-validation auto;
,防止缓存投毒。
6️⃣ 常见故障排查
症状 | 可能原因 | 排查步骤 |
---|---|---|
外部仍解析到 192.168.x.x | 客户端仍使用内部 DNS,或者公网 DNS 记录未生效 | 1. dig @8.8.8.8 host1.example.com 2. 检查公网域名解析是否已经在云平台更新(propagation) |
内部查询得到 202.96.199.133 | 内部 DNS 未收到客户端请求,或者 view 匹配失败 | 1. dig @192.168.0.1 host1.example.com +trace 2. 检查 named.conf 中 acl 与 match-clients 是否写对 |
DNS 查询返回 “SERVFAIL” | 区文件格式错误、SOA 记录不合法、序列号未递增 | named-checkzone example.com /etc/bind/db.example.com.internal |
内部客户端访问慢 | 递归查询走外部 DNS(因 recursion no ) | 确认 view "internal" 中 recursion yes; 以及 forwarders 是否设置(如果内部没有外部根服务器,需要指向上游) |
外部用户无法解析任何记录 | 外部 zone 不在公网 DNS 管理 | 登录域名注册商控制台,确保 example.com 的 NS 指向你的公网 DNS(或 Cloudflare)并已生效。 |
7️⃣ 安全 & 运维建议
-
最小化开放
- 只允许 内部网段 访问你的内部 DNS (
iptables -A INPUT -p udp --dport 53 -s 192.168.0.0/16 -j ACCEPT
)。 - 外部网络只允许访问 公网 DNS(如果你自建公网 DNS,务必放在 DMZ 并限制递归)。
- 只允许 内部网段 访问你的内部 DNS (
-
防止缓存投毒
allow-recursion { internal_clients; };
(只对内部网开放递归)- 启用 DNSSEC:
dnssec-validation auto;
(在 BIND) - 对
dnsmasq
使用no-poll
、cache-size=0
(若不想缓存外部查询)。
-
区文件更新流程
- 每次修改(例如添加/删除记录)后执行
rndc freeze; rndc reload; rndc thaw
,防止半加载导致错误。 - 自动化:使用 Ansible、Chef、Puppet 统一管理 zone 文件,避免手动错误。
- 每次修改(例如添加/删除记录)后执行
-
备份
tar czf /var/backups/bind-$(date +%F).tar.gz /etc/bind
- 对
dnsmasq
的配置同理。
-
监控
- Prometheus + node_exporter 能收集
bind
的统计(bind_exporter
),再通过 Grafana 可视化查询量、错误率。 - 设置阈值报警:
query_failure_rate > 0.01
触发告警。
- Prometheus + node_exporter 能收集
-
日志轮转
- 在
/etc/logrotate.d/bind9
(或dnsmasq
)加入:
- 在
/var/log/named/*.log {
weekly
rotate 4
compress
missingok
notifempty
create 0640 bind bind
}
8️⃣ 小结 & 常用命令速查
场景 | BIND9 命令 | dnsmasq 命令 | 说明 |
---|---|---|---|
检查语法 | named-checkconf | dnsmasq --test | 确认配置文件没有语法错误 |
检查 zone | named-checkzone example.com /etc/bind/db.example.com.internal | - | 验证 zone 文件 |
重载实例 | systemctl reload bind9 | systemctl restart dnsmasq | 让改动生效 |
查询内部 DNS | dig @192.168.0.1 host1.example.com | dig @192.168.0.1 host1.example.com | 手动指定 DNS 服务器 |
查看日志 | journalctl -u bind9 -f | journalctl -u dnsmasq -f | 实时日志 |
调整防火墙 | iptables -A INPUT -p udp --dport 53 -s 192.168.0.0/16 -j ACCEPT | 同上 | 只允许内部网访问 DNS |
一句话概括:
- **内部 DNS(BIND view 或 dnsmasq)**提供 内部 IP 记录。
- **公网 DNS(云平台或外部 BIND)**提供 公网 IP 记录。
- 通过 DHCP/防火墙 把内部用户指向内部 DNS,外部用户直接走公网 DNS,即可实现同域名不同解析。
如需进一步帮助
- 想在 Windows Server DNS 上实现同样的 Split‑Horizon?我可以提供 PowerShell 脚本示例。
- 想把外部 DNS 完全交给 Cloudflare 并让内部 DNS 自动同步?有
cloudflare API + BIND
的自动化脚本。 - 想要在 Kubernetes 中用 CoreDNS 做分级解析?可以给出
Corefile
示例。
随时告诉我你的具体环境(发行版、是否已有外部 DNS,是否需要高可用),我会帮你生成最适合你的完整配置文件以及部署脚本。祝部署顺利 🚀!