如何在我自己的伺服器上設置加密 SNI?
我有執行多個虛擬主機的 Web 伺服器,並且我想讓竊聽者知道客戶端正在訪問哪個虛擬主機。已經有一個 TLS 擴展來解決這個問題:加密 SNI。我看到 Cloudflare 在其伺服器上支持它,並且 Firefox 有一個設置可以在客戶端上啟用它。不過,我找不到任何關於如何在我自己的伺服器上啟用此功能的文件。我該怎麼做呢?(我不依賴於任何特定的伺服器堆棧,並且會接受除“將其置於 Cloudflare 之後”之外的任何工作設置/架構。)
加密伺服器名稱指示 (ESNI) 仍然是 Internet 草案,您不會在任何主要的伺服器實現中找到它,因為它可能會發生變化。事實上,Firefox 實現的草稿版本支持與較新草稿版本不兼容的 draft-ietf-tls-esni-01。
我在這裡發布了 2019 年 4 月觀察到的生態系統狀態:
- 最新版本是https://datatracker.ietf.org/doc/html/draft-ietf-tls-esni-03
- OpenSSL 正在等待草稿完成。https://github.com/openssl/openssl/issues/7482
- Firefox+NSS 支持草稿-01 https://bugzilla.mozilla.org/show_bug.cgi?id=1495120 https://github.com/nss-dev/nss/blob/8a8b92f05d2d/lib/ssl/tls13esni.c
- Cloudflare 支持草案 -01
- picotls 支持它https://github.com/h2o/picotls/pull/155
- 在廣泛部署 ESNI 之前,Go crypto/tls 將不支持它:https ://github.com/golang/go/issues/9671#issuecomment-439561672
如您所見,Nginx 和 Apache 使用的 OpenSSL 不支持它。您可以嘗試使用已修補的 Go crypto/tls 庫(使用tls-tris 中的此 PR )建構Caddy,但隨著時間的推移它可能無法正常工作。
實驗
出於實驗或教育目的,您可以使用tls-tris中的 esnitool 和 tris-localserver 。假設您在 Linux 或 macOS 上安裝了適當的 Go 工具鏈,這樣的事情應該可以工作:
# Get source code and build stuff git clone https://github.com/cloudflare/tls-tris -b pwu/esni cd tls-tris make build-esnitool (cd _dev/tris-localserver && ../go.sh build -v -i .) # Generate ESNI key material, valid for 24 hours (one day) _dev/esnitool/esnitool -validity=24h -esni-keys-file=esni.pub -esni-private-file=esni.key
它將創建兩個文件:
- esni.pub -
/wFsX6klACQA...AAAA=
您必須在 DNS 中配置的值。如果您想為 配置 ESNI ,請使用該值www.example.com
創建一個 TXT 記錄。此格式符合 Firefox 和 Cloudflare 支持的 draft-ietf-tls-esni-01 規範。它不使用最新的草案規範。_esni.www.example.com``/wFsX6klACQA<snip>AAAA=
- esni.priv - 專用於測試實現的私鑰文件。
測試伺服器可以如下啟動:
_dev/tris-localserver/tris-localserver -esni-keys=esni.pub -esni-private=esni.priv
然後配置 Firefox 以啟用使用 ESNI,打開
about:config
並設置network.security.esni.enabled
為 true。您還必須啟用 DNS-over-HTTPS,可以在該頁面上找到 Firefox 說明。還可以在此處找到有關每個首選項的更多詳細資訊:https ://bagder.github.io/TRRprefs/這些說明現在可能有效,但將來會中斷,因為 Firefox 可能會更新以支持較新的草稿版本。上面的 esnitool 還對允許的密碼套件 (AES128-GCM) 和密鑰交換算法 (X25519) 進行了硬編碼。這反映了 Cloudflare 使用的參數。
評論
ESNI 暗示 TLS 1.3,因此證書及其嵌入的主機名將被加密。啟用 ESNI 並使用安全的 DNS 傳輸,例如 DNS-over-HTTPS (DoH) 或 DNS-over-TLS (DoT),伺服器名稱在網路上確實不可見,這可以在 Wireshark 中使用如
frame contains "wireshark"
訪問時過濾wireshark.org
。但是,如果單個 IP 僅託管幾個域,那麼任何被動攻擊者都可以猜測您正在訪問其中一個域。像 Cloudflare 這樣的大型運營商有更多的域,這不是什麼大問題。
由於 ESNI 使用半靜態密鑰,因此洩露私鑰意味著任何竊聽者都可以解密加密的伺服器名稱。這就是為什麼 ESNI 密鑰經常輪換,並且需要自動化的原因。Cloudflare 在 DNS 和 HTTPS 服務中具有這種良好集成的 ESNI 密鑰,並且會定期更新。
總而言之,ESNI 很有前景,但需要客戶端(Web 瀏覽器)、通過安全傳輸 (DoH/DoT) 的 DNS 伺服器和 Web 伺服器的支持。它仍在開發中,除非您密切關注它的開發,否則將其設置用於實驗之外的其他事情可能不是一個好主意。