具有短主機名的萬用字元證書?
我正在嘗試使用以下subjectAltName生成證書:
hostname *.hostname hostname.mydomain.local *.hostname.mydomain.local
我通過 OpenSSL 生成 CSR,然後從 Microsoft Active Directory 證書服務獲取證書。證書適用於以下替代名稱:
hostname hostname.mydomain.local *.hostname.mydomain.local
但是,
*.hostname
就是行不通。使用 Curl 進行測試,我得到以下輸出:% curl https://m.example/ curl: (51) SSL: certificate subject name '*.example' does not match target host name 'm.example'
另一方面,如果我將 ’m.example’ 添加為subjectAltName,那麼它可以工作。因此,帶有縮短主機名的萬用字元只是拒絕工作。
個人經驗
不久前,我遇到了類似的問題。
我已經為 Windows 和 Linux 伺服器設置了一個本地 DNS,並將 .staging 作為 TLD。為了節省為每個虛擬主機創建和簽署證書並避免配置新的 IP 地址(非 SNI Web 伺服器),我創建了一個密鑰和證書,
*.staging
但我嘗試的所有客戶端(包括 curl)只報告證書主題名稱*.staging
每當我嘗試使用 TLS 在我們的暫存伺服器上傳入虛擬主機時,它都與目標主機名不匹配。相關 RFC
我花了很長時間試圖弄清楚為什麼我生成的萬用字元證書
*.staging
不起作用。我已經閱讀了所有相關的 RFC,但沒有一個明確指出這樣的萬用字元證書是無效或非法的。
- 將 TLS 與 IMAP、POP3 和 ACAP 結合使用
- 基於 TLS 的 HTTP
- 在傳輸層安全 (TLS) 的上下文中使用 X.509 (PKIX) 證書在網際網路公鑰基礎設施中表示和驗證基於域的應用程序服務身份
安全堆棧交換答案
在閱讀了這個出色的 Security Stack Exchange 答案後,我最終得到了啟發。
重要的是SSL 客戶端將接受什麼作為“有效證書”,即包含與預期伺服器名稱“匹配”的名稱(包含在 URL 中的名稱)的證書。這在RFC 2818 的第 3.1 節中有名義上的規定,它允許多種萬用字元名稱,包括諸如“
www.*.*c*
”之類的東西,匹配(理論上)任何包含三個組件的伺服器名稱,第一個是“www
”,第三個包含至少一個“c
”。…
所以瀏覽器廠商制定了自己的方案和限制。很久以後,發布了一個 新的 RFC(6125,從 2011 年 3 月起),其中第 6.4.3 節 專門用於處理證書中的萬用字元名稱。RFC 6125 所描述的更符合實際情況,並且是“提議的標準”,因此至少在某種程度上有一些意願來實現它。但是,RFC 6125 中沒有任何內容要求拒絕
*.com
; 但瀏覽器確實拒絕它。可以為二級域頒發萬用字元 SSL 證書的公認答案嗎?也值得一票。
編輯
我認為除了講述個人的挫敗感之外,除了連結到 RFC 和 Security Stack Exchange 上的相關答案之外,我的回答並沒有真正增加太多;我想我會付出更多的努力並蒐索 Chromium 和 Firefox 使用的目前相關原始碼。
*.intranet
請注意,Chromium 原始碼中的註釋明確提到不允許使用未知的頂級域(例如)。另外:沒有引用可以覆蓋此行為的使用者可配置選項。
Mozilla 原始碼
與 NSS 一樣,萬用字元標籤後至少需要兩個標籤。
if (isWildcard) { // If the DNS ID ends with a dot, the last dot signifies an absolute ID. size_t labelCount = (labelLength == 0) ? dotCount : (dotCount + 1); // Like NSS, require at least two labels to follow the wildcard label. // // TODO(bug XXXXXXX): Allow the TrustDomain to control this on a // per-eTLD+1 basis, similar to Chromium. Even then, it might be better to // still enforce that there are at least two labels after the wildcard. if (labelCount < 3) { return false; } // XXX: RFC6125 says that we shouldn't accept wildcards within an IDN // A-Label. The consequence of this is that we effectively discriminate // against users of languages that cannot be encoded with ASCII. if (StartsWithIDNALabel(hostname)) { return false; } // TODO(bug XXXXXXX): Wildcards are not allowed for EV certificates. // Provide an option to indicate whether wildcards should be matched, for // the purpose of helping the application enforce this. }
鉻原始碼
不允許公共/ICANN 註冊管理機構控制域使用萬用字元 - 即,防止 *.com 或 *.co.uk 作為有效的顯示名稱
此外,還隱含地阻止未知頂級域(例如“內部網”域或尚未添加到註冊管理機構控制域數據集中的新 TLD/gTLD)。
if (!reference_domain.empty()) { DCHECK(reference_domain.starts_with(".")); // Do not allow wildcards for public/ICANN registry controlled domains - // that is, prevent *.com or *.co.uk as valid presented names, but do not // prevent *.appspot.com (a private registry controlled domain). // In addition, unknown top-level domains (such as 'intranet' domains or // new TLDs/gTLDs not yet added to the registry controlled domain dataset) // are also implicitly prevented. // Because |reference_domain| must contain at least one name component that // is not registry controlled, this ensures that all reference domains // contain at least three domain components when using wildcards. size_t registry_length = registry_controlled_domains::GetRegistryLength( reference_name, registry_controlled_domains::INCLUDE_UNKNOWN_REGISTRIES, registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES); // Because |reference_name| was already canonicalized, the following // should never happen. CHECK_NE(std::string::npos, registry_length); // Account for the leading dot in |reference_domain|. bool is_registry_controlled = registry_length != 0 && registry_length == (reference_domain.size() - 1); // Additionally, do not attempt wildcard matching for purely numeric // hostnames. allow_wildcards = !is_registry_controlled && reference_name.find_first_not_of("0123456789.") != std::string::npos; }
registry_controlled_domain.h中的註釋也是相關的:
RegistryControlledDomainService 檢查傳遞給它的 GURL 的主機名,並確定由註冊商控制的最長部分。雖然從技術上講,主機名的頂級域 (TLD) 是名稱的最後一個點部分(例如 .com 或 .org),但許多域(例如 co.uk)的功能就像它們是 TLD,分配任何在它們下面的更具體、本質上不相關的名稱的數量。例如,.uk 是 TLD,但不允許任何人直接在 .uk 下註冊域;“有效”的 TLD 是 ac.uk、co.uk 等。我們不希望 *.co.uk 中的任何站點為整個 co.uk 域設置 cookie,因此能夠辨識哪些更高級別的域作為有效的 TLD 以及哪些可以註冊非常重要。
Chromium 和 Mozilla 項目都基於 Mozilla發布的公共後綴列表對有效 TLD的定義。