RabbitMQ 3.6.6 TLS Support(翻译)

简介

  RabbitMQ 已结内置支持 TLS,这包括客户端连接和流行的插件,例如 Fedaration links。同样,在集群中使用 TLS 也能对内部节点间的连接进行加密。

  本指南包含了 RabbitMQ 中关于 TLS 的多个主题:

  > 在 RabbitMQ 中启动 TLS listeners
  > 对于开发和 QA 环境中,如何生成自签名证书
  > Java 和 .NET 客户端中 TLS 配置
  > TLS版本和密码套件配置
  > 证书链验证深度

  还有更多。但是,本文并不是关于 TLS、加密、公钥 Infrastructure 以及相关内容的基础读物,因此,本文不会对它们进行详细的介绍,初学者可以在网络上找到大量的基础读物

  RabbitMQ 支持的所有协议都可以使用 TLS,而不仅仅是本指南关注的 AMQP 0-9-1。HTTP API 在经过配置后也能够很好地使用 TLS(HTTPS)。

  对于常见的 TLS 问题,请参见 Troubleshooting TLS-related issues

Client 使用 TLS 连接 RabbitMQ

  对于客户端连接,有两种方法:

  > 配置 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.0JDK 5 (RabbitMQ Java client requires 6).NET 2.0 (RabbitMQ .NET client requires 4.5)
          TLS 1.1JDK 7 (see Protocols, JDK 8 recommended).NET 4.5
          TLS 1.2JDK 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

转载于:https://www.cnblogs.com/pengsir/p/6492354.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot是一个非常流行的Java Web框架,它简化了Java应用程序的开发和部署过程。 RabbitMQ是一个开源的消息代理,它支持多种协议,包括AMQP、STOMP和MQTT等。TLS协议则是一种加密传输协议,它可以保证数据在传输过程中的安全性。 在Spring Boot应用程序中使用RabbitMQ需要引入相应的依赖,可以使用Maven或Gradle来进行管理。同时,为了保证消息的安全传输,我们可以使用TLS协议对消息进行加密传输。 以下是使用Spring Boot和RabbitMQ进行消息传输并加密的简单示例: 1. 引入依赖 在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-rsa</artifactId> </dependency> ``` 2. 配置RabbitMQTLS 在application.properties文件中添加以下配置: ```properties spring.rabbitmq.host=localhost spring.rabbitmq.port=5671 spring.rabbitmq.username=user spring.rabbitmq.password=password spring.rabbitmq.ssl.enabled=true spring.rabbitmq.ssl.key-store=file:/path/to/keystore spring.rabbitmq.ssl.key-store-password=changeit spring.rabbitmq.ssl.trust-store=file:/path/to/truststore spring.rabbitmq.ssl.trust-store-password=changeit ``` 其中,key-store和trust-store分别为用于TLS加密的密钥库和信任库文件路径,需要根据实际情况进行配置。 3. 发送和接收消息 在Spring Boot应用程序中使用RabbitTemplate来发送和接收消息,示例代码如下: ```java @Service public class RabbitMQService { @Autowired private RabbitTemplate rabbitTemplate; public void send(String message) { rabbitTemplate.convertAndSend("exchange", "routingKey", message); } @RabbitListener(queues = "queue") public void receive(String message) { System.out.println("Received message: " + message); } } ``` 其中,send方法用于发送消息,receive方法用于接收消息。在这个例子中,我们将消息发送到名为exchange的交换机,使用名为routingKey的路由键进行路由,然后将消息发送到名为queue的队列中进行消费。 以上就是在Spring Boot应用程序中使用RabbitMQTLS进行消息传输的简单示例。需要注意的是,这只是一个基本的示例,实际应用中还需要进行更多的配置和处理,以确保消息传输的安全和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值