我正在本地 Fedora 39 机器上dnsmasq
以插件形式运行。我所需要的只是对可以按主题组织的附加文件的支持。NetworkManager
dnsmasq
hosts
我的配置是:
/etc/dnsmasql.conf
:
user=dnsmasq
group=dnsmasq
interface=lo
bind-interfaces
conf-dir=/etc/NetworkManager/dnsmasq.d,*.conf
conf-dir=/etc/dnsmasq.d,.rpmnew,.rpmsave,.rpmorig
/etc/NetworkManager/conf.d/00-use-dnsmasq.conf
[main]
dns=dnsmasq
/etc/NetworkManager/dnsmasq.d/00-add-hosts.conf
log-queries
no-hosts
addn-hosts=/etc/hosts.d
address=/development/127.0.0.1
/etc/hosts.d
是一个带有主机文件的目录,其中包含我想要“sinkhole”的条目:
0.0.0.0 1.example.com
0.0.0.0 2.example.com
...
dnsmasq
已启动并正在运行,我在我的进程中看到了守护进程:
ps aux | grep dnsmasq
dnsmasq 61161 0.4 0.0 228096 4480 ? S 16:08 0:00 /usr/sbin/dnsmasq --no-resolv --keep-in-foreground --no-hosts --bind-interfaces --pid-file=/run/NetworkManager/dnsmasq.pid --listen-address=127.0.0.1 --cache-size=400 --clear-on-reload --conf-file=/dev/null --enable-dbus=org.freedesktop.NetworkManager.dnsmasq --conf-dir=/etc/NetworkManager/dnsmasq.d
我还在dnsmasq
调试日志中看到,主机文件/etc/hosts.d
也被读取:
Dec 30 16:18:40 fedora dnsmasq[61823]: chown of PID file /run/NetworkManager/dnsmasq.pid failed: Operation not permitted
Dec 30 16:18:40 fedora dnsmasq[61823]: DBus support enabled: connected to system bus
Dec 30 16:18:40 fedora dnsmasq[61823]: warning: no upstream servers configured
Dec 30 16:18:40 fedora dnsmasq[61823]: read /etc/hosts.d/private - 10 names
Dec 30 16:18:40 fedora dnsmasq[61823]: setting upstream servers from DBus
Dec 30 16:18:40 fedora dnsmasq[61823]: using nameserver 192.168.0.1#53(via wlp2s0)
但当我尝试从addn-hosts
hosts 文件访问域名时,它们并没有0.0.0.0
像我预期的那样被解析。这些 hosts 文件似乎被忽略了。
另一方面,我添加到系统中的任何内容/etc/hosts
都会按预期工作。即使我在配置no-hosts
中明确使用了选项
dnsmasq
,我也看到它已添加到守护进程调用中。
我还看到dnsmasq
使用了配置,因为该address=/development/127.0.0.1
行按预期工作:
$ ping -c 3 anything.development
PING anything.development (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.091 ms
64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.175 ms
64 bytes from localhost (127.0.0.1): icmp_seq=3 ttl=64 time=0.200 ms
只是addn-hosts
它以某种方式被忽略了。
这是我的/etc/resolv.conf
:
# Generated by NetworkManager
nameserver 127.0.0.1
options edns0 trust-ad
之前我以为是它systemd-resolved.service
干扰了(因为它之前将 127.0.0.53 添加到我的resolv.conf
文件中),但现在我禁用了该服务:
systemctl status systemd-resolved.service
○ systemd-resolved.service - Network Name Resolution
Loaded: loaded (/usr/lib/systemd/system/systemd-resolved.service; disabled; preset: enabled)
Drop-In: /usr/lib/systemd/system/service.d
└─10-timeout-abort.conf
Active: inactive (dead)
我不确定我的配置有什么问题。
答案1
您已经很好地描述了情况,但您可以更加详细地测试您看到的名称解析。您的系统上有dig
或nslookup
作为命令行工具吗?如果有,请使用它们直接查询机器上的名称服务器,而不是您所做的任何操作。
但是当我尝试从 addn-hosts 主机文件访问域时,它们并没有像我预期的那样解析为 0.0.0.0。这些主机文件似乎被忽略了。
我发现您的配置中没有定义上游名称服务器(但显然您正在使用上游名称服务器。)我怀疑黑名单域的解析实际上来自您的上游。所以我要问的第一个问题是:我的本地dnsmasq
实例是否正确响应?
对我来说,成功是这样的:
tai@fay:~ $ dig adserver.com
; <<>> DiG 9.16.44-Raspbian <<>> adserver.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 18567
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;adserver.com. IN A
;; Query time: 259 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Sun Dec 31 16:12:15 EST 2023
;; MSG SIZE rcvd: 41
请注意,SERVER:
倒数第三行中的字段向我保证我正在询问本地服务器。您可以在问题后以这种方式指定服务器名称或 IP 地址,这恰好显示了正常解析(这是我们在本例中不想要的):
tai@fay:~ $ dig adserver.com @8.8.8.8
; <<>> DiG 9.16.44-Raspbian <<>> adserver.com @8.8.8.8
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 23032
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;adserver.com. IN A
;; ANSWER SECTION:
adserver.com. 5400 IN A 159.127.40.163
;; Query time: 119 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Sun Dec 31 16:11:57 EST 2023
;; MSG SIZE rcvd: 57
(我在此处使用的系统与您的设置非常相似,但 1)它是一台专用的 DNS/DHCP 机器,并且 2)我不需要通过 NetworkManager 模块化我的 dnsmasq。)
在这种情况下,DNS 会变得非常复杂,我并不惊讶你和我都无法立即发现问题所在。尝试专门探测本地 dnsmasq,并添加一些有关解析发生位置的详细信息(如果不是来自你的 dnsmasq)!
答案2
问题解决了,感谢@Tai Viinikka!
TLDR;在本地主机上运行的 DNS 服务器dnsmasq
并不一定意味着它被使用NetworkManager
,即使
/etc/resolv.conf
明确说明了这一点;如果您的本地计算机正在使用路由器的 DHCP 服务器,您也可以从中获取 DNS 服务器设置。
TIL;默认情况dig
下使用来自的 DNS 服务器/etc/resolv.conf
,即使由管理的连接也NetworkManager
使用从 DHCP 获得的 DNS 服务器地址;因此dig
,如何curl
解析相同的主机名存在差异。
故障排除:
- 检查我的本地主机 DNS 是否
dnsmasq
确实按预期工作:
# dig or nslookup a host from my addn-hosts's hosts file
$ dig 1.example.com
[...]
;; ANSWER SECTION:
1.example.com. 0 IN A 0.0.0.0
[...]
;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP)
主机名按预期由(本地 DNS 服务器)解析为0.0.0.0
(如 hosts 文件所述)。addn-hosts
127.0.0.1
dnsmasq
curl
那么为什么来自或浏览器到同一主机名的所有请求都没有通过我的本地DNS得到解析dnsmasq
,而是显然通过另一个上游DNS得到解析,尽管/etc/resolv.conf
说:
cat /etc/resolv.conf
# Generated by NetworkManager
nameserver 127.0.0.1
options edns0 trust-ad
这意味着有东西正在覆盖 DNS 设置。一定是NetworkManager
- 检查
NetworkManager
正在使用的 DNS:
$ nmcli device show | grep -i dns
IP4.DNS[1]: 192.168.0.1
IP6.DNS[1]: 2a02:8383:d:c::1000
IP6.DNS[2]: 2a02:8383:d:c::1
确实,正如所言/etc/resolv.conf
,NetworkManager
它使用我的 WiFi 路由器的 DNS 地址。这是因为我本地计算机上的 WiFi 连接使用路由器的DHCP
设置。
- 设置上游 DNS 服务器
dnsmasq
在修复 使用的 DNS 之前NetworkManager
,我们需要添加一些上游 DNS,这些 DNS 将在检查 hosts 文件后使用。这是我的整个dnsmasq
配置现在的样子:
$ cat /etc/NetworkManager/dnsmasq.d/00-add-hosts.conf
# NB! When making changes, don't forget restart dnsmasq & NetworkManager.service:
# $ killall dnsmasq
# $ systemctl restart NetworkManager
# No need to read /etc/resolv.conf as it contains the localhost
# addresses of dnsmasq itself
no-resolv
# Upstream DNS servers
# My router, Google, CloudFlare
server=192.168.0.1
server=8.8.8.8
server=1.1.1.1
# Add debug logging
# $ journalctl --follow -u NetworkManager
log-queries
# Ignore /etc/hosts
no-hosts
# Add custom hosts files;
# If path is a directory, all files from it are loaded
addn-hosts=/etc/hosts.d
NetworkManager
修复 的连接设置中的 DNS 服务器:
打开nm-connection-editor
(或设置 -> WiFi -> 您所连接的网络设置),然后IPv4
:
- 方法 -> 仅限自动 (DHCP) 地址
- DNS 服务器 -> 127.0.0.1(而不是自动)
然后是IPv6
:
- 方法 -> 自动,仅 DHCP(注意,它与 不同
IPv4
)
这对应于以下变化/etc/NetworkManager/system-connections/YOUR-CONNECTION-NAME.nmconnection
:
[ipv4]
dns=127.0.0.1;
ignore-auto-dns=true
method=auto
[ipv6]
addr-gen-mode=stable-privacy
dns=::1;
ignore-auto-dns=true
method=dhcp
现在,重新启动dnsmasq
和NetworkManager
:
$ sudo killall dnsmasq
$ sudo systemctl restart NetworkManager
et voilà!NetworkManager
使用 localhost 作为 DNS 服务器,来自curl
或 Web 浏览器的所有请求都通过它进行解析,来自 的额外 hosts 文件dnsmasq
也addn-hosts
受到尊重:
$ nmcli device show | grep -i dns
IP4.DNS[1]: 127.0.0.1
IP6.DNS[1]: ::1
$ curl -v 1.example.com
* processing: 1.example.com
* Trying 0.0.0.0:80...
* connect to 0.0.0.0 port 80 failed: Connection refused
* Trying [2604:a880:400:d0::2082:1001]:80...
* Immediate connect fail for 2604:a880:400:d0::2082:1001: Network is unreachable
* Failed to connect to lobste.rs port 80 after 1 ms: Couldn't connect to server
* Closing connection