申請ssl證書報提示caa提示


申請ssl證書報下面提示caa提示,這和dns有關,換一組dns重新申請 

send challenge err[acme error 'urn:acme:error:connection': DNS problem: SERVFAIL looking up CAA for

 

什么是 CAA 記錄呢,它全稱是 Certification Authority Authorization ,用於申明只允許特定的 CA 為域名發布證書。在 CA 發布證書的過程中,CA 機構應該檢查這個域名的 CAA 記錄,如果某個域名存在 CAA 記錄,但是 CA 機構的域名不在這個列表里,就應該停止簽發證書。CAA 記錄是可選的,如果權威 DNS 不返回 CAA 記錄則說明任何 CA 機構都可以為該域名發布證書。

起因

之前搭了一個 IPSec 的 VPN,為了避免需要在客戶端導入根證書,使用了 Let's Enrypt 來簽署免費證書。這樣客戶端不用導入自簽名的根證書就能正常地認證,用起來很舒服。

今天早上起來發現 VPN 登錄不了了,看了一下日志,發現是因為證書過期了,上服務器更新證書,certbot 報 "SERVFAIL looking up CAA for example.com",之前 certbot 也報過類似的錯誤,但是其實是其他錯誤導致的,不過這次經過反復嘗試,以及用 dig 測試:

dig -t TYPE257 example.com

發現我的 PowerDNS 確實是返回了一個 SERVFAIL。

調查

首先我的 PowerDNS 其實很久沒動了,為啥之前可以正常地簽證書、更新證書呢。原因是上個月 Let's Encrypt 發布了一個 申明 ,宣布其更新了對 CAA 記錄的支持。

什么是 CAA 記錄呢,它全稱是 Certification Authority Authorization ,用於申明只允許特定的 CA 為域名發布證書。在 CA 發布證書的過程中,CA 機構應該檢查這個域名的 CAA 記錄,如果某個域名存在 CAA 記錄,但是 CA 機構的域名不在這個列表里,就應該停止簽發證書。CAA 記錄是可選的,如果權威 DNS 不返回 CAA 記錄則說明任何 CA 機構都可以為該域名發布證書。

之前 Let's Encrypt 對於 CAA 查詢的策略是,如果權威 DNS 返回 SERVFAIL,則認為該服務器不支持 CAA,則跳過 CAA 的檢查。但是這樣顯然是有一些隱患的,權威 DNS 返回 SERVFAIL 不一定是因為 DNS 服務器不支持,也有可能是因為 DNS 出現了問題(或者被惡意攻擊),在這樣的場景下,Let's Encrypt 有可能會錯誤地簽發不應該簽發的證書。

因此,在確認大部分 DNS 服務提供者都支持 CAA 記錄之后,Let's Encrypt 修改了自身的策略,當權威 DNS 返回 SERVFAIL 的時候則直接拒絕簽發證書。不過我的 DNS 是自己在 CentOS 7 上建的 PowerDNS,看起來它並不支持 CAA。

解決方案1

上服務器檢查了一下 pdns 的版本,是從 EPEL 安裝的 3.4.8,而 EPEL 中最新的版本是 3.4.11。根據 PowerDNS 的 changelog 來看,從 4.0.0 開始 PowerDNS 才開始支持 CAA 記錄。

所幸 PowerDNS 自己的 軟件倉庫 中已經有了 4.0 版本的 pdns,直接添加軟件源, yum update 一下就有了 pdns 4.0.4。

不過奇怪的是 CAA 請求依然得到的是 SERVFAIL。之后我又嘗試了 master 分支的 pdns,結果依然。

解決方案2

既然如此,那就添加一個 CAA 記錄試試吧。Poweradmin 有一個 issue 中提到了這個 PR 已經添加了 CAA 記錄的支持,而這個 PR 已經被 merge 了。不過 poweradmin 的上一個 release 還是 2014 年發布的,至今已經有 3 年沒有發布新版本了。無它,從 master 分支下載代碼,在 poweradmin 里已經可以添加 CAA 記錄了。

根據 RFC ,CAA 記錄由兩部分組成:一個 flags 和 一個 tag 對。flags 是一個字節,當前只有最高位被用於 Issuer Critical,代表這個 tag 對的重要性,即如果 CA 不理解這個 tag 對,應該停止簽證書(1)或忽略這個 tag 對(0)。需要注意的是 Issuer Critical 是最高位,因此實際上的 flags 應該分別是 128 或 0,

當前支持的 tag 包括:issue issuewild iodef。

issue 表示允許 CA 機構簽署證書,issuewild 表示允許 CA 機構簽署 wildcard 證書,iodef 表示簽署證書時通過指定的方式通知域名持有者。

Let's Encrypt 暫時還不支持 wildcard,所以 issuewild 暫時沒什么意義;iodef 是可選的,並且據說 Let's Encrypt 還不支持 iodef。

綜上,在 Poweradmin 里添加一個 CAA 記錄,context 填入 128 issue "letsencrypt.org" 即可。關於這個 CAA 記錄的域名,根據 Let's Encrypt 的 文檔 ,可以放到需要簽證書域名的父域名下,Let's Encrypt 會進行遞歸查詢。另外 CA 域名必須填 letsencrypt.org,這個在文檔中也有提到。

接下來重新運行 certbot renew ,續命成功!

解決方案3

雖然問題解決了,我還是不滿足,為什么 4.0.4 的 Powerdns 依然返回 SERVFAIL 呢?根據 這里 來看,Powerdns 4.0.4 已經徹底解決了 CAA 請求 SERVFAIL 的問題。翻了一下日志,發現大量錯誤:

  1. Backend error: GSQLBackend unable to list metadata: Could not prepare statement: select content from domains, domainmetadata where domainmetadata.domain_id=domains.id and name=? and domainmetadata.kind=?: Table 'powerdns.domainmetadata' doesn't exist 

對比了一下數據庫里的 table 列表和 pdns-mysql-backend 帶的 schema 里的 table 列表,發現缺了不少表,不過有意思的是,其他查詢依然能夠正常進行。於是補上了所有缺的表,刪掉了之前添加的 CAA 記錄,經過測試,發現這時候返回的狀態變成了 NOERROR。

綜上,所有的問題都解決了,如果遇到類似的問題,可以作為一個參考。

至於為啥數據庫缺表,這個 Powerdns 是其他人裝的,這件事就無從考證了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM