DANE(DNS-Based Authentication of Named Entities)是一种基于 DNS 的证书认证机制,通过 TLSA 记录将证书信息绑定到域名上。本文详细介绍 DANE 的原理、TLSA 记录格式以及在 Nginx 中的配置方法。

传统证书验证的问题

传统的 TLS 证书验证依赖 CA(证书颁发机构)体系,存在以下问题:

  1. CA 可能被攻陷:全球有数百个可信 CA,一个 CA 被攻陷即可签发任意域名证书
  2. 证书透明度不足:难以发现恶意或错误签发的证书
  3. 依赖链复杂:多级中间 CA 增加验证复杂度和风险

什么是 DANE?

DANE 定义于 RFC 6698,是一种基于 DNS 的证书认证机制。它通过在 DNS 中添加 TLSA 记录(TLS Authentication),将证书信息直接与域名绑定,绕过传统 CA 验证体系。

DANE 的核心优势

  • 防范 CA 被攻陷:即使 CA 被攻陷,攻击者也无法伪造 DNS 中的 TLSA 记录
  • 自建 CA 的福音:企业内部 CA 签发的证书也能被客户端信任
  • 证书固定:将证书指纹写入 DNS,客户端只能接受指定证书

TLSA 记录格式

TLSA 记录包含四个字段,格式为:Usage Selector MatchingType AssociationData

1
_443._tcp.example.com. IN TLSA 3 1 1 73D2522B56547E710E480F27CCFD6F75959422668C2C300B98AC07E6D7

1. Usage(用法)

名称 说明
0 PKIX-TA 使用受信任 CA 证书验证(X.509 PKIX 路径)
1 PKIX-EE 使用受信任 CA 验证终端实体证书
2 DANE-TA 使用信任锚(Trust Anchor)验证
3 DANE-EE 直接使用证书或公钥,无 CA 验证

2. Selector(选择器)

名称 说明
0 Full 使用完整证书
1 SPKI 使用公钥SubjectPublicKeyInfo

3. MatchingType(匹配类型)

名称 说明
0 NoHash 完整数据
1 SHA-256 SHA-256 哈希
2 SHA-512 SHA-512 哈希

4. AssociationData(关联数据)

实际的证书哈希值或公钥数据。

使用场景详解

场景一:DANE-EE(用法 3)

最常用场景,直接指定证书哈希,无需 CA 验证:

1
2
# 生成证书哈希
openssl x509 -in server.crt -noout -fingerprint -sha256 | cut -d'=' -f2 | tr -d ':'

输出示例:

1
73D2522B56547E710E480F27CCFD6F75959422668C2C300B98AC07E6D778D149

TLSA 记录:

1
_443._tcp.example.com. IN TLSA 3 1 1 73D2522B56547E710E480F27CCFD6F75959422668C2C300B98AC07E6D778D149

场景二:DANE-TA(用法 3,选择器 0)

使用证书链中的 CA 证书:

1
2
# 获取 CA 证书的哈希
openssl x509 -in ca.crt -noout -fingerprint -sha256 | cut -d'=' -f2 | tr -d ':'

场景三:SPKI 模式

只验证公钥,允许证书更新而无需修改 TLSA 记录:

1
2
# 获取公钥 SHA-256 哈希
openssl x509 -in server.crt -noout -pubkey | openssl pkey -pubin -outform der | openssl dgst -sha256 | cut -d' ' -f2

DANE 验证实战

命令行验证 DANE

使用 dig 查询 TLSA 记录:

1
dig TLSA _443._tcp.example.com

使用 openssl 配合 dane 验证:

1
2
# OpenSSL 3.0+ 支持 DANE 验证
openssl s_client -connect example.com:443 -dane_tlsa_domain example.com

编程验证示例

使用 GnuTLS 工具验证:

1
2
# 使用 gnutls-cli 验证 DANE
gnutls-cli --dane example.com

Nginx 配置 DANE

在 Nginx 中配置 DANE 需要:

  1. 配置 DNS TLSA 记录
  2. 配置 Nginx 使用正确的证书
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate /path/to/server.crt;
    ssl_certificate_key /path/to/server.key;

    # 启用 OCSP stapling(推荐配合 DANE 使用)
    ssl_stapling on;
    ssl_stapling_verify on;
}

生成 TLSA 记录的工具

使用 ldns-utils 生成 TLSA 记录:

1
2
3
4
5
6
# 安装 ldns
apt-get install ldnsutils

# 生成 TLSA 记录
ldns-keygen -a sha256 example.com
ldns-rrsig -a sha256 -z example.com example.com

DANE 与 DNSSEC

重要:DANE 必须配合 DNSSEC 使用,否则 DNS 响应可能被篡改。

验证 DNSSEC

1
dig +dnssec example.com

检查响应中的 AD 标志(Authentic Data):

1
dig example.com | grep -i ad

常见问题

Q1:证书到期更新怎么办?

使用 SPKI 模式(选择器 0)可以只验证公钥,证书更新时无需修改 TLSA 记录:

1
2
# 公钥哈希不随证书更新而变化
openssl x509 -in new_server.crt -noout -pubkey | openssl pkey -pubin -outform der | openssl dgst -sha256

Q2:客户端如何支持 DANE?

  • Firefox:内置支持
  • Chrome:使用系统 DNS 解析,支持 DNSSEC 时自动启用
  • curl:需要 GnuTLS 后端

Q3:多个证书如何配置?

支持多个 TLSA 记录,实现证书轮换:

1
2
_443._tcp.example.com. IN TLSA 3 1 1 old-cert-hash
_443._tcp.example.com. IN TLSA 3 1 1 new-cert-hash

总结

DANE 通过 DNS 将证书信任从传统 CA 体系中解放出来,特别适合:

  • 企业内部 PKI
  • 防范 CA 被攻陷的风险
  • 高安全要求的场景

但需要注意:DANE 依赖 DNSSEC,部署前需确保 DNS 基础设施支持 DNSSEC。


参考来源: