Apache NiFi is a powerful data flow automation tool, but its default setup — running on its own port, often secured with a self-signed certificate and a clunky hostname — isn’t exactly friendly for production environments. If NiFi is being exposed to a team, a customer, or the public internet, putting Nginx in front of it as a reverse proxy solves a whole list of problems at once: clean URLs, centralized SSL termination, access control, and the ability to run several internal applications behind a single public IP.
This guide walks through everything needed to get Nginx working as a reverse proxy for Apache NiFi, from the basic concept down to production-grade hardening.
What a Reverse Proxy Actually Does for NiFi
A reverse proxy sits between the outside world and NiFi’s internal web server. Instead of clients connecting directly to https://nifi-server:8443/nifi, they hit Nginx on a standard port (80/443), and Nginx forwards the request internally to NiFi.
This matters more for NiFi than for most applications because NiFi is unusually strict about how it identifies incoming requests. NiFi validates the Host header against a list of allowed hostnames, and when it’s placed behind a proxy, it needs to be told explicitly what the “real” external host, port, scheme, and path are — otherwise it will reject requests outright with an HTTP 403 error, or it will generate broken links in the UI (CSS, JS, and API calls pointing at the wrong internal address).
That’s the core challenge with proxying NiFi: it’s not a simple “forward the request and hope for the best” setup. NiFi has to be explicitly configured to trust and understand the proxy.
Requirements Before Starting
Before touching any configuration, make sure the following are in place:
- A running instance of Apache NiFi (1.x or 2.x), accessible on its internal port, typically
8443for HTTPS or8080for HTTP in unsecured test setups. - A Linux server (Ubuntu, Debian, CentOS, RHEL, or similar) with Nginx installed, either on the same host as NiFi or a separate front-end server.
- Root or sudo access on the Nginx host.
- A domain name pointed at the Nginx server’s IP address, if this is meant to be publicly reachable.
- A valid TLS certificate for that domain (Let’s Encrypt via Certbot is the easiest route).
- Administrative access to NiFi’s
nifi.propertiesfile, since proxy trust settings must be configured there.
Install Nginx if it isn’t already present:
sudo apt update
sudo apt install nginx -y
On RHEL/CentOS/Rocky:
sudo dnf install nginx -y
Step 1: Configure NiFi to Trust the Proxy
Open NiFi’s configuration file, usually located at /opt/nifi/conf/nifi.properties (adjust the path for the actual install location).
Locate and update the following proxy-related properties:
nifi.web.proxy.host=nifi.example.com,nifi.example.com:443
nifi.web.proxy.context.path=
nifi.web.proxy.hostshould list every hostname (and hostname:port combination) that will be used to reach NiFi through the proxy. If this is left blank, NiFi rejects requests coming through an unrecognizedHostheader with a 403.nifi.web.proxy.context.pathonly needs a value if NiFi is being served from a subpath like/nifi-proxyinstead of the root.
If running a NiFi cluster, also verify nifi.cluster.node.protocol.port and related clustering settings remain untouched — proxying is only applied to the web UI/API layer, not internal cluster communication.
Restart NiFi after saving changes:
sudo systemctl restart nifi
Step 2: Write the Nginx Configuration
Create a new server block dedicated to NiFi:
sudo nano /etc/nginx/sites-available/nifi.conf
Here’s a complete, production-ready configuration:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name nifi.example.com;
# Redirect all HTTP traffic to HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name nifi.example.com;
ssl_certificate /etc/letsencrypt/live/nifi.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/nifi.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
client_max_body_size 100M;
location / {
proxy_pass https://127.0.0.1:8443;
proxy_ssl_verify off;
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 $server_port;
proxy_set_header X-ProxyScheme $scheme;
proxy_set_header X-ProxyHost $host;
proxy_set_header X-ProxyPort 443;
proxy_set_header X-ProxyContextPath "";
# WebSocket support (NiFi uses WebSockets for live status updates)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# Long timeouts, since NiFi flows can involve large uploads or long-running requests
proxy_read_timeout 300s;
proxy_send_timeout 300s;
proxy_connect_timeout 60s;
}
}
A few details worth explaining:
proxy_ssl_verify offis used because NiFi typically presents a self-signed or internally-issued certificate on its own port. If a proper internal CA certificate is configured, this can (and should) be set toonalong withproxy_ssl_trusted_certificate.- The
X-ProxyHost,X-ProxyPort, andX-ProxyContextPathheaders are what let NiFi correctly rewrite links in the UI to point back through the proxy rather than its internal address. - WebSocket headers are mandatory. Without them, the NiFi canvas will load, but the live status bar, flow updates, and provenance search results won’t refresh properly.
Enable the site and test the configuration:
sudo ln -s /etc/nginx/sites-available/nifi.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
On RHEL-based systems without sites-available/sites-enabled, place the same server block directly inside /etc/nginx/conf.d/nifi.conf.
Step 3: Testing the Setup
Start with a basic connectivity check:
curl -Ik https://nifi.example.com/nifi/
A 200 OK or 302 response indicates the proxy chain is functioning. Then open the URL in a browser and confirm:
- The NiFi login page (or canvas, if anonymous access is enabled) loads correctly.
- Static assets (CSS/JS) load without console errors about mixed content or 404s.
- The flow status bar in the top corner updates live — this confirms WebSocket proxying is working.
- Uploading a template or large flow definition succeeds without timing out.
If NiFi has single-user or LDAP authentication enabled, log in and verify the session persists across navigation — broken cookie or host header handling often shows up as repeated login prompts.
Troubleshooting Common Issues
403 Forbidden immediately on load This is almost always caused by a missing or incorrect nifi.web.proxy.host entry. NiFi logs (nifi-app.log) will show a line like “The request contained an unexpected Host header.” Add the exact hostname (with port, if non-standard) used in the URL bar to that property.
UI loads but looks broken (no CSS, blank canvas) Usually a missing X-ProxyContextPath header or an actual context path mismatch. If NiFi is served from a subdirectory, both nifi.web.proxy.context.path in nifi.properties and the location block path in Nginx need to agree exactly.
502 Bad Gateway Check that NiFi is actually listening on the port specified in proxy_pass, and that proxy_ssl_verify off is set if NiFi’s cert isn’t trusted by the system CA store. Confirm with:
sudo ss -tlnp | grep 8443
WebSocket connection failures / flow status not updating Double-check the map $http_upgrade $connection_upgrade block is present and that proxy_http_version 1.1 is set. Browser dev tools (Network tab, filtered to WS) will show a failed upgrade if this is misconfigured.
Session keeps dropping / repeated login prompts Verify proxy_set_header Host $host; isn’t being overridden elsewhere, and that clock skew between the Nginx host and NiFi host isn’t causing token validation issues (NiFi uses JWTs with expiration timestamps).
Security Considerations
Since NiFi often has access to sensitive data pipelines, the reverse proxy layer should be treated as a security boundary, not just a convenience layer.
- Terminate TLS at Nginx with a real certificate, and keep the internal NiFi-to-Nginx hop encrypted too, even on the same host, since NiFi handles credentials and flow content.
- Restrict access by IP where possible using
allow/denydirectives, especially for administrative NiFi instances that don’t need to be internet-facing. - Enable HTTP security headers in the Nginx config:
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
- Rate limit login attempts if NiFi’s built-in authentication is exposed publicly, using
limit_req_zonein thehttpblock. - Keep NiFi’s own authentication enabled. A reverse proxy is not a substitute for NiFi’s user authentication and authorization (via
authorizers.xml); it’s an additional layer, not a replacement. - Audit
nifi.web.proxy.hostregularly. An overly broad wildcard here can reopen the exact host-header vulnerability the setting exists to prevent.
Performance Tips
- Increase
worker_connectionsin the Nginxeventsblock if this proxy will handle many concurrent flow-file uploads or dashboard users. - Set
client_max_body_sizegenerously (as shown above) since NiFi templates and flow definitions can be large XML/JSON files. - Avoid buffering large uploads in Nginx by tuning
proxy_request_buffering off;for endpoints handling file uploads, which lets large transfers stream directly to NiFi instead of being cached to disk first. - If NiFi is clustered, consider load balancing across nodes using an
upstreamblock, but be aware that NiFi’s clustering model expects sticky sessions for the UI, soip_hashor a cookie-based sticky method is preferable to round robin.
upstream nifi_cluster {
ip_hash;
server nifi-node1:8443;
server nifi-node2:8443;
server nifi-node3:8443;
}
Real-World Use Cases
- Multi-tenant data platforms where NiFi is one of several internal tools (alongside something like Superset or a custom dashboard) exposed under different subdomains through a single Nginx instance.
- Compliance-driven environments that require centralized TLS certificate management and audit logging at the edge, rather than trusting every internal service to handle its own certificates correctly.
- Simplified DNS and firewall rules, where only Nginx’s port 443 needs to be open externally, while NiFi itself stays bound to localhost or an internal-only network interface.
- Blue-green or canary NiFi upgrades, where Nginx can be pointed at a new NiFi version during testing before cutting traffic over fully.
Best Practices Checklist
- Always set
nifi.web.proxy.hostto match every hostname:port combination used to reach the proxy. - Pass all four proxy headers NiFi expects:
X-ProxyScheme,X-ProxyHost,X-ProxyPort,X-ProxyContextPath. - Enable WebSocket proxying; don’t skip it assuming it’s optional.
- Terminate TLS with a real certificate at Nginx, and keep the backend hop encrypted as well.
- Bind NiFi’s HTTPS port to localhost or a private network interface once the proxy is confirmed working, so it can’t be reached directly, bypassing the proxy’s protections.
- Monitor
nifi-app.logduring initial setup — nearly every proxy issue leaves a clear trace there. - Document the exact header set in version control alongside the Nginx config, since NiFi upgrades occasionally change expected proxy behavior.
Getting Nginx and NiFi to work together cleanly comes down to one core idea: NiFi needs to be told explicitly what the outside world sees, and Nginx needs to pass that information through consistently. Once those two pieces line up — proxy headers on the Nginx side, nifi.web.proxy.host on the NiFi side — the rest is standard reverse proxy hygiene: TLS, timeouts, and access control.
