smartdns icon indicating copy to clipboard operation
smartdns copied to clipboard

客户端与证书无颁发对象CN的doh无法建立连接

Open EarSum opened this issue 11 months ago • 5 comments

问题现象
客户端与证书无颁发对象CN的doh无法建立连接,重新签名携带颁发对象CN证书后正常

运行环境

  1. 固件型号
    Immortalwrt 23.04 stable

  2. 运营商
    China Telecom

  3. smartdns来源以及版本 46-1

  4. 涉及的配置(注意去除个人相关信息)

重现步骤

  1. 上游DNS配置。
    现有两个doh,一个证书带颁发对象cn,一个不携带,如图所示 屏幕截图 2025-01-02 110901 image

使用证书不携带颁发对象cn的doh,smartdns会提示如下图报错 image 而使用证书携带颁发对象cn的doh,smartdns日志如下所示 image

并且后续联系doh提供商更换不携带颁发对象cn的证书至携带颁发对象cn的证书后也能正常使用。

本人尝试了下adgh和technitium dns似乎都能正常使用无颁发对象cn证书认证的doh,doh提供商说他们现在使用的证书大部分都是SAN证书,可能是引起此issue的原因,请问这个问题是否有后续修复的打算?

最后,本人对证书这块不是特别了解,如果说的什么地方有误请各位大佬轻喷,感激不尽。

信息收集

  1. 将/var/log/smrtdns.log日志作为附件上传(注意去除个人相关信息)。
  2. 如进程异常,请将coredump功能开启,上传coredump信息文件,同时上传配套的smartdns进程文件。
    在自定义界面,开启设置->自定义设置->生成coredump配置,重现问题后提交coredump文件 coredump文件在/tmp目录下

EarSum avatar Jan 02 '25 03:01 EarSum

在DNS服务器的高级设置里面,有个停用校验的选项,试试能不能临时解决。 image

giveup avatar Jan 02 '25 06:01 giveup

就我所知X509证书标准要求证书中必须有颁发对象。你需要看一下这个证书的主题。如果里面不包含 CN=域名 或 DNS=ip,那么它不能作为合法的服务器身份认证证书

PikuZheng avatar Jan 02 '25 07:01 PikuZheng

在DNS服务器的高级设置里面,有个停用校验的选项,试试能不能临时解决。 image

感谢回复,我尝试过禁用证书验证但是依然会报错无法验证CN image

EarSum avatar Jan 02 '25 12:01 EarSum

就我所知X509证书标准要求证书中必须有颁发对象。你需要看一下这个证书的主题。如果里面不包含 CN=域名 或 DNS=ip,那么它不能作为合法的服务器身份认证证书

感谢回复,我观察了这个域名的证书,主题中确实没有CN=域名或DNS=ip信息。 image

但是在证书主题背景的备用名称中包含了关键-DNS 名称: hk.beta.xxx.xxx,我不知道该字段对于证书的验证是否有帮助。 image

而且使用technitium dns server内置的dns client app也能正常使用该doh,并不是想表示该工具比smartdns更好用,只是想说明似乎在其他的类似工具上该doh可以被正常使用,如果冒犯了您我感到抱歉。 image

EarSum avatar Jan 02 '25 12:01 EarSum

就我所知X509证书标准要求证书中必须有颁发对象。你需要看一下这个证书的主题。如果里面不包含 CN=域名 或 DNS=ip,那么它不能作为合法的服务器身份认证证书


Subject(CommonName) 并非必须项

RFC 5280 并不强制要求证书包含 Subject(Common Name)。没有 Subject 的情况下,只需要包含 subjectAltName 并将其标记为 critical 就符合要求。

If subject naming information is present only in the subjectAltName extension (e.g., a key bound only to an email address or URI), then the subject name MUST be an empty sequence and the subjectAltName extension MUST be critical.

CA/Browser Forum Baseline Requirements 中对于这一点写的更加明确:

7.1.2.7.12 Subscriber Certificate Subject Alternative Name For Subscriber Certificates, the Subject Alternative Name MUST be present and MUST contain at least one dNSName or iPAddress GeneralName. See below for further requirements about the permitted fields and their validation requirements. If the subject field of the certificate is an empty SEQUENCE, this extension MUST be marked critical, as specified in RFC 5280, Section 4.2.1.6. Otherwise, this extension MUST NOT be marked critical.

此外一些情况下 TLS 证书必定无法包含 Subject(CommonName) ,比如说域名过长时。

RFC 5280 限制 CommonName 长度不能超过 64个字符,对于超过这一长度的域名,想要获取有效的 TLS 证书唯一的办法是将 CommonName 设置为空。

CommonName ::= PrintableString (SIZE (1..ub-common-name-length)) ... ub-common-name-length INTEGER ::= 64

比如说 loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo.ong 这个网站的 TLS 证书便只包含 subjectAltName 而不包含 Common Name。

该网站证书可以至 crt.sh 查看。

验证服务端身份是应基于 subjectAltName 而非 Common Name

2000年5月发布的 RFC 2818 便已经要求当存在 subjectAltName dNSName 时必须使用 subjectAltName 进行服务端身份认证。使用 Common Name 进行认证是 deprecated 的。

If a subjectAltName extension of type dNSName is present, that MUST be used as the identity. Otherwise, the (most specific) Common Name field in the Subject field of the certificate MUST be used. Although the use of the Common Name is existing practice, it is deprecated and Certification Authorities are encouraged to use the dNSName instead.

2011年发布的 RFC 6125 再次强调了一这点。

结合上面提到的 CA/Browser Forum Baseline Requirements 要求证书必须包含 Subject Alternative Name 的要求,目前(2025年)有效的 TLS 证书都应该已经包含了 Subject Alternative Name。 因此认证服务端身份时,符合标准的实现必定是通过 subjectAltName 进行,而不是 Common Name。

在实现方面,2020年发布的 Go 1.15 版本便默认禁止了基于 Common Name 的身份认证。

X.509 CommonName deprecation The deprecated, legacy behavior of treating the CommonName field on X.509 certificates as a host name when no Subject Alternative Names are present is now disabled by default. It can be temporarily re-enabled by adding the value x509ignoreCN=0 to the GODEBUG environment variable. Note that if the CommonName is an invalid host name, it’s always ignored, regardless of GODEBUG settings. Invalid names include those with any characters other than letters, digits, hyphens and underscores, and those with empty labels or trailing dots.

2021年发布的 Go 1.17 更是彻底禁止了基于 Common Name 的服务端身份认证。


虽然目前一些工具(比如说 certbot)出于兼容性考虑会从 Subject Alternative Name(SAN) 中选取出一个域名设置为 Common Name(CN),但不包含 CN 只包含 SAN 的证书也是有效的,客户端拒绝这样的证书是不符合标准的。

yingziwu avatar Apr 15 '25 10:04 yingziwu