dnsmasq
dnsmasq 提供了一个 DNS 服务器、一个支持 DHCPv6 和 PXE 的 DHCP 服务器,以及一个 TFTP 服务器。它被设计为轻量级且占用空间小,适用于资源受限的路由器和防火墙。dnsmasq 也可以配置为缓存 DNS 查询,以提高先前访问站点的 DNS 查找速度。
安装
安装 dnsmasq 软件包。然后启动/启用 dnsmasq.service
。
网络也需要重启,以便 DHCP 客户端可以创建新的 /etc/resolv.conf
。
配置
要配置 dnsmasq,请编辑 /etc/dnsmasq.conf
。该文件包含解释选项的注释。有关所有可用选项,请参阅 dnsmasq(8)。
port=0
显式禁用它。如果 dnsmasq 不用作本地 DNS 解析器,您可能还需要 编辑 dnsmasq.service
,使其不拉取 nss-lookup.target
/etc/systemd/system/dnsmasq.service.d/no-nss-lookup-target.conf
[Unit] Wants=
$ dnsmasq --test
DNS 服务器
要在单台计算机上将 dnsmasq 设置为 DNS 缓存守护程序,请指定 listen-address
指令,并添加本地主机 IP 地址
listen-address=::1,127.0.0.1
要使用此计算机监听其 LAN IP 地址以供网络上的其他计算机使用。建议在这种情况下使用静态 LAN IP。例如:
listen-address=::1,127.0.0.1,192.168.1.1
您可以选择分配网络接口
interface=enp5s0
使用 cache-size=size
设置缓存的域名数量(默认为 150
)
cache-size=10000
要验证 DNSSEC,请加载 dnsmasq 软件包提供的 DNSSEC 信任锚,并设置选项 dnssec
conf-file=/usr/share/dnsmasq/trust-anchors.conf dnssec
有关您可能想要使用的更多选项,请参阅 dnsmasq(8)。
DNS 地址文件和转发
配置 dnsmasq 后,您需要在 /etc/resolv.conf
中添加本地主机地址作为唯一的名称服务器。这会导致所有查询都发送到 dnsmasq。
由于 dnsmasq 是一个存根解析器,而不是递归解析器,因此您必须设置转发到外部 DNS 服务器。这可以通过使用 openresolv 自动完成,也可以通过在 dnsmasq 的配置中手动指定 DNS 服务器地址来完成。
openresolv
如果您的网络管理器支持 resolvconf,您可以使用 openresolv 来 为 dnsmasq 生成配置文件,而不是直接更改 /etc/resolv.conf
。
编辑 /etc/resolvconf.conf
并添加环回地址作为名称服务器,并配置 openresolv 以写出 dnsmasq 配置
/etc/resolvconf.conf
# Use the local name server name_servers="::1 127.0.0.1" resolv_conf_options="trust-ad" # Write out dnsmasq extended configuration and resolv files dnsmasq_conf=/etc/dnsmasq-conf.conf dnsmasq_resolv=/etc/dnsmasq-resolv.conf
运行 resolvconf -u
以创建配置文件。如果文件不存在,dnsmasq.service
将无法启动。
编辑 dnsmasq 的配置文件以使用 openresolv 生成的配置[1]
# Read configuration generated by openresolv conf-file=/etc/dnsmasq-conf.conf resolv-file=/etc/dnsmasq-resolv.conf
手动转发
首先,您必须将本地主机地址设置为 /etc/resolv.conf
中唯一的名称服务器
/etc/resolv.conf
nameserver ::1 nameserver 127.0.0.1 options trust-ad
确保按照 域名解析#覆盖_/etc/resolv.conf 中的描述保护 /etc/resolv.conf
免受修改。
或者,可以将 NetworkManager 配置为使用以下命令为特定连接自动生成 /etc/resolv.conf
文件
$ nmcli connection modify 'connection-name' ipv4.dns 127.0.0.1 $ nmcli connection modify 'connection-name' ipv4.dns-options trust-ad $ nmcli connection modify 'connection-name' ipv4.ignore-auto-dns yes $ nmcli connection modify 'connection-name' ipv6.dns ::1 $ nmcli connection modify 'connection-name' ipv6.dns-options trust-ad $ nmcli connection modify 'connection-name' ipv6.ignore-auto-dns yes
然后重启 NetworkManager.service
。
然后必须在 dnsmasq 的配置文件中将上游 DNS 服务器地址指定为 server=server_address
。还要添加 no-resolv
,以便 dnsmasq 不会不必要地读取仅包含自身本地主机地址的 /etc/resolv.conf
。
/etc/dnsmasq.conf
[...] no-resolv # Google's nameservers, for example server=8.8.8.8 server=8.8.4.4
现在 DNS 查询将通过 dnsmasq 解析,只有当无法从其缓存中回答查询时才会检查外部服务器。
添加自定义域名
您可以通过简单地添加以下内容来分配域名
address=/router/192.168.1.1
或者,如果您继续使用,请将自定义域名添加到您(本地)网络中的主机
local=/lan/ domain=lan
在此示例中,可以 ping 主机/设备(例如在您的 /etc/hosts
文件中定义)为 hostname.lan
。
取消注释 expand-hosts
以将自定义域名添加到主机条目
expand-hosts
如果没有此设置,您将必须将域名添加到 /etc/hosts
的条目中。
测试
要进行查找速度测试,请选择自 dnsmasq 启动以来未访问过的网站(drill 是 ldns 软件包的一部分)
$ drill archlinux.org | grep "Query time"
再次运行该命令将使用缓存的 DNS IP,如果 dnsmasq 设置正确,则会产生更快的查找时间
$ drill archlinux.org | grep "Query time"
;; Query time: 18 msec
$ drill archlinux.org | grep "Query time"
;; Query time: 2 msec
要测试 DNSSEC 验证是否正常工作,请参阅 DNSSEC#测试。
DHCP 服务器
默认情况下,dnsmasq 的 DHCP 功能已关闭,如果您想使用它,则必须将其打开。以下是重要的设置
# Only listen to routers' LAN NIC. Doing so opens up tcp/udp port 53 to localhost and udp port 67 to world: interface=enp0s0 # dnsmasq will open tcp/udp port 53 and udp port 67 to world to help with dynamic interfaces (assigning dynamic IPs). # dnsmasq will discard world requests to them, but the paranoid might like to close them and let the kernel handle them. # You may also need this option if you have other instances of dnsmasq running (eg. because of libvirtd) bind-interfaces # Optionally set a domain name domain=example.org # Set default gateway dhcp-option=3,0.0.0.0 # Set DNS servers to announce dhcp-option=6,0.0.0.0 # If your dnsmasq server is also doing the routing for your network, you can use option 121 to push a static route out. # x.x.x.x is the destination LAN, yy is the CIDR notation (usually /24), and z.z.z.z is the host which will do the routing. dhcp-option=121,x.x.x.x/yy,z.z.z.z # Dynamic range of IPs to make available to LAN PC and the lease time. # Ideally set the lease time to 5m only at first to test everything works okay before you set long-lasting records. # The range of addresses here must lie within the address range assigned to the virtual interface. dhcp-range=192.168.111.50,192.168.111.100,12h # Provide IPv6 DHCP leases, the range is constructed using the network interface as prefix dhcp-range=::f,::ff,constructor:enp0s0 # If you’d like to have dnsmasq assign static IPs to some clients, bind the LAN computers NIC MAC addresses: dhcp-host=aa:bb:cc:dd:ee:ff,192.168.111.50 dhcp-host=aa:bb:cc:ff:dd:ee,192.168.111.51
有关更多选项,请参阅 dnsmasq(8)。
代理 DHCP
如果网络上已经运行了 DHCP 服务器,并且您想与之互操作,则可以将 dnsmasq 设置为充当“代理 DHCP”,因此仅向客户端提供 #PXE 服务器 特定信息。此模式仅适用于 IPv4。使用以下语法,提供现有的 DHCP 服务器地址
dhcp-range=192.168.0.1,proxy
测试
从连接到装有 dnsmasq 的计算机的另一台计算机上,将其配置为使用 DHCP 进行自动 IP 地址分配,然后尝试正常登录网络。
如果您检查服务器上的 /var/lib/misc/dnsmasq.leases
文件,您应该能够看到租约。
TFTP 服务器
dnsmasq 具有内置的 TFTP 服务器。
要使用它,请为 TFTP 创建一个根目录(例如 /srv/tftp
)以放入可传输的文件。
enable-tftp tftp-root=/srv/tftp
为了提高安全性,建议使用 dnsmasq 的 TFTP 安全模式。在安全模式下,只有 dnsmasq
用户拥有的文件才会通过 TFTP 提供服务。您需要 chown TFTP 根目录及其中的所有文件给 dnsmasq
用户才能使用此功能。
tftp-secure
有关更多选项,请参阅 dnsmasq(8)。
PXE 服务器
PXE 需要 DHCP 和 TFTP 服务器;两者都可以由 dnsmasq 提供。要设置 PXE 服务器,请按照以下步骤操作
- 在 dnsmasq 配置文件中设置 #TFTP 服务器 和 #DHCP 服务器(在完整 DHCP 或代理模式下),
- 在 TFTP 根目录中复制并配置 PXE 兼容的引导加载程序(例如 PXELINUX),
- 在 dnsmasq 配置文件中启用 PXE
要仅发送一个文件
dhcp-boot=lpxelinux.0
要根据客户端架构发送文件
pxe-service=x86PC,"PXELINUX (BIOS)",bios/lpxelinux pxe-service=X86-64_EFI,"PXELINUX (EFI)",efi64/syslinux.efi
- 文件路径相对于 TFTP 根路径
- 如果文件带有 .0 后缀,则必须在
pxe-service
选项中排除该后缀
如果 pxe-service
无法识别架构(特别是对于基于 UEFI 的客户端),则可以使用 dhcp-match
和 dhcp-boot
的组合。有关与 dhcp 引导协议一起使用的更多 client-arch
编号,请参见 RFC 4578 2.1。
dhcp-match=set:efi-x86_64,option:client-arch,7 dhcp-match=set:efi-x86_64,option:client-arch,9 dhcp-match=set:efi-x86,option:client-arch,6 dhcp-match=set:bios,option:client-arch,0 dhcp-boot=tag:efi-x86_64,efi64/syslinux.efi dhcp-boot=tag:efi-x86,efi32/syslinux.efi dhcp-boot=tag:bios,bios/lpxelinux.0
有关更多选项,请参阅 dnsmasq(8)。
其余的取决于引导加载程序。
技巧和提示
阻止 OpenDNS 重定向 Google 查询
要防止 OpenDNS 将所有 Google 查询重定向到他们自己的搜索服务器,请添加到 /etc/dnsmasq.conf
server=/www.google.com/<ISP DNS IP>
覆盖地址
在某些情况下,例如在运营访客网络门户时,将特定域名解析为硬编码的地址集可能很有用。这可以通过 address
配置完成
address=/example.com/1.2.3.4
此外,可以使用特殊的通配符为所有未从 /etc/hosts
或 DHCP 回答的域名返回特定地址
address=/#/1.2.3.4
多个实例
如果我们想要每个接口运行两个或多个 dnsmasq 服务器。
静态
要静态地执行此操作,每个接口一个服务器,请使用 interface
和 bind-interfaces
选项。这将强制启动第二个 dnsmasq。
动态
在这种情况下,我们可以排除每个接口并绑定任何其他接口
except-interface=lo bind-dynamic
域名黑名单
要将域名列入黑名单,即使用 NXDOMAIN 回答对它们的查询,请使用 address
选项而不指定 IP 地址
address=/blocked.example/ address=/anotherblocked.example/
/etc/hosts
文件不同,dnsmasq 将阻止这些域名以及所有子域名,例如 subdomain.blocked.example。也支持通配符。在模式的开头添加 *
# blocks both blocked.example and anotherblocked.example and all their subdomains address=/*blocked.example/ # blocks subdomains like mail.google.com but not google.com address=/*.google.com/
可以使用 #
作为服务器地址来解除阻止某些特定的子域名
# blocks google.com and all subdomains except mail.google.com. address=/google.com/ server=/mail.google.com/#
- 选项
address=/example.com/
和server=/example.com/
是等效的。两者都将使用 NXDOMAIN 回答对它们的查询。 - 选项
address=/example.com/#
和server=/example.com/#
不等效。address=/example.com/#
将使用 NULL 地址(0.0.0.0 或 IPv6 的 ::)回答对域名的查询。server=/example.com/#
会将对域名的查询发送到标准配置的服务器。
- 模式
/example.com/
和/.example.com/
是等效的。两者都将匹配 example.com 及其所有子域名。
为了便于使用,请将黑名单放在单独的文件中,例如 /etc/dnsmasq.d/blocklist.conf
,并使用 conf-file=/etc/dnsmasq.d/blocklist.conf
或 conf-dir=/etc/dnsmasq.d/,*.conf
从 /etc/dnsmasq.conf
加载它。
- 可以在 OpenWrt 的 adblock 软件包的 README 中找到黑名单的潜在来源列表。
- 主机文件黑名单可以与
addn-hosts=hosts.txt
选项一起使用,也可以使用此 awk 命令将其转换为 dnsmasq 黑名单:awk '/^[^#]/ { print "address=/"$2"/"$1"" }' hosts.txt
。
查看缓存统计信息
可以使用 chaos 请求查询缓存统计信息,使用 ldns 软件包中的 drill
实用程序
$ drill misses.bind TXT CH $ drill hits.bind TXT CH
输出将分别包含缓存未命中和命中的数量
;; ANSWER SECTION: misses.bind. 0 CH TXT "411"
其他选项包括 cachesize.bind
、insertions.bind
、evictions.bind
、auth.bind
和 servers.bind
。