Ignition 8.3, nginx and keycloak

Hey all

I’m running into a problem after upgrading from Ignition 8.1 to 8.3.1 involving OIDC (Keycloak) authentication through NGINX as a reverse proxy.

Setup:

The flow worked fine in 8.1:

  • Browser redirects from Ignition → Keycloak
  • Keycloak handles login and redirects back to Ignition’s /data/federate/callback/oidc
  • Designer launched successfully

Now in 8.3.1:

  • I had to change in my nginx config:
    •     server_name scada.example.com
          if ($request_method !~ ^(GET|POST|HEAD|PUT|DELETE|PATCH|OPTIONS)$ ) {
          # worked in 8.1 if ($request_method !~ ^(GET|POST|HEAD)$ ) {
              return 444;
          }
      
  • Keycloak redirects correctly, the browser receives a 302 after login
  • I'm encountering a 502 Bad Gateway when trying to access /data/config/web-server
  • But the Ignition Designer client (Jetty) follows the redirect and gets a 444 response from NGINX
  • This seems to break the login session

From the logs:

GET /data/federate/callback/oidc?... HTTP/1.1" 302 ...
GET /data/federate/callback/oidc?... HTTP/1.1" 444 ...
User-Agent: Jetty/12.0.15

:magnifying_glass_tilted_left: What I’ve tried:

  • I added a specific NGINX location = /data/federate/callback/oidc block, allowing access to that path
  • I also tried relaxing method blocking rules for that exact URI
  • Regular browser login works, but Designer fails after redirect

My nginx site config:

server {
        server_name scada.example.com;
        if ($request_method !~ ^(GET|POST|HEAD|PUT|DELETE|PATCH|OPTIONS)$ ) {
             return 444;
        }
    # Nginx Bad Bot Blocker Includes
    # REPO: https://github.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker
        include /etc/nginx/bots.d/ddos.conf;
        include /etc/nginx/bots.d/blockbots.conf;
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    add_header X-Content-Type-Options nosniff;
    add_header X-Frame-Options DENY;
    add_header X-XSS-Protection "1; mode=block";
    add_header Referrer-Policy "no-referrer" always;
        location / {
                proxy_connect_timeout 600s;
                proxy_send_timeout    600s;
                proxy_read_timeout    600s;
                send_timeout          600s;
                client_max_body_size 100M;
                proxy_http_version 1.1;
                proxy_cache_bypass $http_upgrade;
                proxy_set_header Upgrade                $http_upgrade;
                proxy_set_header Connection             "Upgrade";
                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_set_header X-Forwarded-Port 443;  # The proxy is listening on port 443
                proxy_set_header X-Forwarded-Host       $host;
                proxy_pass https://10.0.0.10:8043; #Use ignition container ip address
                proxy_hide_header Strict-Transport-Security;
                proxy_hide_header X-Content-Type-Options;
                proxy_hide_header X-XSS-Protection;
                proxy_hide_header X-Frame-Options;
                proxy_hide_header Referrer-Policy;
        }
        location = /data/federate/callback/oidc {
            proxy_pass https://10.0.0.10:8043;
            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_set_header X-Forwarded-Port 443;
            proxy_set_header X-Forwarded-Host $host;
        }
        location /system/images/ {
                proxy_http_version 1.1;
                proxy_cache_bypass $http_upgrade;
                proxy_set_header Upgrade                $http_upgrade;
                proxy_set_header Connection             "Upgrade";
                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_set_header X-Forwarded-Host       $host;
                proxy_set_header X-Forwarded-Port       $server_port;
                proxy_pass http://10.0.0.10:8088; #Use ignition container ip address
                proxy_hide_header Strict-Transport-Security;
                proxy_hide_header X-Content-Type-Options;
                proxy_hide_header X-XSS-Protection;
                proxy_hide_header X-Frame-Options;
                proxy_hide_header Referrer-Policy;
        }
        location /data/perspective/ {
                proxy_http_version 1.1;
                proxy_cache_bypass $http_upgrade;
                proxy_set_header Upgrade                $http_upgrade;
                proxy_set_header Connection             "Upgrade";
                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_set_header X-Forwarded-Host       $host;
                proxy_set_header X-Forwarded-Port       $server_port;
                proxy_pass http://10.0.0.10:8088; #Use ignition container ip address
                proxy_hide_header Strict-Transport-Security;
                proxy_hide_header X-Content-Type-Options;
                proxy_hide_header X-XSS-Protection;
                proxy_hide_header X-Frame-Options;
                proxy_hide_header Referrer-Policy;
        }
        location /res/perspective/ {
                proxy_http_version 1.1;
                proxy_cache_bypass $http_upgrade;
                proxy_set_header Upgrade                $http_upgrade;
                proxy_set_header Connection             "Upgrade";
                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_set_header X-Forwarded-Host       $host;
                proxy_set_header X-Forwarded-Port       $server_port;
                proxy_pass http://10.0.0.10:8088; #Use ignition container ip address
                proxy_hide_header Strict-Transport-Security;
                proxy_hide_header X-Content-Type-Options;
                proxy_hide_header X-XSS-Protection;
                proxy_hide_header X-Frame-Options;
                proxy_hide_header Referrer-Policy;
        }
        location /system/perspective-download/ {
                proxy_http_version 1.1;
                proxy_cache_bypass $http_upgrade;
                proxy_set_header Upgrade                $http_upgrade;
                proxy_set_header Connection             "Upgrade";
                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_set_header X-Forwarded-Host       $host;
                proxy_set_header X-Forwarded-Port       $server_port;
                proxy_pass http://10.0.0.10:8088; #Use ignition container ip address
                proxy_hide_header Strict-Transport-Security;
                proxy_hide_header X-Content-Type-Options;
                proxy_hide_header X-XSS-Protection;
                proxy_hide_header X-Frame-Options;
                proxy_hide_header Referrer-Policy;
        }
        location /system/pws/ {
                proxy_http_version 1.1;
                proxy_cache_bypass $http_upgrade;
                proxy_set_header Upgrade                $http_upgrade;
                proxy_set_header Connection             "Upgrade";
                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_set_header X-Forwarded-Host       $host;
                proxy_set_header X-Forwarded-Port       $server_port;
                proxy_pass http://10.0.0.10:8088; #Use ignition container ip address
                proxy_hide_header Strict-Transport-Security;
                proxy_hide_header X-Content-Type-Options;
                proxy_hide_header X-XSS-Protection;
                proxy_hide_header X-Frame-Options;
                proxy_hide_header Referrer-Policy;
        }
        location /system/gwinfo {
                proxy_http_version 1.1;
                proxy_cache_bypass $http_upgrade;
                proxy_set_header Upgrade                $http_upgrade;
                proxy_set_header Connection             "Upgrade";
                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_set_header X-Forwarded-Host       $host;
                proxy_set_header X-Forwarded-Port       $server_port;
                proxy_pass http://10.0.0.10:8088; #Use ignition container ip address
                proxy_hide_header Strict-Transport-Security;
                proxy_hide_header X-Content-Type-Options;
                proxy_hide_header X-XSS-Protection;
                proxy_hide_header X-Frame-Options;
                proxy_hide_header Referrer-Policy;
        }
    listen 443 ssl; # managed by Certbot
    # SSL-certifikat
    ssl_certificate /etc/letsencrypt/live/scada.example.com-0001/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/scada.example.com-0001/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
}
server {
    listen 80;
    listen [::]:80;
    server_name scada.example.com;
    return 301 https://$host$request_uri;
    if ($request_method !~ ^(GET|POST|HEAD|PUT|DELETE|PATCH|OPTIONS)$ ) {
    #if ($request_method !~ ^(GET|POST|HEAD)$ ) {
    return 444;
    }
}

Has anything changed in how Ignition 8.3.1 handles OIDC / Designer auth flow via Jetty?

Any tips on how to structure NGINX for this version? I’d appreciate any help

I got it to work with firefox, designer, nginx and keycloak with this config:

# -------------------------------------------
# SCADA Reverse Proxy for Ignition 8.3 + OIDC
# https://scada.example.com
# -------------------------------------------

server {
    listen 443 ssl;
    server_name scada.example.com;

    # SSL Config (Let's Encrypt)
    ssl_certificate /etc/letsencrypt/live/scada.example.com-0001/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/scada.example.com-0001/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

    # Allow headers with underscores (required for Perspective)
    underscores_in_headers on;

    # Timeouts & upload limits
    proxy_connect_timeout 600s;
    proxy_send_timeout    600s;
    proxy_read_timeout    600s;
    send_timeout          600s;
    client_max_body_size 100M;

    # Security headers
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    add_header X-Content-Type-Options nosniff;
    add_header X-Frame-Options DENY;
    add_header X-XSS-Protection "1; mode=block";
    add_header Referrer-Policy "no-referrer" always;

    #  ^|^e Whitelist Jetty user-agent (Ignition Designer)
    if ($http_user_agent ~* "Jetty") {
        set $bad_bot 0;
        set $validate_client 0;
        set $bad_words 0;
        set $bad_referer 0;
    }
	
    # Optional: DDoS/bot protection
     include /etc/nginx/bots.d/ddos.conf;
     include /etc/nginx/bots.d/blockbots.conf;

    # ----------------------------
    # 🔐 Keycloak OIDC callback
    # ----------------------------
    location = /data/federate/callback/oidc {
        proxy_pass https://10.0.0.10:8043;
        proxy_ssl_verify off;
        #        proxy_http_version 1.1;
        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_set_header X-Forwarded-Port 443;
        proxy_set_header X-Forwarded-Host $host;
        proxy_pass_request_headers on;
    }

    # ----------------------------
    # 🔁 General proxy settings
    # ----------------------------
    location ^~ /data/ {
        proxy_pass https://10.0.0.10:8043/data/;
        proxy_http_version 1.1;
        proxy_ssl_verify off;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        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_set_header X-Forwarded-Port 443;
        proxy_set_header X-Forwarded-Host $host;
        proxy_pass_request_headers on;
    }

    location ^~ /system/ {
        proxy_pass https://10.0.0.10:8043/system/;
        proxy_http_version 1.1;
        proxy_ssl_verify off;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        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_set_header X-Forwarded-Port 443;
        proxy_set_header X-Forwarded-Host $host;
        proxy_pass_request_headers on;
    }

    location ^~ /res/ {
        proxy_pass https://10.0.0.10:8043/res/;
        proxy_http_version 1.1;
        proxy_ssl_verify off;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        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_set_header X-Forwarded-Port 443;
        proxy_set_header X-Forwarded-Host $host;
        proxy_pass_request_headers on;
    }

    location ^~ /idp/ {
        proxy_pass https://10.0.0.10:8043/idp/;
        proxy_http_version 1.1;
        proxy_ssl_verify off;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        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_set_header X-Forwarded-Port 443;
        proxy_set_header X-Forwarded-Host $host;
        proxy_pass_request_headers on;
    }

    location ^~ /.well-known/ {
        proxy_pass https://10.0.0.10:8043/.well-known/;
        proxy_http_version 1.1;
        proxy_ssl_verify off;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        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_set_header X-Forwarded-Port 443;
        proxy_set_header X-Forwarded-Host $host;
        proxy_pass_request_headers on;
    }
        location /system/images/ {
                proxy_http_version 1.1;
                proxy_cache_bypass $http_upgrade;
                proxy_set_header Upgrade                $http_upgrade;
                proxy_set_header Connection             "Upgrade";
                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_set_header X-Forwarded-Host       $host;
                proxy_set_header X-Forwarded-Port       $server_port;
                proxy_pass https://10.0.0.10:8043; #Use ignition container ip address
                proxy_hide_header Strict-Transport-Security;
                proxy_hide_header X-Content-Type-Options;
                proxy_hide_header X-XSS-Protection;
                proxy_hide_header X-Frame-Options;
                proxy_hide_header Referrer-Policy;
        }
        location /data/perspective/ {
                proxy_http_version 1.1;
                proxy_cache_bypass $http_upgrade;
                proxy_set_header Upgrade                $http_upgrade;
                proxy_set_header Connection             "Upgrade";
                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_set_header X-Forwarded-Host       $host;
                proxy_set_header X-Forwarded-Port       $server_port;
                proxy_pass https://10.0.0.10:8043; #Use ignition container ip address
                proxy_hide_header Strict-Transport-Security;
                proxy_hide_header X-Content-Type-Options;
                proxy_hide_header X-XSS-Protection;
                proxy_hide_header X-Frame-Options;
                proxy_hide_header Referrer-Policy;
        }
        location /res/perspective/ {
                proxy_http_version 1.1;
                proxy_cache_bypass $http_upgrade;
                proxy_set_header Upgrade                $http_upgrade;
                proxy_set_header Connection             "Upgrade";
                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_set_header X-Forwarded-Host       $host;
                proxy_set_header X-Forwarded-Port       $server_port;
                proxy_pass https://10.0.0.10:8043; #Use ignition container ip address
                proxy_hide_header Strict-Transport-Security;
                proxy_hide_header X-Content-Type-Options;
                proxy_hide_header X-XSS-Protection;
                proxy_hide_header X-Frame-Options;
                proxy_hide_header Referrer-Policy;
        }
        location /system/perspective-download/ {
                proxy_http_version 1.1;
                proxy_cache_bypass $http_upgrade;
                proxy_set_header Upgrade                $http_upgrade;
                proxy_set_header Connection             "Upgrade";
                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_set_header X-Forwarded-Host       $host;
                proxy_set_header X-Forwarded-Port       $server_port;
                proxy_pass https://10.0.0.10:8043; #Use ignition container ip address
                proxy_hide_header Strict-Transport-Security;
                proxy_hide_header X-Content-Type-Options;
                proxy_hide_header X-XSS-Protection;
                proxy_hide_header X-Frame-Options;
                proxy_hide_header Referrer-Policy;
        }
        location /system/pws/ {
                proxy_http_version 1.1;
                proxy_cache_bypass $http_upgrade;
                proxy_set_header Upgrade                $http_upgrade;
                proxy_set_header Connection             "Upgrade";
                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_set_header X-Forwarded-Host       $host;
                proxy_set_header X-Forwarded-Port       $server_port;
                proxy_pass https://10.0.0.10:8043; #Use ignition container ip address
                proxy_hide_header Strict-Transport-Security;
                proxy_hide_header X-Content-Type-Options;
                proxy_hide_header X-XSS-Protection;
                proxy_hide_header X-Frame-Options;
                proxy_hide_header Referrer-Policy;
        }
        location /system/gwinfo {
                proxy_http_version 1.1;
                proxy_cache_bypass $http_upgrade;
                proxy_set_header Upgrade                $http_upgrade;
                proxy_set_header Connection             "Upgrade";
                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_set_header X-Forwarded-Host       $host;
                proxy_set_header X-Forwarded-Port       $server_port;
                proxy_pass https://10.0.0.10:8043; #Use ignition container ip address
                proxy_hide_header Strict-Transport-Security;
                proxy_hide_header X-Content-Type-Options;
                proxy_hide_header X-XSS-Protection;
                proxy_hide_header X-Frame-Options;
                proxy_hide_header Referrer-Policy;
        }
		
    # ----------------------------
    # 🎯 Default fallback
    # ----------------------------
    location / {
        proxy_pass https://10.0.0.10:8043/;
        proxy_http_version 1.1;
        proxy_ssl_verify off;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        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_set_header X-Forwarded-Port 443;
        proxy_set_header X-Forwarded-Host $host;
        proxy_pass_request_headers on;
    }
}

# Redirect all HTTP traffic to HTTPS
server {
    listen 80;
    listen [::]:80;
    server_name scada.example.com;

    return 301 https://$host$request_uri;

    #    # Optional: block invalid HTTP methods
    if ($request_method !~ ^(GET|POST|HEAD|PUT|DELETE|PATCH|OPTIONS)$ ) {
        return 444;
    }
}