描述
template 外掛程式允許您透過編寫 (Go) 範本來動態回應查詢。
語法
template CLASS TYPE [ZONE...] {
match REGEX...
answer RR
additional RR
authority RR
rcode CODE
ederror EXTENDED_ERROR_CODE [EXTRA_REASON]
fallthrough [FALLTHROUGH-ZONE...]
}
- CLASS 查詢類別 (通常是 IN 或 ANY)。
- TYPE 查詢類型 (A、PTR、… 可以是 ANY 以符合所有類型)。
- ZONE 此範本的區域範圍。預設為伺服器區域。
match
REGEX Go 正規表示式,會針對傳入的查詢名稱進行比對。如果未指定正規表示式,則會比對所有內容 (預設值:.*
)。第一個符合的正規表示式會勝出。answer|additional|authority
RR 一個 RFC 1035 風格的資源記錄片段,由包含回覆的 Go 範本所建立。如果未指定 answer,則會產生一個空白 answer 區段的回應。rcode
CODE 一個回應碼 (NXDOMAIN、SERVFAIL、...
)。預設值為NOERROR
。有效的回應碼值根據miekg/dns
套件在msg.go
中定義的RcodeToString
對應。ederror
EXTENDED_ERROR_CODE 是一個擴充的 DNS 錯誤碼,為RFC8914
中定義的數字 (0, 1, 2,…, 24)。EXTRA_REASON 是一個額外的字串,用於說明傳回錯誤的原因。fallthrough
如果 template 的 ZONE 符合查詢名稱但沒有正規表示式符合,則繼續使用下一個 template 執行個體。如果沒有下一個 template,則繼續使用下一個外掛程式進行解析。如果列出 [FALLTHROUGH-ZONE…] (例如in-addr.arpa
和ip6.arpa
),則只有這些區域的查詢才會受到 fallthrough 的影響。如果沒有fallthrough
,當 template 的 ZONE 符合查詢但沒有正規表示式符合時,則會傳回SERVFAIL
回應。
另請參閱 包含額外的閱讀清單。
範本
每個資源記錄都是功能完整的 Go 範本,具有以下預先定義的資料
.Zone
相符的區域字串 (例如example.
)。.Name
查詢名稱,以字串形式 (小寫)。.Class
查詢類別 (通常為IN
)。.Type
要求的 RR 類型 (例如PTR
)。.Match
所有比對的陣列。index .Match 0
指的是整個比對。.Group
具名擷取群組的對應。.Message
完整的傳入 DNS 訊息。.Question
相符的問題區段。.Remote
用戶端的 IP 位址.Meta
一個函式,它接受中繼資料名稱並傳回值 (如果已啟用中繼資料外掛程式)。例如,.Meta "kubernetes/client-namespace"
以及以下預先定義的 範本函式
parseInt
以給定的基數和位元大小解譯字串。相當於 strconv.ParseUint。
範本的輸出必須是 RFC 1035 風格的資源記錄 (通常稱為「區域檔」)。
警告 Go 範本和 CoreDNS 設定檔存在語法問題。類似 {{$var}}
的運算式會被 CoreDNS (和 Caddy) 解釋為對環境變數的參考,而 {{ $var }}
則可以運作。請參閱 錯誤 和 corefile(5)。
度量
如果已啟用監控 (透過 prometheus 外掛程式),則會匯出以下度量
coredns_template_matches_total{server, zone, view, class, type}
依正規表示式比對的要求總數。coredns_template_template_failures_total{server, zone, view, class, type, section, template}
Go 範本失敗的次數。可以使用正規表示式、區段和範本標籤值將錯誤對應回設定檔。coredns_template_rr_failures_total{server, zone, view, class, type, section, template}
範本化的資源記錄無效且無法剖析的次數。可以使用正規表示式、區段和範本標籤值將錯誤對應回設定檔。
兩種失敗情況都表示範本設定有問題。server
標籤表示遞增度量的伺服器,詳細資訊請參閱 metrics 外掛程式。
範例
將所有內容解析為 NXDOMAIN
最簡單的範本是
. {
template ANY ANY {
rcode NXDOMAIN
}
}
- 此範本使用預設區域 (
.
或所有查詢) - 所有查詢都將得到回覆 (沒有
fallthrough
) - 答案始終是 NXDOMAIN
將 .invalid 解析為 NXDOMAIN
.invalid
網域是保留的 TLD (請參閱 RFC 2606 保留的頂級 DNS 名稱),用於指示無效的網域。
. {
forward . 8.8.8.8
template ANY ANY invalid {
rcode NXDOMAIN
authority "invalid. 60 {{ .Class }} SOA ns.invalid. hostmaster.invalid. (1 60 60 60 60)"
ederror 21 "Blocked according to RFC2606"
}
}
- 對 .invalid 的查詢將會產生 NXDOMAIN (rcode)
- 會傳送虛擬 SOA 記錄,以便為快取目的發放 60 秒的 TTL
- 在
CH
類別中查詢.invalid
也會導致 NXDOMAIN/SOA 回應 - 預設的正規表示式為
.*
封鎖無效的搜尋網域完成
假設您執行 example.com
,資料中心為 dc1.example.com
。資料中心網域是 DNS 搜尋網域的一部分。但是,something.example.com.dc1.example.com
表示一個完整網域名稱 (something.example.com
),該名稱無意中新增了預設網域或搜尋路徑 (dc1.example.com
)。
. {
forward . 8.8.8.8
template IN ANY example.com.dc1.example.com {
rcode NXDOMAIN
authority "{{ .Zone }} 60 IN SOA ns.example.com hostmaster.example.com (1 60 60 60 60)"
}
}
更詳細的基於正規表示式的等效項將會是
. {
forward . 8.8.8.8
template IN ANY example.com {
match "example\.com\.(dc1\.example\.com\.)$"
rcode NXDOMAIN
authority "{{ index .Match 1 }} 60 IN SOA ns.{{ index .Match 1 }} hostmaster.{{ index .Match 1 }} (1 60 60 60 60)"
fallthrough
}
}
基於正規表示式的版本可以進行更複雜的比對/範本化,而基於區域的範本化更容易讀取和使用。
為 .example 解析 A/PTR
. {
forward . 8.8.8.8
# ip-a-b-c-d.example A a.b.c.d
template IN A example {
match (^|[.])ip-(?P<a>[0-9]*)-(?P<b>[0-9]*)-(?P<c>[0-9]*)-(?P<d>[0-9]*)[.]example[.]$
answer "{{ .Name }} 60 IN A {{ .Group.a }}.{{ .Group.b }}.{{ .Group.c }}.{{ .Group.d }}"
fallthrough
}
# d.c.b.a.in-addr.arpa PTR ip-a-b-c-d.example
template IN PTR in-addr.arpa {
match ^(?P<d>[0-9]*)[.](?P<c>[0-9]*)[.](?P<b>[0-9]*)[.](?P<a>[0-9]*)[.]in-addr[.]arpa[.]$
answer "{{ .Name }} 60 IN PTR ip-{{ .Group.a }}-{{ .Group.b }}-{{ .Group.c }}-{{ .Group.d }}.example."
}
}
IPv4 位址由 4 個位元組組成,a.b.c.d
。具名群組使其在 PTR 案例中反轉 IP 位址時較不容易出錯。請嘗試使用具名群組來解釋您的正規表示式和範本的作用。
請注意,A 記錄實際上是萬用字元:IP 位址的任何子網域都會解析為 IP 位址。
使用範本對應某些 PTR/A 配對是一種常見模式。
對於只有部分回應被範本化的混合網域,需要使用 Fallthrough。
使用 parseInt 解析十六進位 IP 模式
. {
forward . 8.8.8.8
template IN A example {
match "^ip0a(?P<b>[a-f0-9]{2})(?P<c>[a-f0-9]{2})(?P<d>[a-f0-9]{2})[.]example[.]$"
answer "{{ .Name }} 60 IN A 10.{{ parseInt .Group.b 16 8 }}.{{ parseInt .Group.c 16 8 }}.{{ parseInt .Group.d 16 8 }}"
fallthrough
}
}
IPv4 位址可以使用其十六進位編碼以更緊湊的形式表示。例如,ip-10-123-123.example.
可以改為表示為 ip0a7b7b7b.example.
解析多個 IP 模式
. {
forward . 8.8.8.8
template IN A example {
match "^ip-(?P<a>10)-(?P<b>[0-9]*)-(?P<c>[0-9]*)-(?P<d>[0-9]*)[.]dc[.]example[.]$"
match "^(?P<a>[0-9]*)[.](?P<b>[0-9]*)[.](?P<c>[0-9]*)[.](?P<d>[0-9]*)[.]ext[.]example[.]$"
answer "{{ .Name }} 60 IN A {{ .Group.a}}.{{ .Group.b }}.{{ .Group.c }}.{{ .Group.d }}"
fallthrough
}
}
具名擷取群組可以用於為多個模式範本化一個回應。
為 .example 中的 IP 範本解析 A 和 MX 記錄
. {
forward . 8.8.8.8
template IN A example {
match ^ip-10-(?P<b>[0-9]*)-(?P<c>[0-9]*)-(?P<d>[0-9]*)[.]example[.]$
answer "{{ .Name }} 60 IN A 10.{{ .Group.b }}.{{ .Group.c }}.{{ .Group.d }}"
fallthrough
}
template IN MX example {
match ^ip-10-(?P<b>[0-9]*)-(?P<c>[0-9]*)-(?P<d>[0-9]*)[.]example[.]$
answer "{{ .Name }} 60 IN MX 10 {{ .Name }}"
additional "{{ .Name }} 60 IN A 10.{{ .Group.b }}.{{ .Group.c }}.{{ .Group.d }}"
fallthrough
}
}
在回應中新增權威名稱伺服器
. {
forward . 8.8.8.8
template IN A example {
match ^ip-10-(?P<b>[0-9]*)-(?P<c>[0-9]*)-(?P<d>[0-9]*)[.]example[.]$
answer "{{ .Name }} 60 IN A 10.{{ .Group.b }}.{{ .Group.c }}.{{ .Group.d }}"
authority "example. 60 IN NS ns0.example."
authority "example. 60 IN NS ns1.example."
additional "ns0.example. 60 IN A 203.0.113.8"
additional "ns1.example. 60 IN A 198.51.100.8"
fallthrough
}
template IN MX example {
match ^ip-10-(?P<b>[0-9]*)-(?P<c>[0-9]*)-(?P<d>[0-9]*)[.]example[.]$
answer "{{ .Name }} 60 IN MX 10 {{ .Name }}"
additional "{{ .Name }} 60 IN A 10.{{ .Group.b }}.{{ .Group.c }}.{{ .Group.d }}"
authority "example. 60 IN NS ns0.example."
authority "example. 60 IN NS ns1.example."
additional "ns0.example. 60 IN A 203.0.113.8"
additional "ns1.example. 60 IN A 198.51.100.8"
fallthrough
}
}
捏造 CNAME
此範例會將任何完全針對 foogle.com
提出的 DNS 查詢,以 CNAME 回應至 google.com
。如果上游名稱伺服器可以傳回所要求類型的記錄,則答案也會包含 google.com
的記錄。
. {
template IN ANY foogle.com {
match "^foogle\.com\.$"
answer "foogle.com 60 IN CNAME google.com"
}
forward . 8.8.8.8
}
另請參閱
- Go 正規表示式,以取得有關正規表示式實作的詳細資訊
- RE2 語法參考,以取得有關正規表示式語法的詳細資訊
- RFC 1034 和 RFC 1035,以取得有關資源記錄格式的詳細資訊
- Go 範本,以取得範本語言參考
錯誤
CoreDNS 透過 {$ENV_VAR}
的概念支援 caddyfile 環境變數。此剖析器功能將會中斷類似 {{$variable}}
的 Go 範本變數標記法。等效標記法 {{ $variable }}
將會運作。請嘗試避免在此外掛程式的內容中使用 Go 範本變數。