【问题标题】:Spring Boot app can't connect to RabbitMQ server over TLSv1.2Spring Boot 应用程序无法通过 TLSv1.2 连接到 RabbitMQ 服务器
【发布时间】:2020-08-07 18:40:50
【问题描述】:

应用程序使用 Spring Boot 1.5.20。收到请求后,它需要连接到 RabbitMQ 以将消息放入队列中以供其他应用程序使用。

RabbitMQ 版本:3.8.3
Erlang 版本:Erlang/OTP 22 [erts-10.7.1] [source] [64-bit] [smp:3:3] [ds:3:3:10] [async-threads:64] [hipe]

正在使用的 RabbitMQ 端口:
接口:[::],端口:5671,协议:amqp/ssl,用途:AMQP 0-9-1 和 AMQP 1.0 over TLS

RabbitMQ SSL 配置:

$ sudo cat /etc/rabbitmq/rabbitmq.conf
listeners.tcp.default = 5672

listeners.ssl.default = 5671

ssl_options.cacertfile = /usr/local/dw/keystore/digicert-CA.cer
ssl_options.certfile = /usr/local/dw/keystore/xxx-cert.crt
ssl_options.keyfile = /usr/local/dw/keystore/xxx-key.pem
ssl_options.password = xxx
ssl_options.verify = verify_none
ssl_options.versions.1 = tlsv1.2
ssl_options.fail_if_no_peer_cert = false

SSLPoke 确认 Java 客户端只能通过 TLSv1.2 成功联系 RabbitMQ

$ java --Djdk.tls.client.protocols=TLSv1.2 SSLPoke <server> 5671
Successfully connected

$ java -Djdk.tls.client.protocols=TLSv1.1 SSLPoke <server> 5671
javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
        at sun.security.ssl.Handshaker.activate(Handshaker.java:509)

在 java.security 中尝试的其他配置:

/usr/lib/jvm/java/jre/lib/security$ grep TLSv1 java.security
jdk.certpath.disabledAlgorithms=TLSv1.1
jdk.jar.disabledAlgorithms=TLSv1.1
jdk.tls.disabledAlgorithms=TLSv1, TLVs1.1, SSLv3

运行应用程序的 Java 命令:

java -Xms512m -Xmx512m -Djdk.tls.disabledAlgorithms=TLSv1.1 -Djavax.net.debug=all -Dhttps.protocols=TLSv1.2 -Djdk.tls.client.protocols=TLSv1.2 -jar <path>/<filename>.jar

问题
应用程序无法连接到 RabbitMQ:

2020-08-07 11:02:22,764  INFO [472-exec-8] o.s.a.r.c.CachingConnectionFactory       : Attempting to connect to: xxx.xxx.com:5671
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
https-jsse-nio-7472-exec-8, setSoTimeout(10000) called
Ignoring disabled protocol: TLSv1.1
https-jsse-nio-7472-exec-8, handling exception: javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled
 or cipher suites are inappropriate)
https-jsse-nio-7472-exec-8, SEND TLSv1.2 ALERT:  fatal, description = handshake_failure
https-jsse-nio-7472-exec-8, WRITE: TLSv1.2 Alert, length = 2
[Raw write]: length = 7
0000: 15 03 03 00 02 02 28                               ......(
https-jsse-nio-7472-exec-8, called closeSocket()
https-jsse-nio-7472-exec-8, called close()
https-jsse-nio-7472-exec-8, called closeInternal(true)
Finalizer, called close()
Finalizer, called closeInternal(true)
2020-08-07 11:02:22,824 ERROR [472-exec-8] o.a.c.c.C.[.[.[.[dispatcherServlet]      : Servlet.service() for servlet [dispatcherSer
vlet] in context with path [/xxx] threw exception [Request processing failed; nested exception is org.springframework.
amqp.AmqpIOException: javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inap
propriate)] with root cause
javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
        at sun.security.ssl.Handshaker.activate(Handshaker.java:509)
        at sun.security.ssl.SSLSocketImpl.kickstartHandshake(SSLSocketImpl.java:1474)
        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1346)
        at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:750)
        at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:123)
        at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
        at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)

仅当 RabbitMQ 配置为使用 TLSv1.2(仅)时,才会出现此问题。如果允许使用 TLSv1.1,则连接有效。上面的 SSLPoke 测试似乎证明了 Java 客户端本身可以进行 TLSv1.2 连接。我们无法弄清楚连接失败的原因。尽管配置相反,应用程序是否继续尝试使用 TLSv1.1?还是密码可用性有问题?正如您在上面看到的,所有典型的密码限制都已从 java.security 中删除。此外,还安装了 Java Cryptography Extension (JCE) Unlimited Strength 策略文件。

感谢任何想法!

【问题讨论】:

    标签: java spring-boot rabbitmq tls1.2 spring-amqp


    【解决方案1】:

    我比较有信心这个 Spring AMQP 问题是罪魁祸首:

    https://github.com/spring-projects/spring-amqp/issues/1169

    应用程序似乎需要为 SSL 算法提供配置,以便不使用默认值。

    【讨论】:

    • 我在旧版本的 java amqp-client 中遇到了同样的问题,该版本具有硬编码的默认协议。 JRE 不再支持该协议。
    猜你喜欢
    • 2016-12-11
    • 2020-07-29
    • 1970-01-01
    • 1970-01-01
    • 2020-03-07
    • 2018-08-26
    • 1970-01-01
    • 2016-01-02
    • 1970-01-01
    相关资源
    最近更新 更多