指南:基于 TLS 的 Broker、Proxy 與多語言客戶端全鏈路配置)
Apache Pulsar 傳輸層加密實戰(zhàn)指南基于 TLS 的 Broker、Proxy 與多語言客戶端全鏈路配置【免費下載鏈接】pulsarApache Pulsar - distributed pub-sub messaging system項目地址: https://gitcode.com/gh_mirrors/pulsar28/pulsar本文以 Apache Pulsar 官方安全文檔 security-tls-transport.md 為主體結(jié)合當(dāng)前倉庫中的 broker.conf、proxy.conf、client.conf 以及 PulsarService.java 等源碼與配置系統(tǒng)講解 Pulsar 的 TLS 傳輸加密原理、證書簽發(fā)全流程以及 Broker、Proxy、CLI 工具和 Java/Python/C/Node.js/C# 客戶端的完整配置方法。讀完本文你將能夠獨立為 Pulsar 集群啟用端到端的 TLS 傳輸加密并掌握協(xié)議版本、密碼套件與主機名校驗等安全加固手段。TLS 概述為什么默認(rèn)傳輸不安全默認(rèn)情況下Apache Pulsar 客戶端與 Pulsar 服務(wù)端之間以明文進行通信也就是說所有數(shù)據(jù)包括消息內(nèi)容與元數(shù)據(jù)在網(wǎng)絡(luò)上都是裸奔的。攻擊者只要能夠監(jiān)聽網(wǎng)絡(luò)即典型的中間人攻擊場景就可以竊取或篡改傳輸中的數(shù)據(jù)。啟用 TLS 可以對這條鏈路進行加密從而抵御中間人竊聽。TLS 不僅可以用作傳輸加密還可以在加密的同時承擔(dān)身份認(rèn)證職責(zé)。本文聚焦于純粹的傳輸加密配置如需在 TLS 之上疊加基于證書的客戶端認(rèn)證可參見 security-tls-authentication.md也可以先啟用 TLS 傳輸加密再疊加其他認(rèn)證機制如 Athenz。注意啟用 TLS 會引入加解密的計算開銷可能對性能產(chǎn)生一定影響需要在安全性與吞吐之間做權(quán)衡。TLS 核心概念TLS 基于公鑰密碼學(xué)public key cryptography實現(xiàn)。每一對密鑰由公鑰與私鑰組成公鑰用于加密消息私鑰用于解密消息。要在 Pulsar 中啟用 TLS 傳輸加密你至少需要兩類密鑰對服務(wù)端密鑰對server key pairs由每個 Broker / Proxy 持有。證書頒發(fā)機構(gòu)Certificate AuthorityCA用于簽發(fā)并背書上述證書。如果需要客戶端認(rèn)證還需要第三類密鑰對——客戶端密鑰對client key pairs具體見 security-tls-authentication.md。CA 的私鑰必須存放在極其安全的位置理想情況下是完全離線、物理隔離、全盤加密的計算機而 CA 的公鑰——即信任證書trust cert——可以自由分發(fā)。對于客戶端與服務(wù)端的每一對密鑰管理員的流程是統(tǒng)一的先生成私鑰和證書簽名請求CSR再用 CA 私鑰對 CSR 簽名最終生成一張證書certificate。這張證書本質(zhì)上是該密鑰對的公鑰載體。在傳輸加密場景下客戶端使用 CA 的trust cert來驗證服務(wù)端持有的密鑰對確實由該 CA 簽發(fā)。中間人攻擊者無法接觸 CA 私鑰因此無法偽造出具有合法簽名密鑰對的服務(wù)端。在TLS 認(rèn)證場景下服務(wù)端反過來用 trust cert 驗證客戶端密鑰對是否由 CA 簽發(fā)并將**客戶端證書的 Common NameCN**作為該客戶端的角色令牌role token參見 安全概覽。此外Pulsar 的密碼套件與算法由Bouncy Castle Provider提供。如果需要 FIPS 版本的 Bouncy Castle Provider請參考 security-bouncy-castle.md。創(chuàng)建 TLS 證書為 Pulsar 創(chuàng)建 TLS 證書需要依次完成三件事創(chuàng)建證書頒發(fā)機構(gòu)CA、創(chuàng)建服務(wù)端證書、創(chuàng)建客戶端證書。下面的步驟全部基于 OpenSSL 命令行。你也可以參考網(wǎng)絡(luò)上更詳盡的 OpenSSL CA 搭建資料。當(dāng)前倉庫中提供了一份可直接使用的 OpenSSL 配置文件site2/website/static/examples/openssl.cnf。這份配置以環(huán)境變量CA_HOME定位 CA 目錄下的所有文件與子目錄certs、crl、newcerts、private、index.txt、serial等并預(yù)置了v3_ca、server_cert、usr_cert等擴展模板。另外倉庫的 tests/certificate-authority/openssl.cnf 還保存了一份用于集成測試的同類配置可作為對照。創(chuàng)建證書頒發(fā)機構(gòu)CA為 CA 創(chuàng)建證書。CA 將同時用于簽發(fā) Broker 證書和客戶端證書從而保證各方相互信任。CA 應(yīng)存放在非常安全的位置理想情況是完全離線、隔離網(wǎng)絡(luò)且全盤加密。執(zhí)行以下命令創(chuàng)建 CA 目錄并把 openssl 配置文件放入該目錄。你可以按需修改配置文件中的默認(rèn)公司名、部門等應(yīng)答項。將 CA 目錄位置導(dǎo)出為環(huán)境變量CA_HOME——配置文件正是通過該變量定位其余文件與目錄mkdir my-ca cd my-ca wget https://raw.githubusercontent.com/apache/pulsar/master/site2/website/static/examples/openssl.cnf export CA_HOME$(pwd)執(zhí)行以下命令創(chuàng)建必要的目錄、密鑰與證書mkdir certs crl newcerts private chmod 700 private/ touch index.txt echo 1000 serial openssl genrsa -aes256 -out private/ca.key.pem 4096 chmod 400 private/ca.key.pem openssl req -config openssl.cnf -key private/ca.key.pem \ -new -x509 -days 7300 -sha256 -extensions v3_ca \ -out certs/ca.cert.pem chmod 444 certs/ca.cert.pem回答完提示問題后CA 相關(guān)文件將存放在./my-ca目錄中certs/ca.cert.pem公開證書需要分發(fā)給所有參與方即信任證書 / trust cert。private/ca.key.pem私鑰僅在為 Broker 或客戶端簽發(fā)新證書時需要用到必須嚴(yán)加保管。上面使用的v3_ca擴展在 openssl.cnf 中定義為basicConstraints critical, CA:true與keyUsage critical, digitalSignature, cRLSign, keyCertSign這正是 CA 證書應(yīng)有的關(guān)鍵屬性。創(chuàng)建服務(wù)端證書創(chuàng)建好 CA 證書后就可以生成證書請求并用 CA 為其簽名。下面的命令會詢問若干問題然后生成證書。當(dāng)被問到Common Name時應(yīng)填入 Broker 的主機名也可以使用通配符匹配一組 Broker 主機名例如*.broker.usw.example.com這樣多臺機器可以復(fù)用同一張證書。提示有些場景下無法或沒必要匹配主機名——例如 Broker 的主機名是隨機生成的或者你打算通過 IP 直連主機。此時應(yīng)配置客戶端關(guān)閉 TLS 主機名校驗詳見下文客戶端配置中的主機名校驗小節(jié)。執(zhí)行以下命令生成私鑰openssl genrsa -out broker.key.pem 2048Broker 期望私鑰是PKCS 8格式因此執(zhí)行以下命令進行轉(zhuǎn)換openssl pkcs8 -topk8 -inform PEM -outform PEM \ -in broker.key.pem -out broker.key-pk8.pem -nocrypt執(zhí)行以下命令生成證書簽名請求openssl req -config openssl.cnf \ -key broker.key.pem -new -sha256 -out broker.csr.pem用證書頒發(fā)機構(gòu)對其簽名openssl ca -config openssl.cnf -extensions server_cert \ -days 1000 -notext -md sha256 \ -in broker.csr.pem -out broker.cert.pem此時你擁有了證書broker.cert.pem與私鑰broker.key-pk8.pem它們可以與ca.cert.pem一起用于為 Broker 和 Proxy 節(jié)點配置 TLS 傳輸加密。這里使用的server_cert擴展在 openssl.cnf 中定義了extendedKeyUsage serverAuth確保該證書僅用于服務(wù)端認(rèn)證。創(chuàng)建客戶端證書客戶端證書的生成流程與服務(wù)端證書完全一致生成私鑰 → 生成 CSR → 用 CA 簽名。區(qū)別在于簽發(fā)時使用usr_cert擴展其extendedKeyUsage clientAuth, emailProtection見 openssl.cnf??蛻舳俗C書主要用于TLS 認(rèn)證即客戶端向服務(wù)端證明身份具體配置方法見 security-tls-authentication.md。如果你只需要傳輸加密則不必為客戶端簽發(fā)證書。配置 Broker要為 Pulsar Broker 啟用 TLS 傳輸加密需要修改 Pulsar 安裝目錄conf下的 broker.conf。在 Pulsar 單機安裝 中該文件位于conf/broker.conf。在配置文件中追加以下配置項將證書路徑替換為實際路徑brokerServicePortTls6651 webServicePortTls8081 tlsRequireTrustedClientCertOnConnecttrue tlsCertificateFilePath/path/to/broker.cert.pem tlsKeyFilePath/path/to/broker.key-pk8.pem tlsTrustCertsFilePath/path/to/ca.cert.pem各參數(shù)含義如下均可在 conf/broker.conf 的 TLS 段找到對應(yīng)注釋參數(shù)默認(rèn)值說明brokerServicePortTls空TLS 默認(rèn)關(guān)閉二進制協(xié)議生產(chǎn)/消費的 TLS 監(jiān)聽端口示例取 6651webServicePortTls空TLS 默認(rèn)關(guān)閉HTTP/HTTPS 管理接口的 TLS 監(jiān)聽端口示例取 8081tlsRequireTrustedClientCertOnConnectfalse是否強制要求連接方提供受信任的客戶端證書為true時拒絕未通過tlsTrustCertsFilePath校驗的客戶端連接等效于強制客戶端 TLS 認(rèn)證tlsCertificateFilePath空Broker 服務(wù)端證書如broker.cert.pem路徑tlsKeyFilePath空Broker 私鑰必須是 PKCS 8 格式如broker.key-pk8.pem路徑tlsTrustCertsFilePath空用于校驗連接方證書的信任證書如ca.cert.pem路徑校驗失敗則連接被拒絕關(guān)于端口需要注意brokerServicePortTls與webServicePortTls均為可選端口。從 PulsarService.java 可以看到Broker 啟動時會校驗 web 服務(wù)端口與 TLS 端口至少存在一個否則拋出IllegalArgumentException隨后啟動的 TLS 監(jiān)聽地址會被記錄為webServiceAddressTls與brokerServiceUrlTls并在 PulsarService.java 中注入內(nèi)部客戶端與服務(wù)發(fā)現(xiàn)邏輯。此外broker.conf 還包含以下值得了解的 TLS 相關(guān)配置tlsCertRefreshCheckDurationSec300TLS 證書刷新檢查周期秒設(shè)為0表示每個新連接都重新檢查。這意味著證書輪換后無需重啟 Broker 即可在下一個周期內(nèi)生效。tlsAllowInsecureConnectionfalse是否接受無法用tlsTrustCertsFilePath驗證的客戶端證書注意這與客戶端的allowInsecureConnection是不同方向的概念。生產(chǎn)環(huán)境應(yīng)保持false。tlsHostnameVerificationEnabledfalseBroker 與其他 Broker 建立 TLS 連接時是否校驗主機名。tlsProviderBroker 服務(wù)二進制協(xié)議使用的 TLS Provider。使用 CA 證書做 TLS 認(rèn)證時可選OPENSSL或JDK使用 KeyStore 時可選SunJSSE、Conscrypt等。webServiceTlsProviderConscryptWeb 服務(wù)默認(rèn)使用 Conscrypt 作為 TLS Provider。tlsEnabledWithKeyStorefalse及一組tlsKeyStore*/tlsTrustStore*啟用 KeyStore 類型的 TLS 配置JKS / PKCS12。brokerClientTlsEnabledfalse、brokerClientTrustCertsFilePathBroker 作為內(nèi)部客戶端連接其他 Broker 或集群復(fù)制時的 TLS 開關(guān)與信任證書路徑。棄用項tlsEnabled舊版統(tǒng)一開關(guān)已棄用請改用brokerServicePortTls與webServicePortTls。更多參數(shù)及默認(rèn)值的完整清單見 Broker 配置參考。TLS 協(xié)議版本與密碼套件可以配置 Broker以及 Proxy在 TLS 協(xié)商時強制使用指定的協(xié)議版本與密碼套件從而防止客戶端回退downgrade到存在弱點的舊協(xié)議或舊密碼。協(xié)議版本與密碼套件屬性均支持以逗號分隔的多個值。可選值取決于你使用的 TLS ProviderPulsar優(yōu)先使用 OpenSSL若系統(tǒng)可用否則回退到 JDK 實現(xiàn)。tlsProtocolsTLSv1.3,TLSv1.2 tlsCiphersTLS_DH_RSA_WITH_AES_256_GCM_SHA384,TLS_DH_RSA_WITH_AES_256_CBC_SHAOpenSSL 目前支持TLSv1.1、TLSv1.2和TLSv1.3協(xié)議版本可通過openssl ciphers -tls1_3等命令查詢當(dāng)前 OpenSSL 支持的密碼套件列表。JDK 11 的支持值可從官方文檔獲取TLS 協(xié)議參數(shù)與 SunJSSE 密碼套件兩個章節(jié)。需要注意的是broker.conf 中還單獨提供了webServiceTlsProtocols與webServiceTlsCiphers用于分別控制Web 服務(wù)HTTPS 管理接口的協(xié)議與密碼套件而tlsProtocols/tlsCiphers控制的是二進制協(xié)議端口。同時Broker 內(nèi)部客戶端與其他 Broker 通信的協(xié)議與密碼由brokerClientTlsProtocols/brokerClientTlsCiphers控制——在 PulsarService.java 中可以看到這些值被注入到內(nèi)部 Pulsar 客戶端的setTlsCiphers/setTlsProtocols。配置 ProxyProxy 需要在兩個方向上配置 TLS一是面向連接 Proxy 的客戶端二是 Proxy 連接Broker的方向。相關(guān)配置位于 conf/proxy.conf。# For clients connecting to the proxy tlsEnabledInProxytrue tlsCertificateFilePath/path/to/broker.cert.pem tlsKeyFilePath/path/to/broker.key-pk8.pem tlsTrustCertsFilePath/path/to/ca.cert.pem # For the proxy to connect to brokers tlsEnabledWithBrokertrue brokerClientTrustCertsFilePath/path/to/ca.cert.pem對應(yīng) conf/proxy.conf 中的實際配置項面向客戶端方向tlsEnabledInProxytrue該開關(guān)在 proxy.conf 中標(biāo)注為已棄用新的方式是直接設(shè)置 TLS 監(jiān)聽端口servicePortTls二進制協(xié)議與webServicePortTlsWeb 服務(wù)。棄用項保留僅為兼容。tlsCertificateFilePath/tlsKeyFilePathProxy 對外提供服務(wù)時使用的證書與 PKCS 8 私鑰可以復(fù)用為 Broker 簽發(fā)的服務(wù)端證書。tlsTrustCertsFilePath用于校驗客戶端證書的信任證書。面向 Broker 方向tlsEnabledWithBrokertrue是否在 Proxy 與 Broker 之間啟用 TLS。brokerClientTrustCertsFilePath/path/to/ca.cert.pemProxy 作為客戶端連接 Broker 時使用的信任證書路徑見 proxy.conf 注釋。此外還可配置tlsHostnameVerificationEnabledProxy 連接 Broker 時是否校驗主機名、tlsCertRefreshCheckDurationSec300證書刷新周期等。與 Broker 一樣proxy.conf 也提供tlsProtocols/tlsCiphers二進制協(xié)議與webServiceTlsProtocols/webServiceTlsCiphersWeb 服務(wù)兩組協(xié)議與密碼套件配置以及tlsRequireTrustedClientCertOnConnect強制客戶端證書與 KeyStore 系列配置tlsEnabledWithKeyStore等??蛻舳伺渲脝⒂?TLS 傳輸加密后客戶端需要改用加密協(xié)議與對應(yīng)端口Web 服務(wù) URL使用https://端口 8443對應(yīng) Broker 的webServicePortTls。Broker 服務(wù) URL使用pulsarssl://端口 6651對應(yīng) Broker 的brokerServicePortTls。由于上文生成的服務(wù)端證書不屬于任何系統(tǒng)默認(rèn)信任鏈你還必須顯式指定 trust cert 路徑推薦或者允許客戶端信任未受信任的服務(wù)端證書不推薦見下文主機名校驗討論。主機名校驗Hostname verification主機名校驗是 TLS 的一項安全特性客戶端在連接時若服務(wù)器證書的Common NameCN與正在連接的主機名不匹配則拒絕連接。默認(rèn)情況下Pulsar 客戶端關(guān)閉主機名校驗因為開啟它要求每個 Broker 都有對應(yīng)的 DNS 記錄和獨立證書。與此同時由于管理員完全掌控證書頒發(fā)機構(gòu)攻擊者極難實施中間人攻擊。關(guān)于allowInsecureConnection允許連接證書未經(jīng)受信任 CA 簽名的服務(wù)器客戶端默認(rèn)關(guān)閉該選項生產(chǎn)環(huán)境應(yīng)當(dāng)始終保持關(guān)閉。只要關(guān)閉allowInsecureConnection中間人攻擊就要求攻擊者同時掌握 CA 的私鑰——這正是把 CA 私鑰離線保管的價值所在。一個推薦開啟主機名校驗的場景是多個 Proxy 節(jié)點位于 VIP 之后且 VIP 有 DNS 記錄例如pulsar.mycompany.com。此時可以為pulsar.mycompany.com生成一張 CN 為此域名的 TLS 證書然后在客戶端開啟主機名校驗。下面示例以 Java 客戶端展示主機名校驗的顯式關(guān)閉寫法其實該選項默認(rèn)就是關(guān)閉的可以省略。C/Python/Node.js 客戶端目前不支持配置該項。CLI 工具命令行工具如pulsar-admin、pulsar-perf、pulsar-client統(tǒng)一讀取 Pulsar 安裝目錄中的 conf/client.conf。要使這些工具走 TLS需要在該文件中追加以下參數(shù)webServiceUrlhttps://broker.example.com:8443/ brokerServiceUrlpulsarssl://broker.example.com:6651/ useTlstrue tlsAllowInsecureConnectionfalse tlsTrustCertsFilePath/path/to/ca.cert.pem tlsEnableHostnameVerificationfalse對照 conf/client.conf 中的實際注釋webServiceUrlREST API管理操作地址TLS 時為https://…:8443/。brokerServiceUrl二進制協(xié)議生產(chǎn)/消費地址TLS 時為pulsarssl://…:6651/。tlsAllowInsecureConnectionfalse是否允許連接證書無法驗證的服務(wù)器默認(rèn)false。tlsEnableHostnameVerificationfalse是否要求服務(wù)器主機名與證書 CN 一致默認(rèn)false。tlsTrustCertsFilePath信任證書路徑用于校驗服務(wù)器證書是否由該 CA 簽發(fā)校驗失敗則連接被斷開。此外若需要客戶端證書認(rèn)證可配置authPluginorg.apache.pulsar.client.impl.auth.AuthenticationTls與authParamstlsCertFile:/path/to/client-cert.pem,tlsKeyFile:/path/to/client-key.pem以及 KeyStore 模式下的useKeyStoreTls/tlsTrustStore*系列參數(shù)。Java 客戶端import org.apache.pulsar.client.api.PulsarClient; PulsarClient client PulsarClient.builder() .serviceUrl(pulsarssl://broker.example.com:6651/) .enableTls(true) .tlsTrustCertsFilePath(/path/to/ca.cert.pem) .enableTlsHostnameVerification(false) // false by default, in any case .allowTlsInsecureConnection(false) // false by default, in any case .build();Python 客戶端from pulsar import Client client Client(pulsarssl://broker.example.com:6651/, tls_hostname_verificationTrue, tls_trust_certs_file_path/path/to/ca.cert.pem, tls_allow_insecure_connectionFalse) # defaults to false from v2.2.0 onwardsC 客戶端#include pulsar/Client.h ClientConfiguration config ClientConfiguration(); config.setUseTls(true); // shouldnt be needed soon config.setTlsTrustCertsFilePath(caPath); config.setTlsAllowInsecureConnection(false); config.setAuth(pulsar::AuthTls::create(clientPublicKeyPath, clientPrivateKeyPath)); config.setValidateHostName(true);Node.js 客戶端const Pulsar require(pulsar-client); (async () { const client new Pulsar.Client({ serviceUrl: pulsarssl://broker.example.com:6651/, tlsTrustCertsFilePath: /path/to/ca.cert.pem, }); })();C# 客戶端var certificate new X509Certificate2(ca.cert.pem); var client PulsarClient.Builder() .TrustedCertificateAuthority(certificate) //If the CA is not trusted on the host, you can add it explicitly. .VerifyCertificateAuthority(true) //Default is true .VerifyCertificateName(false) //Default is false .Build();驗證與后續(xù)完成上述配置后可以用pulsar-client已配置 TLS 的 CLI嘗試生產(chǎn)/消費一條消息確認(rèn)鏈路可通也可以使用openssl s_client -connect broker.example.com:6651 -CAfile ca.cert.pem之類的手段直接檢查 TLS 握手與證書鏈。如果在啟用 TLS 傳輸加密的同時還需要客戶端身份認(rèn)證請繼續(xù)閱讀 security-tls-authentication.md若需要 FIPS 合規(guī)的 Bouncy Castle Provider參考 security-bouncy-castle.md所有 Broker 配置項的完整默認(rèn)值清單見 reference-configuration.md?!久赓M下載鏈接】pulsarApache Pulsar - distributed pub-sub messaging system項目地址: https://gitcode.com/gh_mirrors/pulsar28/pulsar創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考