![当 NetworkManager 管理的 dnsmasq 出现时将其绑定到设备](https://linux22.com/image/805363/%E5%BD%93%20NetworkManager%20%E7%AE%A1%E7%90%86%E7%9A%84%20dnsmasq%20%E5%87%BA%E7%8E%B0%E6%97%B6%E5%B0%86%E5%85%B6%E7%BB%91%E5%AE%9A%E5%88%B0%E8%AE%BE%E5%A4%87.png)
我在 VirtualBox 中运行了几台服务器,它们通过仅托管网络互连。父系统是运行 NetworkManager 的 Ubuntu,它根据连接的网络管理 DNS,因此我的服务器resolv.conf
包含
nameserver 127.0.1.1
VirtualBox 配置为父系统具有地址10.1.0.1
,并且虚拟服务器静态配置为10.1.0.2
,10.1.0.3
......
当我更改网络时,我总是通过 找到nmcli
我的实际名称服务器,并将值填充到每个虚拟服务器。这很烦人,因为我经常更改网络并通过不同的接口(wlan0
、eth0
)进行连接。
我的想法是使用 NetworkManager 管理的 DNS 服务器作为虚拟服务器。但是当我将名称服务器放入10.1.0.1
虚拟服务器的 resolv.conf 中时,DNS 无法解析。
显然,NetworkManager 管理的 DNS 服务器仅与 绑定127.0.1.1
。
我尝试添加,listen-interface=10.1.0.1
使其/etc/NetworkManager/dnsmasq.d/<my-file>
在 NetworkManager 重启后工作,但只有当 Virtual Box 正在运行且vboxnet0
接口存在时才有效。当 Virtual Box 关闭时,dnsmasq
无法启动。
我也尝试使用bind-dynamic
dnsmasq 选项,但它与NetworkManagerbind-interface
添加的命令不兼容。dnsmasq
问题:如何让 NetworkManager 在界面出现10.1.0.1
后绑定 dnsmasq vboxnet0
?或者如何让它启动另一个dnsmasq
转发10.1.0.1
请求的实例127.0.1.1
?
附加信息:
# ifconfig
...
vboxnet0 Link encap:Ethernet HWaddr 0a:00:27:00:00:00
inet addr:10.1.0.1 Bcast:10.1.0.255 Mask:255.255.255.0
...
-
# ps aux|grep dnsmasq
nobody 1252 0.0 0.0 52976 4108 ? S dub10 0:00
/usr/sbin/dnsmasq --no-resolv --keep-in-foreground --no-hosts
--bind-interfaces --pid-file=/var/run/NetworkManager/dnsmasq.pid
--listen-address=127.0.1.1 --cache-size=0 --conf-file=/dev/null
--proxy-dnssec --enable-dbus=org.freedesktop.NetworkManager.dnsmasq
--conf-dir=/etc/NetworkManager/dnsmasq.d
-
#netstat -antp|grep ':53'
tcp 0 0 127.0.1.1:53 0.0.0.0:* LISTEN 1252/dnsmasq
-
# nslookup google.com 127.0.1.1
Server: 127.0.1.1
Address: 127.0.1.1#53
Non-authoritative answer:
Name: google.com
Address: 64.233.164
-
# nslookup google.com 10.1.0.1
;; connection timed out; no servers could be reached
答案1
这可以通过将 的包装脚本dnsmasq
替换为 来--bind-interfaces
解决(呵呵) --bind-dynamic
,但由于某种原因NetworkManager
,它的搜索路径是硬编码的,因此首先必须将原始二进制文件移开(在dpkg
基于 的系统上,使用类似 的命令dpkg-divert --local --rename --divert /usr/local/sbin/dnsmasq --add /usr/sbin/dnsmasq
)。
然后创建一个新的/usr/sbin/dnsmasq
:
#!/bin/bash
args=("$@")
for (( i=0; i<${#args}; ++i )); do
case "${args[i]}" in
-z|--bind-interfaces)
args[i]=--bind-dynamic
;;
--)
break
;;
esac
done
exec /usr/local/sbin/dnsmasq "${args[@]}"
根据需要更改/usr/local/sbin/dnsmasq
为指向原始二进制文件,将脚本标记为可执行文件(chmod +x /usr/sbin/dnsmasq
),并将任意interface=
行添加到文件中/etc/NetworkManager/dnsmasq.d
。
注意事项:
- 如果更新以遵守环境变量
/usr/local/sbin
,则可能会中断使用。如果担心这一点,请将实际可执行文件移至非位置,例如(但请参阅下面的 #2)。NetworkManager
PATH
PATH
/usr/lib
- 使用不在
/usr/sbin
in之前的位置$PATH
将导致在命令行上手动调用时--bind-interfaces
(-z
) 被替换。dnsmasq
答案2
扩展上面@lumato-reinstate-monica 的回答,因为我无法在评论中放入额外的代码块。
我还发现取消设置 localhostlisten-address
选项很有用,因为bind-dynamic
它已经涵盖了。
--listen-address=*)
unset args[i]
args=(${args[@]})
;;
bind-dynamic
与 network-manager 的设置一起设置的设置listen-address=127.0.1.1
会生成错误消息,大意是 dnsmasq 无法两次绑定到同一个地址:端口,而这正是此配置所要求的。也许 dnsmasq 应该检测到这种情况,但它没有。