Docker環境RabbitMq配置SSL


RabbitMQ要對外提供服務,考慮到安全性,配置SSL進行訪問,ssl端口5671,內部仍然使用5672進行訪問,兩者同時兼容。

安裝環境

  • CentOS 7.5
  • Docker 1.13.1
  • Git 1.8.3
  • jdk 1.8
  • RabbitMQ鏡像,rabbitmq:management

證書

RabbitMQ也提供了獲取證書的方案,但是使用過程中出現錯誤,未來得及進行解決,在github上查找到一個項目可以生成證書,遂使用之。

安裝git

要從github上將項目克隆下來,需要有git環境,安裝步驟如下


# yum安裝git
$ yum -y install git

# 配置郵箱以及賬號
$ git config --global user.name = 'xxx'
$ git config --global user.email = 'xxx'

# 查看git配置
$ git config --list

生成證書

1.從github上克隆項目

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

2.下載完成后,進入CMF-AMQP-Configuration/ssl/目錄

$ cd CMF-AMQP-Configuration/ssl/

3.生成證書簽發機構

$ sh setup_ca.sh xxx

xxx為自定義的證書簽發機構名稱,該腳本會在當前目錄下生成一個ca目錄,存儲證書頒發機構的信息以及已經簽發的一些證書

執行腳本后的ca目錄如下所示

4.生成服務端公鑰和私鑰

$ sh make_server_cert.sh rabbit-server 123456

注釋:
rabbit-server:生成的密鑰前綴名,自定義
123456: 訪問該密鑰的密碼,自定義

執行該腳本后,在當前目錄生成server目錄,存儲服務端公鑰和私鑰,如下所示

5.生成客戶端公鑰和私鑰

$ sh create_client_cert.sh rabbit-client 123456

注釋:
rabbit-client:生成的密鑰前綴名,自定義。
123456: 訪問該密鑰的密碼,自定義。

執行該腳本后,在當前目錄下生成client目錄,存儲客戶端公鑰和私鑰,如下所示

6.生成客戶端需要的證書
使用java的keytool工具生成客戶端需要的證書,用以支持服務端和客戶端進行通信,生成該證書需要提前安裝配置java環境,此處默認已正確安裝java環境,不會安裝的可以參考本人博客

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

注釋:
-import 將已簽名數字證書導入密鑰庫 
-alias xxx 指定導入條目的別名
-file server/rabbit-server.cert.pem 需要導入的證書
-keystore xxx 指定密鑰庫的名稱
-storepass xxx 指定密鑰庫的密碼(獲取keystore信息所需的密碼)

經過以上6個步驟,我們一共生成了3個文件夾以及1個文件,分別是server/,client/,ca/以及rabbitStore證書,只要以上幾個文件都存在,那么就表示生成證書成。

安裝RabbitMQ並配置SSL

1.拉取management版本的鏡像

$ docker pull rabbitmq:management

2.先使用以下命令啟動容器

$ docker run --restart=unless-stopped -d -p 5672:5672 -p 15672:15672    --name rabbitmq rabbitmq:management

3.創建文件夾
在宿主機上創建以下文件夾

$ mkdir -p /etc/rabbitmq/ssl

4.拷貝容器中的文件到/etc/rabbitmq/目錄下

$ docker cp rabbitmq:/etc/rabbitmq/conf.d /etc/rabbitmq/
$ docker cp rabbitmq:/etc/rabbitmq/enabled_plugins /etc/rabbitmq/
$ docker cp rabbitmq:/etc/rabbitmq/rabbitmq.conf /etc/rabbitmq/

5.拷貝生成的證書到/etc/rabbitmq/ssl/目錄下

在./CMF-AMQP-Configuration/ssl/目錄下執行以下命令

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

6.編輯/etc/rabbitmq/rabbitmq.conf文件,輸入以下內容


# SSL\TLS通信的端口
listeners.ssl.default=5671
# 服務端私鑰和證書文件配置
ssl_options.cacertfile=/etc/rabbitmq/ssl/ca/cacert.pem
ssl_options.certfile=/etc/rabbitmq/ssl/server/rabbit-server.cert.pem
ssl_options.keyfile=/etc/rabbitmq/ssl/server/rabbit-server.key.pem

# 有verify_none和verify_peer兩個選項,verify_none表示完全忽略驗證證書的結果,verify_peer表示要求驗證對方證書
ssl_options.verify=verify_peer
# 若為true,服務端會向客戶端索要證書,若客戶端無證書則中止SSL握手;若為false,則客戶端沒有證書時依然可完成SSL握手
ssl_options.fail_if_no_peer_cert=true
ssl_options.versions.1=tlsv1.2
ssl_options.versions.2=tlsv1.1

ssl_options.ciphers.1 = ECDHE-ECDSA-AES256-GCM-SHA384
ssl_options.ciphers.2 = ECDHE-RSA-AES256-GCM-SHA384
ssl_options.ciphers.3 = ECDHE-ECDSA-AES256-SHA384
ssl_options.ciphers.4 = ECDHE-RSA-AES256-SHA384
ssl_options.ciphers.5 = ECDHE-ECDSA-DES-CBC3-SHA
ssl_options.ciphers.6 = ECDH-ECDSA-AES256-GCM-SHA384
ssl_options.ciphers.7 = ECDH-RSA-AES256-GCM-SHA384
ssl_options.ciphers.8 = ECDH-ECDSA-AES256-SHA384
ssl_options.ciphers.9 = ECDH-RSA-AES256-SHA384
ssl_options.ciphers.10 = DHE-DSS-AES256-GCM-SHA384
ssl_options.ciphers.11= DHE-DSS-AES256-SHA256
ssl_options.ciphers.12 = AES256-GCM-SHA384
ssl_options.ciphers.13 = AES256-SHA256
ssl_options.ciphers.14 = ECDHE-ECDSA-AES128-GCM-SHA256
ssl_options.ciphers.15 = ECDHE-RSA-AES128-GCM-SHA256
ssl_options.ciphers.16 = ECDHE-ECDSA-AES128-SHA256
ssl_options.ciphers.17 = ECDHE-RSA-AES128-SHA256
ssl_options.ciphers.18 = ECDH-ECDSA-AES128-GCM-SHA256
ssl_options.ciphers.19= ECDH-RSA-AES128-GCM-SHA256
ssl_options.ciphers.20 = ECDH-ECDSA-AES128-SHA256
ssl_options.ciphers.21 = ECDH-RSA-AES128-SHA256
ssl_options.ciphers.22 = DHE-DSS-AES128-GCM-SHA256
ssl_options.ciphers.23 = DHE-DSS-AES128-SHA256
ssl_options.ciphers.24 = AES128-GCM-SHA256
ssl_options.ciphers.25 = AES128-SHA256
ssl_options.ciphers.26 = ECDHE-ECDSA-AES256-SHA
ssl_options.ciphers.27 = ECDHE-RSA-AES256-SHA
ssl_options.ciphers.28 = DHE-DSS-AES256-SHA
ssl_options.ciphers.29 = ECDH-ECDSA-AES256-SHA
ssl_options.ciphers.30 = ECDH-RSA-AES256-SHA
ssl_options.ciphers.31= AES256-SHA
ssl_options.ciphers.32 = ECDHE-ECDSA-AES128-SHA
ssl_options.ciphers.33 = ECDHE-RSA-AES128-SHA
ssl_options.ciphers.34 = DHE-DSS-AES128-SHA
ssl_options.ciphers.35 = DHE-DSS-AES128-SHA256
ssl_options.ciphers.36 = ECDH-ECDSA-AES128-SHA
ssl_options.ciphers.37 = ECDH-RSA-AES128-SHA
ssl_options.ciphers.38 = AES128-SHA

注釋:
rabbitmq.conf文件中原有的內容可以直接刪除掉,也可以保留,不影響

也可以不使用上述的rabbitmq.conf文件,而使用rabbitmq.config文件,不過后者需要自己創建,且不可以和rabbitmq.conf共存,RabbitMQ3.7版本以后,推薦使用rabbitmq.conf,因此如果要使用rabbitmq.config,需要先創建,再寫入內容

# 創建rabbitmq.config文件

$ vim 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']}
    ]}
].

注釋:
rabbitmq.conf和rabbitmq.config任選其一即可,個人認為前者可讀性更好一些,但是編寫的內容相對較多一些

7.刪除前面創建的rabbitmq容器,重新創建

使用以下命令重新創建rabbitmq容器,添加5671端口映射以及/etc/rabbitmq/文件夾的掛載

$ docker run --restart=unless-stopped -d  \
        -p 5672:5672 -p 15672:15672 -p 5671:5671  \
        -v  /etc/rabbitmq/:/etc/rabbitmq/   \
        --name rabbitmq \
        rabbitmq:management

8.驗證5671端口

使用以下命令查看rabbitmq容器啟動時的日志

$  docker logs -f rabbitmq

看到日志中出現以下內容表示配置成功

9.創建可以遠程訪問的用戶
由於guest用戶只能本地訪問,因此需要創建一個可以遠程訪問的用戶

# 進入容器內部
$ docker exec -it rabbitmq bash

# 創建一個用戶名為admin,密碼為123456的用戶
$ rabbitmqctl add_user admin 123456

# 設置用戶權限為超級管理員
$ rabbitmqctl set_user_tags admin administrator

# 授權遠程訪問
$ rabbitmqctl set_permissions -p / admin "." "." ".*"

# 退出容器
$ exit

# 重啟rabbitmq
$ docker restart rabbitmq

10.訪問管理頁面

此時可以使用上面創建的admin用戶遠程訪問管理頁面,地址為http://ip:15672

進入之后可以通過如下方式確認ssl是否配置成功

SpringBoot集成SSL

此處只給出配置ssl的部分,springboot集成rabbitmq的方法可以參考本人博客

spring:
  rabbitmq:
    addresses: 192.168.216.129:5671
    username: admin
    password: 123456
    virtual-host: /
    ssl:
      enabled: true
      key-store: classpath:keyStore/129/rabbit-client.keycert.p12
      key-store-password: 123456
      trust-store: classpath:keyStore/129/rabbitStore
      trust-store-password: 123456
      algorithm: TLSv1.2
      trust-store-type: JKS
      key-store-type: PKCS12
      validate-server-certificate: true
      verify-hostname: false

注釋:
addresses: 192.168.216.129:5671 ssl使用的是5671的端口,如果不使用ssl還可以使用5672端口
ssl.enabled 是否啟用ssl,默認false
key-store: 客戶端證書的存儲路徑,前面已經生成,直接拷貝過來即可
key-store-password: 生成客戶端證書的密碼
trust-store: 信任證書的存儲路徑,前面已經生成,直接拷貝過來即可
trust-store-password:生成證書的密碼
verify-hostname:是否驗證hostname,默認是true,需要設置為false,否則啟動報錯(No subject alternative names present),原因是證書中定義的common name和程序運行的機器的domain不匹配,這個感覺沒有必要糾結,直接設置為false即可。

參考文檔

1.RabbitMQ 配置 SSL/TSL
2.RMQ的SSL配置最佳實踐


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM