NiFi Auth with Nginx reverse proxy - nginx

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.

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

Mercure hub behind Nginx reverse proxy

I try to deploy a Mercure hub on a server.
There is already a Symfony app (REST API) served with Apache2 (and Nginx configured in reverse proxy). My idea is to keep the API proxy to Apache2 and configure the Mercure subscriptions to be forwarded to the Mercure Hub (a Caddy server).
All is ok for the API part, but it's impossible to configure Nginx and Caddy correctly to work together. I precise that I reach the hub successfully when it's not behind Nginx. I use a custom certificate and, for some reason, each time I try to subscribe to the hub, I have this error :
DEBUG http.stdlib http: TLS handshake error from 127.0.0.1:36250: no
certificate available for '127.0.0.1'
If I modify my Nginx configuration with proxy_pass https://mydomain:3000; instead of proxy_pass https://127.0.0.1:3000;, the error becomes :
DEBUG http.stdlib http: TLS handshake error from PUBLIC-IP:36250: no
certificate available for 'PRIVATE-IP'
There is no further explaination in the Caddy or Nginx logs.
My guess is Nginx does not transfer the proper requested domain to Caddy, but I don't know why as I applied correctly the configuration instructions I found on the specification. Any help would be appreciated, thank you !
Caddy.dev config
{
# Debug mode (disable it in production!)
{$DEBUG:debug}
# Port update
http_port 3001
https_port 3000
# HTTP/3 support
servers {
protocol {
experimental_http3
}
}
}
{$SERVER_NAME:localhost}
log
tls /path-to-certificate/fullchain.pem /path-to-certificate/privkey.pem
route {
redir / /.well-known/mercure/ui/
encode zstd gzip
mercure {
# Transport to use (default to Bolt)
transport_url {$MERCURE_TRANSPORT_URL:bolt://mercure.db}
# Publisher JWT key
publisher_jwt {env.MERCURE_PUBLISHER_JWT_KEY} {env.MERCURE_PUBLISHER_JWT_ALG}
# Subscriber JWT key
subscriber_jwt {env.MERCURE_SUBSCRIBER_JWT_KEY} {env.MERCURE_SUBSCRIBER_JWT_ALG}
# Permissive configuration for the development environment
cors_origins http://localhost
publish_origins *
demo
anonymous
subscriptions
# Extra directives
{$MERCURE_EXTRA_DIRECTIVES}
}
respond /healthz 200
respond "Not Found" 404
}
NGinx Virtualhost config
server {
listen 80 http2;
server_name mercure-hub-domain.com;
return 301 https://mercure-hub-domain.com;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name mercure-hub-domain.com;
ssl_certificate /path-to-certificate/fullchain.pem; # managed by Certbot
ssl_certificate_key /path-to-certificate/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
location / {
proxy_pass https://127.0.0.1:3000;
proxy_read_timeout 24h;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_connect_timeout 300s;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Configuration des logs
access_log /var/log/nginx/my-project/access.log;
error_log /var/log/nginx/my-project/error.log;
}
Command to launch the Mercure hub
sudo SERVER_NAME='mercure-hub-domain.com:3000' DEBUG=debug MERCURE_PUBLISHER_JWT_KEY='MY-KEY' MERCURE_SUBSCRIBER_JWT_KEY='MY-KEY' ./mercure run -config Caddyfile.dev

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.

Configure nginx with support for multi subdomain and upstream

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.

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