RabbitMq配置ssl

本文详细介绍如何通过生成证书和配置RabbitMQ实现安全的SSL通信。包括证书生成器的下载、证书签发机构及服务端与客户端密钥的生成等步骤,并提供了具体的配置示例。

接下来会简述证书生成,ssl端口开放

##下载SSL证书生成器

git clone https://github.com/Berico-Technologies/CMF-AMQP-Configuration.git

生成证书

cd CMF-AMQP-Configuration/ssl

配置当前目录下的openssl.cnf,基本上不需要改动,证书默认生成后的有效期是一年,如果需要延长可以修改default_days = 365.

生成证书签发机构

该脚本是会在当前目录下生成一个ca目录,里面存放着一些证书颁发机构信息,和已经签发的证书记录

sh setup_ca.sh RabbitSSL  

RabbitSSL: 签发机构名称,自定义。

生成服务端公钥,和私钥

该脚本是会在当前目录下生成一个server目录,里面存放着服务端的公钥,和私钥文件。该文件生成后会在ca目录文件中有签发记录。

sh make_server_cert.sh rabbit-server rabbit

rabbit-server: 生成的密钥前缀名,自定义。
rabbit: 访问该密钥的密码,自定义。

生成客户端公钥,和私钥

该脚本是会在当前目录下生成一个client目录,里面存放着客户端的公钥,和私钥文件。该文件生成后会在ca目录文件中有签发记录。

sh create_client_cert.sh rabbit-client rabbit

rabbit-client: 生成的密钥前缀名,自定义。
rabbit: 访问该密钥的密码,自定义。

生成客户端需要的证书

不同的语言操作方式不一样,这里我们使用的是java语言,使用java的keytool工具生成,首先确保已经安装java并且在环境变量中已经配置

keytool -import -alias rabbit-server -file server/rabbit-server.cert.pem -keystore rabbitStore -storepass rabbit

用服务端的公钥生成证书,这个步骤很关键,该证书用于客户端和服务端通信。

server/rabbit-server.cert.pem: 上个步骤已经生成好的服务端公钥

如果需要删除已经生成的证书,可执行以下命令

keytool -delete -alias rabbit-server -keystore rabbitStore -storepass rabbit

证书生成结束步骤检查

如果你跟着文章一步一步做到这,说明你离成功就只差最后一步了,接下来检查我们前几个步骤的结果,经过几个步骤我们在CMF-AMQP-Configuration/ssl/目录下生成了:

ca
server
client
rabbitStore 证书

如果以上的几个目录和这个证书都存在,说明该大步骤已经完美结束。接下来进入最关键的一步了。

修改RabbitMQ的SSL配置

接下来的步骤就比较关键了,需要用到我们上面所有生成的文件,将它们配置到RabbitMQ的config文件中.

将ca,server,client,rabbitStore拷贝到/etc/rabbitmq目录下

cp -r ca server client rabbitStore /etc/rabbitmq/ssl

如果/etc/rabbitmq目录下没有rabbitmq.config,创建该文件。

vim /etc/rabbitmq/rabbitmq.config

将以下配置复制到rabbitmq.config中

%%Disable SSLv3.0 and TLSv1.0 support.
[
    {ssl, [{versions, ['tlsv1.2', 'tlsv1.1']}]},
    {rabbit, [
        {tcp_listeners, [5672]},
        {ssl_listeners, [5671]},
        {ssl_options, [{cacertfile,"/etc/rabbitmq/ssl/ca/cacert.pem"},
            {certfile,"/etc/rabbitmq/ssl/server/rabbit-server.cert.pem"},
            {keyfile,"/etc/rabbitmq/ssl/server/rabbit-server.key.pem"},
            {verify, verify_peer},
            {ciphers, ["ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-RSA-AES256-GCM-SHA384",
                        "ECDHE-ECDSA-AES256-SHA384","ECDHE-RSA-AES256-SHA384", "ECDHE-ECDSA-DES-CBC3-SHA",
                        "ECDH-ECDSA-AES256-GCM-SHA384","ECDH-RSA-AES256-GCM-SHA384","ECDH-ECDSA-AES256-SHA384",
                        "ECDH-RSA-AES256-SHA384","DHE-DSS-AES256-GCM-SHA384","DHE-DSS-AES256-SHA256",
                        "AES256-GCM-SHA384","AES256-SHA256","ECDHE-ECDSA-AES128-GCM-SHA256",
                        "ECDHE-RSA-AES128-GCM-SHA256","ECDHE-ECDSA-AES128-SHA256","ECDHE-RSA-AES128-SHA256",
                        "ECDH-ECDSA-AES128-GCM-SHA256","ECDH-RSA-AES128-GCM-SHA256","ECDH-ECDSA-AES128-SHA256",
                        "ECDH-RSA-AES128-SHA256","DHE-DSS-AES128-GCM-SHA256","DHE-DSS-AES128-SHA256",
                        "AES128-GCM-SHA256","AES128-SHA256","ECDHE-ECDSA-AES256-SHA",
                        "ECDHE-RSA-AES256-SHA","DHE-DSS-AES256-SHA","ECDH-ECDSA-AES256-SHA",
                        "ECDH-RSA-AES256-SHA","AES256-SHA","ECDHE-ECDSA-AES128-SHA",
                        "ECDHE-RSA-AES128-SHA","DHE-DSS-AES128-SHA","ECDH-ECDSA-AES128-SHA",
                                                "ECDH-RSA-AES128-SHA","AES128-SHA"]},
            {honor_cipher_order, true},
            {fail_if_no_peer_cert, true},
            {versions, ['tlsv1.2', 'tlsv1.1']}
        ]},
        {auth_mechanisms,['PLAIN', 'AMQPLAIN', 'EXTERNAL']}
    ]}
].

复制代码在以上配置中我们将证书颁发机构以及服务端的公钥和私钥配置进去了。client目录和rabbitStore是给客户端使用的,我们使用5671端口作为我们ssl通信端口,5672保持不变,继续为内网tcp提供服务

重启rabbitmq服务

以下命令是参考,每个人服务安装方式不一样,总之将它重启就可以

systemctl restart rabbit-server.service

查看rabbitmq日志输出

less /var/log/rabbitmq/xxx.log

log显示成这样,代表ssl开启成功

或者访问网页查看5671是否开启ssl

如上,ssl服务已经开启.最后一步代码测试
编写Java代码测试证书授权

将前面还没有用到的client目录和rabbitStore证书拷贝的项目中,放入到resource目录下,执行以下代码做测试;

public class SslReceiver {

    public static void main(String[] args) throws TimeoutException {
        String classpath = SslReceiver.class.getResource("/").getPath();
        //证书密码
        char[] sslPwd = "rabbit".toCharArray();
        //读取client密钥,和rabbitStore证书
        try (InputStream sslCardStream = new FileInputStream(classpath + "keyStore/client/rabbit-client.keycert.p12");
             InputStream rabbitStoreStream = new FileInputStream(classpath + "keyStore/rabbitStore")) {

            //加载秘钥
            KeyStore ks = KeyStore.getInstance("PKCS12");
            ks.load(sslCardStream, sslPwd);
            KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
            keyManagerFactory.init(ks, sslPwd);

            //读取授权证书,只含有服务端的公钥
            KeyStore jks = KeyStore.getInstance("JKS");
            jks.load(rabbitStoreStream, sslPwd);
            TrustManagerFactory keyStoreManager = TrustManagerFactory.getInstance("SunX509");
            keyStoreManager.init(jks);
            SSLContext context = SSLContext.getInstance("TLSv1.2");
            context.init(keyManagerFactory.getKeyManagers(), keyStoreManager.getTrustManagers(), null);
            ConnectionFactory factory = new ConnectionFactory();
            factory.setUsername("rabbitTest");
            factory.setPassword("123456");
            factory.setHost("127.0.0.1");
            factory.setPort(5671);
            factory.setAutomaticRecoveryEnabled(true);

            //设置sslContext
            factory.useSslProtocol(context);
            Connection connection = factory.newConnection();
            Channel channel = connection.createChannel();
            channel.queueDeclare("rabbitmq-queue", false, true, true, null); //rabbitmq-queue是rabbitmq队列
            channel.basicPublish("", "rabbitmq-queue", null, "Test,Test".getBytes());
            GetResponse chResponse = channel.basicGet("rabbitmq-queue", false);
            if (chResponse == null){
                System.out.println("No message retrieved");
            }else {
                byte[] body = chResponse.getBody();
                System.out.println("Recieved: " + new String(body));
            }
            channel.close();
            connection.close();
        } catch (KeyStoreException | UnrecoverableKeyException | KeyManagementException
                | CertificateException | NoSuchAlgorithmException | IOException e) {
            log.error("SSL证书解析失败", e);
        }
    }
}

复制代码如果收到了那条消息,到此ssl结束,如果有异常信息,请在启动jvm中传递参数
-Djavax.net.debug=all,查看连接过程,在结合服务端/var/log/rabbitmq下的log一起分析。

RabbitMQ中启用SSL认证需要完成以下步骤,包括生成证书、配置RabbitMQSSL监听端口以及设置客户端连接方式。 ### 1. 生成SSL证书 可以使用`tls-gen`工具来生成所需的SSL证书。该工具支持生成CA(证书颁发机构)、服务器和客户端证书。以下是基本操作步骤: ```bash # 下载 tls-gen 工具 git clone https://github.com/michaelklishin/tls-gen tls-gen cd tls-gen/basic # 生成 CA 和服务器证书,123456 是私钥密码 make PASSWORD=123456 make verify make info ``` 生成的证书将包含CA证书(`ca_certificate.pem`)、服务器证书(`server_certificate.pem`)和服务器私钥(`private_key.pem`),以及客户端使用的证书和私钥文件[^2]。 ### 2. 配置 RabbitMQ 启用 SSL 将生成的证书复制到 RabbitMQSSL 目录下,例如 `/etc/rabbitmq/ssl`,并修改 `rabbitmq.conf` 文件以启用SSL通信。 ```bash cp -r rmqca /etc/rabbitmq/ssl cp -r server /etc/rabbitmq/ssl cp -r client /etc/rabbitmq/ssl ``` 编辑 RabbitMQ配置文件 `rabbitmq.conf`,添加或修改以下内容: ```ini listeners.ssl.default = 5671 ssl_options.cacertfile = /etc/rabbitmq/ssl/ca_certificate.pem ssl_options.certfile = /etc/rabbitmq/ssl/server_certificate.pem ssl_options.keyfile = /etc/rabbitmq/ssl/private_key.pem ssl_options.verify = verify_peer ssl_options.fail_if_no_peer_cert = true ``` 上述配置启用了SSL监听端口为 `5671`,并设置了服务器证书路径、CA证书路径及私钥路径。同时,通过 `verify_peer` 和 `fail_if_no_peer_cert` 参数启用了客户端证书验证(即对等验证)[^1]。 ### 3. 客户端连接配置 客户端连接时也需要提供自己的证书和私钥,并信任服务器的CA证书。例如,在Python中使用 `pika` 库进行SSL连接的示例代码如下: ```python import pika import ssl ssl_options = pika.SSLOptions( ssl_context=ssl.create_default_context(cafile="/path/to/ca_certificate.pem"), ) ssl_options.context.load_cert_chain(certfile="/path/to/client_certificate.pem", keyfile="/path/to/client_private_key.pem") connection = pika.BlockingConnection( pika.ConnectionParameters( host='your.rabbitmq.host', port=5671, virtual_host='/', credentials=pika.ExternalCredentials(), ssl=True, ssl_options=ssl_options ) ) channel = connection.channel() # 使用 channel 进行消息队列操作... ``` 确保客户端的证书和私钥与服务器的信任链一致,并且正确配置了主机名和端口。 ### 4. 测试SSL连接 可以通过管理插件或者命令行工具检查SSL是否已成功启用: ```bash rabbitmqctl list_listeners ``` 此命令会列出当前 RabbitMQ 实例的所有监听端口,确认 `5671` 端口处于 SSL 模式。 ### 总结 通过以上步骤,RabbitMQ 已经成功配置为使用 SSL/TLS 加密通信,并启用了客户端证书验证机制。这不仅提升了通信的安全性,也增强了身份认证的可靠性。 ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值