RabbitMQ Management Over HTTPS and Nginx

11,705

Solution 1

I ended up reverting back to the default rabbitmq.config file, then modified my nginx config block to the below, based on another stackoverflow answer that I can't find right now.

    location ~* /rabbitmq/api/(.*?)/(.*) {
        proxy_pass http://127.0.0.1:15672/api/$1/%2F/$2?$query_string;
        proxy_buffering                    off;
        proxy_set_header Host              $http_host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location ~* /rabbitmq/(.*) {
        rewrite ^/rabbitmq/(.*)$ /$1 break;
        proxy_pass http://127.0.0.1:15672;
        proxy_buffering                    off;
        proxy_set_header Host              $http_host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

Also, I had browser caching for JS files, which was causing issues and have disabled that.

I will try to re-enable SSL piece-by-piece but do have the example URL working for now:

https://example.com/rabbitmq/

Solution 2

I tried the following nginx.conf

    location /rabbitmq/ {
        proxy_pass http://rabbitmq/;
        proxy_buffering                    off;
        proxy_set_header Host              $http_host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

However I couldn't get the details for a queue or exchange. I got 404 errors for api calls. And there was a %2F in the url, it's url encoded /.

We need to keep the %2F in the API url and pass it to rabbitmq.

The following link describes how to keep the encoded url part and rewrite it. Nginx pass_proxy subdirectory without url decoding

So my solution is:

    location /rabbitmq/api/ {
        rewrite ^ $request_uri;
        rewrite ^/rabbitmq/api/(.*) /api/$1 break;
        return 400;
        proxy_pass http://rabbitmq$uri;
        proxy_buffering                    off;
        proxy_set_header Host              $http_host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location /rabbitmq/ {
        proxy_pass http://rabbitmq/;
        proxy_buffering                    off;
        proxy_set_header Host              $http_host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

Solution 3

This did the trick for me

location /rabbitmq {
  proxy_pass http://localhost:15672/;
  rewrite ^/rabbitmq/(.*)$ /$1 break;
}

I didn't have to use any other directives.

Solution 4

In case someone is looking for the solution for the Apache (2.4):

<VirtualHost *:443>
        ServerName              rabbitmq.your-domain.com
        AllowEncodedSlashes     NoDecode 
        ... // rest of the settings

        <Location "/">
          Require all granted
          
          ProxyPass         http://localhost:15672/
          ProxyPassReverse  http://localhost:15672/
        </Location>
        <Location "/api">
          Require all granted

          ProxyPass         http://localhost:15672/api nocanon
        </Location>
</VirtualHost>

In fact, 2 elements are very important:

  1. The 'AllowEncodedSlashes NoDecode' on VirtualHost level
  2. The 'nocanon' parameter for ProxyPass on "/api" location
Share:
11,705
Dario Zadro
Author by

Dario Zadro

Owner of Zadro Web, a Chicago-based web development company with expertise in WordPress, Craft CMS, technical SEO, web hosting, and custom cloud solutions. Also, currently working on Go Auditor, a feature rich SEO audit tool.

Updated on July 21, 2022

Comments

  • Dario Zadro
    Dario Zadro almost 2 years

    I'm trying to access the RabbitMQ interface over HTTPS/SSL with nginx, and I can't figure out what I'm missing.

    Here's my rabbitmq.conf file:

    [
      {ssl, [{versions, ['tlsv1.2', 'tlsv1.1']}]},
      {rabbit, [
          {reverse_dns_lookups, true},
          {hipe_compile, true},
          {tcp_listeners, [5672]},
          {ssl_listeners, [5671]},
          {ssl_options, [
            {cacertfile, "/etc/ssl/certs/CA.pem"},
            {certfile,   "/etc/nginx/ssl/my_domain.crt"},
            {keyfile,    "/etc/nginx/ssl/my_domain.key"},
            {versions, ['tlsv1.2', 'tlsv1.1']}
          ]}
        ]
      },
      {rabbitmq_management, [
        {listener, [
          {port, 15671},
          {ssl,  true},
          {ssl_opts, [
            {cacertfile, "/etc/ssl/certs/CA.pem"},
            {certfile,   "/etc/nginx/ssl/my_domain.crt"},
            {keyfile,    "/etc/nginx/ssl/my_domain.key"},
            {versions, ['tlsv1.2', 'tlsv1.1']}
          ]}
        ]}
      ]}
    ].
    

    All works ok when I restart rabbitmq-server

    My nginx file looks like this:

    location /rabbitmq/ {
            if ($request_uri ~* "/rabbitmq/(.*)") {
                    proxy_pass https://example.com:15671/$1;
            }
    }
    

    Now, I'm guessing there's something with the ngnix config not being able to resolve the HTTPS URL, as I'm getting 504 timeout errors when trying to browse:

    https://example.com/rabbitmq/
    

    Obviously, this is not the correct FQDN, but the SSL cert works fine without the /rabbitmq/

    Has anyone been able to use the RabbitMQ Management web interface on an external connection over a FQDN and HTTPS?

    Do I need to create a new "server" block in nginx config dedicated to the 15671 port?

    Any help would be much appreciated!

  • scnerd
    scnerd over 5 years
    This got me most of the way, but I'm getting a bunch of Cannot read property 'length' of undefined errors from js files, and I've tried both disabling and clearing my cache... did you ever find the core issue with the JS files and how to fix it?
  • Dario Zadro
    Dario Zadro over 5 years
    I removed the .js extension from nginx caching.
  • David Welborn
    David Welborn almost 5 years
    You saved me tons of time here. I only modified the target to another server behind a firewall and it worked perfectly. Just remember to add the "/" at the end of the URL in your browser.
  • Dario Zadro
    Dario Zadro over 4 years
    Awesome David, glad it helped!
  • leoleozhu
    leoleozhu over 4 years
    Thank you Dario. It works for some of the APIs like queue or exchange. But not with user API which doesn't need %2F as a vhost
  • Marko Lahma
    Marko Lahma over 3 years
    I got also the users API part working by removing the first location configuration. It only matched the users API management like rabbitmq/api/users/my-username and broke it. All other API calls were already going through the second location configuration. Tested with github.com/nginxinc/NGINX-Demos/tree/master/nginx-regex-test‌​er .
  • Rafik Farhad
    Rafik Farhad over 3 years
    This answer again proves that copying lots of configuration is dangerous sometimes. This answer ended my 2 days debugging and searching for answer. Thanks.
  • JerMah
    JerMah over 3 years
    Bingo, I tried 5 variants of this but this one did it.
  • Erik Bors
    Erik Bors over 3 years
    This was the best solution.
  • Mihail Shcheglov
    Mihail Shcheglov over 2 years
    An other solution to prevent url decoding is to use $request_uri: location ^~ /rabbitmq/ { if ($request_uri ~* "/rabbitmq/(.*)") { proxy_pass http://rabbitmq_server/$1; }}