RabbitMQ connection through Nginx

24,552

Solution 1

You have configured nginx as an HTTP reverse proxy, however rabbitmq is configured to use the AMQP protocol (see description of tcp_listeners at https://www.rabbitmq.com/configure.html)

In order for nginx to do anything meaningful you will need to reconfigure rabbitmq to use HTTP - for example http://www.rabbitmq.com/web-stomp.html.

Of course, this may have a ripple effect because any clients that are accessing rabbitmq via AMQP must be reconfigured/redesigned to use HTTP.

Solution 2

Since nginx 1.9 there is stream module for the tcp or udp (not compiled with by default).

I configured my nginx (1.13.3) with ssl stream

stream {
    upstream rabbitmq_backend {
        server rabbitmq.server:5672
    }

    server {
        listen      5671 ssl;

        ssl_protocols           TLSv1.2 TLSv1.1 TLSv1;
        ssl_ciphers             RC4:HIGH:!aNULL:!MD5;
        ssl_handshake_timeout   30s;

        ssl_certificate       /path/to.crt;
        ssl_certificate_key   /path/to.key;

        proxy_connect_timeout 1s;
        proxy_pass rabbitmq_backend;
    }
}

https://docs.nginx.com/nginx/admin-guide/security-controls/terminating-ssl-tcp/

Solution 3

You can try and proxy to tcp, installing a tcp-proxy module for nginx to work with AMQP.

https://github.com/yaoweibin/nginx_tcp_proxy_module

Give it a go.

Solution 4

Nginx was originally only HTTP server, I also suggest looking into that above referred tcp proxy module, but if you would like to have proven load-balancer which is general TCP reverse proxy (not just HTTP, but can handle any protocol in general), you might consider using HAproxy.

Share:
24,552
Code Review Doctor
Author by

Code Review Doctor

I'm a review Pull requests on GitHub to improve your Django code

Updated on July 09, 2022

Comments

  • Code Review Doctor
    Code Review Doctor almost 2 years

    I am trying to setup rabbitmq it can be accessed externally (from non-localhost) through nginx.

    nginx-rabbitmq.conf:

    server {
        listen       5672;
        server_name  x.x.x.x;
        location / {
            proxy_pass http://localhost:55672/;
        }
    }
    

    rabbitmq.conf:

    [
     {rabbit,
      [
       {tcp_listeners, [{"127.0.0.1", 55672}]}
      ]
     }
    ]
    

    By default guest user can only interact from localhost, so we need to create another user with required permissions, like so:

    sudo rabbitmqctl add_user my_user my_password
    sudo rabbitmqctl set_permissions my_user ".*" ".*" ".*"
    

    However, when I attempt a connection to rabbitmq through pika I get ConnectionClosed exception

    import pika
    credentials = pika.credentials.PlainCredentials('my_username', 'my_password')
    pika.BlockingConnection(
        pika.ConnectionParameters(host=ip_address, port=55672, credentials=credentials)
    )
    

    --[raises ConnectionClosed exception]--

    If I use the same parameters but change host to localhost and port to 5672 then I connect ok: pika.ConnectionParameters(host=ip_address, port=55672, credentials=credentials)

    I have opened port 5672 on the GCE web console, and communication through nginx is happening: nginx access.log file shows

    [30/Apr/2014:22:59:41 +0000] "AMQP\x00\x00\x09\x01" 400 172 "-" "-" "-"

    Which shows a 400 status code response (bad request).

    So by the looks the request fails when going through nginx, but works when we request rabbitmq directly.

    Has anyone else had similar problems/got rabbitmq working for external users through nginx? Is there a rabbitmq log file where I can see each request and help further troubleshooting?

  • Code Review Doctor
    Code Review Doctor about 10 years
    thanks. is it possible to configure nginx to use ampq protocol? I tried using proxy_pass ampq://localhost:55672/, but nging complained that url was invalid.
  • Guido Simone
    Guido Simone about 10 years
    See nginx.com. It supports HTTP, POP and IMAP by default. There is a list of 3rd party modules but I do not see any for rabbitmq/amqp.
  • Code Review Doctor
    Code Review Doctor about 10 years
    STOMP it is then, thanks. seems like quite an oversight not being able to do AMQP stuff from an external domain via nginx. someone with C skills should make a module :).
  • ldgorman
    ldgorman over 5 years
    dont use HTTP with rabbitmq. its limited on message size
  • Qqwy
    Qqwy over 5 years
    This is really nice and was able to help me! However, is there a way to include this inside your sites-enabled section? (Since normally these files are included in the http {...} block of the config, that does not allow stream {...}?
  • Grunthor
    Grunthor almost 4 years
    Works perfectly. I also make some tunning of your configuration gist.github.com/mPanasiewicz/e7ae1c60d13ab34fe57d78f26747f6e‌​6
  • J.Wolfe
    J.Wolfe almost 4 years
    Has anyone tried this with letsencrypt ? I am using my certificates from letsencrypt and getting an UNABLE_TO_VERIFY_LEAF_SIGNATURE error. I can confirm that it is proxying correctly, just not with actual ssl.