我从 Namecheap/Sectigo/Comodo 购买了两个单域通配符 SSL 证书。我使用 openssl 以典型方式生成了 CSR。
$ openssl req -newkey rsa:4096 -keyout example.com.rsa.key -out example.com.rsa.csr
$ openssl genpkey -genparam -algorithm ec -pkeyopt ec_paramgen_curve:P-256 -out example.com.ecdsa.pem
$ openssl req -newkey ec:example.com.ecdsa.pem -keyout example.com.ecdsa.key -out example.com.ecdsa.csr
我提交了 CSR,并获得了包括 .crt 和 .ca-bundle 在内的每个证书包,一切如预期。
我能够安装这两个证书供 Postfix 使用。每个证书都需要一个未加密版本的私钥,并且必须维护安全权限。
$ openssl rsa -in example.com.rsa.key -out example.com.rsa.key.unencrypted
$ openssl ec -in example.com.ecdsa.key -out example.com.ecdsa.key.unencrypted
我已经正确设置了 SPF、DKIM、DMARC 和 DNSSEC,每个都经过第三方工具的确认,并且已经发送和接收了带有标题中通过分数的邮件。
我再次使用 openssl 为我的 DANE TLSA 记录生成证书哈希值。我创建了两组,每组对应一个算法,端口 25 和 587 也各有一组。这些被添加到我的区域文件中,用 named-checkzone 检查,用 dnssec-signzone 签名,然后在 DNS 中发布。
我首先使用两个外部工具来检查配置,第一个是丹尼查克第二个是dane.sys4.de。两者都报告称使用 RSA 证书总体上成功,但 ECDSA 证书具体失败。
前者成功了,部分报道如下:
DANE TLSA 3 1 1 [9679fc29..]: OK matched EE certificate
DANE TLSA 3 1 1 [ecd29ffd..]: FAIL did not match EE certificate
后者成功了,部分报道如下:
3, 1, 1 9679fc296960a23c[...]149b990a680cad8b *in green*
3, 1, 1 ecd29ffd76d61326[...]dadbcfa42eae9158 - unable to get local issuer certificate: (20) *in red*
我尝试通过更改各种用法、选择器和匹配字段(3 0 1、3 1 1 等)来解决这个问题。我尝试使用 openssl 在本地生成哈希值,并使用在线工具(如gen_tlsa。两种工具都为两个证书生成了相同的哈希结果。同样,RSA TLSA 成功,而 ECDSA 记录失败。我最终找到了 chaingen 脚本,它生成了所有 3 0 1、3 1 1、3 0 2 和 3 1 2 哈希,我将其包含在每个端口中,但 ECDSA 记录没有任何改进。
我花了几个小时尝试每个证书、TLSA 记录、端口等的不同排列。我尝试将 ECDSA 记录的父密钥的 TLSA 记录 (2 0 1) 添加到 DNS。我尝试更改 Postfix 可用的证书,以将 ca-bundle 与证书一起包含在 .pem 文件中。
研究我发现这篇帖子来自 exim-users标题为“如何获得用于 DANE 和 ec+rsa 证书的 ec 证书”,作者是 Viktor Dukhovni,他在 Postfix/DANE 圈子中无需介绍。他认为,也许在线工具是投机取巧的,一旦它们成功获得 RSA 证书,就不会费心测试 ECDSA 证书。他提供了非常有价值的 openssl 调用,以表明在发帖人的情况下密钥确实是正确的。我用两个简短的 shell 脚本重复了这项工作,使用 Viktor 的代码替换了我的信息,一个称为 checkrsa,另一个称为 checkecdsa。
这两个脚本分别执行两个命令,并对 checkrsa(针对 IPv4)进行以下设置:
$ cat checkrsa
echo "quit" | openssl s_client -starttls smtp -connect mail.example.com:25 -4 -verify 9 \
-dane_tlsa_domain mail.example.com \
-dane_tlsa_rrdata "3 0 1 c487cdb079...57aaec4ac9" \
-dane_tlsa_rrdata "3 1 1 9679fc2969...0a680cad8b" \
-sigalgs rsa_pkcs1_sha256:rsa_pkcs1_sha384:rsa_pkcs1_sha512:rsa_pss_rsae_sha256:rsa_pss_rsae_sha384:rsa_pss_rsae_sha512:rsa_pss_pss_sha256:rsa_pss_pss_sha384:rsa_pss_pss_sha512
以及 checkecdsa (针对 IPv6):
$ cat checkecdsa
echo "quit" | openssl s_client -starttls smtp -connect mail.example.com:25 -6 -verify 9 \
-dane_tlsa_domain mail.example.com \
-dane_tlsa_rrdata "3 0 1 87a8c75581...87fb13bfc5" \
-dane_tlsa_rrdata "3 1 1 ecd29ffd76...a42eae9158" \
-sigalgs ecdsa_secp256r1_sha256:ecdsa_secp384r1_sha384:ecdsa_secp521r1_sha512
结果:
root@server:~/bin# ./checkrsa
verify depth is 9
CONNECTED(00000003)
depth=0 CN = *.example.com
verify return:1
---
Certificate chain
0 s:CN = *.example.com
i:C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo RSA Domain Validation Secure Server CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIHNDCCBhygAwIBAgIQAzfJZrX65NjG2FvLmk0I0jANBgkqhkiG9w0BAQsFADCB
...
Xw8UgZDYihDaIxT8SUQUgV9weQg5Lkru
-----END CERTIFICATE-----
subject=CN = *.example.com
issuer=C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo RSA Domain Validation Secure Server CA
---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 2904 bytes and written 386 bytes
Verification: OK
Verified peername: *.example.com
DANE TLSA 3 1 1 ...99d48c44149b990a680cad8b matched EE certificate at depth 0
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 4096 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
250 CHUNKING
DONE
root@server:~/bin# ./checkecdsa
verify depth is 9
CONNECTED(00000003)
depth=0 CN = *.example.com
verify return:1
---
Certificate chain
0 s:CN = *.example.com
i:C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo
ECC Domain Validation Secure Server CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIEqDCCBE6gAwIBAgIRAIIKQBNWh2R9wwvn2/j30PgwCgYIKoZIzj0EAwIwgY8x
...
YemreHq/Cd5HPgIgE6InSF5ko6mWo9GMpR7w1ijpbsnShlS6EiYrpZozD0s=
-----END CERTIFICATE-----
subject=CN = *.example.com
issuer=C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo ECC Domain Validation Secure Server CA
---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: ECDSA
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 1811 bytes and written 348 bytes
Verification: OK
Verified peername: *.example.com
DANE TLSA 3 1 1 ...50d47bccdadbcfa42eae9158 matched EE certificate at depth 0
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 256 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
250 CHUNKING
DONE
因此,两个证书都在本地进行检验,但在外部仍然失败。
看到 Viktor 的消息表明,也许这些工具在成功使用 RSA 后放弃了 ECDSA 哈希,我也尝试只发布 ECDSA TLSA 记录。结果表明,仅使用 ECDSA 哈希就完全失败了。
因此,我遇到了这种情况:我有两套 SSL 证书,一套是 RSA,另一套是 ECDSA。两个证书在 Postfix 中都成功通过。两个证书都使用 openssl 进行签出。根据 RSA 证书,发布两个证书总体上都通过了,但 ECDSA 证书失败了。ECDSA 证书在本地成功,但在外部失败。
我不知道下一步该怎么做,并且正在寻求帮助以便同时设置我的 ECDSA 证书和 DANE 的 RSA 记录。
更新日期:6/5/22
我从 ca-bundle 文件中添加了 CA 随 ECDSA 证书提供的附加信息。
首先,我创建了一个 pem 文件,其中包括证书和 ca-bundle 的内容。
$ cat example.com.ecdsa.cert example.com.ecdsa.ca-bundle > example.com.ecdsa.pem.combined
我让这个文件在 main.cf 中可供 postfix 使用:
smtpd_tls_eccert_file=/etc/ssl/certs/example.com.ecdsa.pem.combined
接下来我使用了一个名为链根生成各种 TLSA 记录并将其添加到 DNS。
;; subject=CN = *.example.com
;; issuer=C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo ECC Domain Validation Secure Server CA
;; notBefore=May 17 00:00:00 2022 GMT
;; notAfter=Jun 17 23:59:59 2023 GMT
;;
_25._tcp.mail IN TLSA 3 0 1 87a8c75581...87fb13bfc5
_25._tcp.mail IN TLSA 3 1 1 ecd29ffd76...a42eae9158
_25._tcp.mail IN TLSA 3 0 2 d09f24a28f...cc8e69b13d
_25._tcp.mail IN TLSA 3 1 2 b83f332b52...4634ec6dce
;; subject=C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo ECC Domain Validation Secure Server CA
;; issuer=C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust ECC Certification Authority
;; notBefore=Nov 2 00:00:00 2018 GMT
;; notAfter=Dec 31 23:59:59 2030 GMT
;;
_25._tcp.mail IN TLSA 2 0 1 61e97375e9...8f5f65825f
_25._tcp.mail IN TLSA 2 1 1 e98044f242...db029d719a
_25._tcp.mail IN TLSA 2 0 2 2d44d5fbb5...33970c93c9
_25._tcp.mail IN TLSA 2 1 2 2042bc624d...a0aef921fe
总共有四组 TLSA 记录,我的 ecdsa 证书和三个父 CA 链式证书。此外,我还为端口 465 和 587 添加了额外的记录集。不幸的是,这些添加并没有改善我的结果。
答案1
是的,您提到的工具不适合测试您的设置。使用逐步检查并返回清晰消息的测试。
一个好的测试需要单独测试可能组合的笛卡尔积,得出以下结果:
- 对于每个 IP
- 对于每个算法
- 对于每种方法,PKI 和 DANE
- 并且可能针对每个 TLSA 使用、TLS 版本、SNI 等。
不幸的是,有些测试只尝试第一个 IP,有些测试只尝试第一个协商的密码套件。大多数测试都无法以明确的语言报告 DANE 或 PKI 匹配是否失败。
- 您的
s_client -dane_tlsa_...
命令很好。我检查时发现您的 DANE 设置很好。 - 因为你的证书意味着你还如果希望 PKI 验证能够正常工作,您还需要配置 Postfix 来发送中间文件,现在看来这已经奏效了。使用以下命令进行验证
s_client -CApath /etc/ssl/certs
回复:编辑:我怀疑您现在添加的 TLSA 记录比您需要的多。我建议不要同时提供用法 2 和 3、两个选择器(0 和 1)和多个 has 算法(1 和 2),而是只为 RSA 和 EC 各设置一个主证书和一个备份证书,而不是设置一大堆证书关联。(不过,我并不认为以这种方式生成的任何记录都会造成损害)。
答案2
我不是 DANE 或 TLSA 的专家(只是在这里学习基础知识),但我猜 @anx 是完全正确的:每个端口的条目太多了。最好一个就足够了3 1 1
(或者3 1 2
如果你更喜欢 SHA512),因为这应该允许发送端检查满的信任链。
这主要是因为我所知道的 DNS 解析器的默认行为(这意味着可能还有很多其他我不是意识到!)是要求全部与查询匹配的记录(例如: 的所有记录_25._tcp.mail
)和在可能的选项中随机选择一个。一些DNS RR 允许加权选择(例如 MX 记录);一些关于 TXT 字段的约定可能有自己的编码优先级和偏好的方式,但是,默认情况下,最多解析器将随机选择一个答复并使用它。
因此,这样的解析器可能只会得到1 x x
答复(因为它是随机选择的)并且严格进行 DANE 检查......并拒绝它,因为它无法验证完整的信任链。
请注意,我只是在推测。我上面的推理无法解释为什么你设法让 RSA 被接受,但 ECDSA 却不行。从理论上讲,由于你对两者的设置相同,所以两者都应该失败——但我假设我在这里遗漏了一些东西。
我自己的 DNS 几乎完全由 Cloudflare 管理(除了几个 DynDNS 域),Cloudflare 强制要求只有一TLSA 规则每个端口可以在区域中处于活动状态。这样,您就不会犯添加多个条目的“错误”——他们的后台界面永远不会允许这样做,即使假设这样做有充分的理由。因此,对于我自己的 DANE 设置,我只有3 1 1
条目。据我测试,这种方式似乎效果很好……