1.3 — Securing Your Instance with Nginx
Securing Your Instance with Nginx: The Reverse Proxy Pattern
Running automation on a raw port (e.g., :5678) is a critical security vulnerability that exposes your entire workflow engine to the public internet. Every bot scanner, credential-stuffing attack, and opportunistic intruder that finds your port can attempt to access your n8n instance directly. In this lesson, we implement an Nginx Reverse Proxy with SSL termination to put a hardened, encrypted gatekeeper in front of your automation engine — turning a hobbyist setup into infrastructure-grade protection that Pakistani clients will trust.
Section 1: Understanding the Proxy Architecture
Nginx acts as the traffic controller for your server. All public requests arrive at port 443 (HTTPS), Nginx validates the SSL certificate, then forwards the request internally to n8n on port 5678. From the outside, your port 5678 is completely invisible.
INBOUND TRAFFIC FLOW
Internet
│
│ HTTPS :443 (encrypted, public-facing)
↓
┌───────────────────────────────────────────┐
│ Nginx Layer │
│ │
│ ├── SSL Termination (Let's Encrypt) │
│ ├── Request Header Injection │
│ ├── Rate Limiting (optional) │
│ └── Proxy Pass → localhost:5678 │
└───────────────────┬───────────────────────┘
│ HTTP :5678 (internal only)
↓
┌───────────────────────────────────────────┐
│ n8n Docker Container │
│ │
│ ├── Workflow Engine │
│ ├── Webhook Receiver │
│ └── Admin UI │
└───────────────────────────────────────────┘
Firewall (ufw): blocks all external access to :5678
Only Nginx on localhost can reach n8n directly
Section 2: Installing and Configuring Nginx
On a fresh Ubuntu 22.04 VPS (Contabo, Hetzner, or DigitalOcean), run:
sudo apt update && sudo apt install nginx -y
sudo systemctl enable nginx
sudo systemctl start nginx
Create the n8n site configuration at /etc/nginx/sites-available/n8n:
# Redirect all HTTP to HTTPS
server {
listen 80;
server_name automate.yourdomain.com;
return 301 https://$host$request_uri;
}
# HTTPS reverse proxy to n8n
server {
listen 443 ssl;
server_name automate.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/automate.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/automate.yourdomain.com/privkey.pem;
# Security headers
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header Strict-Transport-Security "max-age=31536000" always;
location / {
proxy_pass http://localhost:5678;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Connection '';
proxy_http_version 1.1;
chunked_transfer_encoding off;
proxy_buffering off;
proxy_cache off;
}
}
Enable the site and test configuration:
sudo ln -s /etc/nginx/sites-available/n8n /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Section 3: Obtaining a Free SSL Certificate with Certbot
In 2026 there is zero excuse for unencrypted traffic. Certbot automates the entire SSL certificate lifecycle — initial issuance, and automatic renewal every 90 days.
# Install Certbot
sudo apt install certbot python3-certbot-nginx -y
# Obtain and auto-configure SSL for your domain
sudo certbot --nginx -d automate.yourdomain.com
# Verify auto-renewal timer is active
sudo systemctl status certbot.timer
Certbot will automatically edit your Nginx config to point to the new certificate. The timer runs twice daily to renew certificates before they expire.
Section 4: Firewall Configuration with UFW
Blocking direct access to port 5678 is mandatory. Without this step, your Nginx proxy provides no real security — anyone can bypass it.
# Install and configure UFW
sudo apt install ufw -y
# Allow only necessary ports
sudo ufw allow 22 # SSH (never block this first)
sudo ufw allow 80 # HTTP (Nginx redirect)
sudo ufw allow 443 # HTTPS (Nginx secure)
# Block direct n8n port access
sudo ufw deny 5678
# Enable the firewall
sudo ufw enable
# Verify rules
sudo ufw status verbose
Expected output confirming n8n is protected:
Status: active
To Action From
-- ------ ----
22/tcp ALLOW IN Anywhere
80/tcp ALLOW IN Anywhere
443/tcp ALLOW IN Anywhere
5678 DENY IN Anywhere
Section 5: Comparison of Domain Options for Pakistani Automation Agencies
| Domain Type | Registrar | Annual Cost (PKR) | Client Trust Level | Best For |
|---|---|---|---|---|
.com | Namecheap | PKR 2,800 | High (global) | International clients |
.pk | PKNIC | PKR 2,500 | Very High (PK) | Local Karachi/Lahore clients |
.com.pk | PKNIC | PKR 2,500 | Very High (PK) | Local businesses |
.io | Various | PKR 9,000 | Medium (tech) | SaaS products |
| Free subdomain | No-IP | PKR 0 | Low | Testing only |
For a Pakistani automation agency, the recommended setup is automate.yourcompany.pk — it signals local presence and Google Pakistan search rankings favor .pk TLDs.
Section 6: n8n Environment Variables for Proxy Compatibility
When n8n runs behind a reverse proxy, it needs to know its public URL. Update your Docker docker-compose.yml or .env:
# Required for n8n to generate correct webhook URLs
N8N_HOST=automate.yourdomain.com
N8N_PORT=5678
N8N_PROTOCOL=https
WEBHOOK_URL=https://automate.yourdomain.com/
# Optional: Basic auth for extra protection
N8N_BASIC_AUTH_ACTIVE=true
N8N_BASIC_AUTH_USER=admin
N8N_BASIC_AUTH_PASSWORD=your-strong-password-here
Without WEBHOOK_URL, n8n generates webhook URLs pointing to localhost:5678 instead of your public domain — and your webhooks will never fire from external systems like Shopify or Typeform.
Practice Lab
Task 1 — Nginx Basics: Install Nginx on your VPS (or a local Ubuntu VM via VirtualBox). Create a simple configuration that serves a plain HTML "Hello World" page on port 80. Verify it loads in your browser using your VPS IP address.
Task 2 — Proxy Redirect: Modify your Nginx config to proxy localhost:80 to a Python HTTP server running on localhost:8080 (start it with python3 -m http.server 8080). Test that visiting port 80 serves content from the Python server — not Nginx's default page.
Task 3 — Full Secure Stack: Point a real or test domain to your VPS IP (use a free subdomain from afraid.org if needed). Run Certbot to generate SSL. Add the UFW firewall rules. Confirm the green padlock appears in your browser when visiting https://yourdomain.
Pakistan Case Study
Character: Bilal Raza, a 24-year-old freelancer from Gulshan-e-Iqbal, Karachi. He landed his first n8n client — a mid-size textile exporter on the SITE area who processes 200+ Daraz orders per day.
The Problem: Bilal had deployed n8n on a Contabo VPS (PKR 1,800/month) and shared the raw URL http://65.21.XX.XX:5678 with the client for a demo. Within 48 hours, a credential-stuffing bot had attempted 3,000 logins on the exposed port. Bilal's client received an alert from their IT person and almost cancelled the contract.
The Fix: Bilal registered automate.textileexport.pk from PKNIC for PKR 2,500/year. He set up Nginx with Certbot SSL in 45 minutes, blocked port 5678 with UFW, and enabled n8n's built-in basic auth as a second layer. The client's IT person ran a security scan, saw only port 443 open with valid SSL, and approved the setup.
The Outcome: Bilal's monthly retainer for the client is PKR 45,000/month. The PKR 2,500 domain + 45 minutes of configuration was the difference between losing the contract and keeping it. His Romanized Urdu note to himself: "Security seedha aata hai — pehle lagao, baad mein client ko dikhao."
Key Takeaways
- Running n8n on a raw port exposes your admin interface, webhook endpoints, and credentials to public internet scanners — never skip the proxy setup
- Nginx reverse proxy + SSL termination is the industry standard for self-hosted web services; the same pattern works for all your other tools (API Hub, dashboards)
- Certbot from Let's Encrypt provides free, auto-renewing SSL certificates — there is no valid reason to pay for SSL in 2026
- UFW firewall must explicitly block port 5678 — Nginx alone does not prevent direct port access
- Set
WEBHOOK_URLin n8n's environment variables, or all your webhook URLs will point to localhost and fail silently - PKNIC
.pkdomains cost PKR 2,500/year and dramatically increase client trust for Pakistani automation agencies - Add basic auth (
N8N_BASIC_AUTH_ACTIVE=true) as a second security layer on top of Nginx — defense in depth - Pakistan's PECA data protection rules create legal liability if customer data leaks through an unprotected endpoint — SSL is not just good practice, it is a legal safeguard
- The security headers (
X-Frame-Options,HSTS) added in the Nginx config protect against clickjacking and protocol downgrade attacks with zero performance cost - Test your full security setup with
nmap -sV YOUR_VPS_IP— you should see only ports 22, 80, and 443 open; port 5678 should not appear
Recommended Resources
- Official n8n reverse proxy documentation:
docs.n8n.io/hosting/advanced-setup/reverse-proxy/nginx/ - Certbot (Let's Encrypt) documentation:
certbot.eff.org/instructions - UFW firewall guide for Ubuntu: Ubuntu Community Help Wiki, search "UFW"
- PKNIC domain registration:
pknic.net.pk— register.pkand.com.pkdomains - n8n environment variable reference:
docs.n8n.io/hosting/configuration/environment-variables/
Lesson Summary
Quiz: Securing Your Instance with Nginx
5 questions to test your understanding. Score 60% or higher to pass.