Nginx reverse proxy subdirectory to root - nginx

So. I am using Nginx as a load balancer to load traffic between couple of instances.
Let's say my Nginx loadbalancer is at platform.staging.com (example).
I am trying to redirect traffic from
platform.staging.com/sync
To one of these:
sync1.staging.com:12345
sync2.staging.com:12345
Notice that what I am trying to achieve is to have /sync part stripped down and requests to sync instances should have path /.
This is what I tried but it doesn't work:
upstream sync-cluster {
ip_hash;
server sync1.staging.com:12345;
server sync2.staging.com:12345;
}
server {
listen 443 ssl spdy;
server_name platform.staging.com;
location /sync {
proxy_pass http://sync-cluster;
}
}
In the logs I can see:
2014/01/14 23:20:38 [error] 2385#0: *1 connect() failed (111: Connection refused) while connecting to upstream, client: XX.XXX.XX.XXX, server: platform.staging.com, request: "GET /sync HTTP/1.1", upstream: "http://X.X.X.XXX:12345/sync", host: "platform.staging.com"

Try adding a rewrite before doing the proxy pass, I'll assume you are going to preserve what's after /sync, hope this works for you
location ^~ /sync(.*) {
rewrite ^ $1;
proxy_pass ...;
}

Related

Nginx in Cloud Run with internal traffic works but gives connect errors

I'm running an Nginx in a Cloud Run instance as a Reverse-Proxy to a backend Cloud Run app (it will do more stuff in the future, but let's keep it simple for this example).
The Nginx Cloud Run requires authentication (via IAM), but the backend app doesn't. The Nginx is connected to the same VPC and has the setting (vpc_access_egress = all-traffic), and the backend app is set to Allow internal traffic only only.
events {}
http {
resolver 169.254.169.254;
server {
listen 8080;
server_name mirror_proxy;
location / {
proxy_pass https://my-backend.a.run.app:443;
proxy_cache off;
proxy_redirect off;
}
}
}
The setup works, and I send authenticated requests to the Nginx and get the responses from the backend. However I also get a lot of error messages from the Nginx per request.
2022/12/22 13:57:51 POST 200 1.76 KiB 1.151s curl 7.68.0 https://nginx.a.run.app/main
2022/12/22 13:57:50 [error] 4#4: *21 connect() to [1234:5678:4802:34::35]:443 failed
(113: No route to host) while connecting to upstream, client: 169.254.1.1,
server: mirror_proxy, request: "POST /main HTTP/1.1",
upstream: "https://[1234:5678:4802:34::35]:443/main", host: "nginx.a.run.app"
2022/12/22 13:57:50 [error] 4#4: *21 connect() to [1234:5678:4802:36::35]:443 failed
(113: No route to host) while connecting to upstream, client: 169.254.1.1,
server: mirror_proxy, request: "POST /main HTTP/1.1",
upstream: "https://[1234:5678:4802:36::35]:443/main", host: "nginx.a.run.app"
2022/12/22 13:57:50 [error] 4#4: *21 connect() to [1234:5678:4802:32::35]:443 failed
(113: No route to host) while connecting to upstream, client: 169.254.1.1,
server: mirror_proxy, request: "POST /main HTTP/1.1",
upstream: "https://[1234:5678:4802:32::35]:443/main", host: "nginx.a.run.app"
Why are there errors, when the request succeeds?
Doesn't the VPC router don't know the exact IP address of the Cloud Run yet, and Nginx has to try them out? Any idea?
GCP only uses IPv4 inside the VPC network.
Since I forced the Nginx to use the VPC network (vpc_access_egress = all-traffic), Nginx will fail when it tries to resolve an IPv6, and fall back to IPv4.
With the following setting you can force Nginx to immediately resolve the IPv4.
http {
resolver 169.254.169.254 ipv6=off;
...
}
``

nginx proxy_pass could not be resolved (3: Host not found)

I have the following nginx configuration which returns 502
server {
listen 2052;
listen 2082;
server_name good.abc.com;
location / {
proxy_pass http://goodServer:$server_port;
}
}
Testing:
proxy_pass http://goodServer:2052; When the fixed port is 2052
curl good.abc.com:2052 It can be accessed normally.
Question:
The port I want to forward user requests to
For example.
curl good.abc.com:2052 ---> goodServer:2052
curl good.abc.com:2082 ---> goodServer:2082
So the port must be a variable, just like $server_port
Log:
2021/04/04 14:10:11 [error] 24#24: *19 good could not be resolved (3: Host not found), client: 162.158.91.119, server: good.abc.com, request: "GET / HTTP/1.1", host: "good.abc.com:2052"

NGINX - Short domain proxy to full path on another domain

I have two domains, let's say ex.io and example.com. I own both and have access to both servers. Both run NGINX.
Goal: I'd like to have any request from ex.io forward to a specific path under example.com, e.g. http://ex.io passes to https://example.com/foo/bar. This has to be done without a redirect (more in Context)
Context: The goal is to host a shell script at https://example.com/foo/bar so that curl ex.io | sh will run the shell script. I'd like no redirects to happen so no additional flags are needed for curl.
My current .conf setup for both servers follows:
server {
listen 80;
listen [::]:80;
server_name example.com
return 308 https://$host$request_uri;
}
server {
listen 80;
listen [::]:80;
server_name ex.io;
return 308 https://example.com/foo/bar;
}
# ...
This works, but requires the extra flag -L to run properly under curl. How can I proxy ex.io to go directly to https://example.io/foo/bar?
EDIT: I'm forwarding http://ex.io/ to https://example.com/foo/bar which may be tricky going from http to https. Bananenkönig's response fails with a 502 Bad Gateway error and the following logs:
2020/10/26 23:28:45 [error] 223#223: *281 SSL_do_handshake() failed (SSL: error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:SSL alert number 40) while SSL handshaking to upstream, client: XXX.XXX.XXX.XXX, server: ex.io, request: "GET / HTTP/1.1", upstream: "https://XXX.XXX.XXX.XXX:443/foo/bar/", host: "ex.io"
2020/10/26 23:28:45 [warn] 223#223: *281 upstream server temporarily disabled while SSL handshaking to upstream, client: XXX.XXX.XXX.XXX, server: ex.io, request: "GET / HTTP/1.1", upstream: "https://XXX.XXX.XXX.XXX:443/foo/bar/", host: "ex.io"
I would try it like this:
server {
listen 80;
listen [::]:80;
server_name ex.io;
location /some/location/on/ex.io/ {
proxy_pass https://example.com/some/location/on/example.com/;
}
}
when you want ex.io/ (on location /) to be forwarded to example.com/... write "location / { "

Convert uWSGI HTTP server to work behind Nginx instead

I'm serving my app with uWSGI using uwsgi --http-socket 127.0.0.1:3031 -w app:app, which works when I go to 127.0.0.1:3031 in a browser. I want to use Nginx, so I told it to uwsgi_pass to that url, but now I get a 502 Bad Gateway error. How do I put uWSGI behind Nginx?
server {
listen 8080;
server_name 127.0.0.1;
location / {
uwsgi_pass 127.0.0.1:3031;
include uwsgi_params;
}
location /static {
alias /static/folder/location;
}
}
2016/05/16 19:50:09 [error] 6810#0: *4 upstream prematurely closed
connection while reading response header from upstream, client:
127.0.0.1, server: 127.0.0.1, request: "GET / HTTP/1.1", upstream:
"uwsgi://127.0.0.1:3031", host: "127.0.0.1:8080"
You can use http-socket between nginx and uWSGI.
For example, if you launch your python app with uWSGI:
uwsgi --http-socket 127.0.0.1:3031 --wsgi-file application.py --callable app --processes 4 --threads 2 --stats 127.0.0.1:9191
Configure Nginx with:
location / {
proxy_pass http://127.0.0.1:3031/;
}
Use socket, not http-socket.
uwsgi --socket 127.0.0.1:3031 -w app:app
http-socket makes uWSGI act like a web server that speaks HTTP, and is not correct if you're using Nginx, since it understands uWSGI directly.

uWSGI nginx error : connect() failed (111: Connection refused) while connecting to upstream

I'm experiencing 502 gateway errors when accessing my IP on nginx(http://52.xx.xx.xx/), the logs simply says this:
2015/09/18 13:03:37 [error] 32636#0: *1 connect() failed (111: Connection refused) while connecting to upstream, client: xx.xx.xx.xx, server: xx.xx.xx.xx, request: "GET / HTTP/1.1", upstream: "uwsgi://127.0.0.1:8000", host: "xx.xx.xx.xx"
my nginx.conf file
# the upstream component nginx needs to connect to
upstream django {
# server unix:///path/to/your/mysite/mysite.sock; # for a file socket
server 127.0.0.1:8000; # for a web port socket (we'll use this first)
}
# configuration of the server
server {
# the port your site will be served on
listen 80;
# the domain name it will serve for
server_name xx.xx.xx.xx; # substitute your machine's IP address or FQDN
charset utf-8;
access_log /home/ubuntu/test_django/nginx_access.log;
error_log /home/ubuntu/test_django/nginx_error.log;
# max upload size
client_max_body_size 75M; # adjust to taste
# Django media
location /media {
alias /home/ubuntu/test_django/static/media/; # your Django project's media files - amend as required
}
location /static {
alias /home/ubuntu/test_django/static/; # your Django project's static files - amend as required
}
# Finally, send all non-media requests to the Django server.
location / {
uwsgi_pass django;
include /home/ubuntu/test_django/uwsgi_params; # the uwsgi_params file you installed
}
}
Is there anything wrong with nginx.conf file.....if i use default conf then it is working.
I resolved it by changing the socket configuration in uwsgi.ini
from socket = 127.0.0.1:3031, to socket = :3031. I was facing this issue when I ran nginx in one Docker container and uWSGI in another. If you are using command line to start uWSGI then do uwsgi --socket :3031.
Hope this helps someone stuck with the same issue, during deployment of a Django application using Docker.
change this address:
include /home/ubuntu/test_django/uwsgi_params;
to
include /etc/nginx/uwsgi_params;
I ran into this issue when setting up the env by nginx + gunicorn and solve it by
adding '*' to ALLOWED_HOSTS or your specific domain.
In my case with a debian server it worked moving:
include /etc/nginx/uwsgi_params;
In the location tag in my nginx server config file, like this:
location /sistema {
include /etc/nginx/uwsgi_params;
uwsgi_pass unix://path/sistema.sock;
}
Also, check you have the following packages installed:
uwsgi-plugin-python
pip3 install uWSGI did the trick for me :D

Resources