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 而不是直接更改 /etc/resolv.conf
,可以使用 openresolv 生成 dnsmasq 的配置文件。
編輯 /etc/resolvconf.conf
並將 loopback 地址添加為名稱伺服器,然後配置 openresolv 輸出 dnsmasq 配置:
/etc/resolvconf.conf
# 使用本地名稱伺服器 name_servers="::1 127.0.0.1" resolv_conf_options="trust-ad" # 輸出 dnsmasq 擴展配置和解析文件 dnsmasq_conf=/etc/dnsmasq-conf.conf dnsmasq_resolv=/etc/dnsmasq-resolv.conf
運行 resolvconf -u
創建配置文件。如果文件不存在,則 dnsmasq.service
無法啟動。
編輯 dnsmasq 的配置文件使用 openresolv 生成的配置 [1]:
# 读取 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
不被修改,詳述見 Domain name resolution#Overwriting of /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 的配置文件中設置 server=server_address
指定上游 DNS 伺服器地址。還要添加 no-resolv
,以便 dnsmasq 不會非必要地讀取只包含本地主機地址的 /etc/resolv.conf
。
/etc/dnsmasq.conf
[...] no-resolv # 示例:Google 的名稱伺服器 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#Testing。
DHCP 伺服器
默認情況下,dnsmasq 關閉了 DHCP 功能,如要使用則必須將其打開。以下是重要的設置:
# 僅偵聽路由器的 LAN NIC。這樣會將 tcp/udp 埠 53 開放給本地主機,並將 udp 埠 67 開放給全世界: interface=enp0s0 # dnsmasq 將向全世界開放 tcp/udp 埠 53 和 udp 埠 67,以幫助動態接口(分配動態 IP)。 # dnsmasq 將丟棄全部請求,但某些人可能希望關閉它並由內核處理。 # 如果您有其他 dnsmasq 實例在運行(例如由於 libvirtd),您可能也需要此選項。 bind-interfaces # 設置域名(可選) domain=example.org # 設置默認網關 dhcp-option=3,0.0.0.0 # 設置要公布的 DNS 伺服器 dhcp-option=6,0.0.0.0 # 如果 dnsmasq 伺服器同時也為網絡執行路由,則可以使用選項 121 推出靜態路由。 # x.x.x.x 是目標 LAN,yy 是 CIDR 表示法(通常為 /24),z.z.z.z 是執行路由的主機。 dhcp-option=121,x.x.x.x/yy,z.z.z.z # 提供給 LAN PC 的 IP 動態範圍和租賃時間。 # 建議首先將租賃時間設置為 5m,以便測試一切正常之後再設置持久記錄。 # 這裡的地址範圍必須位於分配給虛擬接口的地址範圍內。 dhcp-range=192.168.111.50,192.168.111.100,12h # 提供 IPv6 DHCP 租約,使用網絡接口作為前綴構建範圍 dhcp-range=::f,::ff,constructor:enp0s0 # 如果要讓 dnsmasq 將固定 IP 分配給某些客戶端,請綁定 LAN 計算機的 NIC MAC 地址: 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)。
Proxy 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 或代理模式),
- 複製並配置 PXE 兼容的引導加載程序(例如 PXELINUX)到 TFTP 根目錄,
- 在 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
的組合。有關更多 client-arch
編號,請參閱 RFC 4578 2.1 以用於 dhcp 引導協議。
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。還支持通配符。在模式的開頭添加 *
:
# 阻止 blocked.example 和 anotherblocked.example 及其所有子域名 address=/*blocked.example/ # 阻止像 mail.google.com 这样的子域名,但不阻止 google.com address=/*.google.com/
可以使用 #
作為伺服器地址來解除阻止某些特定子域名:
# 阻止 google.com 及其所有子域名,除了 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 地址(IPv6 為 0.0.0.0 或 ::)回答域名的查詢。 -
server=/example.com/#
將域名的查詢發送到標準配置的伺服器。
-
- 模式
/example.com/
和/.example.com/
是等效的。兩者都將匹配 example.com 及其所有子域名。
為了方便使用,將阻止列表放在單獨的文件中,例如 /etc/dnsmasq.d/blocklist.conf
,並從 /etc/dnsmasq.conf
加載它,使用 conf-file=/etc/dnsmasq.d/blocklist.conf
或 conf-dir=/etc/dnsmasq.d/,*.conf
。
- 可以在 OpenWrt 的 adblock 包的 README 中找到阻止列表的潛在來源列表。
- 可以使用
addn-hosts=hosts.txt
選項使用 hosts 文件阻止列表,或者可以使用此 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
。