Windows DNS 按客户端网段返回不同地址教程
1. 需求说明
在 DNS 服务器 example 上,为域名 llm.example.com 配置按来源网段返回不同 IPv4 地址:
| 客户端源地址 | 返回地址 |
|---|---|
10.28.10.0/24 |
192.168.1.200 |
| 其他来源 | 保持原配置 192.168.1.100 |
现有 DNS 区域:
example.com
现有普通区域中的 A 记录:
llm.example.com. A 192.168.1.100
实现方式是使用 Windows DNS Policy 的:
- Client Subnet:定义客户端网段;
- Zone Scope:为指定来源保存专用解析记录;
- Query Resolution Policy:将匹配的客户端请求导向专用 Zone Scope。
2. 前置条件
请在具有 DNS 管理权限的 PowerShell 中执行,建议使用管理员权限。
服务器名称:
example
确认 DNS 区域存在:
Get-DnsServerZone -ComputerName "example" -Name "example.com"
确认原始 A 记录:
Get-DnsServerResourceRecord -ComputerName "example" -ZoneName "example.com" -Name "llm"
预期原始记录为 192.168.1.100。执行修改前建议记录 TTL、主机名和原始地址,便于回滚。
3. 创建客户端子网对象
先检查名称为 vdi 的客户端子网是否存在:
Get-DnsServerClientSubnet -ComputerName "example" -Name "vdi" | Format-List Name,IPv4Subnet
如果没有输出,则创建:
Add-DnsServerClientSubnet -ComputerName "example" -Name "vdi" -IPv4Subnet "10.28.10.0/24"
确认配置:
Get-DnsServerClientSubnet -ComputerName "example" -Name "vdi" | Format-List Name,IPv4Subnet
预期输出:
Name : vdi
IPv4Subnet : {10.28.10.0/24}
其中 EQ 表示 Equal,即“等于”。例如 EQ,vdi 表示客户端必须匹配名为 vdi 的客户端子网。
4. 创建 Zone Scope
检查专用作用域是否存在:
Get-DnsServerZoneScope -ComputerName "example" -ZoneName "example.com"
如果列表中没有 vdiscope,则创建:
Add-DnsServerZoneScope -ComputerName "example" -ZoneName "example.com" -Name "vdiscope"
5. 写入专用 A 记录
先查询专用作用域中的记录:
Get-DnsServerResourceRecord -ComputerName "example" -ZoneName "example.com" -ZoneScope "vdiscope" -Name "llm"
如果没有 llm 记录,创建:
Add-DnsServerResourceRecordA -ComputerName "example" -ZoneName "example.com" -ZoneScope "vdiscope" -Name "llm" -IPv4Address "192.168.1.200" -TimeToLive 01:00:00
如果提示资源已存在,例如 WIN32 9711,不要再次添加,先删除专用作用域中的旧记录,再创建正确记录:
Remove-DnsServerResourceRecord -ComputerName "example" -ZoneName "example.com" -ZoneScope "vdiscope" -Name "llm" -RRType "A" -Force; Add-DnsServerResourceRecordA -ComputerName "example" -ZoneName "example.com" -ZoneScope "vdiscope" -Name "llm" -IPv4Address "192.168.1.200" -TimeToLive 01:00:00
确认专用作用域记录:
Get-DnsServerResourceRecord -ComputerName "example" -ZoneName "example.com" -ZoneScope "vdiscope" -Name "llm"
预期地址:
192.168.1.200
6. 创建查询解析策略
先检查区域级策略:
Get-DnsServerQueryResolutionPolicy -ComputerName "example" -ZoneName "example.com" -Name "llm-vdi-policy" | Format-List *
如果没有输出,创建策略:
Add-DnsServerQueryResolutionPolicy -ComputerName "example" -ZoneName "example.com" -Name "llm-vdi-policy" -Action ALLOW -ClientSubnet "EQ,vdi" -Fqdn "EQ,llm.example.com" -ZoneScope "vdiscope,1" -ProcessingOrder 1 -PassThru
参数含义:
| 参数 | 含义 |
|---|---|
-ClientSubnet "EQ,vdi" |
只匹配客户端子网 vdi |
-Fqdn "EQ,llm.example.com" |
只匹配指定完整域名 |
-ZoneScope "vdiscope,1" |
将请求导向 vdiscope,权重为 1 |
-Action ALLOW |
允许该匹配请求继续解析 |
-ProcessingOrder 1 |
设置策略处理顺序 |
如果提示策略已存在,例如“策略 llm-vdi-policy 已存在”,说明创建步骤已经完成,不要重复添加,直接执行验证命令。
7. 验证配置对象
7.1 验证策略状态
Get-DnsServerQueryResolutionPolicy -ComputerName "example" -ZoneName "example.com" -Name "llm-vdi-policy" | Format-List *
关键输出应包括:
IsEnabled : True
Level : Zone
Name : llm-vdi-policy
ProcessingOrder: 1
ZoneName : example.com
7.2 验证匹配条件和目标作用域
$p=Get-DnsServerQueryResolutionPolicy -ComputerName "example" -ZoneName "example.com" -Name "llm-vdi-policy"; $p.Criteria | Format-List *; $p.Content | Format-List *
预期看到:
Criteria : EQ,vdi
CriteriaType : ClientSubnet
Criteria : EQ,llm.example.com.
CriteriaType : Fqdn
ScopeName : vdiscope
Weight : 1
7.3 验证专用作用域记录
Get-DnsServerResourceRecord -ComputerName "example" -ZoneName "example.com" -ZoneScope "vdiscope" -Name "llm"
预期为:
192.168.1.200
8. 从客户端验证实际解析结果
必须从实际源地址属于 10.28.10.0/24 的客户端执行,不能只在 DNS 服务器本机验证。
在目标网段客户端执行:
Clear-DnsClientCache; Resolve-DnsName -Name "llm.example.com" -Server "example" -Type A -DnsOnly
预期返回:
192.168.1.200
在其他网段客户端执行相同命令,预期仍返回默认区域记录:
192.168.1.100
如果客户端使用了 DNS 缓存,也可以使用:
Clear-DnsClientCache; Resolve-DnsName -Name "llm.example.com" -Server "example" -Type A -DnsOnly -NoHostsFile
9. 故障排查
9.1 查询策略为空
服务器级查询可能没有输出,因为该策略是区域级策略。请使用带区域参数的命令:
Get-DnsServerQueryResolutionPolicy -ComputerName "example" -ZoneName "example.com"
9.2 添加策略提示已存在
使用以下命令读取现有策略:
Get-DnsServerQueryResolutionPolicy -ComputerName "example" -ZoneName "example.com" -Name "llm-vdi-policy" | Format-List *
不要重复执行 Add-DnsServerQueryResolutionPolicy。
9.3 添加记录提示资源已存在
说明 vdiscope 已有同名记录。先查询:
Get-DnsServerResourceRecord -ComputerName "example" -ZoneName "example.com" -ZoneScope "vdiscope" -Name "llm"
确认确实需要替换后,再执行第 5 节中的删除并重建命令。
9.4 目标客户端仍解析到旧地址
依次检查:
- 客户端实际源 IP 是否属于
10.28.10.0/24; - 客户端使用的 DNS 服务器是否为
example; vdi是否仍包含10.28.10.0/24;- 策略是否为
IsEnabled : True; - FQDN 是否为
llm.example.com.; - 是否清除了客户端 DNS 缓存。
快速检查命令:
Get-DnsServerClientSubnet -ComputerName "example" -Name "vdi" | Format-List *; Get-DnsServerQueryResolutionPolicy -ComputerName "example" -ZoneName "example.com" -Name "llm-vdi-policy" | Format-List *; Get-DnsServerResourceRecord -ComputerName "example" -ZoneName "example.com" -ZoneScope "vdiscope" -Name "llm"
10. 回滚方案
回滚前确认只删除本次创建的对象:llm-vdi-policy、vdiscope 中的 llm 记录,以及必要时的 vdiscope 和 vdi 对象。
10.1 只停用策略
Set-DnsServerQueryResolutionPolicy -ComputerName "example" -ZoneName "example" -Name "llm-vdi-policy" -IsEnabled $false
停用后,所有来源将回到默认区域记录 192.168.1.100。
10.2 删除策略
Remove-DnsServerQueryResolutionPolicy -ComputerName "example" -ZoneName "example.com" -Name "llm-vdi-policy" -Force
10.3 删除专用记录和作用域
Remove-DnsServerResourceRecord -ComputerName "example" -ZoneName "example.com" -ZoneScope "vdiscope" -Name "llm" -RRType "A" -Force; Remove-DnsServerZoneScope -ComputerName "example" -ZoneName "example.com" -Name "vdiscope" -Force
10.4 删除客户端子网对象(仅确认没有其他策略使用时)
Remove-DnsServerClientSubnet -ComputerName "example" -Name "vdi" -Force
不要删除默认区域中的 llm 记录;它应继续保持:
192.168.1.100
浙公网安备 33010602011771号