具有短主机名的通配符证书?

具有短主机名的通配符证书?

我正在尝试使用以下内容生成证书主题替代名称

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”作为主题替代名称,那么它就可以正常工作。因此,带有缩短主机名的通配符无法正常工作。

答案1

个人经验

不久前我遇到了类似的问题。

我已经为 Windows 和 Linux 服务器设置了本地 DNS,并将 .staging 作为 TLD。为了节省为每个虚拟主机创建和签署证书的时间,并避免必须配置新的 IP 地址(非 SNI Web 服务器),我创建了一个密钥和证书,*.staging但每当我尝试使用 TLS 在我们的 Staging 服务器上加载虚拟主机时,我尝试的所有客户端(包括 curl)都只报告证书主体名称与*.staging目标主机名不匹配。

相关 RFC

我花了很长时间才弄清楚为什么我生成的通配符证书不起作用*.staging。我读过所有相关的 RFC,但没有一个明确指出这种通配符证书无效或非法。

安全 Stack Exchange 答案

读完后我终于开悟了这个出色的 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 源代码

mozilla-central Mercurial 存储库

与 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.
}

Chromium 源代码

Chromium Git 存储库

不允许公共/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;
}

评论注册表_控制域.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 发布。

答案2

出于安全原因,HTTPS 客户端应该拒绝匹配 TLD 通配符,如*.com*.net(甚至*):任何单个证书都不应对整个 TLD 声称拥有权威性。

现在客户端该如何确定 .example 是 TLD(*.example禁止匹配)还是缩写形式(允许匹配)?特别是考虑到每隔一天就会出现新的 TLD,并且任何静态 TLD 列表很快就会过时。

因此客户端只是拒绝匹配任何通配符*.XYZ并期望在通配符中看到至少两个点。

请注意,他们仍应维护通配符黑名单等*.co.uk *.co.jp

相关内容