The Digital Guardian of My Homelab: Setting Up a Secure Reverse Proxy with HTTPS
Goals
- Access all your internal web services (Proxmox, n8n, and databases) securely over HTTPS domains using a reverse proxy.
- Use Let’s Encrypt for free, automated SSL certificates.
Why Use a Reverse Proxy?
A reverse proxy acts as a centralized gateway to your homelab services, providing several critical benefits:
- Unified SSL Management: Single point for certificate management
- Security Layer: Protection against direct service exposure
- Custom Domains: Clean URLs instead of IP:PORT combinations
- Load Balancing: Distribute traffic across multiple backend servers
Architecture Overview
Internet/LAN
↓
pfSense Firewall
↓
Nginx Proxy Manager (Reverse Proxy)
↓
├── Proxmox (192.168.x.x:8006)
├── n8n (192.168.x.x:5678)
├── Databases (192.168.x.x:XXXX)
└── Other Services
Step 1: Deploy Reverse Proxy VM/Container
Option A: Lightweight VM
- Create a new VM on Proxmox (Debian/Ubuntu recommended)
- Allocate minimal resources: 1 CPU, 2GB RAM, 10GB storage
- Install Docker and Docker Compose
Option B: LXC Container (Recommended)
- Use Proxmox helper scripts for faster deployment
- More efficient resource usage
- Easier management
Install Docker and Docker Compose
# Update system
sudo apt update && sudo apt upgrade -y
# Install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# Install Docker Compose
sudo apt install docker-compose -y
# Add user to docker group
sudo usermod -aG docker $USERStep 2: Install Nginx Proxy Manager
Docker Compose Configuration
Create docker-compose.yml:
version: '3'
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
container_name: nginx-proxy-manager
restart: unless-stopped
ports:
- '80:80' # HTTP
- '81:81' # Admin UI
- '443:443' # HTTPS
environment:
DB_MYSQL_HOST: "db"
DB_MYSQL_PORT: 3306
DB_MYSQL_USER: "npm"
DB_MYSQL_PASSWORD: "npm"
DB_MYSQL_NAME: "npm"
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
db:
image: 'jc21/mariadb-aria:latest'
container_name: npm-database
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: 'npm'
MYSQL_DATABASE: 'npm'
MYSQL_USER: 'npm'
MYSQL_PASSWORD: 'npm'
volumes:
- ./data/mysql:/var/lib/mysqlLaunch Nginx Proxy Manager
docker-compose up -dAccess Admin UI
- Navigate to:
http://<proxy-vm-ip>:81 - Default credentials:
- Email:
admin@example.com - Password:
changeme
- Email:
- Immediately change these credentials after first login!
Step 3: Configure Internal DNS
Using pfSense DNS Resolver
- Navigate to Services > DNS Resolver
- Enable DNS Resolver if not already enabled
- Under Host Overrides, add entries:
- Host:
proxmox, Domain:lab, IP:<proxy-ip> - Host:
n8n, Domain:lab, IP:<proxy-ip> - Host:
db, Domain:lab, IP:<proxy-ip>
- Host:
Alternative: Local Hosts File
For testing purposes, edit your local /etc/hosts:
<proxy-ip> proxmox.lab
<proxy-ip> n8n.lab
<proxy-ip> db.lab
Step 4: Add Services as Proxy Hosts
In Nginx Proxy Manager UI
- Click “Proxy Hosts” → “Add Proxy Host”
- Details Tab:
- Domain Names:
n8n.lab - Scheme:
http - Forward Hostname/IP:
<n8n-container-ip> - Forward Port:
5678 - Block Common Exploits: ✓
- Websockets Support: ✓ (important for n8n)
- Domain Names:
- Repeat for other services:
- Proxmox: Port
8006, Schemehttps - Databases: Port varies, Scheme
http
- Proxmox: Port
Step 5: Request SSL Certificates
Enable Let’s Encrypt
- In Proxy Host entry, go to SSL Tab
- Select “Request a new SSL Certificate”
- Options:
- Force SSL: ✓
- HTTP/2 Support: ✓
- HSTS Enabled: ✓ (recommended)
- Email for Let’s Encrypt: Your email
- Click Save
Let’s Encrypt will automatically: - Generate SSL certificate - Configure HTTPS - Set up auto-renewal (every 90 days)
DNS Challenge (For Wildcard Certificates)
If you own a domain and want *.yourdomain.com:
- Use DNS challenge method
- Configure DNS provider credentials in NPM
- Request wildcard certificate:
*.yourdomain.com
Step 6: Open Port 443 in Firewall
pfSense Configuration
- Navigate to Firewall > NAT > Port Forward
- Create rule:
- Interface: WAN
- Protocol: TCP
- Destination Port Range: 443
- Redirect Target IP:
<proxy-vm-ip> - Redirect Target Port: 443
- Description: Reverse Proxy HTTPS
- Create corresponding firewall rule if needed
VM/Container Firewall
If using UFW:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 81/tcp # Admin UI (restrict to LAN only!)Step 7: Test Access
Internal Testing
From your LAN:
curl -k https://n8n.lab
curl -k https://proxmox.lab:8006Browser Testing
- Open browser
- Navigate to
https://n8n.lab - Verify:
- ✅ Valid SSL certificate (green padlock)
- ✅ Service loads correctly
- ✅ No certificate warnings
Security Hardening
Restrict Admin UI Access
In Nginx Proxy Manager:
- Access Lists → Create new
- Authorization: Require username/password
- Apply to admin UI proxy host
Firewall rules:
# Allow admin UI only from LAN sudo ufw deny 81/tcp sudo ufw allow from 192.168.0.0/16 to any port 81
Enable Fail2Ban
Protect against brute-force attacks:
sudo apt install fail2ban -y
# Create NPM filter
sudo nano /etc/fail2ban/filter.d/npm.conf[Definition]
failregex = ^<HOST> .* "(GET|POST|HEAD).*HTTP.*" (4|5)\d\d
ignoreregex =Monitoring and Maintenance
Check Certificate Expiry
Nginx Proxy Manager automatically renews certificates 30 days before expiry.
Verify in UI: - SSL Certificates → Check expiry dates
Log Monitoring
# View NPM logs
docker logs -f nginx-proxy-manager
# Access logs location
cd ./data/logsPerformance Monitoring
Add monitoring with: - Prometheus + Grafana - Uptime Kuma for service availability
Common Issues and Solutions
Issue 1: Certificate Request Fails
Problem: Let’s Encrypt challenge fails
Solution: - Verify port 80 is accessible from internet - Check DNS resolution - Try HTTP challenge instead of DNS
Issue 2: WebSocket Connection Fails
Problem: Real-time features don’t work (n8n, Proxmox console)
Solution: - Enable Websockets
Support in proxy host - Add custom Nginx configuration:
nginx proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade";
Issue 3: Proxmox WebUI Access Denied
Problem: Cannot access Proxmox through proxy
Solution: - Set Forward Scheme to
https - Add custom headers:
nginx proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr;
Conclusion
Setting up a reverse proxy with Nginx Proxy Manager provides centralized, secure access to all your homelab services. The combination of automated SSL certificates, custom domains, and unified management creates a professional infrastructure that’s both secure and easy to maintain.
This setup serves as the digital guardian of your homelab, protecting services while providing convenient access. With proper configuration and security hardening, you can safely expose selected services to the internet while maintaining robust protection against unauthorized access.
Remember: Security is an ongoing process. Regularly update your reverse proxy, monitor logs, and review access patterns.