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!
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/
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;
}
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.
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:
The 'AllowEncodedSlashes NoDecode' on VirtualHost level
The 'nocanon' parameter for ProxyPass on "/api" location
This worked for me and I did not need any other header settings. This is a variation on the answer by #user3142747:
location /rabbitmq/ {
# Strip off the "/rabbitmq" prefix
rewrite ^/rabbitmq/(.*) /$1 break;
# Do NOT suffix proxy_pass path with a trailing "/". This allows NGINX to pass the client request completely unchanged.
# - see http://mailman.nginx.org/pipermail/nginx/2009-November/016577.html
proxy_pass $scheme://localhost:15672;
}
if have a subdomain on my nginx webserver configuration: sub.mydomain.com
and i have a backend server which listen on port 5000: http://127.0.0.1:5000
is it possible to pass all subdomain calls to the backend?
Like: https://sub.mydomain.com/list to http://127.0.0.1:5000/sub/list
This should work with all methods: POST, PUT, GET, DELETE
UPDATE:
when i call my server: https://mysubdomain.mydomain.com
with the following configuration:
upstream http_backend {
server 127.0.0.1:5000;
}
server_name ~^(?<subdomain>[^.]+)\.mydomain\.com;
This does not work (error: 404):
location / {
proxy_pass http://http_backend/$subdomain/;
proxy_redirect off;
proxy_set_header Host $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 https;
}
This works fine:
location / {
proxy_pass http://http_backend/mysubdomain/;
proxy_redirect off;
proxy_set_header Host $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 https;
}
When i log the $subdomain variable in the access_log, it seems to be correct.
nginx version: nginx/1.9.15
To pass all subdomains you need to set it in server name by putting dot before domain.
server_name .mydomain.com;
Yes, you can use variables in proxy_pass. And you can extract part of domain using regexp server name.
server {
server_name ~^(?<sub>[^.]+)\.example\.com;
# now subdomain of example.com placed to $sub
# please, note, this rule do not work for http://example.com
location / {
proxy_pass http://127.0.0.1:5000/$sub/;
# Path part of proxy_par URI will replace path
# part of location directive (so / -> /$sub/, /xxxx/ -> /$sub/xxxx/)
}
}
Thats all :)
It seems nginx does not add the $uri to the proxy_pass if i use the $subdomain variable.
The following solution works:
location / {
proxy_pass http://http_backend/$subdomain/$uri;
proxy_redirect off;
proxy_set_header Host $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 https;
}
I'm currently switching my blog from Wordpress to Ghost. There is nginx in front of ghost.
After migration i recognized that old urls
http://domain.org/2015/10/some-topic
are migrated like
http://domain.org/some-topic
So date is gone. Anyway there is some backlinking i don't want to loose, but i'm not so familiar with nginx...So what is the best way to redirect from old url style to new?
My curent configuration looks like:
server {
listen 80;
server_name domain.org;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header HOST $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://10.240.0.2:2368;
proxy_redirect off;
}
}
What should be added?. I suppose i need new location but how it should look like?
I would recommend using a map:
map $uri $redirect_topic {
"~^/\d{4}/\d{2}/(?<topic>.*)" $topic;
}
server {
listen 80;
server_name domain.org;
if ($redirect_topic) {
return 301 $scheme://$host/$redirect_topic;
}
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header HOST $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://10.240.0.2:2368;
proxy_redirect off;
}
}
I think you should put into server section:
rewrite ^/[0-9]*/[0-9]*(/.*) $1 last;
But if you've any additional requests maybe would better in a location section (as you wrote).
About more information see on the official nginx documentation.
I want http://example.com to map to a subpage from somewhere else:
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://somewhere.com/foo;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
}
}
The problem is that this page will load stuff like
<script src="/assets/script.js">
which will then be attempted to get loaded from http://example.com/assets/script.js - but this will actually go to http://somewhere.com/foo/assets/script.js instead of http://somewhere.com/assets/script.js
So how can I convince nginx to just map the root domain - http://example.com to http://somewhere.com/foo and everything else to http://somewhere.com/*?
I tried many things but couldn't get it to work...
location ~* ^\/$ {
proxy_pass http://127.0.0.1:8888;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
break;
}
Currently domain.com/?get=parameters goes to port 8888, but need to go to 80 port.
How to complete location block?
Thanks ;)
You can make use of this is_args variable available in nginx. Give it a try the below condition in your above conf. block:
if ($is_args != "") {
proxy_pass http://127.0.0.1:80;
...
...
}