Search code examples
c#dockerrabbitmq.net-6.0suse

RabbitMQ client inside a docker container cannot connect to RabbitMQ server inside another docker container by SSL+PLAIN


I'm going crazy... I am spending hours trying to configure my RabbitMQ client within a .net 6 asp.net web service with HTTPS/AMQP/SSL.

I have made several attempts on both server and client side. The SSL connection works fine when I run the service/client on my local Windows machine from Visual Studio and connect to the RabbitMQ server mentioned above.

As soon as I deploy my service on the Linux host as a web service contained in Docker, the connection cannot be established. It just comes up with an error from the underlying SSL stream, which tells me nothing about what is going wrong....

"System.IO.IOException: Received an unexpected EOF or 0 bytes from the transport stream. at System.Net.Security.SslStream.ReceiveBlobAsync[TIOAdapter](TIOAdapter adapter)" or "RabbitMQ.Client.Exceptions.BrokerUnreachableException: None of the specified endpoints were reachable System.IO.IOException: Received an unexpected EOF or 0 bytes from the transport stream."

So I tried different SSL configurations on the server side, checked the TLS settings and so on. A check with Wireshark shows me that there is no network traffic at all between the client docker port and the RabbitMQ server port. So I 'apt install' telnet inside the webserivce docker container and connected to port 5671 of my RabbitMQ server ... connection established ... Connection closed by foreign host ... but still no network traffic visible?! Maybe I cannot see any traffic due to the default bridged docker network configuration?

Here is my server config in /etc/rabbitmq/conf.d/10-defaults.conf

loopback_users.guest = false

log.console = true
log.file = true
log.file = /tmp/rabbit.log
log.file.level = debug

management.ssl.port       = 15671
management.ssl.cacertfile = /https/ca.pem
management.ssl.certfile   = /https/wildcard.pem
management.ssl.keyfile    = /https/wildcard.key

listeners.ssl.default = 5671
auth_mechanisms.1 = PLAIN

ssl_options.cacertfile = /https/ca.pem
ssl_options.certfile   = /https/wildcard.pem
ssl_options.keyfile    = /https/wildcard.key

Here is my client C# config

var certPath = Environment.GetEnvironmentVariable("ASPNETCORE_Kestrel__Certificates__Default__Path");
var certPassphrase = Environment.GetEnvironmentVariable("ASPNETCORE_Kestrel__Certificates__Default__Password");
var connectionFactory = new BasicConnectionFactory("hostname_docker_server", "myusr", "mypwd", new SecuredConnectionSettings("hostname_docker_server", certPath, certPassphrase))
                    .GetSecuredConnectionFactory();

"connectionFactory" is the RabbitMQ.Client.ConnectionFactory for establishing the connection. (version 6.4.0)

The webservice docker run command looks like this:

docker run --user root --restart always -p 5441:443 -e ASPNETCORE_HTTPS_PORT=5441 -e ASPNETCORE_URLS="https://+" -e ASPNETCORE_Kestrel__Certificates__Default__Password=${env.WILDCARD_SECRET} -e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/wildcard.pfx -v /etc/ssl:/https -d nexus.api:18444/api.prod:latest

The RabbitMQ server docker run command looks like this:

docker run --hostname localhost --name rabbitmq -p 5671:5671 -p 15671:15671 -e RABBITMQ_NODENAME='rabbit@localhost' --volume /etc/ssl:/https -d rabbitmq:latest

Furthermore I execute the following inside the docker bash as soon RabbitMQ is up and running:

rabbitmq-plugins enable rabbitmq_management
rabbitmq-plugins enable rabbitmq_auth_mechanism_ssl

Both services are running on the same SuseLinux host machine.

So my question now is.... What is happening to my RabbitMQ client so that it is not even able to connect to the server/network, while everything else, like the swaggerUI, is working like on my dev machine? Has anyone had similar experiences? Can someone give me a hint or point me in the right direction? Thx in advance, while I bang my head against the wall.


Solution

  • Finally, the simple solution was not to pass the client/server certificate to the connection factory when using user/password (PLAIN) auth...

    var connectionFactory = new ConnectionFactory()
    {
        HostName = "hostname_docker_server",
        Ssl = new SslOption()
        {
            Enabled = true,
            ServerName = "hostname_docker_server",
        },
        UserName = "myusr",
        Password = "mypwd"
    };