• 禁用AMQP配置中的明文身份验证机制(包含Springboot结果测试+踩坑)


    前言

    最近公司内网部署RabbitMQ服务器,部署上测试后安全部门扫描到MQ服务器有一个漏洞【禁用AMQP配置中的明文身份验证机制】。本文记录解决该漏洞的过程和方法,以及遇到的问题

    配置流程

    主要步骤为:

    1. 在服务器生成所需的两对密钥和CA证书,然后将CA、服务器公私钥放到Rabbit目录下并添加配置文件
    2. 将服务器公钥转换为Java专用JKS格式,然后将客户端私钥和JKS一起拷贝到本地,通过Java或者Springboot-amqp连接

    生成CA证书、客户端密钥、服务器密钥

    目前网络上常用两种生成工具:

    1. CMF-AMQP-Configuration(https://github.com/Berico-Technologies/CMF-AMQP-Configuration.git)
    2. tls-gen(https://github.com/rabbitmq/tls-gen.git)

    本文基于CMF-AMQP-Configuration来生成SSL自签名文件

    git clone https://github.com/Berico-Technologies/CMF-AMQP-Configuration.git
    cd CMF-AMQP-Configuration/ssl
    sh setup_ca.sh CANAME # CA名称任意
    sh make_server_cert.sh rabbitmq-server SERVER_PASS # 密码任意
    sh create_client_cert.sh rabbitmq-client CLIENT_PASS # 密码任意
    
    • 1
    • 2
    • 3
    • 4
    • 5

    生成的目录如下

    ca #保存CA证书
    server # 保存服务器密钥
    client # 保存客户端密钥
    
    • 1
    • 2
    • 3

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    复制文件到服务器/etc/rabbitmq/ssl

    1. cacert.pem # CA证书文件
    2. server.cert.pem # 服务器公钥
    3. server.key.pem # 服务器私钥
    
    • 1
    • 2
    • 3

    在这里插入图片描述

    然后使用JDK的Keytool工具,将服务器公钥转换为JKS格式

    keytool -import -alias rabbitmq-server \
      -file server/rabbitmq-server.cert.pem \
      -keystore rabbitmqStore -storepass STORE_PASS 
      # -alias后为别称,-file后是服务端公钥位置,-keystore后是输出JSK证书位置 STORE_PASS任意
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    拷贝客户端需要文件

    1. rabbitmqTrustStore # JKS格式服务器公钥文件
    2. client/client.key.pem  # 客户端私钥
    
    • 1
    • 2

    在这里插入图片描述

    Docker部署RabbitMQ

    先启动rabbitmq拷贝/etc/rabbitmq/下的
    enabled_plugins、conf.d、rabbitmq.conf(如果存在的话)拷贝
    到/home/mapping/rabbitmq/etc/rabbitmq下,然后删除容器,继续执行下面的操作

    docker pull rabbitmq:3.8.12-management
    docker run --restart=unless-stopped --name rabbitmq -p 5672:5672 -p 5671:5671 -p 15672:15672 \
    -v /home/mapping/rabbitmq/etc/rabbitmq:/etc/rabbitmq \
    -e RABBITMQ_DEFAULT_USER=admin \
    -e RABBITMQ_DEFAULT_PASS=Rabbit@123 \
    -d rabbitmq:3.8.12-management
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    添加SSL插件

    部署完成后,docker exec进入容器,添加插件才能启用SSL验证的功能

    rabbitmq-plugins enable rabbitmq_auth_mechanism_ssl
    #查看启动结果
    rabbitmq-plugins list
    
    • 1
    • 2
    • 3

    添加证书登录用户

    #用户名要与客户端证书名称前缀一致
    rabbitmqctl add_user 'rabbitmq-client' PASS_WORD
    #添加权限 不要忘记了
    rabbitmqctl set_permissions -p "/" "rabbitmq-client" ".*" ".*" ".*"
    
    • 1
    • 2
    • 3
    • 4

    创建etc/rabbitmq/rabbitmq.conf(如果不存在)

    listeners.tcp.default = 5672
    listeners.tcp = none # 关闭非tls的端口
    listeners.ssl.default=5671
    ssl_options.cacertfile=/etc/rabbitmq/ssl/cacert.pem
    ssl_options.certfile=/etc/rabbitmq//ssl/rabbitmq-server.cert.pem
    ssl_options.keyfile=/etc/rabbitmq//ssl/rabbitmq-server.key.pem
    
    ssl_options.verify=verify_peer
    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
    
    auth_mechanisms.1 = EXTERNAL # 使用rabbit-ssl插件进行认证 首先要配置SSL插件
    #auth_mechanisms.2 = PLAIN # 明文
    #auth_mechanisms.3 = AMQPLAIN # 明文
    management.tcp.port = 15672
    ssl_cert_login_from = common_name # 使用证书种的CN作为登录用户名
    loopback_users.guest = false
    default_pass = Rabbit@123
    default_user = admin
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59

    验证证书有效性

    # 进入生成的目录下,通过证书连接rabbit
    openssl s_client -connect localhost:5671 \
      -cert client/rabbitmq-client.cert.pem \
      -key client/rabbitmq-client.key.pem \
      -CAfile ca/cacert.pem
    
    • 1
    • 2
    • 3
    • 4
    • 5

    遇到问题&注意事项

    1. 部署在服务器上的rabbit 5671端口一直无法telnet通,因为忘记配防火墙的5671端口了。。。
    2. rabbit忘记创建证书登录用户,无法连接
    3. 没有配置ssl_cert_login_from,就无法从证书用户进行登录
    4. 不能在本地生成然后上传到服务器,必须在服务器生成,下载客户端密钥到本地

    Springboot连接测试

    主要配置文件

    server.port=8085
    #基础配置请根据实际配置,此种配置方式无需配置用户名与密码
    spring.rabbitmq.host=
    #ssl协议端口
    spring.rabbitmq.port=5671
    spring.rabbitmq.virtual-host=/
    #启用rabbitmq客户端SSL连接
    spring.rabbitmq.ssl.enabled=true
    #客户端PKCS12证书及密码
    spring.rabbitmq.ssl.key-store=classpath:ssl/rabbitmq-client.keycert.p12
    spring.rabbitmq.ssl.key-store-password=123456
    #公钥证书及类型
    spring.rabbitmq.ssl.trust-store=classpath:ssl/rabbitmqStore
    spring.rabbitmq.ssl.trust-store-password=123456
    spring.rabbitmq.ssl.trust-store-type=JKS
    #不校验主机名,默认开启会导致连接失败
    spring.rabbitmq.ssl.verify-hostname=false
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在这里插入图片描述

    参考文献

    [1] https://blog.csdn.net/u012586326/article/details/122373289
    [2] https://blog.freessl.cn/ssl-cert-format-introduce/
    [3] https://www.cnblogs.com/ybyn/p/13959135.html
    [4] https://www.rabbitmq.com/ssl.html

  • 相关阅读:
    基于JAVA医院远程诊断系统计算机毕业设计源码+系统+mysql数据库+lw文档+部署
    数据结构与算法:树 二叉树入门(一)
    深度优先搜索和广度优先搜索
    听懂未来:AI语音识别技术的进步与实战
    开具数电票如何减少认证频次?
    1.8 运用C编写ShellCode代码
    pycharm安装第三方库
    java毕业设计仓库管理系统Mybatis+系统+数据库+调试部署
    uboot启动流程-run_main_loop 到 cmd_process处理说明一
    电子科技大学《数据库原理及应用》(持续更新)
  • 原文地址:https://blog.csdn.net/u013551615/article/details/126314195