威DNS排查)
申請通配符或多域名證書時ACME DNS-01常見的第一句報錯就是NXDOMAIN。它不是“TXT值不對”的同義詞而是查詢鏈路里連這個名字都沒有找到。先把重試按鈕放一邊查錯名稱重試只是在給DNS服務(wù)器增加心理負擔。本文把驗證域名、CNAME委托、權(quán)威NS、TXT傳播和DNSSEC拆開定位到哪一層再修哪一層。一、NXDOMAIN到底說明了什么DNS-01要求客戶端把客戶端根據(jù)token與賬戶密鑰派生出的驗證值放在_acme-challenge.待驗證域名的TXT記錄中ACME服務(wù)器再查詢該名稱并比對值。Let’s Encrypt官方文檔明確了這個名稱和TXT驗證方式RFC 8555也把dns-01定義為由ACME服務(wù)器查詢DNS記錄完成驗證。NXDOMAIN的重點是“名稱不存在”和NOERROR但沒有TXT、SERVFAIL、超時不是一回事。不同解析器可能緩存負結(jié)果所以改完記錄后不能只看本機一次查詢。二、先確認ACME真正查詢的名稱最容易犯的錯是把待簽發(fā)域名直接加TXT或者通配符寫成帶星號的查詢名。驗證*.example.com時常規(guī)DNS-01查詢?nèi)試@_acme-challenge.example.com不是_acme-challenge.*.example.com。實際名稱以ACME客戶端日志和訂單授權(quán)對象為準不要憑記憶拼接。DOMAINexample.com NAME_acme-challenge.${DOMAIN} printf query%s\n $NAME dig noall answer $NAME TXT dig noall authority $NAME TXT第一條看答案第二條看權(quán)威區(qū)是否返回SOA。若查詢名寫錯后面的CNAME和TXT檢查都沒有意義。生產(chǎn)腳本應(yīng)把最終規(guī)范化FQDN寫入日志避免把根域、子域和通配符混成一鍋。三、區(qū)分NOERROR空答案與NXDOMAIN兩者在排障上完全不同NXDOMAIN通常表示權(quán)威服務(wù)器認為該名字不存在NOERROR/NODATA表示名字存在但沒有所請求類型的記錄。若父域存在而子域不存在權(quán)威響應(yīng)里的SOA通常能幫助判斷否定緩存邊界。dig noall comments authority _acme-challenge.example.com TXT dig trace _acme-challenge.example.com TXT # 只把實際返回的狀態(tài)寫入診斷日志不用grep到空輸出就判定成功 dig noall answer _acme-challenge.example.com TXT不要只執(zhí)行dig TXT后看“沒有輸出”。保存 status、ANSWER、AUTHORITY 和 SERVER才能區(qū)分沒有記錄、被權(quán)威拒答和本地遞歸緩存異常。trace適合定位委派鏈路不代表ACME服務(wù)器一定使用同一個遞歸解析器。四、沿權(quán)威NS一路查別被本地緩存帶偏先查域名的NS再直接詢問權(quán)威服務(wù)器。權(quán)威服務(wù)器沒有記錄而公共遞歸仍有舊TXT說明緩存尚未過期權(quán)威已有記錄而本地仍NXDOMAIN則優(yōu)先檢查負緩存、查詢線路和DNSSEC。ZONEexample.com dig short NS $ZONE for ns in $(dig short NS $ZONE); do printf \nserver%s\n $ns dig noall comments answer authority \ $ns _acme-challenge.$ZONE TXT done本例驗證區(qū)域根域查子域時單獨指定NAME不能把查詢名改成區(qū)域根域。ZONE應(yīng)為實際權(quán)威區(qū)域子區(qū)委派需用trace確認。若DNS服務(wù)商控制臺顯示記錄但權(quán)威NS回答沒有它常見原因是改錯了賬戶、區(qū)域或記錄名若權(quán)威回答正確再看遞歸緩存和傳播不要繼續(xù)改記錄。五、CNAME委托時查目標不要同時塞CNAME和TXT如果把_acme-challenge.example.comCNAME到專用驗證域TXT通常應(yīng)放在CNAME目標上。DNS名稱不能同時把同名CNAME和其他數(shù)據(jù)記錄當成普通并列項使用委托目標也必須再追到它自己的權(quán)威NS。NAME_acme-challenge.example.com dig noall answer $NAME CNAME TARGET$(dig short $NAME CNAME | sed s/\.$//) if [ -n $TARGET ]; then dig noall answer $TARGET TXT dig noall authority $TARGET TXT fi這里有個很隱蔽的坑CNAME目標末尾的點表示完整域名API填值時有的服務(wù)商要求相對名有的要求FQDN。最終以權(quán)威查詢結(jié)果為準。若歷史TXT殘留先確認是否屬于仍在進行的并發(fā)驗證再按服務(wù)商語義刪除不能用“清空全部TXT”這種粗暴方案。六、DNSSEC、SERVFAIL和傳播延遲怎么分層NXDOMAIN修正后變成SERVFAIL方向可能已經(jīng)從記錄名轉(zhuǎn)到DNSSEC、簽名過期或委派不一致。對比普通解析器、權(quán)威NS和帶DNSSEC校驗的結(jié)果不要把SERVFAIL當作TXT值錯誤。響應(yīng)現(xiàn)象通常含義先做什么NXDOMAIN權(quán)威認為名稱不存在查驗證名稱、區(qū)域和委派NOERROR無TXT名稱存在但沒有TXT查記錄類型、目標和生效區(qū)SERVFAIL解析鏈或DNSSEC失敗查權(quán)威狀態(tài)、簽名和委派NOERROR有舊TXT能查到但值不匹配保留并發(fā)值核對token后重試DNS傳播不是一個固定秒數(shù)。TTL影響緩存但負緩存還受SOA中的否定緩存參數(shù)影響權(quán)威服務(wù)器、遞歸解析器和CA驗證器看到的時間可能不同。修改后等待并重復(fù)查詢比連續(xù)創(chuàng)建新訂單更穩(wěn)妥。七、用三種方案做中立對照純命令行可以直接調(diào)用DNS Provider APIacme.sh等開源客戶端也能通過DNS API自動寫入TXT平臺化方案則通常把訂單、權(quán)限、重試和多目標部署統(tǒng)一管理。無論選哪種核心驗收都一樣寫入的是正確驗證名稱權(quán)威NS能查到正確TXT驗證完成后按策略清理舊值。本文只作技術(shù)邊界對照不把某個方案寫成唯一答案。參考Let’s Encrypt DNS-01文檔、acme.sh開源倉庫 與 CertbotX。八、續(xù)期前驗收清單從ACME日志取出準確授權(quán)域名確認沒有把星號寫進查詢名。遞歸查詢與至少一臺權(quán)威NS分別讀取TXT并記錄status、ANSWER和AUTHORITY。存在CNAME時只沿目標查TXT確認目標區(qū)域和末尾點語義。把NXDOMAIN、NOERROR空答案、SERVFAIL和舊TXT分開處理。確認驗證完成后再清理對應(yīng)TXT不刪除并發(fā)訂單仍需要的值。最終用ACME staging或受控測試訂單復(fù)驗再接入自動續(xù)期和告警。事實依據(jù)RFC 8555 第8.4節(jié)、Let’s Encrypt Challenge Types文檔。線上證書是否真正更新還要另行讀取部署節(jié)點的證書指紋和有效期DNS查詢成功不等于Nginx已經(jīng)加載新證書。