DANE DNS 基礎憑證驗證

DANE DNS-Based Authentication of Named Entities

DANE 概述

DANE(DNS-Based Authentication of Named Entities)是一種利用 DNS 基礎設施來驗證 TLS 憑證的安全協定。它透過 DNSSEC 簽署的 DNS 記錄來發布憑證資訊,讓用戶端可以直接從 DNS 查詢中驗證伺服器的憑證是否正確。

DANE 的主要優勢包括:

  • 減少對 CA 的依賴:網域擁有者可以自行指定信任的憑證
  • 防止中間人攻擊:透過 DNSSEC 確保 DNS 記錄的完整性
  • 降低憑證濫發風險:即使 CA 被入侵,攻擊者也無法輕易偽造憑證

DANE 與傳統 PKI 比較

項目傳統 PKIDANE
信任模型信任所有 CA只信任網域指定的憑證
憑證驗證CA 簽章驗證DNS 記錄驗證
安全基礎CA 的可信度DNSSEC 簽章
憑證撤銷CRL/OCSP更新 DNS 記錄
部署複雜度較低需要 DNSSEC

傳統 PKI 模型中,任何一個被信任的 CA 都可以為任何網域簽發憑證,這造成了安全隱患。DANE 透過將憑證資訊綁定到 DNS 記錄,讓網域擁有者能夠明確指定哪些憑證是合法的。

TLSA 記錄格式

DANE 使用 TLSA(Transport Layer Security Authentication)資源記錄來發布憑證資訊。TLSA 記錄的格式如下:

1
_port._protocol.hostname. IN TLSA usage selector matching-type certificate-data

各欄位說明:

  • _port:服務的連接埠號碼(如 _443 代表 HTTPS)
  • _protocol:傳輸協定(如 _tcp_udp
  • hostname:主機名稱
  • usage:憑證使用模式(0-3)
  • selector:選擇器(0-1)
  • matching-type:匹配類型(0-2)
  • certificate-data:憑證資料或雜湊值

憑證使用模式

DANE 定義了四種憑證使用模式(Certificate Usage):

模式 0:PKIX-TA(CA Constraint)

限制憑證必須由指定的 CA 簽發,並且必須通過 PKIX 驗證。

1
2
# 使用模式 0 的 TLSA 記錄範例
_443._tcp.example.com. IN TLSA 0 0 1 abc123...

模式 1:PKIX-EE(Service Certificate Constraint)

指定伺服器必須使用特定的憑證,並且必須通過 PKIX 驗證。

1
2
# 使用模式 1 的 TLSA 記錄範例
_443._tcp.example.com. IN TLSA 1 0 1 def456...

模式 2:DANE-TA(Trust Anchor Assertion)

指定信任錨點,不需要 PKIX 驗證。適合使用自簽憑證的情境。

1
2
# 使用模式 2 的 TLSA 記錄範例
_443._tcp.example.com. IN TLSA 2 0 1 ghi789...

模式 3:DANE-EE(Domain Issued Certificate)

直接指定伺服器憑證,不需要 PKIX 驗證。這是最常用的模式。

1
2
# 使用模式 3 的 TLSA 記錄範例
_443._tcp.example.com. IN TLSA 3 0 1 jkl012...

選擇器與匹配類型

選擇器(Selector)

名稱說明
0Cert使用完整憑證
1SPKI只使用 Subject Public Key Info

建議使用選擇器 1(SPKI),因為在憑證更新時,只要公鑰不變,就不需要更新 TLSA 記錄。

匹配類型(Matching Type)

名稱說明
0Full完整資料
1SHA-256SHA-256 雜湊
2SHA-512SHA-512 雜湊

建議使用匹配類型 1(SHA-256),在安全性和資料大小之間取得平衡。

產生 TLSA 記錄

以下是使用 OpenSSL 產生 TLSA 記錄的方法:

方法一:從憑證檔案產生

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 產生完整憑證的 SHA-256 雜湊(選擇器 0,匹配類型 1)
openssl x509 -in certificate.crt -outform DER | \
    openssl dgst -sha256 -binary | \
    xxd -p -c 256

# 產生 SPKI 的 SHA-256 雜湊(選擇器 1,匹配類型 1)
openssl x509 -in certificate.crt -noout -pubkey | \
    openssl pkey -pubin -outform DER | \
    openssl dgst -sha256 -binary | \
    xxd -p -c 256

方法二:從伺服器直接取得

1
2
3
4
5
# 從運行中的伺服器取得憑證並產生 TLSA 記錄
echo | openssl s_client -connect example.com:443 2>/dev/null | \
    openssl x509 -outform DER | \
    openssl dgst -sha256 -binary | \
    xxd -p -c 256

方法三:使用專用工具

1
2
3
4
5
# 安裝 hash-slinger 套件(包含 tlsa 工具)
sudo apt install hash-slinger

# 產生 TLSA 記錄
tlsa --create --certificate certificate.crt --selector 1 --mtype 1 example.com

DNS 設定範例

以下是在不同 DNS 服務中設定 TLSA 記錄的範例:

BIND DNS 設定

在 zone 檔案中加入以下記錄:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
; TLSA record for HTTPS (port 443)
_443._tcp.www    IN    TLSA    3 1 1 (
    a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4
    e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2
)

; TLSA record for SMTP (port 25)
_25._tcp.mail    IN    TLSA    3 1 1 (
    f6e5d4c3b2a1f6e5d4c3b2a1f6e5d4c3
    b2a1f6e5d4c3b2a1f6e5d4c3b2a1f6e5
)

Cloudflare DNS 設定

在 Cloudflare 控制台中:

  1. 進入 DNS 管理頁面
  2. 點擊「新增記錄」
  3. 類型選擇「TLSA」
  4. 填入相關資訊:
    • 名稱:_443._tcp.www
    • 使用模式:3
    • 選擇器:1
    • 匹配類型:1
    • 憑證資料:(貼上雜湊值)

使用 nsupdate 動態更新

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 建立 nsupdate 指令檔
cat << 'EOF' > update-tlsa.txt
server ns1.example.com
zone example.com
update delete _443._tcp.www.example.com. TLSA
update add _443._tcp.www.example.com. 3600 TLSA 3 1 1 a1b2c3d4...
send
EOF

# 執行更新
nsupdate -k /path/to/dns-key.private update-tlsa.txt

驗證 DANE 設定

使用 dig 查詢 TLSA 記錄

1
2
3
4
5
# 查詢 TLSA 記錄
dig +short TLSA _443._tcp.www.example.com

# 查詢完整資訊
dig +dnssec TLSA _443._tcp.www.example.com

使用 openssl 驗證

1
2
# 驗證憑證與 TLSA 記錄是否匹配
openssl s_client -connect www.example.com:443 -dane_tlsa_domain www.example.com

使用線上工具驗證

以下是一些實用的線上驗證工具:

  • DANE SMTP Validator:https://dane.sys4.de/
  • Internet.nl:https://internet.nl/
  • SSL Labs:https://www.ssllabs.com/ssltest/

使用 danetool 驗證

1
2
3
4
5
# 安裝 gnutls-bin 套件
sudo apt install gnutls-bin

# 驗證 DANE 設定
danetool --check www.example.com --port 443

部署注意事項

前置條件

  1. 啟用 DNSSEC:DANE 依賴 DNSSEC 來確保 DNS 記錄的完整性,沒有 DNSSEC 的 DANE 記錄將被忽略
  2. 確認 DNS 解析器支援:確保用戶端使用的 DNS 解析器支援 DNSSEC 驗證

憑證更新流程

更新憑證時,請遵循以下步驟以避免服務中斷:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 1. 產生新憑證的 TLSA 記錄
NEW_HASH=$(openssl x509 -in new-cert.crt -noout -pubkey | \
    openssl pkey -pubin -outform DER | \
    openssl dgst -sha256 -binary | xxd -p -c 256)

# 2. 先新增新的 TLSA 記錄(保留舊記錄)
# 等待 DNS TTL 過期

# 3. 更換伺服器憑證

# 4. 確認服務正常後,移除舊的 TLSA 記錄

常見問題排解

問題可能原因解決方案
TLSA 查詢無結果DNS 未正確設定檢查 DNS 記錄語法
驗證失敗雜湊值不匹配重新產生 TLSA 記錄
DNSSEC 驗證失敗簽章過期或無效重新簽署 DNS zone
憑證不匹配使用錯誤的選擇器確認選擇器設定

安全建議

  1. 使用 DANE-EE(模式 3)配合選擇器 1:這是最推薦的組合
  2. 設定適當的 TTL:建議 3600 秒(1 小時)
  3. 監控 TLSA 記錄:定期檢查記錄是否正確
  4. 憑證更新前預先部署:新增新 TLSA 記錄後等待 TTL 過期再更換憑證

參考資料

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy