为了测试目的,我想在本地机器上运行 dnsmasq 来配置通配符来解析为 127.0.0.1。
但是,当我使用 systemd 启动 dnsmasq 时,我收到以下错误消息:
[root@dhcppc4 ~]# systemctl status dnsmasq -l
● dnsmasq.service - DNS caching server.
Loaded: loaded (/usr/lib/systemd/system/dnsmasq.service; disabled; vendor preset: disabled)
Active: failed (Result: exit-code) since Fri 2015-10-09 21:49:58 BST; 14s ago
Process: 2652 ExecStart=/usr/sbin/dnsmasq -k (code=exited, status=2)
Main PID: 2652 (code=exited, status=2)
Oct 09 21:49:58 dhcppc4 systemd[1]: Started DNS caching server..
Oct 09 21:49:58 dhcppc4 systemd[1]: Starting DNS caching server....
Oct 09 21:49:58 dhcppc4 dnsmasq[2652]: dnsmasq: failed to create listening socket for port 53: Address already in use
Oct 09 21:49:58 dhcppc4 systemd[1]: dnsmasq.service: main process exited, code=exited, status=2/INVALIDARGUMENT
Oct 09 21:49:58 dhcppc4 systemd[1]: Unit dnsmasq.service entered failed state.
Oct 09 21:49:58 dhcppc4 systemd[1]: dnsmasq.service failed.
我很困惑在没有当前 DNS 服务器运行的情况下端口 53 是如何被占用的(并通过 确认dig @127.0.0.1
),我运行netstat -ln
后发现有一个进程在地址 的端口 53 上进行监听192.168.122.1
:
tcp 0 0 192.168.122.1:53 0.0.0.0:* LISTEN
udp 0 0 192.168.122.1:53 0.0.0.0:*
ifconfig 显示这192.168.122.1
是虚拟接口 virbr0。
经过快速的 Google 搜索和 Wiki 搜索,我了解到 libvirt 为主机提供虚拟网络,以抽象物理接口。Libvirt 使用虚拟网络交换机,所有流量都通过该交换机进行路由[1]. 守护进程首次启动时会创建默认的虚拟网络交换机 virbr0。
然后我可以确认我可以通过 DIG 向此接口上的 dnsmasq 发送查询:
[grobinson@dhcppc4 ~]$ dig @192.168.122.1 +short
a.root-servers.net.
j.root-servers.net.
m.root-servers.net.
b.root-servers.net.
i.root-servers.net.
k.root-servers.net.
l.root-servers.net.
d.root-servers.net.
g.root-servers.net.
c.root-servers.net.
h.root-servers.net.
e.root-servers.net.
f.root-servers.net.
问题 1:我不明白让 dnsmasq 监听这个虚拟接口的原因是什么?对于 /etc/resolv.conf,我可以看到 DHCP 服务器上配置的 DNS 服务器告诉机器将查询定向到 Google DNS 服务器。它有什么用处?
# Generated by NetworkManager
nameserver 8.8.8.8
nameserver 8.8.4.4
我发现我可以编辑/etc/NetworkManager/NetworkManager.conf
并添加该行dns=dnsmasq
,然后使用 systemd 重新启动网络管理器。从这里开始,网络管理器配置为将查询定向到环回地址上的 dnsmasq,只需简单调用 dig 即可看到:
[grobinson@dhcppc4 ~]$ dig @127.0.0.1 +short
l.root-servers.net.
g.root-servers.net.
i.root-servers.net.
...
输出netstat -ln
现在显示两个套接字绑定并监听端口 53:
tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN
tcp 0 0 192.168.122.1:53 0.0.0.0:* LISTEN
问题2:为什么网络管理器可以在 127.0.0.1 上启动 dnsmasq,而我无法使用 systemctl 启动?这是因为默认配置尝试侦听所有接口,而 virbr0 却失败了吗?我只需要说明所需的接口?
问题 3:dnsmasq 似乎有两个配置选项:/etc/dnsmasq.conf
以及一个/etc/NetworkManager/dnsmasq.d/
可以写入配置文件的文件夹。后者似乎用于dns=dnsmasq
设置时间,dnsmasq 监听 127.0.0.1,因为编辑/etc/dnsmasq.conf
对 @127.0.0.1 的查询没有影响。前者可能是用于 libvirt 中的 dnsmasq 吗?
答案1
默认情况下,libvirt 会为其每个虚拟接口桥启动一个 dnsmasq 实例。这样做是为了向虚拟网络中运行的 VM 提供 DHCP 服务。
http://wiki.libvirt.org/page/VirtualNetworking
本质上,每次使用默认设置启动虚拟机时,libvirt 都会创建 virbr 桥。如果要防止这种情况发生,您需要在启动虚拟机之前自己创建桥,然后以“桥接”模式启动它,并将您的自定义桥指定为参数。这里有一个手册页对此进行了很好的解释。查看 --network 选项:
https://www-01.ibm.com/support/knowledgecenter/linuxonibm/liaat/liaatvirtinstalloptions.htm
每次在 libvirt 中创建“虚拟网络”时,它都会为其启动一个 dnsmasq 实例。因此,您必须停止使用 libvrt 的虚拟网络并转而使用手动方式。
答案2
如果您希望本地 /etc/hosts 更改使用相同接口传播到您的虚拟机,您可以简单地 SIGHUP 本地 libvirt 进程。
答案3
将您的 dnsmasq 实例配置为您希望它监听的接口的明确列表。
您/etc/dnsmasq.conf
可以使用接口名称interface=eth0
或接口 IP listen-address=192.168.0.1
。即使这样设置,dnsmasq 也会绑定到所有接口,因此请通过添加bind-interfaces
到配置文件中来禁用它。
或者,在配置文件中,使用 指定接口黑名单except-interface=virtbr*
。
资料来源: