场景需求: 你有一台物理机(称为物理机A
),并在其上运行了一个虚拟机(称为虚拟机B
),你希望在虚拟机B
上搭建一个DNS服务器(例如使用BIND9),并配置网络,使得物理机A
能够将虚拟机B
作为其首选DNS服务器来解析域名,这通常用于本地开发测试、内部域名解析或学习DNS配置。
核心原理: 关键在于确保物理机A
的网络配置指向虚拟机B
的IP地址作为DNS服务器,并且虚拟机B
上的DNS服务已正确安装、配置、启动,且网络允许物理机A
访问该服务。
配置步骤详解:
第一步:配置虚拟机B的网络(关键:获取稳定IP)
-
网络模式选择:
- 桥接模式 (Bridged): 虚拟机获得物理网络中的一个独立IP(与物理机A同级),这是最推荐的方式,因为物理机A可以直接通过这个IP访问虚拟机B的DNS服务,就像访问网络上的其他设备一样,确保你的网络环境允许分配额外IP。
- NAT模式 + 端口转发: 虚拟机使用私有IP(如192.168.122.x),物理机通过虚拟化软件(如VirtualBox, VMware, KVM/libvirt)的端口转发规则,将物理机A对UDP 53端口的请求转发到虚拟机B的IP和UDP 53端口,配置相对复杂,且可能受限于虚拟化软件的功能。
- 仅主机模式 (Host-Only): 物理机A和虚拟机B在一个私有的、隔离的网络中通信,需要为物理机A和虚拟机B配置该私有网络内的IP地址(例如192.168.56.1和192.168.56.2),物理机A配置DNS指向虚拟机B在此网络中的IP。
-
设置静态IP(强烈推荐):
- 为了避免虚拟机B的IP地址在重启后发生变化导致DNS配置失效,务必在虚拟机B的操作系统中设置静态IP地址。
- 具体设置方法取决于虚拟机B的操作系统(如Ubuntu, CentOS等)和使用的网络管理工具(
netplan
,NetworkManager
,/etc/network/interfaces
),请根据你的系统查找“如何设置静态IP”的指南。 - 假设你为虚拟机B设置了静态IP:
168.1.100
(桥接模式示例) 或168.56.100
(仅主机模式示例)。请记录下这个IP,这是物理机A需要指向的DNS服务器地址。
第二步:在虚拟机B上安装和配置DNS服务(以BIND9为例)
-
安装BIND9:
- Ubuntu/Debian:
sudo apt update sudo apt install bind9 bind9utils bind9-dnsutils -y
- CentOS/RHEL:
sudo yum install bind bind-utils -y
- Ubuntu/Debian:
-
配置主配置文件 (
named.conf
或named.conf.options
):-
主要需要修改监听地址和允许查询的客户端。
-
编辑配置文件(位置可能因发行版而异,常见如
/etc/bind/named.conf.options
(Ubuntu) 或/etc/named.conf
(CentOS))。 -
找到
options { ... }
部分,修改或添加:options { directory "/var/cache/bind"; // Ubuntu默认,CentOS可能是 "/var/named" ... # 允许物理机A查询,根据你的网络环境设置: # a) 允许特定IP (推荐):替换为物理机A的IP allow-query { localhost; 192.168.1.50; }; // 假设物理机A的IP是192.168.1.50 (桥接) # 或 b) 允许整个子网 (测试方便,生产环境慎用):替换为你的子网 # allow-query { localhost; 192.168.1.0/24; }; # 或 c) 允许任何客户端 (仅限测试环境!) # allow-query { any; }; # 监听地址:允许在虚拟机B的所有网络接口上监听DNS请求 listen-on port 53 { any; }; listen-on-v6 port 53 { any; }; # 如果不需要IPv6,可设为 { none; } ... recursion yes; # 允许递归查询(通常需要) ... };
-
-
配置区域文件 (Zone File):
- 你需要至少定义一个正向解析区域(域名 -> IP)和一个反向解析区域(IP -> 域名)。
- 定义区域: 在主配置文件(如
/etc/bind/named.conf.local
(Ubuntu) 或/etc/named.conf
的zone
部分 (CentOS))中添加区域声明。# 正向区域 (example.com -> IP) zone "example.com" IN { type master; file "/etc/bind/zones/db.example.com"; # 指定正向区域文件路径 allow-update { none; }; }; # 反向区域 (192.168.1.x -> 域名) - 根据你的IP网段修改 zone "1.168.192.in-addr.arpa" IN { # 注意IP段要倒着写 (192.168.1 -> 1.168.192) type master; file "/etc/bind/zones/db.192.168.1"; # 指定反向区域文件路径 allow-update { none; }; };
- 创建正向区域文件 (
db.example.com
):sudo mkdir -p /etc/bind/zones # 创建目录 (如果不存在) sudo nano /etc/bind/zones/db.example.com
示例:
$TTL 86400 ; 默认TTL 1天 @ IN SOA ns1.example.com. admin.example.com. ( 2025051501 ; 序列号 (YYYYMMDDNN) 28800 ; 刷新间隔 (8小时) 7200 ; 重试间隔 (2小时) 604800 ; 过期时间 (1周) 86400 ) ; 最小TTL (1天) ; @ IN NS ns1.example.com. ; 本域的DNS服务器 ns1 IN A 192.168.1.100 ; DNS服务器本身的IP (虚拟机B的IP) ; 添加其他主机记录 physicalA IN A 192.168.1.50 ; 物理机A的A记录 www IN A 192.168.1.101 ; 示例Web服务器
- 创建反向区域文件 (
db.192.168.1
):sudo nano /etc/bind/zones/db.192.168.1
示例:
$TTL 86400 @ IN SOA ns1.example.com. admin.example.com. ( 2025051501 28800 7200 604800 86400 ) @ IN NS ns1.example.com. ; PTR记录 (IP -> 域名) 100 IN PTR ns1.example.com. ; 192.168.1.100 -> ns1.example.com 50 IN PTR physicalA.example.com. ; 192.168.1.50 -> physicalA.example.com
-
检查配置语法并重启BIND9:
-
sudo named-checkconf # 检查主配置文件语法 sudo named-checkzone example.com /etc/bind/zones/db.example.com # 检查正向区域 sudo named-checkzone 1.168.192.in-addr.arpa /etc/bind/zones/db.192.168.1 # 检查反向区域
- 如果所有检查都通过(没有报错):
sudo systemctl restart bind9 # Ubuntu # 或 sudo systemctl restart named # CentOS
- 设置开机启动:
sudo systemctl enable bind9 # Ubuntu # 或 sudo systemctl enable named # CentOS
-
-
在虚拟机B上本地测试DNS:
- 临时修改虚拟机B的
/etc/resolv.conf
,将nameserver
指向0.0.1
(localhost) 或168.1.100
(自身IP)。 - 使用
nslookup
或dig
测试解析:nslookup ns1.example.com nslookup www.example.com nslookup 192.168.1.50 # 应解析出physicalA.example.com dig physicalA.example.com @localhost
- 确保解析结果正确,如果失败,检查BIND日志(
/var/log/syslog
或/var/log/messages
)和之前的配置文件、区域文件。
- 临时修改虚拟机B的
第三步:配置物理机A使用虚拟机B作为DNS服务器
- 修改物理机A的网络设置:
- 图形界面 (推荐):
- Windows:进入“控制面板” -> “网络和 Internet” -> “网络和共享中心” -> 点击当前连接 -> “属性” -> 双击“Internet 协议版本 4 (TCP/IPv4)” -> 选择“使用下面的 DNS 服务器地址” -> 在“首选 DNS 服务器”中输入虚拟机B的IP地址(
168.1.100
)-> 确定 -> 确定。 - Linux (GNOME/KDE等):进入网络设置 -> 选择当前连接(有线/Wi-Fi)-> IPv4 或 IPv6 设置 -> 方法选择“手动”或仅修改DNS -> 在“DNS 服务器”框中输入虚拟机B的IP地址(
168.1.100
)-> 应用。
- Windows:进入“控制面板” -> “网络和 Internet” -> “网络和共享中心” -> 点击当前连接 -> “属性” -> 双击“Internet 协议版本 4 (TCP/IPv4)” -> 选择“使用下面的 DNS 服务器地址” -> 在“首选 DNS 服务器”中输入虚拟机B的IP地址(
- 命令行 (Linux):
- 编辑
/etc/resolv.conf
(注意: 此文件可能被网络管理服务覆盖,修改网络配置文件更持久):sudo nano /etc/resolv.conf
将
nameserver
行改为:nameserver 192.168.1.100 # 虚拟机B的IP # 可选添加备用DNS,如 nameserver 8.8.8.8
- 更持久的方法 (使用
netplan
– Ubuntu): 编辑/etc/netplan/*.yaml
文件,在对应网络接口下添加nameservers
部分:network: version: 2 ethernets: ens33: # 你的网卡名 dhcp4: no # 如果是静态IP addresses: [192.168.1.50/24] # 物理机A的IP/掩码 gateway4: 192.168.1.1 nameservers: addresses: [192.168.1.100] # 虚拟机B的IP
应用配置:
sudo netplan apply
- 更持久的方法 (使用
NetworkManager
– CentOS/RHEL): 编辑连接配置文件或使用nmcli
:sudo nmcli con mod "YourConnectionName" ipv4.dns "192.168.1.100" sudo nmcli con up "YourConnectionName"
- 编辑
- 图形界面 (推荐):
第四步:在物理机A上测试DNS解析
- 清除DNS缓存 (可选但推荐):
- Windows: 以管理员身份运行命令提示符:
ipconfig /flushdns
- Linux: 取决于缓存服务(如
systemd-resolved
):sudo systemd-resolve --flush-caches
或sudo resolvectl flush-caches
- Windows: 以管理员身份运行命令提示符:
- 使用命令行工具测试:
- Windows:
nslookup ns1.example.com nslookup www.example.com nslookup 192.168.1.100 # 应解析出ns1.example.com ping physicalA.example.com # 应能ping通192.168.1.50
- Linux:
nslookup ns1.example.com dig www.example.com @192.168.1.100 # 显式指定向虚拟机B查询 nslookup 192.168.1.50 ping physicalA.example.com
- Windows:
- 检查解析结果: 确认返回的IP地址与你配置的区域文件一致,如果解析失败:
- 检查物理机A是否真的将DNS设置为虚拟机B的IP (
ipconfig /all
(Windows) 或cat /etc/resolv.conf
/nmcli dev show
(Linux))。 - 检查物理机A是否能
ping
通虚拟机B的IP。 - 检查虚拟机B上的防火墙是否放行了UDP 53端口(见下方注意事项)。
- 查看虚拟机B上BIND服务的日志 (
journalctl -u bind9
或journalctl -u named
)。
- 检查物理机A是否真的将DNS设置为虚拟机B的IP (
关键注意事项 (E-A-T体现):
-
防火墙: 这是最常见的障碍!
- 虚拟机B: 必须确保其防火墙允许入站 (Inbound) 的 UDP 53 端口(DNS查询)和 TCP 53 端口(区域传输等,如果不需要可不开),使用
ufw
(Ubuntu) 或firewall-cmd
(CentOS) 配置:sudo ufw allow 53/udp sudo ufw allow 53/tcp # 可选,非必须 sudo ufw reload
sudo firewall-cmd --permanent --add-service=dns sudo firewall-cmd --reload
- 物理机A: 通常不需要特殊配置,除非有非常严格的出站规则,需确保允许出站UDP 53。
- 物理机防火墙 (Host Firewall): 如果物理机A本身运行了防火墙(如Windows Defender防火墙),确保它允许与虚拟机B IP(
168.1.100
)的通信(特别是DNS端口),在虚拟网络(如仅主机模式、NAT网络)内部通信通常不受主机防火墙严格限制,但最好检查。 - 虚拟化软件防火墙: 某些虚拟化平台(如VirtualBox Host-Only网络)可能没有防火墙问题,但像VMware或KVM/libvirt的NAT网络可能需要检查虚拟网络设置。
- 虚拟机B: 必须确保其防火墙允许入站 (Inbound) 的 UDP 53 端口(DNS查询)和 TCP 53 端口(区域传输等,如果不需要可不开),使用
-
SELinux/AppArmor (Linux): 如果虚拟机B启用了SELinux (CentOS/RHEL) 或 AppArmor (Ubuntu),确保它们没有阻止BIND访问其配置文件或网络端口,查看相关日志 (
/var/log/audit/audit.log
,dmesg
) 并根据需要调整策略(使用audit2allow
或配置AppArmor profile),对于学习环境,可考虑暂时禁用(不推荐生产)。 -
网络隔离: 确保虚拟机B的网络配置(桥接/仅主机/NAT)确实能让物理机A访问到它,使用
ping
测试连通性是基础。 -
静态IP的重要性: 再次强调,虚拟机B的IP必须是静态的,动态IP(DHCP)会导致IP变化,物理机A的DNS配置将失效。
-
配置文件权限: BIND9对区域文件有特定的权限要求(通常
named
或bind
用户需要可读),如果修改区域文件后解析失败,检查权限和所有者。 -
备份: 修改任何重要配置文件(如
named.conf*
, 区域文件)之前,建议先备份。 -
递归查询限制: 在
allow-query
中谨慎使用any
,如果虚拟机B的DNS暴露在公网上且允许递归查询,可能被利用进行DNS放大攻击,内部网络或测试环境风险较低,但仍建议仅允许必要的IP或网段。 -
测试工具: 熟练掌握
nslookup
、dig
、ping
、traceroute
/tracert
、systemctl status
、日志查看等工具,是诊断问题的关键。
配置虚拟机作为物理机的DNS服务器,核心在于三点:(1) 虚拟机拥有稳定、可达的IP地址;(2) 虚拟机上的DNS服务(如BIND9)正确安装、配置并运行,监听正确端口且防火墙允许访问;(3) 物理机的网络设置明确指向虚拟机的IP作为DNS服务器,遵循上述详细步骤,并特别注意防火墙和静态IP的设置,即可成功实现此目标,此配置对于构建本地开发测试环境、学习DNS原理或管理小型内部网络非常有用。
引用说明:
- BIND9 官方文档: https://www.isc.org/bind/ (最权威的配置参考)
- Ubuntu Server Guide – BIND9: https://ubuntu.com/server/docs/service-domain-name-service-dns (Ubuntu特定指南)
- Red Hat Documentation – BIND: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/configuring_and_managing_networking/assembly_setting-up-and-configuring-a-bind-dns-server_configuring-and-managing-networking (RHEL/CentOS特定指南)
systemd-resolved
手册页:man systemd-resolved
(Linux DNS缓存管理)- **
ufw
手册页:
原创文章,发布者:酷盾叔,转转请注明出处:https://www.kd.cn/ask/40910.html