Spring Boot应用无法通过TLSv1.2连接到RabbitMQ服务器。

huangapple go评论113阅读模式
英文:

Spring Boot app can't connect to RabbitMQ server over TLSv1.2

问题

Application使用了Spring Boot 1.5.20。在接收到请求后,它需要连接到RabbitMQ,将消息放置在队列中供另一个应用程序使用。

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

正在使用的RabbitMQ端口:
接口:[::],端口:5671,协议:amqp/ssl,用途:AMQP 0-9-1和AMQP 1.0通过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确认只有通过TLSv1.2才能成功与RabbitMQ的Java客户端联系:

$ 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密码扩展(JCE)无限制策略文件。

任何想法都将不胜感激!

英文:

Application uses Spring Boot 1.5.20. Upon receiving a request, it needs to connect to RabbitMQ to place a message on a queue for another application.

RabbitMQ version: 3.8.3<br/>
Erlang version: Erlang/OTP 22 [erts-10.7.1] [source] [64-bit] [smp:3:3] [ds:3:3:10] [async-threads:64] [hipe]

RabbitMQ port in use: <br/>
Interface: [::], port: 5671, protocol: amqp/ssl, purpose: AMQP 0-9-1 and AMQP 1.0 over TLS

RabbitMQ SSL config:

$ 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 confirms RabbitMQ can be successfully contacted by java client only via TLSv1.2

$ java --Djdk.tls.client.protocols=TLSv1.2 SSLPoke &lt;server&gt; 5671
Successfully connected

$ java -Djdk.tls.client.protocols=TLSv1.1 SSLPoke &lt;server&gt; 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)

Additional configurations attempted in java.security:<br/>

/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 command under which application is running:<br/>

java -Xms512m -Xmx512m -Djdk.tls.disabledAlgorithms=TLSv1.1 -Djavax.net.debug=all -Dhttps.protocols=TLSv1.2 -Djdk.tls.client.protocols=TLSv1.2 -jar &lt;path&gt;/&lt;filename&gt;.jar

Problem
The application cannot connect to 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)

This is only an issue when RabbitMQ is configured to use TLSv1.2 (only). If allowed to use TLSv1.1, the connection works. The SSLPoke test above seems to prove that the Java client itself can make the TLSv1.2 connection. We can't figure out why the connection is failing. Is the application continuing to try to use TLSv1.1 despite the configurations to the contrary? Or is it an issue with cipher availability? As you can see above, all typical cipher restrictions have been removed from java.security. Additionally, Java Cryptography Extension (JCE) Unlimited Strength policy files were installed.

Any ideas are appreciated!

答案1

得分: 1

我相对有信心认为这个 Spring AMQP 问题是罪魁祸首:

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

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

英文:

I'm relatively confident that this Spring AMQP issue is the culprit:

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

It seems that the application needs to provide a configuration for the SSL algorithm so that the default isn't used.

huangapple
  • 本文由 发表于 2020年8月8日 02:40:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/63307541.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定