文章目錄
C# 在啟用 TLS 的 RabbitMQ 上收發訊息
之前筆記 為 RabbitMQ container 啟用 TLS 連線 提到最近 partner 為了安全性考量,在與我們介接的 RabbitMQ 上啟用 TLS 連線,連線由 port 5672 改為 port 5671,造成 application 這邊完全陣亡,也紀錄到如何為 RabbitMQ container 啟用 TLS 連線建立測試環境,今天就來紀錄一下如何使用 C# 在啟用 TLS 的 RabbitMQ 上收發訊息
application 錯誤
錯誤訊息
Unhandled exception. RabbitMQ.Client.Exceptions.BrokerUnreachableException: None of the specified endpoints were reachable ---> System.IO.IOException: connection.start was never received, likely due to a network timeout at RabbitMQ.Client.Framing.Impl.Connection.StartAndTune() at RabbitMQ.Client.Framing.Impl.Connection.Open(Boolean insist) at RabbitMQ.Client.Framing.Impl.Connection..ctor(IConnectionFactory factory, Boolean insist, IFrameHandler frameHandler, String clientProvidedName) at RabbitMQ.Client.Framing.Impl.Connection..ctor(IConnectionFactory factory, Boolean insist, IFrameHandler frameHandler, ArrayPool`1 memoryPool, String clientProvidedName) at RabbitMQ.Client.Framing.Impl.AutorecoveringConnection.Init(IFrameHandler fh) at RabbitMQ.Client.Framing.Impl.AutorecoveringConnection.Init(IEndpointResolver endpoints) at RabbitMQ.Client.ConnectionFactory.CreateConnection(IEndpointResolver endpointResolver, String clientProvidedName)
錯誤截圖
基本環境說明
- macOS Sonoma 14.3 (Apple M2 Pro)
- OrbStack Version 1.3.0 (16556)
- .NET SDK 8.0.100
- JetBrains Rider 2023.3.3
Container Images
- rabbitmq:3.12.12-management
NuGet Library
- RabbitMQ.Client 6.8.1
rabbitmq.conf
docker-compose.yml
設定方式
建立客戶端憑證
這個部份可以參考 為 RabbitMQ container 啟用 TLS 連線 的說明:用同一份 ca 證書來建立 client 證書,client 證書建立方式與 server 相同,再只是需要將 client 私鑰與 client 證書匯出成 p12 檔
建立 client 私鑰
openssl genrsa -out client.key.pem 4096
建立 CSR(Certificate Signing Request)
openssl req -new -key client.key.pem -sha256 -out client.csr.pem
- Country Name (2 letter code):預設
AU
- State or Province Name (full name) :
Some-State
- Locality Name (eg, city):預設空值
- Organization Name (eg, company) :預設
Internet Widgits Pty Ltd
- Organizational Unit Name (eg, section):預設空值
- Common Name (e.g. server FQDN or YOUR name) :預設空值
Email Address :預設空值
- Country Name (2 letter code):預設
使用 CA 證書和私鑰簽署 CSR 以產生 client 證書
openssl x509 -req -in client.csr.pem -CA ca.cert.pem -CAkey ca.key.pem -sha256 -days 365 -out client.cert.pem
將 client 私鑰與 client 證書匯出成 p12 檔
openssl pkcs12 -export -out cert.p12 -in client.cert.pem -inkey client.key.pem -passin pass:pass.123 -passout pass:pass.123
檢驗 client 證書有效性
openssl verify -CAfile ca.cert.pem cert.p12
程式碼
Publish
Consume
心得
- 原則上 publish 跟 consume 的程式跟沒有 tls 的相同,只是在連線的時候需要設定 SslOption 並指定 client 證書與對應的密碼
為了避免 ssl 驗證失敗也需要在 SslOption 中加上以下設定
AcceptablePolicyErrors = System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors | System.Net.Security.SslPolicyErrors.RemoteCertificateNameMismatch | System.Net.Security.SslPolicyErrors.RemoteCertificateNotAvailable
另外過去我都是使用 amqpTcpEndpoints 來設定 endpoint,但有 tls 的版本我還沒有試出正確的寫法,暫時先用 uri 的方式來設定 endpoint
完整程式碼可以參考 GitHub:yowko/rabbitmq-tls-csharp
參考資訊
文章作者 Yowko Tsai
上次更新 2024-02-01
授權合約
本部落格 (Yowko's Notes) 所有的文章內容(包含圖片),任何轉載行為,必須通知並獲本部落格作者 (Yowko Tsai) 的同意始得轉載,且轉載皆須註明出處與作者。
Yowko's Notes 由 Yowko Tsai 製作,以創用CC 姓名標示-非商業性-相同方式分享 3.0 台灣 授權條款 釋出。