当 NetworkManager 管理的 dnsmasq 出现时将其绑定到设备

当 NetworkManager 管理的 dnsmasq 出现时将其绑定到设备

我在 VirtualBox 中运行了几台服务器,它们通过仅托管网络互连。父系统是运行 NetworkManager 的 Ubuntu,它根据连接的网络管理 DNS,因此我的服务器resolv.conf包含

nameserver 127.0.1.1

VirtualBox 配置为父系统具有地址10.1.0.1,并且虚拟服务器静态配置为10.1.0.210.1.0.3......

当我更改网络时,我总是通过 找到nmcli我的实际名称服务器,并将值填充到每个虚拟服务器。这很烦人,因为我经常更改网络并通过不同的接口(wlan0eth0)进行连接。

我的想法是使用 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-dynamicdnsmasq 选项,但它与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

注意事项:

  1. 如果更新以遵守环境变量/usr/local/sbin,则可能会中断使用。如果担心这一点,请将实际可执行文件移至非位置,例如(但请参阅下面的 #2)。NetworkManagerPATHPATH/usr/lib
  2. 使用不在/usr/sbinin之前的位置$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 应该检测到这种情况,但它没有。

相关内容