RabbitMQ 3.6.6 TLS Support(翻譯)

簡介html

  RabbitMQ 已結內置支持 TLS,這包括客戶端鏈接和流行的插件,例如 Fedaration links。一樣,在集羣中使用 TLS 也能對內部節點間的鏈接進行加密。java

  本指南包含了 RabbitMQ 中關於 TLS 的多個主題:node

  > 在 RabbitMQ 中啓動 TLS listeners
  > 對於開發和 QA 環境中,如何生成自簽名證書
  > Java 和 .NET 客戶端中 TLS 配置
  > TLS版本和密碼套件配置
  > 證書鏈驗證深度linux

  還有更多。可是,本文並非關於 TLS、加密、公鑰 Infrastructure 以及相關內容的基礎讀物,所以,本文不會對它們進行詳細的介紹,初學者能夠在網絡上找到大量的基礎讀物git

  RabbitMQ 支持的全部協議均可以使用 TLS,而不只僅是本指南關注的 AMQP 0-9-1。HTTP API 在通過配置後也可以很好地使用 TLS(HTTPS)。github

  對於常見的 TLS 問題,請參見 Troubleshooting TLS-related issuesweb

Client 使用 TLS 鏈接 RabbitMQubuntu

  對於客戶端鏈接,有兩種方法:瀏覽器

  > 配置 RabbitMQ,讓其處理 TLS 鏈接
  > 使用代理或者負載均衡器(例如 HAproxy)做爲 TLS 鏈接的終端,接受該鏈接,而後使用純 TCP 鏈接到 RabbitMQ 節點。安全

  這兩種方法都是可行的,同時都有優缺點。本指南將關注第一種方法。

TLS 支持對 Erlang/OTP 的需求

  爲了支持 TLS 鏈接,RabbitMQ 須要在 Erlang/OTP 安裝時啓用 TLS 和加密相關的模塊。所以建議使用 TLS 的 Erlang/OTP 版本是 18.2 或者更高。R16B03 可能在使用某些證書時可以工做,可是存在已知的侷限性

  Erlang crypto, asn1, public_key, and ssl libraries (applications)必須安裝且正常運行。在 Debian and Ubuntu 系統中,erlang-ssl package 已經提供如上內容。RabbitMQ 的零依賴 Eralng RPM 包括上述的全部模塊。

  若是 Erlang/OTP 是從源代碼編譯的,則須要確保配置文件可以找到 OpenSSL 並構建上述庫。

已知的不兼容和侷限

  若是非要使用 elliptic curve cryptography (ECC) 密碼套件,強烈推薦最近的 Erlang/OTP release 版本(例如 19.x)。早期的 releases 版本對於 ECC 存在已知的侷限性。

  若是你遇到上面的侷限性或者其它的不兼容現象,請使用 TLS 終止選項(見上文).

  對於運行 RabbitMQ 做爲 service 的 Windows xp 用戶:要在 Windows XP 上結合 OpenSSL 0.9.8 及其以後版本,在 RabbitMQ server 中使用 SSL 是不可行的.此 bug 已在 Windows XP SP3 和O penSSL v0.9.8r 以及 v1.0.0d 版本上通過了確認。若是你想將 RabbitMQ 做爲 server, 建議將其升級爲 Windows 7 或者將 OpenSSL 降級爲更早的版本 (v0.9.7e能夠正常工做).

關於生成 CA,證書和祕鑰的簡短介紹

  本指南將指導你完成設置證書受權中心(Certificate Authority)並使用它生成 client 和 server 證書/祕鑰對。當 client 經過使能 TLS port 鏈接到服務器時,對於 RabbitMQ 和 client 來講,祕鑰和證書是必須的。可是,這個過程是及其費力而且易於出錯。在 MacOS 或者 linux 環境中,更簡單生成全部東西的方法是使用 tls-gen:全部你須要的東西就是在 PATH 中進行 make 和 openssl 操做。

  請注意,tls-gen 及其生成的證書/密鑰對是自簽名的,而且只適用於開發環境和測試環境。絕大多數生產環境應當使用著名商業CA頒發的證書和祕鑰。

祕鑰、證書和 CA 證書

  TLS 是一個大而複雜的話題。爲了完全瞭解 TLS、OpenSSL 以及如何充分利用它們,咱們建議使用其它資源,例如:Network Security with OpenSSL。

  TLS 不只僅用來創建加密的通訊信道,並且可以在信道的兩端之間交換籤名證書,而且這些證書能夠隨意地驗證。證書的驗證須要創建一條受信任的鏈路,這條鏈路根據已知信任的根證書和已提供的證書創建。根證書是一種自簽名證書,由證書受權中心構提供。這些證書頒發機構做爲商業公司,將簽署你生成的 SSL 證書,並收取費用。

  爲了達到本指南的目的,咱們將從建立咱們本身的證書受權中心開始。一旦咱們這樣作,咱們將以多種格式生成 server 和 client 的簽名證書。請注意, Mono 對 OpenSSL 證書有嚴格的要求,所以咱們將使用比平時稍微嚴格的祕鑰約束。

1 # mkdir testca
2 # cd testca
3 # mkdir certs private
4 # chmod 700 private
5 # echo 01 > serial
6 # touch index.txt

  如今,請將如下內容拷貝到咱們剛剛建立的 testca 目錄的 openssl.cnf 文件中:

[ ca ]
default_ca = testca

[ testca ]
dir = .
certificate = $dir/cacert.pem
database = $dir/index.txt
new_certs_dir = $dir/certs
private_key = $dir/private/cakey.pem
serial = $dir/serial

default_crl_days = 7
default_days = 365
default_md = sha256

policy = testca_policy
x509_extensions = certificate_extensions

[ testca_policy ]
commonName = supplied
stateOrProvinceName = optional
countryName = optional
emailAddress = optional
organizationName = optional
organizationalUnitName = optional
domainComponent = optional

[ certificate_extensions ]
basicConstraints = CA:false

[ req ]
default_bits = 2048
default_keyfile = ./private/cakey.pem
default_md = sha256
prompt = yes
distinguished_name = root_ca_distinguished_name
x509_extensions = root_ca_extensions

[ root_ca_distinguished_name ]
commonName = hostname

[ root_ca_extensions ]
basicConstraints = CA:true
keyUsage = keyCertSign, cRLSign

[ client_ca_extensions ]
basicConstraints = CA:false
keyUsage = digitalSignature
extendedKeyUsage = 1.3.6.1.5.5.7.3.2

[ server_ca_extensions ]
basicConstraints = CA:false
keyUsage = keyEncipherment
extendedKeyUsage = 1.3.6.1.5.5.7.3.1

  如今,咱們生產咱們 test 證書受權中心將使用的祕鑰和證書。任然在 testca 目錄中執行:

# openssl req -x509 -config openssl.cnf -newkey rsa:2048 -days 365 -out cacert.pem -outform PEM -subj /CN=MyTestCA/ -nodes
# openssl x509 -in cacert.pem -out cacert.cer -outform DER

  這就是生成咱們 test 證書受權中心的所有操做。根證書在 testca/cacert.pem 中,同時也在 testca/cacert.cer 中。這兩個文件包含相同的信息,但格式不一樣。雖然世界上絕大多數人喜歡使用 PEM 格式,但微軟和 Mono 喜歡走不尋常路,它們使用 DER 格式。

  設置好咱們的證書受權中心後,咱們如今須要作的是爲 client 和 server 生成祕鑰和證書。Elang 客戶端和 RabbitMQ broker 可以直接使用 PEM 文件。它們能夠經過三個文件來被通知:隱式可信任的根證書、用於驗證公共證書全部權的私有祕鑰以及標示 peer 的公共證書自己。

  爲了方便起見,咱們提供 Java 和 .Net 客戶端,a PCKS#12 store,它們包含客戶端的證書和祕鑰。PKCS store 一般受密碼保護的,所以還必須提供密碼。

  建立 server 和 client 證書的過程很是的類似。惟一的不通點就是簽署證書時要添加 keyUsage 字段。首先看 server:

# cd ..
# ls
testca
# mkdir server
# cd server
# openssl genrsa -out key.pem 2048
# openssl req -new -key key.pem -out req.pem -outform PEM -subj /CN=$(hostname)/O=server/ -nodes
# cd ../testca
# openssl ca -config openssl.cnf -in ../server/req.pem -out ../server/cert.pem -notext -batch -extensions server_ca_extensions
# cd ../server
# openssl pkcs12 -export -out keycert.p12 -in cert.pem -inkey key.pem -passout pass:MySecretPassword

  而後 client 以下:

# cd ..
# ls
server testca
# mkdir client
# cd client
# openssl genrsa -out key.pem 2048
# openssl req -new -key key.pem -out req.pem -outform PEM -subj /CN=$(hostname)/O=client/ -nodes
# cd ../testca
# openssl ca -config openssl.cnf -in ../client/req.pem -out ../client/cert.pem -notext -batch -extensions client_ca_extensions
# cd ../client
# openssl pkcs12 -export -out keycert.p12 -in cert.pem -inkey key.pem -passout pass:MySecretPassword

在 RabbitMQ 中開啓 SSL 支持

  爲了在 RabbitMQ 中開啓 SSL/TLS 支持,咱們須要向 RabbitMQ 提供根證書的位置、server 的證書的位置文件以及 server 祕鑰的位置。咱們還須要告訴 RabbitMQ 去監聽用於 SSL 鏈接的 socket,咱們還須要告訴 RabbitMQ 是否要求 client 提供證書,若是 client 可以提供了證書,在 client 和 RabbitMQ 之間沒有創建信任鏈的狀況下,咱們是否應該接收這個證書。在 RabbitMQ 中,這些設置能夠經過兩個參數進行控制:

-rabbit ssl_listeners

  這是一個監聽 SSL 鏈接的端口列表。爲了在單個網絡接口上進行監聽,須要在列表中添加相似以下配置 {"127.0.0.1", 5672}

-rabbit ssl_options

  這是一個 new_ssl 選項的元組列表。完整可用的 ssl_options 能夠經過 new_ssl 手冊產看,例如:erl -man new_ssl,可是最重要的是 cacertfile、certfile 和 keyfile 三個選項。

  設置這些選項的最簡單方法就是編輯配置文件。一個簡單的配置文件例子以下所示,它將在此主機上的全部網絡接口的 5671 端口上進行監聽。

[
  {rabbit, [
     {ssl_listeners, [5671]},
     {ssl_options, [{cacertfile,"/path/to/testca/cacert.pem"},
                    {certfile,"/path/to/server/cert.pem"},
                    {keyfile,"/path/to/server/key.pem"},
                    {verify,verify_peer},
                    {fail_if_no_peer_cert,false}]}
   ]}
].

  Windows 用戶請注意:在配置文件中的反斜槓("\")被解釋爲轉義序列,例如,要爲 CA 證書指定 c:\cacert.pem 路徑,你須要輸入 {cacertfile, "c:\\cacert.pem"} 或者 {cacertfile, "c:/cacert.pem"}。

  當 web 瀏覽器鏈接到 HTTPS web server 上時,服務器提供其公共證書,web 瀏覽器嘗試在瀏覽器知道的根證書和服務器證書之間創建一條受信任的連接,若是一切正常,一條加密通訊信道就創建好了。儘管,web 服務器和 web 瀏覽器不經常使用,但 SSL 容許 server 請求 client 提供證書。經過這種方式,server 能夠驗證 client 是誰。

  server 是否要求 client 提供證書以及它們是否相信這個證書的策略,是經過 verify 和 fail_if_no_peer_cert 參數進行控制的。經過  {fail_if_no_peer_cert,false} 選項,咱們聲明,即便 client 沒有向 server 發送證書,咱們也準備接受它的鏈接。可是,經過 {verify,verify_peer} 選項,咱們聲明,若是 client 向 server 發送證書,咱們必須可以和它創建一條信任鏈。注意,這些值可能會隨着 Erlang/OTP 中的 SSL 版本變化而變化,所以經過檢查你的 man page,erl -man new_ssl 來確保你使用了正確的值。

  在啓動 broker 以後,你可以在 rabbit.log 中看到以下信息:

=INFO REPORT==== 9-Aug-2010::15:10:55 ===
started TCP Listener on 0.0.0.0:5672

=INFO REPORT==== 9-Aug-2010::15:10:55 ===
started SSL Listener on 0.0.0.0:5671

  注意最後一行,它表示 RabbitMQ server 正常啓動,運行,並正在監聽 ssl 連接。

信任 client 的 Root CA

  當前,咱們將告訴 RabbitMQ 查看 testca/cacert.pem 文件。這個文件僅僅只包含咱們 test 證書受權中心的公共證書。咱們可能有不少 client 提交過來的證書,這些證書由幾個不一樣的證書受權中心簽名。咱們但願 RabbitMQ 信任它們。所以,咱們能夠將這些證書追加到另一個證書文件中,並提供這個新文件的路徑以做爲 RabbitMQ 的 cacerts 參數。

# cat testca/cacert.pem >> all_cacerts.pem
# cat otherca/cacert.pem >> all_cacerts.pem

  and so on

提供證書密碼

  可使用 password 選項,向私有祕鑰提供密碼。

[
 {rabbit, [
           {ssl_listeners, [5671]},
           {ssl_options, [{cacertfile,"/path/to/ca_certificate.pem"},
                          {certfile,  "/path/to/server_certificate.pem"},
                          {keyfile,   "/path/to/server_key.pem"},
                          {password,  "t0p$3kRe7"}
                         ]}
          ]}
].

已知 TLS 漏洞:POODLE、BEAST 等等

  POODLE

  POODLE 是已知的 SSL/TLS 攻擊,它最早出如今 SSLv3 中。從 3.4.0 版本開始,RabbitMQ server 拒絕接受 SSLv3 連接。在 2014 年 12 月,一個 POODLE 的變種版本能夠攻擊 TLSv1.0。所以,建議運行 Erlang 18.0 或者更高版本,這樣能夠消除針對 POODLE 的 TLS 1.0 漏洞,或者禁用 TLSv1.0 支持(見下文)。

  BEAST

  BEAST 攻擊是影響 TLSv1.0 的已知漏洞。爲了緩解它帶來的影響,請禁用 TLSv1.0 支持(見下文).

經過配置文件禁用 SSL/TLS 版本上通過

  要限制某個 SSL/TLS 協議版本,請使用 versions 選項:

%% Disable SSLv3.0 support, leaves TLSv1.0 enabled.
[
 {ssl, [{versions, ['tlsv1.2', 'tlsv1.1', tlsv1]}]},
 {rabbit, [
           {ssl_listeners, [5671]},
           {ssl_options, [{cacertfile,"/path/to/ca_certificate.pem"},
                          {certfile,  "/path/to/server_certificate.pem"},
                          {keyfile,   "/path/to/server_key.pem"},
                          {versions, ['tlsv1.2', 'tlsv1.1', tlsv1]}
                         ]}
          ]}
].
%% Disable SSLv3.0 and TLSv1.0 support.
[
 {ssl, [{versions, ['tlsv1.2', 'tlsv1.1']}]},
 {rabbit, [
           {ssl_listeners, [5671]},
           {ssl_options, [{cacertfile,"/path/to/ca_certificate.pem"},
                          {certfile,  "/path/to/server_certificate.pem"},
                          {keyfile,   "/path/to/server_key.pem"},
                          {versions, ['tlsv1.2', 'tlsv1.1']}
                         ]}
          ]}
].

  若是要驗證,請使用 openssl s_client:

# connect using SSLv3
openssl s_client -connect 127.0.0.1:5671 -ssl3
# connect using TLSv1.0 through v1.2
openssl s_client -connect 127.0.0.1:5671 -tls1

  並在輸出中查找如下內容:

SSL-Session:
  Protocol  : TLSv1

在 Java client 中配置 TLS 版本

  因爲 RabbitMQ server 能夠經過配置支持特定的 TLS 版本,所以須要在 Java client 中配置首選 TLS 版本。這是經過使用 ConnectionFactory#useSslProtocol 重載可接受協議版本名稱或者 SSL Context 完成的。

ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
factory.setPort(5671);

factory.useSslProtocol("TLSv1.2");

  從 Java client 3.6.4 開始,庫將嘗試使用運行時支持的最新TLS版本。

JDK 和 .NET 的 TLS 版本支持表

  禁用 TLSv1.0 會限制 client 平臺支持的數量。下面是一個表,說明 JDK 和 .NET 支持的 TLS 版本 。

        TLS version                                       Minimum JDK version                                          Minimum .NET version                       
          TLS 1.0 JDK 5 (RabbitMQ Java client requires 6) .NET 2.0 (RabbitMQ .NET client requires 4.5)
          TLS 1.1 JDK 7 (see Protocols, JDK 8 recommended) .NET 4.5
          TLS 1.2 JDK 7 (see Protocols, JDK 8 recommended) .NET 4.5

  *>.NET versions source.  
  *>JDK versions source.

配置密碼套件

  能夠配置 RabbitMQ 使用什麼密碼套件。注意,如今全部的套件能夠在全部平臺上使用。例如,使用 elliptic curve 密碼,請運行最新的的 Erlang 版本。下面的例子將演示如何使用密碼 TLS 選項。

%% List allowed ciphers
[
 {ssl, [{versions, ['tlsv1.2', 'tlsv1.1']}]},
 {rabbit, [
           {ssl_listeners, [5671]},
           {ssl_options, [{cacertfile,"/path/to/ca_certificate.pem"},
                          {certfile,  "/path/to/server_certificate.pem"},
                          {keyfile,   "/path/to/server_key.pem"},
                          {versions, ['tlsv1.2', 'tlsv1.1']},
                          {ciphers,  [{ecdhe_ecdsa,aes_128_cbc,sha256},
                                      {ecdhe_ecdsa,aes_256_cbc,sha}]}
                         ]}
          ]}
].

  要列出 Erlang 運行環境所支持的全部密碼套件,請使用:

rabbitmqctl eval 'ssl:cipher_suites().'

  輸出格式是 Erlang terms,所以這些能夠複製到 RabbitMQ 的配置文件中。

  這些套件也能夠用 OpenSSL 格式羅列出來:

rabbitmqctl eval 'ssl:cipher_suites(openssl).'

信任級別

  當設置 SSL 連接時,在協議中有兩個重要的階段。

  第一個階段是,the peers 選擇性交換證書。在交換證書後,peers 選擇性地嘗試在它們的根證書和其它存在的證書之間創建一條受信任的連接。這樣作的目的是驗證 peer 的身份(提供的私有密鑰不會被偷!)

  第二個階段是,peers 協商將用於通訊的其他部分的對稱加密密鑰。若是證書被交換,公鑰/私鑰將用於祕鑰協商。

  所以,您能夠建立加密的 SSL 鏈接,而無需驗證證書。 Java client 支持這兩種操做模式。

密鑰管理器、信任管理器以及密鑰庫

  在 Java 安全框架中,有三個須要注意的組件: 密鑰管理, 信任管理以及密鑰庫.、

  peer 使用祕鑰管理器管理它本身的證書。這就意味着,在會話創建中,祕鑰管理器將控制哪些證書將發送給遠端的 peer。

  peer 使用信任管理器管理遠端的證書。這就意味着,在會話創建中,信任管理器將管理遠端哪些證書時受信任的。

  祕鑰庫是證書的 Java 封裝。 Java 須要將全部證書轉換爲 Java 特定的二進制格式或採用 PKCS#12 格式。這些格式使用 the Key Store class 進行管理。對於 server 證書,咱們將使用 Java 二進制格式,但對於 client 密鑰/證書對,咱們將使用 PKCS#12 格式。

在不驗證證書的狀況下鏈接

  咱們的第一個例子將展現一個簡單的 client,這個 client 經過 SSL 鏈接到 RabbitMQ server,而不驗證服務器證書,並不提供任何客戶端證書。

import java.io.*;
import java.security.*;

import com.rabbitmq.client.*;

public class Example1
{
    public static void main(String[] args) throws Exception
    {

        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        factory.setPort(5671);

        factory.useSslProtocol();
        // Tells the library to setup the default Key and Trust managers for you
        // which do not do any form of remote server trust verification

        Connection conn = factory.newConnection();
        Channel channel = conn.createChannel();

        //non-durable, exclusive, auto-delete queue
        channel.queueDeclare("rabbitmq-java-test", false, true, true, null);
        channel.basicPublish("", "rabbitmq-java-test", null, "Hello, World".getBytes());


        GetResponse chResponse = channel.basicGet("rabbitmq-java-test", false);
        if(chResponse == null) {
            System.out.println("No message retrieved");
        } else {
            byte[] body = chResponse.getBody();
            System.out.println("Recieved: " + new String(body));
        }


        channel.close();
        conn.close();
    }
}

  這個簡單的例子只是一個 echo test。它建立了一個 rabbitmq-java-test channel,並向 default direct exchange pushlish 消息,而後讀回已經 publish 的內容並打印它們。注意,咱們使用了一個 exclusive, non-durable, auto-delete 的 queue,所以咱們不須要擔憂後期的手動清除。

提供和驗證證書

  首先,咱們須要設置咱們的密碼庫。咱們將假設咱們有想要鏈接 server 的證書,所以如今咱們須要將它添加到咱們的祕鑰庫中,信任管理器將會使用到它。

# keytool -import -alias server1 -file /path/to/server/cert.pem -keystore /path/to/rabbitstore

  上面的命令將把 cert.pem 導入到 rabbitstore 中,並將其稱爲 server1。當有不少證書或祕鑰時,可使用 alias 參數,由於它們必須有不一樣的內部別名。

  當選擇信任這個證書的時候,確保必定要回復 yes,並選擇一個密碼。例如在這個例子中,我將個人密碼設置爲 rabbitstore。

  而後,咱們使用在 PKCS#12 文件中咱們 client 的證書和祕鑰,如上所示。

  咱們下一個例子將對前面的例子進行修改,使用咱們祕鑰管理器和信任管理器的祕鑰庫。

import java.io.*;
import java.security.*;
import javax.net.ssl.*;

import com.rabbitmq.client.*;

public class Example2
{
  public static void main(String[] args) throws Exception
  {

    char[] keyPassphrase = "MySecretPassword".toCharArray();
    KeyStore ks = KeyStore.getInstance("PKCS12");
    ks.load(new FileInputStream("/path/to/client/keycert.p12"), keyPassphrase);

    KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
    kmf.init(ks, passphrase);

       char[] trustPassphrase = "rabbitstore".toCharArray();
       KeyStore tks = KeyStore.getInstance("JKS");
       tks.load(new FileInputStream("/path/to/trustStore"), trustPassphrase);

       TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
       tmf.init(tks);

       SSLContext c = SSLContext.getInstance("TLSv1.1");
       c.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

       ConnectionFactory factory = new ConnectionFactory();
       factory.setHost("localhost");
       factory.setPort(5671);
       factory.useSslProtocol(c);

       Connection conn = factory.newConnection();
       Channel channel = conn.createChannel();

       channel.queueDeclare("rabbitmq-java-test", false, true, true, null);
       channel.basicPublish("", "rabbitmq-java-test", null, "Hello, World".getBytes());


       GetResponse chResponse = channel.basicGet("rabbitmq-java-test", false);
       if(chResponse == null) {
           System.out.println("No message retrieved");
       } else {
           byte[] body = chResponse.getBody();
           System.out.println("Recieved: " + new String(body));
       }

       channel.close();
       conn.close();
   }
}

  爲了確保上述代碼在其它狀況也也能工做,請嘗試使用未導入到密碼庫中的證書設置你的 RabbitMQ server,並觀察出如今你屏幕上的異常信息。

配置 .Net client

  略

證書鏈和驗證深度

  當使用由中間 CA 簽名的 client 證書的時候,可能須要配置 RabbitMQ server 以確保使用更高的驗證深度。深度是指在有效證書路徑中遵循 peer 證書的非自頒發中間證書的最大數目。所以,若是深度爲0,the peer(例如:client) 證書必須由可信任的 CA 直接簽署;若是深度爲1,路徑能夠是「peer, CA, trusted CA」;若是深度爲2,路徑能夠是 "peer, CA, CA, trusted CA" 等待。下面的例子演示瞭如何配置 RabbitMQ server 證書驗證的深度。

[
  {rabbit, [
     {ssl_listeners, [5671]},
     {ssl_options, [{cacertfile,"/path/to/testca/cacert.pem"},
                    {certfile,"/path/to/server/cert.pem"},
                    {keyfile,"/path/to/server/key.pem"},
                    {depth, 2},
                    {verify,verify_peer},
                    {fail_if_no_peer_cert,false}]}
   ]}
].

  當使用 RabbitMQ 插件,例如 federation 或者具備 TLS 功能的 shovel,可能須要爲 erlang client 配置驗證深度,解釋以下。

Erlang R16B01 以前的版本

  能夠在舊 Erlang 版本中使用 SSL。這些舊版本可能只支持某些證書,在別的證書下可能存在問題。

  可是,它們還包含 OTP-10905 bug,這使得它不能禁用任何協議版本。特別地,因爲不能禁用 SSLv3,所以使用 SSL 和舊 Erlang 版本的系統不能避免 POODLE 攻擊

  若是檢測到舊 Erlang 版本,RabbitMQ 3.4.0 將會自動禁用 SSL listeners。若是這不是你想要的,你能夠在 rabbit 配置項中設置 ssl_allow_poodle_attack 爲 true。

  ssl_allow_poodle_attack 是一個全局設置;在 rabbit 運用程序中設置它,將控制全部 SSL listeners (AMQP, management, STOMP, 等等)的行爲。

  如下示例演示了這一點:

[
  {rabbit, [
     {ssl_listeners, [5671]},
     {ssl_allow_poodle_attack, true},
     {ssl_options, [{cacertfile,"/path/to/testca/cacert.pem"},
                    {certfile,"/path/to/server/cert.pem"},
                    {keyfile,"/path/to/server/key.pem"},
                    {verify,verify_peer},
                    {fail_if_no_peer_cert,false}]}
   ]}
].

配置 Erlang client

  在 RabbitMQ Erlang client 中啓動 SSL 至關簡單。在 #amqp_params_network record 中,咱們僅僅須要在 ssl_options 字段中提供值。這些,你將從咱們指定給 RabbitMQ 的選項中見到。

  Erlang SSL 選項

  必須提供的三個重要選項:

  cacertfile 選項指定了根證書受權中心的證書,該機構是咱們絕對信任的;

  certfile 是 client 的 本身的 PEM 格式的證書;

  keyfile 是客戶端 PEM 格式的私有密鑰文件。

  和 RabbitMQ 自身同樣,若是 server 不可以提供證書或者若是咱們沒法創建對服務器證書的信任鏈,則 verify 和 fail_if_no_peer_cert 選項用於指定採用何種操做。深度配置證書驗證深度(見上文)。

  代碼

Params = #amqp_params_network { port = 5671,
                                ssl_options = [{cacertfile, "/path/to/testca/cacert.pem"},
                                               {certfile, "/path/to/client/cert.pem"},
                                               {keyfile, "/path/to/client/key.pem"},
                                               %% only necessary with intermediate CAs
                                               %% {depth, 2},
                                               {verify, verify_peer},
                                               {fail_if_no_peer_cert, true}] },
{ok, Conn} = amqp_connection:start(Params),

   You can now go ahead and use Conn as a normal connection.

   http://www.cnblogs.com/pengsir

相關文章
相關標籤/搜索