Routing to different servers with nginx - nginx

Is there a way to use nginx as a router while keeping the requested domain in the URL? For example, if I hit mysite.com, the nginx routing server looks at the URL and directs traffic to a particular server, all while maintaining the original requested domain in the URL.
E.g.
mysite.com/site1/params
Router -> site1.mysite.com/params
But even though behind the scenes site1.mysite.com/params is being called, the user sees mysite.com/site1/params in the URL.
I've taken a stab at the configuration, but seem to be getting 404's.
upstream site1 {
server site1.mysite.com;
}
location /site1 {
rewrite ^(.*)$ /$1 break;
proxy_pass http://site1;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_redirect off;
proxy_buffering 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;
}

Use location with trailing slash, remove rewrite and use proxy_pass with / uri. Nginx will take of replacing /site1/ with /. Also, you may need to set Host header to site1.mysite.com not the $host.
location /site1/ {
proxy_pass http://site1/;
proxy_set_header Host site1.mysite.com;
...
}

Related

Nginx redirects instead of doing reverse proxy with proxy_pass

I have an nginx running on a docker container, which serves a web client.
I want to proxy requests from the client, so that the nginx will pass the POST requests to the server, since the actual destination endpoint is not accessible to the client.
This is the location directive:
location /zipkin {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header Host $host;
proxy_pass http://my-ip:9411/;
}
The client makes requests to http://localhost:8080/zipkin/api/v2/span, which I want the nginx to pass (without redirection) to http://my-ip:9411/api/v2/span.
What happens in practice is that I get a 301 response (to http://localhost:8080/api/v2/span), and the POST is never sent to the destination.
Edit: another try that returns 404 -
location /zipkin/ {
rewrite ^/zipkin/(.*) /$1 break;
proxy_pass http://my-ip:9411$uri; # tried 9411;, 9411/, 9411$uri, 9411$uri/
}
Here $uri is /api/v2/span.
The solution in the end was:
location ~ ^/zipkin(/?)(.*) {
proxy_pass http://my-ip:9411/$2;
}
One of my tries was ^/zipkin(.*) but it evidently didn't work.
Probably the / after the /zipkin is problematic, so (/?) removes it,
And that leaves the (.*) the clean part of the url which needs to be attached to the proxy_passed url.

Nginx catch and rewrite all requests begining with /api to proxy

I want to redirect all requests that have /api/ (http://example.com/api/) to my proxy application and drop the /api in the process. I have tried this but I get a 404 when curling it. It doesn't reach the application, I'm thinking it's something to do with the rewrite but I'm not sure if it's correct.
location ~ ^/api {
rewrite ^/api/(.*) /$1 break;
proxy_pass http://127.0.0.1:8070;
}
The following works when hard-coded. It redirects me to my application /error.
location = /api/error {
proxy_pass http://127.0.0.1:8070/error;
}
For example, I want http://example.com/api/login to hit my proxy application like so http://example.com/login.
This works for me. The $1$is_args$args part passes every thing after the /api in the URL. Now when hitting my domain, example.com/api/something passes /something to my proxy application.
location ~/api(.*)$ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8070$1$is_args$args;
}

Avoid duplication in password protect URL with proxy in nginx

I have a Flask application served using gunicorn, and with NGINX on top of it. I want to use Basic Authentication (user/password) to protect all URL's starting with /admin, which is the back office, but still continue serving all other URLs with gunicorn without password.
Here is my current NGINX config:
server {
listen 80;
server_name example.com;
charset utf-8;
location / {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /admin {
auth_basic "Administrator Login";
auth_basic_user_file /home/app/.htpasswd;
# the following four directives are duplicated :(
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
If I don't duplicate the proxy_* directives in the second location block, then the URLs starting with /admin doesn't get forwarded to gunicorn and I get a 404.
Is there any way to avoid the configuration duplication? I tried location nesting but apparently in the end NGINX only "executes" a single location block.
The proxy_pass must be within the location block. However, there's no need to duplicate the proxy_set_header directives, they can be moved into the server block. So your mistake was simply the assumption that proxy_pass could live in the server block :-)

Routing a subdomain to a folder on another server via AWS route53

I have an EC2 Win2008 server running an ASP.NET 4.5 site www.mysite.com.
In the same AWS zone but another separate EC2 Linux server, I have an NginX/PHP Wordpress site running blog.mysite.com.
I would like to create an AWS Route53 route so that all incoming requests to www.mysite.com/blog get silently routed to blog.mysite.com WITHOUT a redirect so that the user's web browser stays on the URL www.mysite.com/blog
How would I achieve this with Route53? If not achievable with Route53, is there any other way?
I don't want to run PHP/MySQL/WordPress on my Windows server, unless I absolutely have to.
Thanks!
Only way is to put an Apache or nginx in front of both the site that is hosting your ASP.NET 4.5 app and your Wordpress site.
Then you can setup a reverse proxy on that server that makes that /blog path point to your Wordpress site and the / path point to your ASP.NET 4.5 app.
For nginx you would have something like this:
server {
listen 80;
server_name www.yourdomain.com;
access_log /var/log/nginx/log/www.yourdomain.access.log main;
error_log /var/log/nginx/log/www.yourdomain.error.log;
location /blog {
proxy_pass http://yourblogserver;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_redirect off;
proxy_buffering 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;
}
location / {
proxy_pass http://youraspnet40server;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_redirect off;
proxy_buffering 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;
}
}
Keep in mind that your /blog path has to be first in the priority otherwise all the requests will get sent to just /

nginx removes content length http header after proxy_pass

I have a problem that nginx removes the content-length header after the proxy pass. the application back-end sends a gzip stream but specifies the content length. NGINX changes the type content-type to chunked and removes the content length header. This is not acceptable for the app since it is read not by the browser but by an proprietary app that requires the content-legth to be specified.
After specified chunked_transfer_encoding off; it stops adding the content type header but still removes the content length. How to disable any header modifications in nginx?
The confing:
upstream backend {
server 127.0.0.1:9090;
}
server {
root /usr/share/nginx/www;
index index.html index.htm;
chunked_transfer_encoding off;
location / {
proxy_pass http://backend;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_redirect off;
proxy_buffering 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;
}
}
This was a known bug in nginx in the past. Update to the latest build.
http://forum.nginx.org/read.php?2,216085,216085#msg-216085

Resources