Nginx in front of keycloak and local microservices - nginx

I am trying to setup nginx + keycloak to protect my spring boot microservices.
I hope to config the following structure
internet ---https---> nginx --http--> keycloak and other protected microservices
keycloak <----http----> zuul and other microservices
I could not figure out how to set the nginx to correctly pass original https request to http backend servers
here are my configurations:
NGINX
server {
listen 443 ssl default_server;
server_name localhost;
ssl_certificate /etc/nginx/localhost.crt;
ssl_certificate_key /etc/nginx/localhost.key;
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;
access_log /var/log/nginx/ledgerrun.access.log;
proxy_set_header Host $host:443;
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;
# keycloak redirect
location /auth {
proxy_pass https://keycloak:8443;
}
location / {
proxy_pass http://192.168.1.15:15700;
}
# all /lr-servies redirect to 15700
#location ~* ^/lr-(.*) {
# proxy_pass https://192.168.1.15:15700;
#}
}
Keycloak instance opens 8443 for https and 8080 for http.
Spring Cloud Zuul config as the following
server:
port: "15700"
keycloak:
auth-server-url: "https://my.external.ip:8443/auth"
realm: "LedgerRunCTP"
public-client: true
resource: gateway-service
security-constraints[0]:
authRoles[0]: "user"
securityCollections[0]:
name: "internal services"
patterns[0]: "/swagger-ui.html"
I have to configure the "auth-server-url" to https, since client need to login with keycloak first and that requires https for non-local connection. Is there a way to just use http for keycloak?
with above configuration, once keycloak authenticated the user, gets the following error:
The plain HTTP request was sent to HTTPS port
What is the correct configuration to set it up to achieve
only https to nginx
all http behind nginx

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 returns web requests with internal IP address

I am deploying InvenioRDM as local.
Here is a gist of the limitations.
InvenioRDM as local instance for prototyping
Application is strictly IP address and port bound
Aim is to link IP to URL in a seamless manner
The work so far:
InvenioRDM local instance exposes application frontend only
Approaches:
i) Mimic production: The Nginx configuration was initially setup that
mirrored the production. The production environment is purely
containers. Very complex so i decided to try a simpler approach.
ii) Transparent Proxy: Use Nginx to pass on everything and replace
the URLs at ingress (proxy_pass) and egress (proxy_redirect). The
benefit is to simplify the web server configuration as the
application does handle http requests.
My default.conf is as follows.
# HTTP server
server {
# Redirects all requests to https. - this is in addition to HAProxy which
# already redirects http to https. This redirect is needed in case you access
# the server directly (e.g. useful for debugging).
listen 80; # IPv4
server_name server.name;
return 301 https://$host$request_uri;
}
#HTTPS Server
server {
listen 443 ssl;
server_name server.name;
charset utf-8;
keepalive_timeout 5;
ssl_certificate /etc/ssl/test.crt;
ssl_certificate_key /etc/ssl/test.key;
ssl_session_cache builtin:1000 shared:SSL:50m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AE$
#ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/access.log;
proxy_request_buffering off;
proxy_http_version 1.1;
location / {
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;
proxy_pass https://127.0.0.1:5000;
proxy_read_timeout 90;
proxy_redirect https://127.0.0.1:5000 https://server.name;
}
}
My issue is that when accessing publicly on the IP address server.name (hidden for obvious reasons), it returns with the internal Class A IP address (10.X.X.X) of the machine which is offcourse not accessible publicaly. What am I missing here.
I am new to this, and I am at my wits end.

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.

Using nginx as reverse Proxy and blocking any HTTP requests

I am using nginx as reverse proxy for my flask API. When I make a http request I still receive the API response , whereas of my understanding I should receive an 400 error.
I have tried all the things I could find for that topic, but I couldn't get it working properly. I just replaced the redirect with the return code.
for example I used this guide
https://serversforhackers.com/c/redirect-http-to-https-nginx
default file
server {
listen 80;
server_name _;
return 400;
}
server {
listen 443 ssl;
server_name _;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
ssl on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH: !aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;
location / {
# reverse proxy and serve the app # running on the localhost: 8000 proxy_pass http: //127.0.0.1:8000/;
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
The result should be that when you make a http request you should get an error and when you make a https request you should get the JSON respond.
You need to remove ssl on; directive
ssl flag in listen will handle it.
You can also check http://nginx.org/en/docs/http/configuring_https_servers.html#single_http_https_server

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.

Resources