1. 从一个真实需求说起:为什么自建 DNS 解析服务
很多做后端或运维的朋友都遇到过这样的场景:内网有一批服务需要互相调用,用 IP 直连吧,改一次地址就要翻遍所有配置文件;用公网域名吧,解析延迟高不说,流量还绕了一圈公网。这时候,自建一套 DNS 解析服务就成了刚需。
我最早接触 DNS 服务搭建,是因为一个内部测试环境的需求。当时团队有十几台机器,跑着各种微服务和中间件,每次环境迁移或者扩容,光是改 hosts 文件就让人崩溃。后来想着干脆搭一个内部 DNS,把所有服务名统一管理起来,谁需要解析就指向这台 DNS 服务器。试过几种方案之后,最终选定了 Windows Server 自带的 DNS 服务角色,原因很简单:图形化界面友好、和现有域环境集成度高、维护成本低。
这篇文章要聊的,就是围绕 Windows Server 上 DNS 服务的完整实战过程。从角色安装、区域规划、记录管理,到转发器配置、条件转发、排错思路,我会把整个链路拆开揉碎讲清楚。不管你是刚接触 DNS 的新手,还是想系统梳理一遍的老手,应该都能从中找到有用的东西。文章里涉及的操作步骤和参数配置,都来自实际项目中的反复验证,不是照搬文档。
2. 安装 DNS 服务角色前的规划工作
2.1 先想清楚:这台 DNS 服务器扮演什么角色
在动手安装之前,有一个问题必须先回答:这台 DNS 服务器是只服务于内网解析,还是同时要承担公网域名解析?这个定位直接决定了后续的配置策略。
如果只做内网解析,那它就是一台纯粹的内部 DNS 服务器,只需要创建正向查找区域,把内部服务名和 IP 的对应关系维护好就行。客户端把 DNS 指向它,所有内部域名都能解析,外部域名通过转发器交给上游 DNS 处理。
如果还要承担公网解析,那就涉及到权威 DNS 的概念了。你需要为某个公网域名创建区域,配置 SOA、NS、A 记录等,还要考虑和域名注册商的对接。这种场景一般企业用得少,除非是自己管理域名解析。
我建议大部分内部场景就按第一种来规划,简单、可控、不容易出问题。下面要讲的也是以内部 DNS 为主,公网解析的部分会简单提一下思路。
2.2 网络拓扑和 IP 规划
DNS 服务器的 IP 地址必须是静态的,这一点没有商量余地。如果 DNS 服务器自己都用动态 IP,那客户端配置的 DNS 地址过一段时间就失效了,整个解析链路直接崩掉。
假设我们有一台 Windows Server,IP 规划如下:
| 项目 | 值 | 说明 |
|---|---|---|
| 服务器 IP | 192.168.10.10 | 静态地址 |
| 子网掩码 | 255.255.255.0 | 标准 C 类 |
| 网关 | 192.168.10.1 | 出口设备 |
| DNS 服务器自身 DNS | 127.0.0.1 | 指向自己 |
| 备用 DNS | 8.8.8.8 | 上游公共 DNS |
这里有个细节值得说一下:DNS 服务器自己的 DNS 地址应该指向自己(127.0.0.1 或本机 IP),而不是直接填上游 DNS。原因在于,如果指向外部,那么本机在解析内部域名时就会去问外部服务器,结果当然是解析失败。指向自己之后,内部域名由本地区域负责解析,外部域名通过转发器转发出去,逻辑才闭环。
2.3 区域命名的选择:内部域名用什么后缀
内部域名的后缀选择是个容易被忽视但影响深远的问题。常见的有几种做法:
- 用
internal.xxx.com这种子域名形式,好处是不会和公网域名冲突,坏处是名字比较长。 - 用
xxx.local这种本地后缀,简单好记,但要注意某些场景下.local会和 mDNS 冲突。 - 直接用单标签名字,比如
server1、db,不带后缀,解析的时候直接写主机名就行。
我个人比较推荐用internal.xxx.com这种形式,结构清晰,不容易和外部域名混淆。如果团队规模小、服务不多,用单标签名字也完全可以,配置起来更省事。
3. 安装与基础配置的完整操作链路
3.1 通过服务器管理器添加 DNS 角色
安装过程本身不复杂,但有几个地方容易踩坑,我一步步说。
打开服务器管理器,点击"添加角色和功能",一路下一步到"服务器角色"页面,勾选DNS 服务器。这时候会弹出一个提示框,告诉你需要一些额外的功能支持,直接点"添加功能"就行。
继续下一步到"确认"页面,点击"安装"。安装完成后,服务器管理器里会出现 DNS 的管理入口。如果你习惯用命令行,也可以用 PowerShell 一条命令搞定:
Install-WindowsFeature -Name DNS -IncludeManagementTools安装完成后,建议重启一下服务器,虽然不重启也能用,但重启能确保所有服务状态正常。
注意:如果这台服务器同时装了 Active Directory 域服务,DNS 角色可能会在域控提升过程中自动安装。这种情况下不需要手动再装一遍,直接配置就行。
3.2 创建正向查找区域
安装完角色之后,打开DNS 管理器,展开服务器节点,右键"正向查找区域",选择"新建区域"。
向导会问你几个问题:
- 区域类型:选"主要区域"。如果这台 DNS 是域控的一部分,并且区域要复制到其他 DNS 服务器,可以勾选"在 Active Directory 中存储区域"。纯内部解析场景下,选主要区域就够了。
- 区域名称:填你规划好的域名,比如
internal.example.com。 - 区域文件:默认会创建一个同名
.dns文件,保持默认即可。 - 动态更新:如果不需要客户端自动注册记录,选"不允许动态更新"。需要的话可以选"仅安全更新"。
创建完成后,在正向查找区域里就能看到这个新区域了。区域里面会自动生成两条记录:SOA 和 NS,这是 DNS 区域的基础记录,不用动它们。
3.3 添加 A 记录和 CNAME 记录
区域建好了,接下来就是往里加记录。右键区域名称,选择"新建主机(A 或 AAAA)"。
举个例子,我们要把db.internal.example.com解析到192.168.10.20:
- 名称填
db - IP 地址填
192.168.10.20 - 勾选"创建相关的指针(PTR)记录"(如果反向区域已经建好)
这样一条 A 记录就加好了。客户端把 DNS 指向这台服务器之后,db.internal.example.com就能解析到对应的 IP。
CNAME 记录用来做别名。比如mysql.internal.example.com是db.internal.example.com的别名,那就新建一条 CNAME,名称填mysql,目标填db.internal.example.com。这样两个名字都能解析到同一个 IP,以后换 IP 只需要改 A 记录,CNAME 不用动。
批量添加记录的时候,用 PowerShell 效率更高:
Add-DnsServerResourceRecordA -Name "db" -ZoneName "internal.example.com" -IPv4Address "192.168.10.20" Add-DnsServerResourceRecordCName -Name "mysql" -ZoneName "internal.example.com" -HostNameAlias "db.internal.example.com"3.4 反向查找区域的建立
反向查找区域的作用是通过 IP 反查域名。很多场景下这个功能不是必须的,但有些应用会依赖反向解析来做日志记录或者访问控制,所以建议还是建上。
右键"反向查找区域",新建区域,选择"主要区域",网络 ID 填192.168.10,向导会自动创建10.168.192.in-addr.arpa这个反向区域。建好之后,添加 PTR 记录,把 IP 和域名对应起来。
如果正向区域添加 A 记录时勾选了"创建相关的指针记录",PTR 会自动生成,不用手动加。
4. 转发器与条件转发的配置策略
4.1 转发器:让内部 DNS 能解析外部域名
内部 DNS 服务器只负责自己区域内的域名解析,那客户端想访问外部网站怎么办?这就需要配置转发器。
在 DNS 管理器里,右键服务器节点,选择"属性",切换到"转发器"选项卡。点击"编辑",添加上游 DNS 服务器的 IP,比如8.8.8.8和114.114.114.114。
配置好之后,当客户端请求解析www.example.com这种外部域名时,内部 DNS 发现自己没有这个区域,就会把请求转发给上游 DNS,拿到结果后再返回给客户端。
这里有个经验:转发器最好配两个以上,避免单个上游 DNS 故障导致解析中断。另外,如果内网有防火墙,要确保 DNS 服务器能正常访问上游 DNS 的 53 端口。
4.2 条件转发:把特定域名交给指定服务器解析
条件转发是转发器的一个精细化版本。它的作用是:只把特定域名的解析请求转发给指定的 DNS 服务器,其他域名还是走默认转发器。
什么场景下会用到?举个例子,公司有两个内网环境,一个是internal.example.com,另一个是test.example.com,分别由不同的 DNS 服务器管理。你希望本地的 DNS 服务器在解析test.example.com时,直接问那台专门的 DNS 服务器,而不是走默认转发器。
配置方法:右键"条件转发器",新建条件转发器,DNS 域名填test.example.com,IP 地址填对应的 DNS 服务器 IP。这样配置之后,所有以test.example.com结尾的解析请求都会转发到指定的服务器。
条件转发的优先级高于默认转发器,所以不用担心冲突问题。
4.3 转发器和条件转发的选择逻辑
很多人搞不清楚什么时候用转发器、什么时候用条件转发。我总结了一个简单的判断标准:
| 场景 | 选择 | 原因 |
|---|---|---|
| 所有外部域名都交给同一组上游 DNS | 转发器 | 配置简单,统一出口 |
| 特定域名需要单独指定 DNS 服务器 | 条件转发 | 精细化控制,互不干扰 |
| 内网多个域之间需要互访 | 条件转发 | 每个域指向各自的 DNS |
| 只想让部分域名走特定线路 | 条件转发 | 按域名分流 |
实际项目中,两者经常是配合使用的:默认转发器负责大部分外部解析,条件转发处理特殊域名的定向解析。
5. 客户端配置与解析验证
5.1 客户端 DNS 指向的配置方式
DNS 服务器搭好了,客户端得知道去哪里解析。配置方式有几种:
- 手动配置:在网络适配器属性里,把 DNS 服务器地址改成内部 DNS 的 IP。适合服务器和固定设备。
- DHCP 下发:如果网络里有 DHCP 服务器,可以在 DHCP 作用域选项里配置 DNS 服务器地址,客户端自动获取。适合大量终端。
- 组策略下发:域环境下,通过组策略统一配置 DNS 设置。适合集中管理的场景。
不管用哪种方式,核心就是让客户端的 DNS 指向这台内部 DNS 服务器。
5.2 用 nslookup 验证解析结果
配置完成后,第一件事就是验证解析是否正常。nslookup是最常用的工具。
nslookup db.internal.example.com如果返回了正确的 IP 地址,说明正向解析没问题。再试试反向解析:
nslookup 192.168.10.20返回对应的域名,说明 PTR 记录也正常。
再验证一下外部域名解析:
nslookup www.example.com如果能正常返回结果,说明转发器配置生效了。
5.3 解析失败的常见原因排查
解析失败的原因有很多,我按排查顺序列一下:
- 客户端 DNS 指向是否正确:先用
ipconfig /all确认 DNS 服务器地址。 - DNS 服务是否运行:在服务器上检查 DNS 服务状态。
- 区域和记录是否存在:在 DNS 管理器里确认记录有没有建错。
- 转发器是否可达:在 DNS 服务器上 ping 一下上游 DNS,确认网络通。
- 防火墙是否放行:DNS 用的是 UDP 53 和 TCP 53,确认防火墙规则。
按照这个顺序排查,大部分问题都能定位到。
6. 日常维护与高频问题处理
6.1 记录的批量管理与清理
DNS 记录用久了会积累很多废弃条目,定期清理很有必要。PowerShell 可以批量导出和删除记录:
# 导出所有 A 记录 Get-DnsServerResourceRecord -ZoneName "internal.example.com" -RRType "A" | Export-Csv "dns_records.csv" -NoTypeInformation # 删除指定记录 Remove-DnsServerResourceRecord -ZoneName "internal.example.com" -Name "old-server" -RRType "A" -Force建议每个月做一次记录审查,把不再使用的记录清理掉,避免解析混乱。
6.2 日志与监控的配置
DNS 服务默认不记录详细日志,出问题的时候不好排查。可以在 DNS 管理器里右键服务器属性,切换到"调试日志"选项卡,勾选"启用调试日志记录",并配置日志文件路径和大小。
不过调试日志会占用磁盘空间,也会影响性能,所以只建议在排查问题时临时开启,问题解决后关掉。
日常监控的话,可以关注几个指标:查询量、失败率、响应时间。Windows 性能监视器里有对应的计数器,可以配置数据收集器集,定期记录。
6.3 区域传输与冗余配置
如果对可用性要求高,可以配置多台 DNS 服务器做冗余。主 DNS 服务器配置区域传输,把区域数据同步到辅助 DNS 服务器。
配置方法:在主 DNS 的区域属性里,切换到"区域传送"选项卡,允许传送到指定的辅助服务器 IP。然后在辅助服务器上新建辅助区域,指定主服务器的 IP,区域数据会自动同步过来。
客户端配置两个 DNS 地址,一个主一个备,主挂了自动切到备,解析不中断。
6.4 几个容易踩的坑
最后分享几个我在实际项目中踩过的坑:
- DNS 服务器自己指向了外部 DNS:导致内部域名解析失败,一定要指向自己。
- 转发器只配了一个:上游 DNS 挂了之后整个解析链路瘫痪,至少配两个。
- 区域名称和公网域名冲突:比如内部用了
example.com,结果外部解析被劫持到内网,访问不了真正的公网服务。内部域名一定要加后缀区分。 - 忘记建反向区域:某些应用依赖反向解析,没有 PTR 记录会导致功能异常。
- 动态更新没关:客户端自动注册了一堆乱七八糟的记录,区域文件越来越乱。不需要动态更新就关掉。
这些问题看起来简单,但真到出故障的时候,往往就是这些细节在作怪。希望这篇内容能帮你在搭建和维护 DNS 服务的时候少走一些弯路。