Node-RED Security Variants Discussed and Tested
Context
The goal is to protect a Node-RED installation exposed through a router, while keeping the setup simple and understandable.
The following four variants were discussed and tested in stages.
Common assumptions:
-
Node-RED runs on port 1880.
-
Node-RED admin authentication is enabled.
-
Nginx is used as a reverse proxy.
-
Nginx access logs are enabled.
-
Failed Node-RED editor logins appear as:
POST /auth/token ... 403
-
Fail2ban monitors the Nginx access log.
-
The Fail2ban filter used is:
[Definition]
failregex = ^ .* "POST /auth/token HTTP/." 403 .
ignoreregex =
================================================
VARIANT 1
HTTP + Nginx + Fail2ban Full IP Ban
Architecture:
Internet / LAN
|
v
Nginx :80
|
v
Node-RED :1880
Fail2ban watches:
POST /auth/token ... 403
Jail configuration:
[nodered]
enabled = true
filter = nodered
backend = polling
action = route
logpath = /var/log/nginx/access.log
maxretry = 5
findtime = 600
bantime = 300
Meaning:
- 5 failed login attempts
- within 10 minutes
- full source IP ban
- ban duration: 5 minutes
The important line is:
action = route
This blocks the entire source IP address, not only Node-RED.
As a result, the banned IP loses access to:
- Nginx
- Node-RED
- SSH
- other services on the same host
Advantages:
- Very simple.
- Easy to understand.
- Strong response to repeated failed logins.
- No nftables multiport configuration is required.
Disadvantage:
- The administrator can accidentally ban their own IP and lose SSH access.
This variant was tested successfully.
================================================
VARIANT 2
HTTP + Nginx + Fail2ban Ban Only Port 80
Architecture:
Internet / LAN
|
v
Nginx :80
|
v
Node-RED :1880
Fail2ban still watches:
POST /auth/token ... 403
However, instead of blocking the entire source IP, the ban is applied only to TCP port 80.
nftables is required.
Example action:
action = nftables[type=multiport, port="80", protocol="tcp"]
Result:
- HTTP access through Nginx port 80 is blocked.
- SSH port 22 remains accessible.
- Direct Node-RED port 1880 remains accessible if Node-RED is still listening on all interfaces.
Advantages:
- Safer for remote administration.
- Accidental login failures do not lock the administrator out of SSH.
Disadvantages:
- More complex than Variant 1.
- Direct port 1880 must still be closed separately.
This variant was also tested successfully.
================================================
VARIANT 3
HTTPS + Nginx + Fail2ban Ban Only Port 443
Architecture:
Internet
|
v
Nginx HTTPS :443
|
v
Node-RED :1880
A self-signed certificate is used.
Example Nginx configuration:
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
ssl_certificate /etc/nginx/ssl/nodered.crt;
ssl_certificate_key /etc/nginx/ssl/nodered.key;
access_log /var/log/nginx/access.log;
location / {
proxy_pass http://127.0.0.1:1880;
proxy_http_version 1.1;
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;
}
}
Fail2ban action:
action = nftables[type=multiport, port="443", protocol="tcp"]
Example jail:
[nodered]
enabled = true
filter = nodered
backend = polling
port = 443
protocol = tcp
action = nftables[type=multiport, port="443", protocol="tcp"]
logpath = /var/log/nginx/access.log
maxretry = 5
findtime = 600
bantime = 600
Meaning:
- 5 failed login attempts
- within 10 minutes
- only HTTPS port 443 is blocked
- ban duration: 10 minutes
Result:
- HTTPS access is blocked for the attacker.
- SSH remains accessible.
- Node-RED direct port 1880 remains accessible if not separately restricted.
Advantages:
- Encrypted connection.
- Fail2ban protects only the public web entry point.
- SSH remains available.
Disadvantages:
- More configuration.
- Self-signed certificates generate browser warnings.
- Port 1880 still needs separate protection.
This variant was tested successfully.
================================================
VARIANT 4
HTTPS + Nginx + Fail2ban + Node-RED Bound to Localhost
This is the hardened version of Variant 3.
Architecture:
Internet
|
v
Nginx HTTPS :443
|
v
127.0.0.1:1880
|
v
Node-RED
Node-RED is changed from:
0.0.0.0:1880
to:
127.0.0.1:1880
In Node-RED settings.js:
uiHost: "127.0.0.1",
Example file:
/mnt/dietpi_userdata/node-red/settings.js
After restart:
sudo systemctl restart node-red
Verification:
sudo ss -ltnp | grep -E '1880|443'
Expected result:
127.0.0.1:1880
0.0.0.0:443
[::]:443
Effect:
-
Node-RED port 1880 is no longer reachable directly from LAN or WAN.
-
Only local processes on the same machine can access Node-RED on port 1880.
-
Nginx can still proxy requests to:
-
All external access must go through Nginx.
Advantages:
- Direct access to Node-RED port 1880 is completely removed.
- Nginx becomes the single public web entry point.
- Fail2ban protection cannot be bypassed by connecting directly to port 1880.
- This is the strongest architecture of the four variants.
Disadvantage:
- Slightly more configuration than Variant 1.
================================================
Summary
Variant 1:
HTTP :80
Nginx
Node-RED :1880
Fail2ban full IP ban
action = route
Variant 2:
HTTP :80
Nginx
Node-RED :1880
Fail2ban ban only port 80
nftables multiport
Variant 3:
HTTPS :443
Nginx
Node-RED :1880
Fail2ban ban only port 443
nftables multiport
Variant 4:
HTTPS :443
Nginx
Node-RED only on 127.0.0.1:1880
Fail2ban on the public Nginx entry point
Recommended progression:
- Start with Variant 1 because it is simple and easy to verify.
- Add localhost binding for Node-RED port 1880.
- Add HTTPS if encrypted remote access is required.
- Use port-specific nftables bans if preserving SSH access during a web ban is important.
================================================
Additional Observation
The Node-RED editor login can be detected reliably in Nginx logs by:
POST /auth/token ... 403
However, other Node-RED interfaces such as /ui may use different authentication mechanisms.
For example, failed access to /ui may appear as:
GET /ui ... 401
Therefore, a separate Fail2ban rule may be required if the dashboard/user interface must also be protected against repeated authentication attempts.