- Organized 252 files across project - Root directory: 187 → 2 files (98.9% reduction) - Moved configuration guides to docs/04-configuration/ - Moved troubleshooting guides to docs/09-troubleshooting/ - Moved quick start guides to docs/01-getting-started/ - Moved reports to reports/ directory - Archived temporary files - Generated comprehensive reports and documentation - Created maintenance scripts and guides All files organized according to established standards.
14 KiB
Cloudflare DNS Mapping to Proxmox LXC Containers
Last Updated: 2025-01-20
Document Version: 1.0
Status: Implementation Guide
Overview
This guide explains how to map Cloudflare DNS records to Proxmox VE LXC containers using Cloudflare Zero Trust tunnels (cloudflared). This provides secure, public access to your containers without exposing them directly to the internet.
Architecture
Internet → Cloudflare DNS → Cloudflare Tunnel → cloudflared LXC → Target Container
Components
- Cloudflare DNS - DNS records pointing to tunnel
- Cloudflare Tunnel - Secure connection between Cloudflare and your network
- cloudflared LXC - Tunnel client running in a container
- Target Containers - Your application containers (web servers, APIs, etc.)
Prerequisites
- Cloudflare Account with Zero Trust enabled
- Domain managed by Cloudflare
- Proxmox Host with network access
- Target Containers running and accessible on local network
Step-by-Step Guide
Step 1: Set Up Cloudflare Tunnel
1.1 Create Tunnel in Cloudflare Dashboard
-
Access Cloudflare Zero Trust:
- Navigate to: https://one.dash.cloudflare.com
- Sign in with your Cloudflare account
-
Create Tunnel:
- Go to Zero Trust → Networks → Tunnels
- Click Create a tunnel
- Select Cloudflared
- Enter tunnel name (e.g.,
proxmox-primary) - Click Save tunnel
-
Copy Tunnel Token:
- After creation, you'll see installation instructions
- Copy the tunnel token (you'll need this in Step 2)
1.2 Deploy cloudflared LXC Container
Option A: Create New Container
# Assign VMID (e.g., 8000)
VMID=8000
# Create container
pct create $VMID local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst \
--hostname cloudflared \
--net0 name=eth0,bridge=vmbr0,ip=192.168.11.80/24,gw=192.168.11.1 \
--memory 512 \
--cores 1 \
--storage local-lvm \
--rootfs local-lvm:4
# Start container
pct start $VMID
Option B: Use Existing Container
If you already have a container for cloudflared (e.g., VMID 102), skip to installation.
1.3 Install cloudflared
# Replace $VMID with your container ID
pct exec $VMID -- bash -c "
wget -q https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
dpkg -i cloudflared-linux-amd64.deb
cloudflared --version
"
1.4 Configure Tunnel
# Install tunnel with token (replace <TUNNEL_TOKEN> with actual token)
pct exec $VMID -- cloudflared service install <TUNNEL_TOKEN>
# Enable and start service
pct exec $VMID -- systemctl enable cloudflared
pct exec $VMID -- systemctl start cloudflared
# Check status
pct exec $VMID -- systemctl status cloudflared
Step 2: Map DNS to Container
2.1 Identify Container Information
Get Container IP and Port:
# List containers and their IPs
pct list
# Get specific container IP
pct config <VMID> | grep ip
# Or check running containers
pct exec <VMID> -- ip addr show eth0
Example Container:
- VMID: 2500 (besu-rpc-1)
- IP: 192.168.11.250
- Port: 8545 (RPC port)
- Service: HTTP JSON-RPC API
2.2 Configure Tunnel Ingress Rules
In Cloudflare Dashboard:
-
Navigate to Tunnel Configuration:
- Go to Zero Trust → Networks → Tunnels
- Click on your tunnel name
- Click Configure
-
Add Public Hostname:
- Click Public Hostname tab
- Click Add a public hostname
-
Configure Route:
Subdomain: rpc Domain: yourdomain.com Service: http://192.168.11.250:8545 -
Save Configuration
Example Configuration:
For multiple containers, add multiple hostname entries:
Subdomain: rpc-core
Domain: yourdomain.com
Service: http://192.168.11.250:8545
Subdomain: rpc-sentry
Domain: yourdomain.com
Service: http://192.168.11.251:8545
Subdomain: blockscout
Domain: yourdomain.com
Service: http://192.168.11.100:4000
2.3 Create DNS Records
In Cloudflare DNS Dashboard:
-
Navigate to DNS:
- Go to your domain in Cloudflare
- Click DNS → Records
-
Create CNAME Record:
- Click Add record
- Type: CNAME
- Name:
rpc(or your subdomain) - Target:
<tunnel-id>.cfargotunnel.com- Or use:
proxmox-primary.yourteam.cloudflareaccess.com(if using Zero Trust)
- Or use:
- Proxy status: 🟠 Proxied (orange cloud) - Important!
-
Save Record
DNS Record Examples:
| Service | Type | Name | Target | Proxy |
|---|---|---|---|---|
| RPC Core | CNAME | rpc-core |
<tunnel-id>.cfargotunnel.com |
🟠 Proxied |
| RPC Sentry | CNAME | rpc-sentry |
<tunnel-id>.cfargotunnel.com |
🟠 Proxied |
| Blockscout | CNAME | blockscout |
<tunnel-id>.cfargotunnel.com |
🟠 Proxied |
| FireFly | CNAME | firefly |
<tunnel-id>.cfargotunnel.com |
🟠 Proxied |
Important Notes:
- ✅ Always enable proxy (orange cloud) for tunnel-based DNS records
- ✅ Use CNAME records (not A records) for tunnel endpoints
- ✅ Target should be the tunnel's cloudflareaccess.com domain or cfargotunnel.com
Step 3: Verify Configuration
3.1 Check Tunnel Status
# Check cloudflared service
pct exec $VMID -- systemctl status cloudflared
# View tunnel logs
pct exec $VMID -- journalctl -u cloudflared -f
In Cloudflare Dashboard:
- Go to Zero Trust → Networks → Tunnels
- Tunnel status should show "Healthy"
3.2 Test DNS Resolution
# Test DNS resolution
dig rpc-core.yourdomain.com
nslookup rpc-core.yourdomain.com
# Should resolve to Cloudflare IPs (if proxied)
3.3 Test Container Access
# Test from container network (should work directly)
curl http://192.168.11.250:8545
# Test via public DNS (should work through tunnel)
curl https://rpc-core.yourdomain.com
Common Container Types & Examples
Web Applications (HTTP/HTTPS)
Example: Blockscout Explorer
DNS Record:
Name: blockscout
Target: <tunnel-id>.cfargotunnel.com
Proxy: Enabled
Tunnel Ingress:
Subdomain: blockscout
Domain: yourdomain.com
Service: http://192.168.11.100:4000
API Services (JSON-RPC, REST)
Example: Besu RPC Node
DNS Record:
Name: rpc
Target: <tunnel-id>.cfargotunnel.com
Proxy: Enabled
Tunnel Ingress:
Subdomain: rpc
Domain: yourdomain.com
Service: http://192.168.11.250:8545
Databases (Optional - Not Recommended)
⚠️ Warning: Never expose databases directly through tunnels unless absolutely necessary. Use Cloudflare Access with strict policies if needed.
Monitoring Dashboards
Example: Grafana
DNS Record:
Name: grafana
Target: <tunnel-id>.cfargotunnel.com
Proxy: Enabled
Tunnel Ingress:
Subdomain: grafana
Domain: yourdomain.com
Service: http://192.168.11.200:3000
Security: Add Cloudflare Access policy to restrict access (see Step 4).
Step 4: Add Cloudflare Access (Optional but Recommended)
For additional security, add Cloudflare Access policies to restrict who can access your containers.
4.1 Create Access Application
-
Navigate to Applications:
- Go to Zero Trust → Access → Applications
- Click Add an application
-
Configure Application:
- Application Name: RPC Core API
- Application Domain:
rpc-core.yourdomain.com - Session Duration: 24 hours
-
Add Policy:
Rule Name: RPC Access Action: Allow Include: - Email domain: @yourdomain.com - OR Email: admin@yourdomain.com Require: - MFA (optional) -
Save Application
4.2 Apply to Multiple Services
Create separate applications for each service that needs access control:
- Blockscout (public or restricted)
- Grafana (admin only)
- FireFly (team access)
- RPC nodes (API key authentication recommended in addition)
Advanced Configuration
Multiple Tunnels (Redundancy)
For high availability, deploy multiple cloudflared instances:
Primary Tunnel:
- Container: VMID 8000 (cloudflared-1)
- IP: 192.168.11.80
- Tunnel:
proxmox-primary
Secondary Tunnel:
- Container: VMID 8001 (cloudflared-2)
- IP: 192.168.11.81
- Tunnel:
proxmox-secondary
DNS Configuration:
- Use same DNS records for both tunnels
- Cloudflare will automatically load balance
- If one tunnel fails, traffic routes to the other
Custom cloudflared Configuration
For advanced routing, use a config file:
# /etc/cloudflared/config.yml
tunnel: <tunnel-id>
credentials-file: /etc/cloudflared/credentials.json
ingress:
# Specific routes
- hostname: rpc-core.yourdomain.com
service: http://192.168.11.250:8545
- hostname: rpc-sentry.yourdomain.com
service: http://192.168.11.251:8545
- hostname: blockscout.yourdomain.com
service: http://192.168.11.100:4000
# Catch-all
- service: http_status:404
Apply Configuration:
pct exec $VMID -- systemctl restart cloudflared
Using Reverse Proxy (Nginx Proxy Manager)
Architecture:
Internet → Cloudflare → Tunnel → cloudflared → Nginx Proxy Manager → Containers
Benefits:
- Centralized SSL/TLS termination
- Advanced routing rules
- Rate limiting
- Request logging
Configuration:
-
Tunnel Points to Nginx:
Subdomain: * Service: http://192.168.11.105:80 # Nginx Proxy Manager -
Nginx Routes to Containers:
- Create proxy hosts in Nginx Proxy Manager
- Configure upstream servers (container IPs)
- Add SSL certificates
See: CLOUDFLARE_NGINX_INTEGRATION.md
Current Container Mapping Examples
Based on your deployment, here are example mappings:
Besu Validators (1000-1004)
Recommendation: ⚠️ Do not expose validators publicly. Keep them private.
If Needed (VPN/Internal Access Only):
Internal Access: 192.168.11.100-104 (via VPN)
Besu RPC Nodes (2500-2502)
Example Configuration:
DNS Record:
Name: rpc
Target: <tunnel-id>.cfargotunnel.com
Proxy: Enabled
Tunnel Ingress:
- hostname: rpc-1.yourdomain.com
service: http://192.168.11.250:8545
- hostname: rpc-2.yourdomain.com
service: http://192.168.11.251:8545
- hostname: rpc-3.yourdomain.com
service: http://192.168.11.252:8545
Troubleshooting
Tunnel Not Connecting
Symptoms: Tunnel shows as "Unhealthy" in dashboard
Solutions:
# Check service status
pct exec $VMID -- systemctl status cloudflared
# View logs
pct exec $VMID -- journalctl -u cloudflared -f
# Verify token is correct
pct exec $VMID -- cat /etc/cloudflared/config.yml
DNS Not Resolving
Symptoms: DNS record doesn't resolve or resolves incorrectly
Solutions:
- Verify DNS record type is CNAME
- Verify proxy is enabled (orange cloud)
- Check target is correct tunnel domain
- Wait for DNS propagation (up to 5 minutes)
Container Not Accessible
Symptoms: DNS resolves but container doesn't respond
Solutions:
- Verify container is running:
pct status <VMID> - Test direct access:
curl http://<container-ip>:<port> - Check tunnel ingress configuration matches DNS record
- Verify firewall allows traffic from cloudflared container
- Check container logs for errors
SSL/TLS Errors
Symptoms: Browser shows SSL certificate errors
Solutions:
- Verify proxy is enabled (orange cloud) in DNS
- Check Cloudflare SSL/TLS mode (Full or Full Strict)
- Ensure service URL uses
http://nothttps://(Cloudflare handles SSL) - If using self-signed certs, set SSL mode to "Full" not "Full (strict)"
Best Practices
Security
- ✅ Use Cloudflare Access for sensitive services
- ✅ Enable MFA for admin access
- ✅ Use IP allowlists in addition to Cloudflare Access
- ✅ Monitor access logs in Cloudflare dashboard
- ✅ Never expose databases directly
- ✅ Keep containers updated with security patches
Performance
- ✅ Use proxy (orange cloud) for DDoS protection
- ✅ Enable Cloudflare caching for static content
- ✅ Use multiple tunnels for redundancy
- ✅ Monitor tunnel health regularly
Management
- ✅ Document all DNS mappings in a registry
- ✅ Use consistent naming conventions
- ✅ Version control tunnel configurations
- ✅ Backup cloudflared configurations
DNS Mapping Registry Template
Keep track of your DNS mappings:
| Service | Subdomain | Container VMID | Container IP | Port | Tunnel | Access Control |
|---|---|---|---|---|---|---|
| RPC Core | rpc-core | 2500 | 192.168.11.250 | 8545 | proxmox-primary | API Key |
| Blockscout | blockscout | 5000 | 192.168.11.100 | 4000 | proxmox-primary | Cloudflare Access |
| Grafana | grafana | 6000 | 192.168.11.200 | 3000 | proxmox-primary | Admin Only |
Quick Reference Commands
Check Container Status
pct list
pct status <VMID>
pct config <VMID>
Check Tunnel Status
pct exec <VMID> -- systemctl status cloudflared
pct exec <VMID> -- journalctl -u cloudflared -f
Test DNS Resolution
dig <subdomain>.yourdomain.com
nslookup <subdomain>.yourdomain.com
curl -I https://<subdomain>.yourdomain.com
Test Container Direct Access
curl http://<container-ip>:<port>
pct exec <VMID> -- curl http://<target-ip>:<port>
Related Documentation
- CLOUDFLARE_ZERO_TRUST_GUIDE.md - Complete Cloudflare Zero Trust setup
- CLOUDFLARE_NGINX_INTEGRATION.md - Using Nginx Proxy Manager
- NETWORK_ARCHITECTURE.md - Network architecture overview
- DEPLOYMENT_STATUS_CONSOLIDATED.md - Current container inventory
Document Status: Complete (v1.0)
Maintained By: Infrastructure Team
Review Cycle: Quarterly
Last Updated: 2025-01-20