首页 > 解决方案 > Spring Boot / Stomp / RabbitMQ + TLS

问题描述

我,

我尝试将 Reactor Netty TCP 客户端配置为连接到 RabbitMQ Stomp,但我从 JVM 收到 TLS 错误。有谁能够帮我?

版本:

        JDK: 11.0.10 (but I tried with 1.8 and 15)
         OS: Fedora 33
Spring Boot: 1.4.21
   RabbitMQ: 3.7

RabbitMQ 配置:

loopback_users.guest = false

ssl_options.cacertfile = /etc/ssl/rabbitmq/ca.loc.pem
ssl_options.certfile = /etc/ssl/rabbitmq/broker.loc.pem
ssl_options.keyfile = /etc/ssl/rabbitmq/broker.loc.key
ssl_options.verify = verify_none
ssl_options.fail_if_no_peer_cert = false

listeners.tcp.default = 5672
listeners.ssl.default = 5671

stomp.listeners.tcp.1 = 61613
stomp.listeners.ssl.1 = 61614

RabbitMQ 在 Docker 容器中运行,配置如下:

broker:
  image: gleroy/rabbitmq-stomp:3.7-1
  ports:
    - 61613:61613
    - 61614:61614
  volumes:
    - ./docker/broker/ssl:/etc/ssl/rabbitmq
    - ./docker/broker/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf

gleroy/rabbitmq-stomp图像包含一个启用了 stomp 插件的 RabbitMQ 3.7。

踩踏配置:

@Configuration
class WebSocketConfiguration(
    private val props: Properties
) : WebSocketMessageBrokerConfigurer {
    override fun configureMessageBroker(registry: MessageBrokerRegistry) {
        val client = ReactorNettyTcpClient(
            { tcpClient ->
                val sslContextBuilder = SslContextBuilder.forClient()
                val configuredTcpClient = tcpClient
                    .host(props.broker.host.hostAddress)
                    .port(props.broker.port)
                if (props.broker.tlsEnabled) {
                    configuredTcpClient.secure { it.sslContext(sslContextBuilder) }
                } else {
                    configuredTcpClient
                }
            },
            StompReactorNettyCodec()
        )
        registry
            .setApplicationDestinationPrefixes("/app")
            .enableStompBrokerRelay(ApiConstants.WebSocket.TopicPath)
            .setTcpClient(client)
            .setClientLogin(props.broker.username)
            .setClientPasscode(props.broker.password)
    }

    override fun registerStompEndpoints(registry: StompEndpointRegistry) {
        registry
            .addEndpoint(ApiConstants.WebSocket.Path)
            .setAllowedOriginPatterns(*props.server.allowedOrigins.split(",").toTypedArray())
            .withSockJS()
    }
}

和:

props.broker.tlsEnabled设置为时一切正常false

日志(使用-Djavax.net.debug=all,我删除了一些无用的日志):

javax.net.ssl|DEBUG|01|main|2021-03-14 18:20:22.063 CET|TrustStoreManager.java:112|trustStore is: api/ssl/truststore.p12
trustStore type is: pkcs12
trustStore provider is: 
the last modified time is: Sun Mar 14 16:21:48 CET 2021
javax.net.ssl|DEBUG|01|main|2021-03-14 18:20:22.063 CET|TrustStoreManager.java:311|Reload the trust store
javax.net.ssl|DEBUG|01|main|2021-03-14 18:20:22.211 CET|TrustStoreManager.java:318|Reload trust certs
javax.net.ssl|DEBUG|01|main|2021-03-14 18:20:22.212 CET|TrustStoreManager.java:323|Reloaded 1 trust certs
javax.net.ssl|DEBUG|01|main|2021-03-14 18:20:22.215 CET|X509TrustManagerImpl.java:79|adding as trusted certificates (
  "certificate" : {
    "version"            : "v3",
    "serial number"      : "36 05 A8 93 C7 A7 66 F8 95 9A DF 15 F0 D1 FD 60 62 6A 90 59",
    "signature algorithm": "SHA256withRSA",
    "issuer"             : "CN=ca.loc, L=Montpellier, C=FR",
    "not before"         : "2021-03-14 16:20:51.000 CET",
    "not  after"         : "2048-07-29 17:20:51.000 CEST",
    "subject"            : "CN=ca.loc, L=Montpellier, C=FR",
    "subject public key" : "RSA",
    "extensions"         : [
      {
        ObjectId: 2.5.29.35 Criticality=false
        AuthorityKeyIdentifier [
        KeyIdentifier [
        0000: 50 06 35 EA AB 26 C5 FC   A1 56 98 45 D1 42 FB 60  P.5..&...V.E.B.`
        0010: DD 56 F0 EE                                        .V..
        ]
        ]
      },
      {
        ObjectId: 2.5.29.19 Criticality=true
        BasicConstraints:[
          CA:true
          PathLen:2147483647
        ]
      },
      {
        ObjectId: 2.5.29.14 Criticality=false
        SubjectKeyIdentifier [
        KeyIdentifier [
        0000: 50 06 35 EA AB 26 C5 FC   A1 56 98 45 D1 42 FB 60  P.5..&...V.E.B.`
        0010: DD 56 F0 EE                                        .V..
        ]
        ]
      }
    ]}
)

...

d.gleroy.ivanachess.api.IvanaChessApiKt  : Started IvanaChessApiKt in 3.962 seconds (JVM running for 4.371)
javax.net.ssl|DEBUG|31|tcp-client-loop-nio-2|2021-03-14 18:20:22.850 CET|HandshakeContext.java:296|Ignore unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 for TLS13
javax.net.ssl|DEBUG|31|tcp-client-loop-nio-2|2021-03-14 18:20:22.850 CET|HandshakeContext.java:296|Ignore unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 for TLS13
javax.net.ssl|DEBUG|31|tcp-client-loop-nio-2|2021-03-14 18:20:22.850 CET|HandshakeContext.java:296|Ignore unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 for TLS13
javax.net.ssl|DEBUG|31|tcp-client-loop-nio-2|2021-03-14 18:20:22.850 CET|HandshakeContext.java:296|Ignore unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 for TLS13
javax.net.ssl|DEBUG|31|tcp-client-loop-nio-2|2021-03-14 18:20:22.850 CET|HandshakeContext.java:296|Ignore unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA for TLS13
javax.net.ssl|DEBUG|31|tcp-client-loop-nio-2|2021-03-14 18:20:22.850 CET|HandshakeContext.java:296|Ignore unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA for TLS13
javax.net.ssl|DEBUG|31|tcp-client-loop-nio-2|2021-03-14 18:20:22.850 CET|HandshakeContext.java:296|Ignore unsupported cipher suite: TLS_RSA_WITH_AES_128_GCM_SHA256 for TLS13
javax.net.ssl|DEBUG|31|tcp-client-loop-nio-2|2021-03-14 18:20:22.850 CET|HandshakeContext.java:296|Ignore unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA for TLS13
javax.net.ssl|DEBUG|31|tcp-client-loop-nio-2|2021-03-14 18:20:22.850 CET|HandshakeContext.java:296|Ignore unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA for TLS13
javax.net.ssl|WARNING|31|tcp-client-loop-nio-2|2021-03-14 18:20:22.860 CET|ServerNameExtension.java:261|Unable to indicate server name
javax.net.ssl|DEBUG|31|tcp-client-loop-nio-2|2021-03-14 18:20:22.860 CET|SSLExtensions.java:260|Ignore, context unavailable extension: server_name
javax.net.ssl|WARNING|31|tcp-client-loop-nio-2|2021-03-14 18:20:22.863 CET|SignatureScheme.java:295|Signature algorithm, ed25519, is not supported by the underlying providers
javax.net.ssl|WARNING|31|tcp-client-loop-nio-2|2021-03-14 18:20:22.863 CET|SignatureScheme.java:295|Signature algorithm, ed448, is not supported by the underlying providers
javax.net.ssl|ALL|31|tcp-client-loop-nio-2|2021-03-14 18:20:22.865 CET|SignatureScheme.java:371|Ignore unsupported signature scheme: ed25519
javax.net.ssl|ALL|31|tcp-client-loop-nio-2|2021-03-14 18:20:22.865 CET|SignatureScheme.java:371|Ignore unsupported signature scheme: ed448
javax.net.ssl|ALL|31|tcp-client-loop-nio-2|2021-03-14 18:20:22.865 CET|SignatureScheme.java:391|Ignore disabled signature scheme: dsa_sha256
javax.net.ssl|ALL|31|tcp-client-loop-nio-2|2021-03-14 18:20:22.865 CET|SignatureScheme.java:391|Ignore disabled signature scheme: dsa_sha224
javax.net.ssl|ALL|31|tcp-client-loop-nio-2|2021-03-14 18:20:22.865 CET|SignatureScheme.java:391|Ignore disabled signature scheme: ecdsa_sha1
javax.net.ssl|ALL|31|tcp-client-loop-nio-2|2021-03-14 18:20:22.865 CET|SignatureScheme.java:391|Ignore disabled signature scheme: rsa_pkcs1_sha1
javax.net.ssl|ALL|31|tcp-client-loop-nio-2|2021-03-14 18:20:22.865 CET|SignatureScheme.java:391|Ignore disabled signature scheme: dsa_sha1
javax.net.ssl|ALL|31|tcp-client-loop-nio-2|2021-03-14 18:20:22.865 CET|SignatureScheme.java:391|Ignore disabled signature scheme: rsa_md5
javax.net.ssl|INFO|31|tcp-client-loop-nio-2|2021-03-14 18:20:22.865 CET|AlpnExtension.java:161|No available application protocols
javax.net.ssl|DEBUG|31|tcp-client-loop-nio-2|2021-03-14 18:20:22.865 CET|SSLExtensions.java:260|Ignore, context unavailable extension: application_layer_protocol_negotiation
javax.net.ssl|DEBUG|31|tcp-client-loop-nio-2|2021-03-14 18:20:22.866 CET|SSLExtensions.java:260|Ignore, context unavailable extension: cookie
javax.net.ssl|DEBUG|31|tcp-client-loop-nio-2|2021-03-14 18:20:22.874 CET|PreSharedKeyExtension.java:634|No session to resume.
javax.net.ssl|DEBUG|31|tcp-client-loop-nio-2|2021-03-14 18:20:22.874 CET|SSLExtensions.java:260|Ignore, context unavailable extension: pre_shared_key
javax.net.ssl|DEBUG|31|tcp-client-loop-nio-2|2021-03-14 18:20:22.876 CET|ClientHello.java:653|Produced ClientHello handshake message (
"ClientHello": {
  "client version"      : "TLSv1.2",
  "random"              : "93 46 41 CB 92 A2 3B 07 86 DD 4A 5A 66 90 5C 58 04 1D C4 84 F5 BE 62 86 79 E9 C1 F0 39 E5 7E C9",
  "session id"          : "8E F4 F0 4E A9 EA 27 11 47 F9 E7 69 E2 76 8A 51 A2 AD 19 22 C1 85 BD 92 CD 7F F3 5C 51 4A 3A 97",
  "cipher suites"       : "[TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384(0xC02C), TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256(0xC02B), TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256(0xC02F), TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384(0xC030), TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA(0xC013), TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA(0xC014), TLS_RSA_WITH_AES_128_GCM_SHA256(0x009C), TLS_RSA_WITH_AES_128_CBC_SHA(0x002F), TLS_RSA_WITH_AES_256_CBC_SHA(0x0035), TLS_AES_128_GCM_SHA256(0x1301), TLS_AES_256_GCM_SHA384(0x1302)]",
  "compression methods" : "00",
  "extensions"          : [
    "status_request (5)": {
      "certificate status type": ocsp
      "OCSP status request": {
        "responder_id": <empty>
        "request extensions": {
          <empty>
        }
      }
    },
    "supported_groups (10)": {
      "versions": [x25519, secp256r1, secp384r1, secp521r1, x448, ffdhe2048, ffdhe3072, ffdhe4096, ffdhe6144, ffdhe8192]
    },
    "ec_point_formats (11)": {
      "formats": [uncompressed]
    },
    "signature_algorithms (13)": {
      "signature schemes": [ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384, ecdsa_secp521r1_sha512, rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512, rsa_pss_pss_sha256, rsa_pss_pss_sha384, rsa_pss_pss_sha512, rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha512, ecdsa_sha224, rsa_sha224]
    },
    "signature_algorithms_cert (50)": {
      "signature schemes": [ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384, ecdsa_secp521r1_sha512, rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512, rsa_pss_pss_sha256, rsa_pss_pss_sha384, rsa_pss_pss_sha512, rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha512, ecdsa_sha224, rsa_sha224]
    },
    "status_request_v2 (17)": {
      "cert status request": {
        "certificate status type": ocsp_multi
        "OCSP status request": {
          "responder_id": <empty>
          "request extensions": {
            <empty>
          }
        }
      }
    },
    "extended_master_secret (23)": {
      <empty>
    },
    "supported_versions (43)": {
      "versions": [TLSv1.3, TLSv1.2]
    },
    "psk_key_exchange_modes (45)": {
      "ke_modes": [psk_dhe_ke]
    },
    "key_share (51)": {
      "client_shares": [  
        {
          "named group": x25519
          "key_exchange": {
            0000: 8A B2 32 3D FC 8D 2D EF   B9 1A 94 7D 98 17 69 C1  ..2=..-.......i.
            0010: 65 39 F2 1E C6 FA B5 ED   0E 15 D4 DB 7F 02 7C 3C  e9.............<
          }
        },
      ]
    },
    "renegotiation_info (65,281)": {
      "renegotiated connection": [<no renegotiated connection>]
    }
  ]
}
)
javax.net.ssl|DEBUG|31|tcp-client-loop-nio-2|2021-03-14 18:20:22.891 CET|SSLEngineOutputRecord.java:505|WRITE: TLS13 handshake, length = 287
javax.net.ssl|DEBUG|31|tcp-client-loop-nio-2|2021-03-14 18:20:22.892 CET|SSLEngineOutputRecord.java:523|Raw write (
  0000: 16 03 03 01 1F 01 00 01   1B 03 03 93 46 41 CB 92  ............FA..
  0010: A2 3B 07 86 DD 4A 5A 66   90 5C 58 04 1D C4 84 F5  .;...JZf.\X.....
  0020: BE 62 86 79 E9 C1 F0 39   E5 7E C9 20 8E F4 F0 4E  .b.y...9... ...N
  0030: A9 EA 27 11 47 F9 E7 69   E2 76 8A 51 A2 AD 19 22  ..'.G..i.v.Q..."
  0040: C1 85 BD 92 CD 7F F3 5C   51 4A 3A 97 00 16 C0 2C  .......\QJ:....,
  0050: C0 2B C0 2F C0 30 C0 13   C0 14 00 9C 00 2F 00 35  .+./.0......./.5
  0060: 13 01 13 02 01 00 00 BC   00 05 00 05 01 00 00 00  ................
  0070: 00 00 0A 00 16 00 14 00   1D 00 17 00 18 00 19 00  ................
  0080: 1E 01 00 01 01 01 02 01   03 01 04 00 0B 00 02 01  ................
  0090: 00 00 0D 00 1E 00 1C 04   03 05 03 06 03 08 04 08  ................
  00A0: 05 08 06 08 09 08 0A 08   0B 04 01 05 01 06 01 03  ................
  00B0: 03 03 01 00 32 00 1E 00   1C 04 03 05 03 06 03 08  ....2...........
  00C0: 04 08 05 08 06 08 09 08   0A 08 0B 04 01 05 01 06  ................
  00D0: 01 03 03 03 01 00 11 00   09 00 07 02 00 04 00 00  ................
  00E0: 00 00 00 17 00 00 00 2B   00 05 04 03 04 03 03 00  .......+........
  00F0: 2D 00 02 01 01 00 33 00   26 00 24 00 1D 00 20 8A  -.....3.&.$... .
  0100: B2 32 3D FC 8D 2D EF B9   1A 94 7D 98 17 69 C1 65  .2=..-.......i.e
  0110: 39 F2 1E C6 FA B5 ED 0E   15 D4 DB 7F 02 7C 3C FF  9.............<.
  0120: 01 00 01 00                                        ....
)
javax.net.ssl|ALL|31|tcp-client-loop-nio-2|2021-03-14 18:20:22.908 CET|SSLEngineImpl.java:752|Closing outbound of SSLEngine
javax.net.ssl|ALL|31|tcp-client-loop-nio-2|2021-03-14 18:20:22.908 CET|SSLEngineImpl.java:724|Closing inbound of SSLEngine
javax.net.ssl|ERROR|31|tcp-client-loop-nio-2|2021-03-14 18:20:22.908 CET|TransportContext.java:341|Fatal (INTERNAL_ERROR): closing inbound before receiving peer's close_notify (
"throwable" : {
  javax.net.ssl.SSLException: closing inbound before receiving peer's close_notify
    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:133)
    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:336)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:292)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:283)
    at java.base/sun.security.ssl.SSLEngineImpl.closeInbound(SSLEngineImpl.java:733)
    at io.netty.handler.ssl.SslHandler.setHandshakeFailure(SslHandler.java:1848)
    at io.netty.handler.ssl.SslHandler.channelInactive(SslHandler.java:1115)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:241)
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelInactive(DefaultChannelPipeline.java:1405)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248)
    at io.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:901)
    at io.netty.channel.AbstractChannel$AbstractUnsafe$8.run(AbstractChannel.java:819)
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:497)
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.base/java.lang.Thread.run(Thread.java:834)}

)
javax.net.ssl|ALL|31|tcp-client-loop-nio-2|2021-03-14 18:20:22.908 CET|SSLSessionImpl.java:784|Invalidated session:  Session(1615742422831|SSL_NULL_WITH_NULL_NULL)
2021-03-14 18:20:22.911  INFO 62266 --- [ient-loop-nio-2] o.s.m.s.s.StompBrokerRelayMessageHandler : TCP connection failure in session _system_: Failed to connect: null

java.nio.channels.ClosedChannelException: null
    at io.netty.handler.ssl.SslHandler.channelInactive(SslHandler.java:1112) ~[netty-handler-4.1.58.Final.jar:4.1.58.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:241) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelInactive(DefaultChannelPipeline.java:1405) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
    at io.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:901) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
    at io.netty.channel.AbstractChannel$AbstractUnsafe$8.run(AbstractChannel.java:819) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164) ~[netty-common-4.1.58.Final.jar:4.1.58.Final]
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472) ~[netty-common-4.1.58.Final.jar:4.1.58.Final]
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:497) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989) ~[netty-common-4.1.58.Final.jar:4.1.58.Final]
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.58.Final.jar:4.1.58.Final]
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.58.Final.jar:4.1.58.Final]
    at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]

标签: spring-bootsslrabbitmqstompreactor-netty

解决方案


推荐阅读