1
votes

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
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:
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 <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)

Additional configurations attempted in 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 command under which application is running:

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

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 Answers

1
votes

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.