Nginx proxy_pass backend server sends 302 to client and redirects client to a backend IP - nginx-reverse-proxy

I have a backend server with IP 192.168.1.10 port 8090 the nginx can reach this via example 10.0.0.10 which is then NATed to 192.168.1.10
nginx ----> 10.0.0.10 ----> 192.168.1.10
This works well in general but we are facing a specific problem here it seems with redirections.
The client goes to https://nginx/gateway and the connection is established and the backend server app now requires authentication so the backend server send a 302 redirect back to the client. What I notice in the client web browser is that the address changes and the client tries to establish a connection to http://192.168.1.10:8080 (auth service is located on a different port). The page fails to load as the client has no route to this destination.
My expectation is that nginx takes care of this redirect internally and is simply passing the content to the client using its own https://nginx address.
The config is simple:
location / {
proxy_pass "http://10.0.0.10:8090";
proxy_set_header Host $host:$server_port;
}
Any suggestions? Many thanks!

Related

How to resolve Http Load Balancing Error 1003 on cloudflare dns?

SSL/TLS encryption mode on Cloudflare side is on "flexible" status (https on)
server side setting on third server is:
upstream backend {
server domain1.com;
server domain2.com;
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
Error message is:
Error 1003
Direct IP access not allowed
Cloudflare explains:
Error 1003 Access Denied: Direct IP Access Not Allowed
Common cause
A client or browser directly accesses a Cloudflare IP address.
Resolution
Browse to the website domain name in your URL instead of the Cloudflare IP address.
I resolved this problem with set proxy to the header
proxy_set_header Host www.domain.io;

400 Bad Request load balancer for Apache servers with NGINX

I am using NGINX as load balancer for Apache WebServers (WordPress). All servers are made with AWS EC2. My config for NGINX:
cat /etc/nginx/sites-available/default
upstream web_backend {
server 35.157.101.5;
server 35.156.213.23;
}
server {
listen 80;
location / {
proxy_pass http://web_backend;
}
}
But after NGINX restart i am access load balancer via public ip and getting an error:
Bad Request
Your browser sent a request that this server could not understand.
Additionally, a 400 Bad Request error was encountered while trying to
use an ErrorDocument to handle the request.
Apache/2.4.29 (Ubuntu) Server at
ip-172-31-35-36.eu-central-1.compute.internal Port 80
If i refresh page i am getting same error but with another ip in the end (second server’s private ip), so i understand that NGINX do the work and it is Apache problem.
I tried to add 80 port for my servers in nginx config, replace ips with dns and private ip, but it didn’t help. Access log on Apache doesn’t show anything useful, just 400 errors.
What could be the problem?
Don’t use ‘_’ for upstream name, it was the only reason for my problem.
Just check on which ports are the Apache WebServers Running. You have to add those to your upstreams.
E.g.:
upstream web_backend {
server 35.157.101.5:8080; //assuming that your apache webserver is running on this port on this host
server 35.156.213.23:3000;//And a different port on the other.. you still need to add them here if your ports are same
}

Nginx reverse proxy to https location causes ssl_error_rx_record_too_long

ttI am adding an nginx reverse proxy in front of my existing nextcloudpi server in order to be able to route traffic to different servers in my network depending to the domain that is used. Currently the nextcloudpi server is the only one running, so all traffic is directly routed to it.
The server is only accessible via https and letsencrypt handles the certifactes on the nextcloudpi server.
In order to route traffic from my reverse proxy to the nextcloudpi server via https, I have set up the default.conf file to look like this:
server {
listen 443;
listen [::]:443;
server_name <my-public-url>;
location / {
proxy_pass https://<hostname-of-my-nextcloudpi-server>;
}
}
Unfortunately that doesn't work. Firefox returns SSL_ERROR_RX_RECORD_TOO_LONG and Chrome ERR_SSL_PROTOCOL_ERROR
I have also not seen anywhere where traffic is proxied to a https location. I am aware that in my internal network I can and should just route to the target location on port 80 but since the server is already set up to use https I want to keep it that way.
Thanks for your help

Difference HTTP Redirect vs Reverse Proxy in NGINX

I'm having some difficulty in understanding the difference between reverse proxy (i.e. using proxy_pass directive with a given upstream server) and a 301 permanent redirect. How are they similar/different?
Reverse Proxy
upstream backend {
server backend1.example.com weight=5;
server backend2.example.com:8080;
}
server {
location / {
proxy_pass http://backend;
}
}
HHTP Redirect
Apache Example: http://www.inmotionhosting.com/support/website/htaccess/redirect-without-changing-url
NGINX example:
server {
listen 80;
server_name domain1.com;
return 301 $scheme://domain2.com$request_uri;
}
Hence, it seems that both approaches have no difference from an end-user perspective. I want to ensure efficient bandwidth usage, while utilizing SSL. Currently, the app server uses its own self-signed SSL certificate with Nginx. What is the recommended approach for redirecting users from a website hosted by a standard web hosting company (hostgator, godaddy, etc.) to a separate server app server?
With a redirect the server tells the client to look elsewhere for the resource. The client will be aware of this new location. The new location must be reachable from the client.
A reverse proxy instead forwards the request of the client to some other location itself and sends the response from this location back to the client. This means that the client is not aware of the new location and that the new location does not need to be directly reachable by the client.

Is it possible to have a forward proxy with ssl encryption between the proxy and the user?

First of all I want to make clear that i am not talking about accessing content which is on origin servers that deliver using https which can be done using the module mod_proxy_connect.
What I want is a secured connection between the client and the proxy, also when the origin that is requested actually is served by an unsecured standard http server.
I am using apache 2.2 and also would like to make this possible with apache if that works.
I sniffed some requests using wireshark and noted the following:
A usual http of the url http://example.com/file looksl ike this:
on a connection to the origin server:
GET /file HTTP 1.1
Host: example.com
Note that the host information is stripped from the actual request and the host header is supplied instead (which can be handled server side in named virtual hosts).
When the request goes through a proxy server it looks slightly different:
on a connection to the proxy server:
GET http://example.com/file HTTP 1.1
Host: example.com
Note that the request line now actually contains the full url including protocol and hostname.
The host header is probably redundant, bus if I read the RFC correctly it is required by HTTP 1.1.
So I think about setting up an apache webserver listening on port 443, enable a virtualhost with ssl engine and certificates up and do not bind it to any hostname.
I think that should get apache to talk ssl, but however the certificates common name will not match the host specfied in the connect line to the proxys server ip adress.
Is what I want to to even possible with current standards and if so how can I do it?
Yes of course, that's what HTTPS proxy is.
Client connects to proxy over SSL, sends commands to proxy in text.
It is also possible to use HTTP CONNECT to establish HTTPS connection "inside" the SSL connection to HTTPS proxy, though not all clients support this:
HTTPS connection over HTTPS proxy
client proxy server
ssl \-------/ ssl
connect---------200 OK
ssl \---------------------------/ ssl
data-------------------------------data
/---------------------------\
/-------\
HTTP connection over HTTPS proxy
client proxy server
ssl \-------/ ssl
GET http://server/ ->
GET /
Host: server ->
<---------OK, data
<--------------OK, data
/-------\