NGINX Forward HTTPS request to HTTP Backend Server and Back - nginx

On a single server instance, I have an NGINX web server that operates without any problems with the HTTPS and I have a backend server in Spring Boot running on port 8080. I do not want to open this port to the internet, therefore I would like to setup a reverse proxy with NGINX to forward the request that start with /api to my backend and return the response.
When I send request to the domain in the browser, my frontend application which runs in browser, sends some requests to my backend (starting with /api), my frontend uses the following base url:
http://my-ip:8080/api
And the nginx configuration is as follows:
server {
listen 80;
ssl_certificate /cert/cert.pem;
ssl_certificate_key /cert/privkey.pem;
server_name www.mydomain.com;
rewrite ^(.*) https://$server_name$1 permanent;
}
server {
listen 443 ssl;
server_name www.mydomain.com mydomain.com;
ssl_certificate /cert/cert.pem;
ssl_certificate_key /cert/privkey.pem;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
error_page 404 /index.html;
location = / {
root /usr/share/nginx/html;
internal;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location /api {
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://127.0.0.1:8080;
}
}
I keep getting Mixed Content Error and my backend requests are being blocked by the browser since my Frontend uses http for the request.
If I try to use https in the Frontend URL, such as:
https://my-ip:8080/api
Then I get a different error:
GET https://my-ip/api/... net::ERR_CERT_COMMON_NAME_INVALID
This is probably because my certificate is generated for my domain name and not for the IP.

Solution: In the frontend, we should send the request to https version and use the actual domain instead of the ip address because the domain name should match the domain of the certification.
The request: https://my-domain:8080/api
Then the nginx forwards this request properly.

Related

Nginx: How to deploy front end & backend apps on same machine with same domain but different ports?

I have two apps one for frontend built using ReactJS and one is for backend built using FastAPI. I have server machine where I have deployed both the apps. Now I want to use Nginx (because of SSL) to host both my application on the same machine with same domain name but the ports are different. I know how to do it for different domains or subdomain but I don't have another domain/subdomain with me right now. So I want to aks how I can achive this in Nginx?
For example my FE is using port 5000 & BE is using 8000,I am able to configure Nginx to serve my FE but I am getting this error,
Blocked loading mixed active content
because my FE which is httpstrying to connect to backend on port 8000 which is not https.
Here is my nginx config file,
server {
listen 443 ssl;
ssl_certificate /opt/ssl/bundle.crt;
ssl_certificate_key /opt/ssl/custom.key;
# add here the ip address of your server
# or a domain pointing to that ip (like example.com or www.example.com)
server_name something-c11.main0.auto.qa.use1.mydomain.net;
keepalive_timeout 5;
client_max_body_size 100M;
access_log /opt/MY_FE/nginx-access.log;
error_log /opt/MY_FE/nginx-error.log;
# checks for static file, if not found proxy to app
location / {
try_files $uri #proxy_to_app;
}
location #proxy_to_app {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass http://localhost:5000;
proxy_redirect off;
}
}
server {
if ($host = something-c11.main0.auto.qa.use1.mydomain.nett) {
return 301 https://$host$request_uri;
}
listen 80;
server_name something-c11.main0.auto.qa.use1.mydomain.net;
return 404;
}
Any help would be appreciated....

Hide port with gunicorn and nginx

The Flask server starts at port 5000. With gunicorn and nginx, when I typed http://localhost:80 (or http://localhost) in browser, the browser redirects to http://localhost:5000.
I added a few lines in the nginx config file
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
How can I hide port(5000 in this case) after redirection? Thanks a lot.
This is how you should structure your configuration file:
server {
# listen on port 80
listen 80;
server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
A server block is a subset of Nginx’s configuration that defines a virtual server used to handle requests of a defined type.
A location block lives within a server block and is used to define how Nginx should handle requests for different resources and URIs (the part of the request that comes after the domain name or IP address/port) for the parent server
How nginx processes a request

nginx redirect proxy requests http to https get to many redirections message

in my nginx server i would to redirect all http incoming request to https.
I use gunicorn and i set as / location a proxy 127.0.0.1:8080
Part of my nginx.conf configuration file is:
server {
listen 80;
listen 443 default ssl http2;
ssl_certificate /var/www/web/core/mycert.crt;
ssl_certificate_key /var/www/web/core/mykey.key;
server_name ~^(?<subdomain>\w+)\.mydomain\.io$;
root /var/www;
return 301 https://$server_name$request_uri;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location /static/ {
alias /var/www/web/core/frontend/static/;
}
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
#add_header P3P 'CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"';
proxy_set_header X-DTS-SCHEMA $subdomain;
}
but when i try to open the http version of my page i get "Error to many redirections"
I also tried to add in my proxy directives:
proxy_redirect http:// https://;
but nothing happens.
How can i redirect my proxy request to https everytime?
Thanks in advance
There is a big mistake in your code, you can't do this like you did:
return 301 https://$server_name$request_uri;
If you wish to use like that, you should split the http and https server. When you read your file, you just redirect each time you arrive on the vhost, that's causing the too many redirection.
You could also put a condition on the return to not execute if you already are in https...

Nginx reverse folder location to external website

As a Nginx newbie i am trying to get a reverse proxy working to an external domain. Later on I will need to port to an internal domain. When trying to reverse proxy to an external domain i seem to hit a wall and the response is a 404 cannot be found.
The goal is when i try to access http://localhost/example the reverse proxy serves www.example.com.
This is my config:
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /example/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://www.example.com/;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
Any hint what i am doing wrong?
When speaking about http, webserver detects which of configured servers was requested by checking Host header. In you case, you tell nginx to proxy requests to another server, but instruct it to pass original Host header to that server. Obviously, there is no configuration on remote server, which could accept request with that domain. So it responds you with 404.
To make it work, just change header to proxy_set_header Host www.example.com; where instead of www.example.com you should use same host as in proxy_pass directive. (or same variable)

Nginx doesn't listen on specified port

I've set up and deployed a rails application using unicorn and nginx on linode. However when I go to the URL I've set in the applications config in sites-enable I am served with the default site that is listening on port 80.
If I got to the IP and port I don't get anything at all.
If I set the site to listen on 80 it works
The URL is pointing from the registrar to the linode IP and is working correctly.
xxxx.co.uk file in sites-enabled
upstream unicorn
server unix:/tmp/unicorn.xxxx.co.uk.sock fail_timeout=0;
}
server {
server_name xxxx xxxx;
listen 3001 default deferred;
root /var/www/apps/nocn.org.uk/current/public;
location ^~ /assets/ {
gzip_static on;
#try $uri /old$uri
expires max;
add_header Cache-Control public;
}
try_files $uri/index.html $uri #unicorn;
location #unicorn {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://unicorn;
}
error_page 500 502 503 504 /500.html;
client_max_body_size 4G;
keepalive_timeout 10;
}
Make sure you enabled remote access to port 3001 in linode's firewall or config (by using iptables probably).

Resources