跳至內容
出自 Arch Linux 中文维基

dnsmasq 提供 DNS 伺服器、支持 DHCPv6PXEDHCP 伺服器TFTP 伺服器。它設計為輕量且占用空間小,適用於資源受限的路由器和防火牆。還可以將 dnsmasq 配置為 DNS 緩存查詢,以提高對以前訪問過站點的 DNS 查找速度。

安裝

安裝 dnsmasq 軟體包,然後 啟動/啟用 dnsmasq.service

還需要重新啟動網絡,以便 DHCP 客戶端可以創建新的 /etc/resolv.conf

配置

要配置 dnsmasq,需要編輯 /etc/dnsmasq.conf。該文件包含選項的注釋。有關全部可用選項,請參閱 dnsmasq(8)

注意:dnsmasq 的默認配置啟用 DNS 伺服器。如果不使用的話,需要顯式設置 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 啟動以來未訪問過的網站(drillldns 軟體包的一部分):

$ 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 伺服器

這篇文章的某些內容需要擴充。

原因:添加 IPv6 的說明 (在 Talk:Dnsmasq 中討論)

默認情況下,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 伺服器,請按照以下步驟操作:

  1. 在 dnsmasq 配置文件中設置 #TFTP 伺服器#DHCP 伺服器(完整 DHCP 或代理模式),
  2. 複製並配置 PXE 兼容的引導加載程序(例如 PXELINUX)到 TFTP 根目錄,
  3. 在 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-matchdhcp-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 伺服器。

靜態

要靜態執行此操作,每個接口使用一個伺服器,請使用 interfacebind-interfaces 選項。這將強制啟動第二個 dnsmasq。

動態

在這種情況下,我們可以排除每個接口並綁定任何其他接口:

except-interface=lo
bind-dynamic
注意:這是 libvirt 中的默認設置。

域名阻止列表

要阻止域名,即使用 NXDOMAIN 回答查詢,請使用 address 選項而不指定 IP 地址:

address=/blocked.example/
address=/anotherblocked.example/
注意:/etc/hosts 文件不同,dnsmasq 將阻止這些域名及其所有子域名,例如 subdomain.blocked.example

還支持通配符。在模式的開頭添加 *

# 阻止 blocked.exampleanotherblocked.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.confconf-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.bindinsertions.bindevictions.bindauth.bindservers.bind

參閱