The Architecture Rationale
Public-facing infrastructure requires a robust gatekeeper. Rather than exposing Proxmox (or any internal application) directly to the internet, this architecture utilizes an Nginx-based edge proxy. This serves three critical purposes:
- SSL Termination: Consolidating certificate management at the edge.
- Hardening: Enforcing Basic Authentication and blocking search engine indexing before traffic reaches internal services.
- Protocol Upgrading: Managing specialized headers for WebSockets (required for NoVNC consoles) and handling long-lived connections for idle terminal sessions.
Option A: Lightweight Nginx (Manual Hardening)
Ideal for low-overhead environments requiring custom security modules.
1. Setup & Dependencies
Deployed as an Alpine Linux LXC for minimal resource usage.
Bash
apk update & apk -U upgrade
apk add nginx certbot openssl curl bash certbot-dns-cloudflare apache2-utils
2. Edge Authentication
To add a secondary layer of defense, we force Basic Auth at the Nginx level.
Bash
htpasswd -c /etc/nginx/.htpasswd admin
3. Certificate Management (Cloudflare DNS Challenge)
Using the Cloudflare DNS challenge allows for wildcard certificate generation (*.domain.com), eliminating the need to expose ports for HTTP-01 challenges.
- Credential Setup: Create a restricted API token in Cloudflare.
- Secure Config: Save to
/root/cloudflare.iniwithchmod 600permissions.
Bash
# Generate wildcard cert
certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /root/cloudflare.ini \
-d "*.domain.com" -d domain.com \
--agree-tos --non-interactive --email [YOUR_EMAIL]
4. Reverse Proxy Configuration
Key configurations for Proxmox GUI compatibility:
proxy_ssl_verify off: Required because Proxmox uses self-signed certificates for internal communication.proxy_buffering off: Critical for maintaining the responsiveness of the NoVNC console.proxy_set_header Upgrade $http_upgrade: Enables WebSocket support for real-time terminal interaction.
Option B: Nginx Proxy Manager (High-Availability GUI)
Ideal for rapid deployment and multi-app management.
For more complex environments hosting multiple services (Vaultwarden, Gitea, etc.), Nginx Proxy Manager (NPM) is preferred.
- Deployment: Automated via Proxmox Helper-Scripts.
- Efficiency: NPM provides a centralized GUI to manage SSL renewals, stream configurations, and access lists, significantly reducing the maintenance time for 10+ internal apps.
Security & Maintenance Notes
Nginx hardening
Always include the following headers in your server blocks to prevent search engines from indexing your internal tools:
Nginx
add_header X-Robots-Tag "noindex, nofollow, nosnippet, noarchive";
Configuration Hygiene
When decommissioning or moving services, use clean-up routines to prevent log rot and stale configuration entries:
Bash
# Example: Purging old service config
rm -rf /var/log/nginx/[SERVICE].access.log
rm -rf /etc/nginx/http.d/[SERVICE].conf
rc-service nginx reload
Tooling Evaluation: Why Nginx?
The selection of the reverse proxy was based on architectural fit, prioritizing minimal overhead and stability within an LXC-heavy environment. My evaluation included:
- Traefik & Caddy: While these are industry standards for dynamic discovery, they are fundamentally designed for Docker-orchestrated ecosystems. In a static Proxmox LXC setup, their reliance on dynamic provider APIs and container labeling felt like significant architectural “overkill.” The configuration complexity introduced unnecessary layers of abstraction that did not solve the problem of hosting fixed LXC services.
- Zoraxy: Successfully tested for its intuitive GUI and built-in features. It is a fantastic lightweight alternative for users who prefer GUI-driven management over configuration files.
- Nginx / Nginx Proxy Manager (NPM): Ultimately, I standardized on Nginx for its deterministic performance and ability to operate independently of any container orchestration. It provides the highest degree of control over the request lifecycle (specifically the WebSocket handling required for Proxmox consoles) without the heavy resource footprint of a dynamic discovery engine.
