Change Host header in nginx reverse proxy - nginx

I am running nginx as reverse proxy for the site example.com to loadbalance a ruby application running in backend server. I have the following proxy_set_header field in nginx which will pass host headers to backend ruby. This is required by ruby app to identify the subdomain names.
location / {
proxy_pass http://rubyapp.com;
proxy_set_header Host $http_host;
}
Now I want to create an alias beta.example.com, but the host header passed to backend should still be www.example.com otherwise the ruby application will reject the requests. So I want something similar to below inside location directive.
if ($http_host = "beta.example.com") {
proxy_pass http://rubyapp.com;
proxy_set_header Host www.example.com;
}
What is the best way to do this?

You cannot use proxy_pass in if block, so I suggest to do something like this before setting proxy header:
set $my_host $http_host;
if ($http_host = "beta.example.com") {
set $my_host "www.example.com";
}
And now you can just use proxy_pass and proxy_set_header without if block:
location / {
proxy_pass http://rubyapp.com;
proxy_set_header Host $my_host;
}

map is better than set + if.
map $http_host $served_host {
default $http_host;
beta.example.com www.example.com;
}
server {
[...]
location / {
proxy_pass http://rubyapp.com;
proxy_set_header Host $served_host;
}
}

I was trying to solve the same situation, but with uwsgi_pass.
After some research, I figured out that, in this scenario, it's required to:
uwsgi_param HTTP_HOST $my_host;
Hope it helps someone else.

Just a small tip. Sometimes you may need to use X-Forwarded-Host instead of Host header. That was my case where Host header worked but only for standard HTTP port 80. If the app was exposed on non-standard port, then this port was lost when the app generated redirects. So finally what worked for me was:
proxy_set_header X-Forwarded-Host $http_host;

Related

NGINX Proxy pass to external site that has internal redirect

i'm trying to configure an nginx proxy that hide an internal site via the proxy pass but without success.
the config i used is
location /internal1/ {
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 15;
proxy_read_timeout 180;
proxy_pass http://internal1/;
}
upstream internal1 {
server a.b.c.d:80;
}
the problem is that when i try to reach the a.b.c.d site it redirect to a login page that sould be http://a.b.c.d/login and after i login it redirect at another page http://a.b.c.d/device/config . with the proxy it redirect to http://mysite/login and http://mysite/device/config
that make the proxy do not work and show me resource not found and i couldn not see any of the pages.
If i change the proxy_pass value to http://a.b.c.d/login/ it show the login page at http://mysite/internal1 and after i login it show no resource found because it try to reach http://mysite/device/config.
someone have some suggestion on how to configure it in the proper way?
thanks for all the answer
EDIT:
sorry for the late answer but i got very busy in the meanwhile, anyway that solution work for 1 device but now all my device connected go only that device "internal" page and i cannot differentiate between more cause nginx do not support the same location in multiple config ( all device have ip/page1 )
location /page1/
{
proxy_pass mysite/internal1/page1;
proxy_redirect off;
proxy_set_header Host $host;
}
EDIT2:
unlucky it's not possible to expose all device to internet directly. the solution i found is:
create a custom DNS subdomain and then create a different nginx server block for every device with his own location and future redirect/proxy ecc...
If you want to expose the web UI of all your devices that live in the internal network to be accessible through Internet - then you will have to create a subdomain (and a corresponding virtual host config) for each device.
Suppose that the domain that points to your nginX is mydevices.net and that you have 2 devices - on 192.168.2.10 and 192.168.2.20
Then your nginX config will look like this:
server {
listen 80;
server_name dev1.mydevices.net;
location / {
proxy_pass internal1;
proxy_redirect default;
}
}
upstream internal1 {
server 192.168.2.10;
}
server {
listen 80;
server_name dev2.mydevices.net;
location / {
proxy_pass internal2;
proxy_redirect default;
}
}
upstream internal2 {
server 192.168.2.20;
}

How to setup Nginx with Auth0?

I got an app running in port 3000.
this app is working behind a reverse proxy such as:
server {
listen 80;
server_name myapp;
location / {
proxy_pass http://127.0.0.1:3000;
}
}
so, everytime I access to my site, it will serve to localhost the content from port 3000, and it's working ok.
The problem is after the auth0 authentication, when the user is authenticated it keeps redirecting to localhost:3000/#, how can I make it work to localhost?
this is my Nginx config file:
server {
listen 80;
server_name myapp;
location / {
proxy_pass http://127.0.0.1:3000;
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;
}
location /generic_oauth/ {
proxy_pass http://127.0.0.1:3000;
}
}
callback is localhost/login/generic_oauth
my auth0 settings callback is: http://localhost:3000/login/generic_oauth
if I change my auth0 callback to http://localhost/login/generic_oauth
got the error:
the callback must be http://localhost:3000/login/generic_oauth
sorry for my bad english
The application has to know what domain name to use on the URLs it issues. nginx may also need to do some rewriting.
Add an X-Forwarded-Host header, and potentially a proxy_redirect directive, as per instructions here
https://www.nginx.com/resources/wiki/start/topics/examples/likeapache/
127.0.0.1 is the loopback address (also known as localhost).
0.0.0.0 is a non-routable meta-address used to designate an invalid, unknown, or non-applicable target (a 'no particular address' place holder).

Nginx Reverse proxy config

I'm having issues with getting a simple config to work with nginx. I have a server that host docker containers so nginx is in a container. So lets call the url foo.com. I would like for the url foo.com/service1 to actually just go to foo.com on another port, so it would actually be pulling foo.com:4321 and foo.com/service2 to be pulling foo.com:5432 and so on. Here is the config I have been having issues with.
http {
server {
listen 0.0.0.0:80;
location /service1/ {
proxy_pass http://192.168.0.2:4321/;
}
location /service2/ {
proxy_pass http://192.168.0.2:5432/;
}
}
}
So the services and nginx live at 192.168.0.2. What is the prefered way to be able to do this? Thank you in advance!
As A side note, this is running in a docker container. Thanks!
I think you should check whether your foo.com is pointing to the right ip address or not first by removing the reverse proxy config. E.g.
http {
server {
listen 80;
server_name foo.com;
location / {
}
}
}
Then, if your ip address already has a service running on port 80 you should specify the server_name for each service like in my example. Nginx can only distinguish which service to respond to which domain by server_name.
*My guess is that you forgot the server_name option.
http {
server {
listen 80;
server_name foo.com;
location /service1/ {
proxy_pass http://192.168.0.2:4321/;
}
location /service2/ {
proxy_pass http://192.168.0.2:5432/;
}
}
}
I have a guess your problem is not related to Nginx per se, but instead it is related to Docker networking. You provided insufficient information to make a detailed conclusion, but here it is a couple of suggestions:
run a simple Docker container at the same host where nginx container is running and try curl from inside that container (I've seen your answer that you are able to call curl from the server running Nginx, but it's not really the same)
for example, if the server running nginx container is OSX or Windows, it may use an intermediate Linux virtual machine with its own network stack, IP addreses, routing, etc.
This is my conf sending to inner glassfish. Check out the use of proxy_redirect off & proxy_set_header X-NginX-Proxy true;
#Glassfish
location /MyService/ {
index index.html;
add_header Access-Control-Allow-Origin $http_origin;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-NginX-Proxy true;
proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:18000/MyService/;
}

nginx reverse proxying multiple application requesting similar assets

I have several applications located at:
http://www.foo.com:80
http://www.bar.com:42
http://www.baz.com:1337
that I am attempting to reverse proxy with one nginx machine. the issue I have right now is that these applications are requesting files that are identical in name, but not identical in content:
location /bootstrap.css {
proxy_pass http://www.foo.com:80/bootstrap.css;
}
location /bootstrap.css {
proxy_pass http://www.bar.com:42/bootstrap.css;
}
location /baz {
proxy_pass http://www.baz.com:1337;
}
location /foo {
proxy_pass http://www.foo.com:80/;
}
is it possible for me to re-write all responses coming from a particular application server to point to it's application subfolder?
ex: redirect
http://www.foo.com:80/*
to
/foo
You can setup something like:
location /foo {
proxy_pass http://www.foo.com:80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
However, your application foo might need to know about this. See this post for example.
EDIT:
Nginx might be able to do what you want by using sub_filter from ngx_http_sub_module
Try the example in: answer 1 and answer 2

I need to do a redirect on a proxied path in Nginx

I'm working with a strangely architected app and I have a need to proxy / and redirect it to a sub-directory (unless someone can comeup with a better solution). Here's the layout of the paths the app uses:
var securePaths = [
"/someaction",
"/anotheraction",
"/athirdaction",
"/client/interfaceishere/index.html" //path to client interface
];
As you can see the place where the client interfaces with the app is two levels in so I need a redirect to there. I can't proxy the app there because it needs access to top level paths like "/someaction". I have nginx configured to the proxy the app like this:
upstream socket_nodes {
ip_hash;
server 127.0.0.1:8080;
}
server {
server_name myapp.example.com;
listen 80;
location / {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8080;
}
}
What's the best way to get the user down to "/client/interfaceishere/index.html"?
The previous users of this app solved this by iframing which is not an option for me.
Then you need to split it up, the paths inside location blocks instead of passing everything with /. You really first need to think and write down where each path needs to go and then either use 'map' to redirect or/and location blocks to handle things. You can use location blocks to handle each uri separately.

Resources