nginx upstream load balancing through private networking showing 404 - nginx

I have two droplets on Digital Ocean. One load balancer with nginx and one node/express webserver with nginx reverse proxy. Let's call them load-1 and web-1. load-1 handles SSL termination and forwards requests via nginx upstream module to web-1 via http over private networking provided by Digital Ocean.
When accessing web-1 on it's public IP everything works. When accessing through load-1 I receive only 404s. I have verified that the requests are actually forwarded to web-1, this is what the nginx access log for web-1 shows on every request received from load-1:
load-1.private.ip - [09/Jan/2017:13:14:00 +0000] "GET / HTTP/1.0" 404 580 "-" >"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) >Chrome/55.0.2883.87 Safari/537.36"
Why are forwarded requests not working when direct requests are working? Since web-1 is working when accessed directly there must be something wrong with how I forward requests from load-1 to web-1?
My nginx config on load-1:
upstream web-servers {
server web-1.private.ip;
}
server {
listen 80;
listen 443 ssl;
server_name mydomain.com;
ssl on;
ssl_certificate /etc/ssl/mycert.crt;
ssl_certificate_key /etc/ssl/mykey.key;
ssl_session_cache shared:SSL:20m;
ssl_session_timeout 10m;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
add_header Strict-Transport-Security "max-age=31536000";
location / {
proxy_pass http://web-servers;
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 $scheme;
}
}
My nginx config on web-1:
server {
listen 80;
server_name web-1.public.ip web-1.private.ip;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_cache_bypass $http_upgrade;
}
}

Simply, Nginx on web-1 doesn't know what configuration to use.
Nginx looks at the host header to determine the server configuration to use. You're setting the host to be mydomain.com in the proxy settings on load-1, But there's no corresponding entry for mydomain.com on web-1.
Either
Set the default_server flag on web-1 (by changing the listen 80; directive to listen 80 default_server;)
Remove any other server blocks so this is the only block (causing Nginx to treat it as the default server)
Add mydomain.com to the server_name list

Related

proxy_pass connection insecure

I have a problem with nginx and proxy_pass. I try to secure connection to old server without option to upgrade apache there. I can't establish there ssl connection with tls 1.2. So i Tried to secure it by reverse proxy in nginx with some success. when i open website like http://example.com or https://example.com connection is secure and it works well. But there are other sites whitch have links like https://example.com/login https://example.com/investitions (basicly every uri example.com/foo/bar/ ect.)and those connections are insecure. my nginx config looks like this:
server {
listen 443 ssl;
server_name example.com www.example.com;
ssl_certificate ssl.crt;
ssl_certificate_key ssl.key;
ssl_client_certificate ca.crt;
proxy_ssl_protocols TLSv1.2;
proxy_ssl_ciphers HIGH:!aNULL:!MD5;
proxy_ssl_verify on;
proxy_ssl_verify_depth 2;
proxy_ssl_session_reuse on;
location / {
proxy_set_header X-Scheme https;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr
proxy_pass http://baza.example.com/;
}
Please help me.

Reverse proxy to two separate nginx instances

I have several repositories that I need to be able to run individually, or together on the same host. In this case, I have two applications: A and B. Both are run using docker compose.
Each one has:
API (Django): API for application A runs on port 5000; API for application B runs on port 5001 (through channels socket)
its own database: Database A runs on 5432; Database B runs on 5433
its own nginx reverse proxy: Application A listens on port 8001; Application B listens on port 8002
Both are meant to be reached through a reverse proxy listening on port 80 and 443. This is the config for the "main" nginx instance:
ssl_password_file /etc/nginx/certificates/global.pass;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_protocols TLSv1.2 TLSv1.1;
server {
listen 80;
server_name _;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
ssl_certificate /etc/nginx/certificates/certificate.crt;
ssl_certificate_key /etc/nginx/certificates/privatekey.key;
proxy_set_header X-Forwarded-Proto $scheme;
server_name a.my.domain.com;
location / {
proxy_redirect off;
proxy_pass http://a.my.domain.com:8001;
}
}
server {
listen 443 ssl;
ssl_certificate /etc/nginx/certificates/certificate.crt;
ssl_certificate_key /etc/nginx/certificates/privatekey.key;
proxy_set_header X-Forwarded-Proto $scheme;
server_name b.my.domain.com;
location / {
proxy_redirect off;
proxy_pass http://b.my.domain.com:8002;
}
}
This is the config for Application A:
upstream channels-backend {
server api:5000;
}
server {
listen 8001 default_server;
server_name a.my.domain.com [local IP address];
access_log /var/log/nginx/access.log;
underscores_in_headers on;
location /static {
alias /home/docker/code/static;
}
location / {
try_files $uri #proxy_to_app;
}
location #proxy_to_app {
proxy_read_timeout 30;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $server_name;
proxy_redirect off;
proxy_pass http://channels-backend;
}
}
This is the pretty much identical config for Application B:
upstream channels-backend {
server api:5001;
}
server {
listen 8002 default_server;
server_name b.my.domain.com [same local IP address];
keepalive_timeout 70;
access_log /var/log/nginx/access.log;
underscores_in_headers on;
location /static {
alias /home/docker/code/static;
}
location / {
try_files $uri #proxy_to_app;
}
location #proxy_to_app {
proxy_read_timeout 30;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $server_name;
proxy_redirect off;
proxy_pass http://channels-backend;
}
}
When I run all three application using docker-compose up --build, starting with Application A, then Application B, then the "main" reverse proxy, I can open a web browser, go to b.my.domain.com and use Application B just fine. If I try a.my.domain.com, however, I get 502 Bad Gateway. Nginx shows:
[error] 27#27: *10 connect() failed (111: Connection refused) while connecting to upstream, client: [my IP address], server: a.my.domain.com, request: "GET / HTTP/1.1", upstream: "http://[local IP address]:8001/", host: "a.my.domain.com"
So I'm assuming there's some sort of conflict. Because if I run Application A in isolation and access it directly through http://a.my.domain.com:8001, it works fine.
Any ideas? Suggestions on a better setup are also welcome, though I vastly prefer ease of maintenance over performance. I don't want to keep both applications in the same repository. I don't want to rely on the third ("main") reverse proxy, I just want to be able to quickly add more applications on the same server if need be and proxy to one or the other depending on the subdomain of the request.
Edit: If I switch the order in which the applications are built and run, Application B will return 502 Bad Gateway instead of Application A, so the issue is not with either of the applications.
There were a couple of problems: Container names were the same, the configuration for channels was outdated. This was a very specific case, so I doubt this will be helpful to anyone, but I gave each service of each compose file a unique name and made sure that there were no port conflicts. I also changed the compose files so that port 8001 maps to port 80, for example, so the nginx configuration doesn't need to be aware of any unusual port numbers. I updated the channels configuration to reflect the new container names, and now it's working.

nginx giving 404 for location a whereas it is working fine for location b

I am trying to serve a python app and a tomcat app from nginx. The tomcat app is running fine whereas python is giving 404. My files are:
1.
mysite.conf
server {
listen 80 default_server;
listen [::]:80 default_server;
return 301 https://mysite-url$request_uri;
}
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
ssl on;
ssl_prefer_server_ciphers on;
ssl_ciphers 'ECDH !aNULL !eNULL !SSLv2 !SSLv3';
ssl_certificate /home/sslcerts/my.crt;
ssl_certificate_key /home/sslcerts/mykey.pem;
server_name mydomain ;
location ^~/api/ {
include proxy_params;
proxy_pass http://unix:/home/ubuntu/pyapi/pyapi.sock;
proxy_ssl_server_name on;
}
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://127.0.0.1:8080/;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_redirect off;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
When I access https://mysite/api
error log says:
myIP - - [15/May/2020:13:26:03 +0000] "GET /api/ HTTP/1.1" 404 209 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:76.0) Gecko/20100101 Firefox/76.0"
Not Found
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
Whereas if I access https://mysite, it works absolutely fine. Any idea where am I missing?
I have a service running to serve gunicorn app for the python app.
Thanks

Enabling http and https to port 8000

I'm having trouble of being able to access http://example.com:8000 and https://example.com:8000 but I can't seem to get them both work. This will serve as our backend and will API requests all through out. I want to either
open http://example.com:8000 and https://example.com:8000 open for API request
or
redirect from http to https redirect including the CORS authentication and and everything so the client can still get the return even with the redirect
This is my configuration so far
server {
listen 8000 ssl;
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.com/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com/example.com.key;
charset utf-8;
location / {
proxy_pass http://ghost:8000;
proxy_set_header Host $host:$proxy_port;
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;
}
error_page 497 https://$host:$server_port$request_uri;
}
You need to use different ports:
server {
listen 8000;
listen 8443 ssl;
# other directives
}

Connection refused : Nginx HTTPS reverse proxy in docker container

I wanted to setup https reverse proxy with nginx on docker container either ubuntu/centos. On Browser side, I am getting connection refused error. And also, I cannot see anything under /var/log/nginx/access.log or /var/log/nginx/error.log.
I am able to setup http reverse proxy with nginx on docker container again. And, also https reverse proxy with nginx on normal ubuntu and centos virtual machines.
Can understand the reason why https reverse proxy with nginx on docker containers is failing to connect from browser.?
If any additional information needed, I can provide you. Thanks in advance.
For reference, Please check this sites-available/default file.
server {
listen 80;
server_name localhost;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name localhost;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/cert.key;
ssl on;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;
location ~* /rabbitmq/(.*) {
rewrite ^\/rabbitmq\/(.*)$ /$1 break;
proxy_pass http://127.0.0.1:15672;
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-NginX-Proxy true;
proxy_redirect http:// https://;
}
location ~* /api/(.*) {
rewrite ^/api/(.*)$ /$1 break;
proxy_pass http://127.0.0.1:3000;
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-NginX-Proxy true;
proxy_redirect http:// https://;
}
}
Thanks,
Ganesh
Looks, I need to expose both HTTP and HTTPS ports, since nginx reverse proxy configured to server only HTTPS traffic.
docker run -d -p 80:80 -p 443:443 nginx-container
When I started exposing HTTPS port, then it worked.
You're probably running your container in "bridge" network mode (it's default), which means that your 127.0.0.1 is not what you think it is. It would use virtualised network adapter for your container running nginx. To quickly fix it you can add
--net=host
parameter to your docker run command. There are other options, but I need to know more about your setup and requirements to suggest them.

Resources