DNS-over-QUIC 到 UDP 代理程式和用戶端實作。
2019—2023 © NS1
此程式碼根據 Apache License 2.0 發布。您可以在許可證文件中找到條款和條件。
此實作遵循 RFC 9250:基於專用 QUIC 連線的 DNS。
QUIC 協定相容性取決於 quic-go 函式庫。
建立 DoQ 代理和測試客戶端。
go build ./cmd/proxy
go build ./cmd/client
為代理伺服器產生測試金鑰和自簽名憑證。
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -pkeyopt ec_param_enc:named_curve -out server.key
openssl req -x509 -days 30 -subj "/CN=DNS-over-QUIC Test" -addext "subjectAltName=DNS:localhost,IP:127.0.0.1,IP:::1" -key server.key -out server.crt
啟動代理。預設情況下,伺服器從上面產生的檔案載入 TLS 金鑰和證書,將使用 8.8.4.4(Google 公共 DNS)作為後端伺服器,並將偵聽 UDP 連接埠 853(草案中的實驗連接埠)。使用命令列選項修改預設行為。請注意,使用預設連接埠需要以超級使用者身分啟動代理程式。
sudo ./proxy
使用測試實用程式查詢代理程式。客戶端與伺服器建立 QUIC 會話,並透過專用串流傳送每個查詢。在上游,XFR 請求透過 TCP 發送,所有其他請求透過 UDP 發送。回覆依完成順序列印:
./client ns1.com A ns1.com AAAA
;; opcode: QUERY, status: NOERROR, id: 25849
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; QUESTION SECTION:
;ns1.com. IN AAAA
;; ANSWER SECTION:
ns1.com. 195 IN AAAA 2606:4700:10::6814:31b6
ns1.com. 195 IN AAAA 2606:4700:10::6814:30b6
ns1.com. 195 IN RRSIG AAAA 13 2 200 20190325121641 20190323121641 44688 ns1.com. m17G7sGkXNhBiKINI2LuQLvUL0Qb+l6LMUmKSoVo2TP5sw3Yd27L44QOZhVU1GS//tD1e6YVOVsMrW3arlk/bQ==
;; ADDITIONAL SECTION:
;; OPT PSEUDOSECTION:
; EDNS: version 0; flags: do; udp: 512
;; opcode: QUERY, status: NOERROR, id: 26044
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; QUESTION SECTION:
;ns1.com. IN A
;; ANSWER SECTION:
ns1.com. 25 IN A 104.20.49.182
ns1.com. 25 IN A 104.20.48.182
ns1.com. 25 IN RRSIG A 13 2 26 20190325121645 20190323121645 44688 ns1.com. xJK5DhMiFqxWx/gC7gHQXM8wkVFDyocIF3Zuehqa+S92zAq3yOtZMrqVRXxsKNw2lfCMQXLHr7hVUDm5H4B5eA==
;; ADDITIONAL SECTION:
;; OPT PSEUDOSECTION:
; EDNS: version 0; flags: do; udp: 512
代理伺服器支援客戶端證書認證。為了啟用該功能,請提供 PEM 格式的 CA 憑證套件作為代理參數-mtls_ca_certs
。
產生測試 CA 憑證:
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -pkeyopt ec_param_enc:named_curve -out ca.key
openssl req -x509 -days 30 -subj "/CN=DNS-over-QUIC Test CA" -addext "basicConstraints=critical,CA:true,pathlen:0" -key ca.key -out ca.crt
產生伺服器和用戶端憑證並使用 CA 憑證對其進行簽署:
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -pkeyopt ec_param_enc:named_curve -out server.key
openssl req -x509 -CA ca.crt -CAkey ca.key -days 30 -subj "/CN=server" -addext "subjectAltName=DNS:localhost,IP:127.0.0.1,IP:::1" -key server.key -out server.crt
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -pkeyopt ec_param_enc:named_curve -out client.key
openssl req -x509 -CA ca.crt -CAkey ca.key -days 30 -subj "/CN=client" -key client.key -out client.crt
運行代理程式並透過提供 CA 憑證作為 CA 捆綁包來啟用 mTLS:
./proxy -mtls_ca_certs ca.crt
透過提供客戶端憑證來執行查詢。 CA 捆綁包啟用伺服器憑證驗證:
./client -ca_certs ca.crt -cert client.crt -key client.key ns1.com. AAAA
請注意,這是建立在實驗協議之上的實驗代碼。
此儲存庫中的伺服器和用戶端使用相同的 QUIC 庫,因此它們應該相容。但是,如果使用不同的客戶端,版本協商時握手可能會失敗。當客戶端無法連線時,建議先檢查抓包狀況。
代理還記錄有關已接受的連接和流的信息,這些信息可用於檢查事件的順序:
$ sudo ./proxy -listen 127.0.0.1:853 -cert cert.pem -key key.pem -backend 8.8.4.4:53
ts=2019-03-24T10:31:32.408891Z msg="listening for clients" addr=127.0.0.1:853
ts=2019-03-24T12:16:45.048583Z client=127.0.0.1:52212 msg="session accepted"
ts=2019-03-24T12:16:45.050231Z client=127.0.0.1:52212 stream_id=0 msg="stream accepted"
ts=2019-03-24T12:16:45.050278Z client=127.0.0.1:52212 stream_id=4 msg="stream accepted"
ts=2019-03-24T12:16:45.091568Z client=127.0.0.1:52212 stream_id=4 msg="stream closed"
ts=2019-03-24T12:16:45.104623Z client=127.0.0.1:52212 stream_id=0 msg="stream closed"
ts=2019-03-24T12:16:45.110261Z client=127.0.0.1:52212 msg="session closed"
該項目得到維護。
歡迎提出請求和問題。有關詳細信息,請參閱 NS1 貢獻指南。