描述
forward 外掛程式會重複使用已開啟的連線至上游。它支援 UDP、TCP 和 DNS over TLS,並使用內建的健康檢查。
當偵測到錯誤時,會執行健康檢查。此檢查會在迴圈中執行,以 _0.5 秒_ 的間隔執行每次檢查,只要上游回報為不健康狀態。一旦恢復健康,我們就會停止健康檢查 (直到下次發生錯誤)。健康檢查使用遞迴 DNS 查詢 (. IN NS
) 來取得上游的健康狀態。任何非網路錯誤的回應 (REFUSED、NOTIMPL、SERVFAIL 等) 都會被視為上游健康。健康檢查會使用在 TO 中指定的相同協定。如果 max_fails
設定為 0,則不會執行檢查,且上游將始終被視為健康。
當所有上游都關閉時,它會假設健康檢查機制已失敗,並會嘗試連線至隨機上游 (這可能有效或無效)。
語法
最基本的形式中,一個簡單的轉發器使用此語法
forward FROM TO...
- FROM 是要比對以轉發請求的基礎網域。使用 CIDR 表示法展開為多個反向區域的網域不完全支援;僅使用第一個展開的區域。
- TO… 是要轉發到的目的地端點。TO 語法允許您指定協定,例如
tls://9.9.9.9
或dns://
(或沒有協定) 代表純 DNS。上游的數量限制為 15 個。
多個上游會在第一次使用時隨機化 (請參閱 policy
)。當一個健康的代理在交換期間返回錯誤時,會嘗試清單中的下一個上游。
可使用展開的語法取得額外的控制項
forward FROM TO... {
except IGNORED_NAMES...
force_tcp
prefer_udp
expire DURATION
max_fails INTEGER
tls CERT KEY CA
tls_servername NAME
policy random|round_robin|sequential
health_check DURATION [no_rec] [domain FQDN]
max_concurrent MAX
}
-
FROM 和 TO… 如上所述。
-
except
中的 IGNORED_NAMES 是以空格分隔的網域清單,會排除在轉發之外。符合這些名稱的請求將會被略過。 -
force_tcp
,即使請求是透過 UDP 傳入,仍使用 TCP。 -
prefer_udp
,即使請求是透過 TCP 傳入,仍先嘗試使用 UDP。如果回應被截斷 (回應中設定了 TC 旗標),則透過 TCP 再次嘗試。如果同時指定了force_tcp
和prefer_udp
選項,則force_tcp
優先。 -
max_fails
是在上游被視為關閉之前,需要後續失敗的健康檢查次數。如果為 0,則上游將永遠不會被標記為關閉 (也不會進行健康檢查)。預設值為 2。 -
expire
DURATION,在此時間之後過期 (快取) 連線,預設值為 10 秒。 -
tls
CERT KEY CA 定義 TLS 連線的 TLS 屬性。可以提供 0 到 3 個參數,其含義如下所述tls
- 不使用用戶端驗證,並使用系統 CA 來驗證伺服器憑證tls
CA - 不使用用戶端驗證,並使用檔案 CA 來驗證伺服器憑證tls
CERT KEY - 用戶端驗證使用指定的憑證/金鑰對。伺服器憑證會使用系統 CA 進行驗證tls
CERT KEY CA - 用戶端驗證使用指定的憑證/金鑰對。伺服器憑證會使用指定的 CA 檔案進行驗證
-
tls_servername
NAME 允許您在 TLS 設定中設定伺服器名稱;例如 9.9.9.9 需要將其設定為dns.quad9.net
。在此案例中仍然允許使用多個上游,但它們必須使用相同的tls_servername
。例如,將 9.9.9.9 (QuadDNS) 與 1.1.1.1 (Cloudflare) 混合將無法運作。使用 TLS 轉發但未設定tls_servername
會導致任何人都能夠對您轉發至 DNS 伺服器的連線進行中間人攻擊。因此,強烈建議在使用 TLS 轉發時設定此值。 -
policy
指定用於選擇上游伺服器的策略。預設值為random
。random
是一種實作隨機上游選擇的策略。round_robin
是一種基於循環配置順序選擇主機的策略。sequential
是一種基於循序選擇主機的策略。
-
health_check
設定上游伺服器健康檢查的行為<duration>
- 使用不同的持續時間進行健康檢查,預設持續時間為 0.5 秒。no_rec
- 可選參數,將健康檢查中使用的 dns 查詢的 RecursionDesired 旗標設定為false
。此旗標預設為true
。domain FQDN
- 將健康檢查所使用的網域名稱設定為 FQDN。如果未設定,則健康檢查所使用的網域名稱為.
。
-
max_concurrent
MAX 將並行查詢的數量限制為 MAX。任何會使並行查詢數量超過 MAX 的新查詢都會導致 REFUSED 回應。此回應不會被視為健康失敗。在選擇 MAX 的值時,請選擇一個至少大於上游伺服器的預期上游查詢速率 * 延遲 的數字。作為 MAX 的上限,請考慮每個並行查詢將使用大約 2kb 的記憶體。
另請注意,TLS 設定對於整個轉發代理是「全域」的,如果您需要針對不同的上游使用不同的 tls_servername
,那就沒辦法了。
在每個端點上,通訊的逾時設定如下
- 撥號逾時預設為 30 秒,並且可以根據早期結果自動減少到 1 秒。
- 讀取逾時固定為 2 秒。
中繼資料
如果也啟用了 metadata 外掛程式,則 forward 外掛程式會發佈以下中繼資料
forward/upstream
:用於轉發請求的上游
指標
如果啟用了監控 (透過 prometheus 外掛程式),則會匯出以下指標
coredns_forward_healthcheck_broken_total{}
- 當所有上游都不健康時的計數,我們會隨機 (這始終使用random
策略) 向一個上游發送請求。coredns_forward_max_concurrent_rejects_total{}
- 由於並行查詢的數量達到最大值而被拒絕的查詢計數。coredns_proxy_request_duration_seconds{proxy_name="forward", to, rcode}
- 每個上游、RCODE 的直方圖coredns_proxy_healthcheck_failures_total{proxy_name="forward", to, rcode}
- 每個上游失敗的健康檢查計數。coredns_proxy_conn_cache_hits_total{proxy_name="forward", to, proto}
- 每個上游和協定的連線快取命中計數。coredns_proxy_conn_cache_misses_total{proxy_name="forward", to, proto}
- 每個上游和協定的連線快取未命中計數。
其中 to
是其中一個上游伺服器 (來自設定的 TO),rcode
是從上游返回的 RCODE,proto
是傳輸協定,如 udp
、tcp
、tcp-tls
。
以下指標最近已被棄用
coredns_forward_healthcheck_failures_total{to, rcode}
- 可以使用
coredns_proxy_healthcheck_failures_total{proxy_name="forward", to, rcode}
來取代
- 可以使用
coredns_forward_requests_total{to}
- 可以使用
sum(coredns_proxy_request_duration_seconds_count{proxy_name="forward", to})
來取代
- 可以使用
coredns_forward_responses_total{to, rcode}
- 可以使用
coredns_proxy_request_duration_seconds_count{proxy_name="forward", to, rcode}
來取代
- 可以使用
coredns_forward_request_duration_seconds{to, rcode}
- 可以使用
coredns_proxy_request_duration_seconds{proxy_name="forward", to, rcode}
來取代
- 可以使用
範例
將 example.org.
內的所有請求代理轉發到在不同連接埠上執行的名稱伺服器
example.org {
forward . 127.0.0.1:9005
}
將 lab.example.local.
內的所有請求傳送至 10.20.0.1
,將 example.local.
(且不在 lab.example.local.
中) 內的所有請求傳送至 10.0.0.1
,將所有其他請求傳送至 /etc/resolv.conf
中定義的伺服器,並快取結果。請注意,在伺服器區塊中設定多個 forward 外掛程式的 CoreDNS 伺服器會在處理請求時依照列出的順序評估這些 forward 外掛程式。因此,子網域應放置在父網域之前,否則子網域請求將會轉發至父網域的上游。因此,在此範例中,lab.example.local
在 example.local
之前,而 example.local
在 .
之前。
. {
cache
forward lab.example.local 10.20.0.1
forward example.local 10.0.0.1
forward . /etc/resolv.conf
}
上面的範例幾乎等同於以下範例,只是以下範例定義了三個獨立的外掛程式鏈 (因此有 3 個獨立的 cache 執行個體)。
lab.example.local {
cache
forward . 10.20.0.1
}
example.local {
cache
forward . 10.0.0.1
}
. {
cache
forward . /etc/resolv.conf
}
在三個解析器之間進行所有請求的負載平衡,其中一個解析器具有 IPv6 位址。
. {
forward . 10.0.0.10:53 10.0.0.11:1053 [2003::1]:53
}
轉發除 example.org
以外的所有請求
. {
forward . 10.0.0.10:1234 {
except example.org
}
}
使用主機的 resolv.conf
的名稱伺服器代理除 example.org
以外的所有內容
. {
forward . /etc/resolv.conf {
except example.org
}
}
使用 DNS over TLS (DoT) 協定將所有請求代理轉發至 9.9.9.9,並將每個答案快取最多 30 秒。請注意,如果您想要正常運作的設定,則 tls_servername
是強制性的,因為 9.9.9.9 無法在 TLS 交涉中使用。此外,請將健康檢查持續時間設定為 5 秒,以免健康檢查完全淹沒服務。
. {
forward . tls://9.9.9.9 {
tls_servername dns.quad9.net
health_check 5s
}
cache 30
}
或為健康檢查請求設定其他網域名稱
. {
forward . tls://9.9.9.9 {
tls_servername dns.quad9.net
health_check 5s domain example.org
}
cache 30
}
或來自同一提供者的多個上游
. {
forward . tls://1.1.1.1 tls://1.0.0.1 {
tls_servername cloudflare-dns.com
health_check 5s
}
cache 30
}
或者,當您有多個具有不同 tls_servername
的 DoT 上游時,您可以執行以下操作
. {
forward . 127.0.0.1:5301 127.0.0.1:5302
}
.:5301 {
forward . tls://8.8.8.8 tls://8.8.4.4 {
tls_servername dns.google
}
}
.:5302 {
forward . tls://1.1.1.1 tls://1.0.0.1 {
tls_servername cloudflare-dns.com
}
}
另請參閱
RFC 7858,了解 DNS over TLS。