Configure nginx with support for multi subdomain and upstream - nginx

I have been trying to setup nginx as a proxy wherein request is routed to upstream based on subdomain. I hope example makes it more clear
upstream ubuntu {
server www.ubuntu.com:443;
}
upstream google {
server www.google.com:443;
}
server {
listen 443 ssl ;
ssl_certificate /etc/ssl/certs/client-certs/server.crt;
ssl_certificate_key /etc/ssl/certs/client-certs/server.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1.2;
resolver 127.0.0.1 ipv6=off;
# Make site accessible from http://localhost/
server_name ~^(.*)\.test\.com$;
location / {
proxy_pass https://$1;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
so if i request https://google.test.com it should go to https://www.google.com
With this current setup nginx returns me 404 for any of the site that i query. Though i can see that request goes to my queried upstream site(in this case google.com).
Not getting if am missing anything.

Related

Block incoming request when SSL verification is disabled

I have my REST APIs configured to work over https using nginx( java APIs deployed in tomcat and nginx is configured for DNS mapping). Our testing team has managed to access the APIs using burp tool (I assume it allows them to access with SSL verification disabled) and they were able to alter the API response before the client receives it. My nginx server is configured to work on SSL with proxy forward setup for http to https. How can I block the API requests which has SSL verification disabled, so that I can stop them altering the response? Below is my nginx config.
upstream mlljava{
server 172.31.5.222:8090;
}
server {
listen 443 ssl;
server_name mllwebapi.xyz.in www.mllwebapi.xyz.in;
underscores_in_headers on;
client_max_body_size 10M;
ssl_protocols TLSv1.3;
ssl_certificate /home/ubuntu/175e9.crt;
ssl_certificate_key /home/ubuntu/key.key;
location / {
proxy_pass http://mlljava/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-for $remote_addr;
proxy_pass_request_headers on;
}
}
Does adding this to server configuration helps?
# force https-redirects
if ($scheme = http) {
return 401 https://$server_name$request_uri;
Configure Nginx SSL + force HTTP to redirect to HTTPS + force www to non-www on Serverpilot free plan (Using Nginx configuration file only)
Nginx: force SSL on one path, non-SSL on others

Nginx local proxy with backup to prod server

I am trying to setup nginx proxy on my local machine.
What I want to achieve is like this:
site.local -> proxy_pass -> HTTP://localhost:3000
if localhost:3000 is down, then proxy to -> site.com
So far this is my config:
upstream mysite {
server localhost:3000 fail_timeout = 5 max_fails = 1;
server example.com backup max_fails = 2;
}
server {
server_name site.local;
listen ssl;
ssl_certificate /path/to/site-local.crt;
ssl_certificate_key /path/to/site-local.key;
ssl_ciphers HIGH: !aNULL: !MD5;
location / {
proxy_pass https://mysite;
proxy_set_header Host site.com;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
And I've made entry in hosts file for site.local 127.0.0.1.
I am getting multiple errors with slightly different configurations:
I am doing proxy_pass HTTP://mysite, then it is 301 redirecting to https://example.com, and not proxying to https.
If I did proxy_pass: https://mysite, then it is giving 502.
If I am doing server site.com:443 then it is saying non https traffic to 443 server is not allowed.
Any ideas around how to achieve this.

NGINX Incorrectly Forwarding Requests to Default Location

I have a React web application that I'm trying to deploy on an AWS EC2 instance and I'm using NGINX. I am trying to set it up so that all http requests get redirected to https. Right now it does appear to be redirecting all http requests to https, but NGINX is forwarding the request to the default path /usr/share/nginx/html/ instead of to the web application that I have running on localhost. I have read dozens of articles and have been trying to figure this out for days. Pointers would be much appreciated. Thanks in advance.
Here is my NGINX server configuration at /etc/nginx/sites-available/default:
server {
listen 80;
if ($http_x_forwarded_proto = "http") {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2 default_server;
listen 443 ssl http2 default_server;
ssl on;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1h;
location / {
proxy_pass http://127.0.0.1:3839;
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 https;
}
}
Also, the application is running and accessible at the port specified in my location block. I can reach it on the machine with curl 127.0.0.1:3839 with no problems. I am able to see in /var/log/nginx/error.log that nginx is attempting to serve requests out of the /usr/share/nginx/html/ directory which is how I figured out that is the issue. I just have no idea why it's sending requests there instead of to the port on localhost that I specified in my location block. If I go to the root url for my application I get the "Welcome to NGINX" page. If I go to any subpath under my root url like example.com/login, then I get a 404 and error.log shows that it couldn't find resource /usr/share/nginx/html/login for example. Thanks :)
Update:
Inside of the listen 80 server block I added
location / {
proxy_pass http://127.0.0.1:3839;
}
and now it seems to be working correctly, but I have no idea why I would need to define a location block in the listen 80 server definition if requests in that block are just being redirected to be caught by the other server definition listening on 443. Any idea why this is working now?
I figured out the reason that location block in the http server definition worked. In AWS I accidentally had my load balancer forwarding all requests to port 80 on the EC2 instance. So even though my http server definition was redirecting to the https version of the site, those https requests were still ending up being handled by that same http server definition and since it didn't have a location block at all previously, that was causing it to fail. In the end, I removed the location block from the http server definition and then correctly updated my load balancer to forward https requests to port 443 on the EC2 instance and now everything works as expected.

NiFi Auth with Nginx reverse proxy

Is it possible to have NiFi with user authentication but with SSL termination on NGINX. I have NGINX running on port 443 and a proxy_pass passing to nifi at port 8080. I played around with these headers:
X-ProxyScheme - the scheme to use to connect to the proxy
X-ProxyHost - the host of the proxy
X-ProxyPort - the port the proxy is listening on
X-ProxyContextPath - the path configured to map to the NiFi instance
But it seems impossible to get NiFi to recognise it's on https connection behind the proxy. I updated my auth configuration however NiFi still throws an error:
IllegalStateException: User authentication/authorization is only supported when running over HTTPS.. Returning Conflict response.
java.lang.IllegalStateException: User authentication/authorization is only supported when running over HTTPS
Basically https to nginx than to http port for nifi.
Am not familiar with NiFi, but on RHEL with nginx the below gives me a reverse proxy with a HTTPS connection terminated in nginx and an onward HTTP connection with a /abc_end_point. Perhaps you can use this as a template?
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name _;
root /usr/share/nginx/html;
ssl_certificate "/etc/pki/tls/certs/abc.com.crt";
ssl_certificate_key "/etc/pki/tls/private/abc.com.key";
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers PROFILE=SYSTEM;
ssl_prefer_server_ciphers on;
proxy_connect_timeout 7d;
proxy_send_timeout 7d;
proxy_read_timeout 7d;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
}
location /abc_end_point {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://localhost:9090/abc_end_point;
}
}
You are trying to setup Nifi with SSL offloading on the reverse proxy (nginx) - this kind of setup is not supported.
See: http://apache-nifi-users-list.2361937.n4.nabble.com/Nifi-and-SSL-offloading-td7790.html#a7799
I recommended to use TLS (HTTPS) also between reverse proxy and Nifi.

How can I use nginx to forward incoming requests from a certain URL on port 80 to various docker applications

this is my story.
I'm running a Meteor.js app that launches docker containers on the same host machine. Meteor.js is set to run on port 8080; where all http and https requests for "/" are forwarded to. My nginx configuration at /etc/nginx/project/sites-available/site is as follows:
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
root /usr/share/nginx/html;
index index.html index.htm;
server_name **projectdomain.com**;
location / {
rewrite ^ https://$server_name$request_uri? permanent;
}
}
server {
listen 443 ssl spdy;
server_name **projectdomain.com**;
root html;
index index.html;
ssl_certificate /etc/nginx/ssl/project.crt;
ssl_certificate_key /etc/nginx/ssl/project.key;
ssl_stapling on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 5m;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-$
add_header Strict-Transport-Security "max-age=31536000;";
if ($http_user_agent ~ "MSIE" ) {
return 303 https://browser-update.org/update.html;
}
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Forwarded-For $remote_addr;
if ($uri != '/') {
expires 30d;
}
}
}
i want a certain URL, such as projectdomain.com/4200 to point to projectdomain.com:4200, where my docker container would be listening to. I want to do this because the target audience of my project are behind a corporate firewall that does not enable them to access the app running at port 4200. i mean, the docker app runs just fine and is accessible when one's not behind a firewall by heading to projectdomain.com:4200. i just want it bridged over 80 or 443 in compliance with my current nginx settings.
when i do
location /4200 {
proxy_pass http://127.0.0.1:4200;
}
although my docker container is running at 4200, heading to projectdomain.com/4200 gives an nginx 502 error. this probably has something to do with the netstat -tulpn output.
whereas my meteor project seems to run un 127.0.0.1:8080, the docker container shows to be running at :::4200. i think, the reason i get the 502 is because nginx forwards the request at /4200 to 127.0.0.1:4200 where nothing is running (as stated by netstat).
question is, what should i do to make docker run the container at 127.0.0.1:4200 instead of :::4200 , or is there any other approach i should follow?
First you can try nginx proxy image.
nginx-proxy sets up a container running nginx and docker-gen. docker-gen generates reverse proxy configs for nginx and reloads nginx when containers are started and stopped.
This image can't work with location. But you can use subdomains. Like 4200.projectdomain.com. It is most simple way.
Second you can configure nginx manually.
you need link containers, and configure nginx as described here
First of all, proxy_pass should set IP address on host which container running on, not localhost, 127.0.0.1 neither.
If you have many dynamic port urls, want to map them to upstream ports, use this:
location ~ ^/(\d{4,})$ {
set $p_port $1;
proxy_pass http://HOSTIP:$p_proxy;
}

Resources