Files
proxmox/docs/04-configuration/cloudflare/CLOUDFLARE_TUNNEL_RPC_SETUP.md
defiQUG bea1903ac9
Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled
Sync all local changes: docs, config, scripts, submodule refs, verification evidence
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-21 15:46:06 -08:00

520 lines
14 KiB
Markdown

# Cloudflare Tunnel Setup for RPC Endpoints
**Last Updated:** 2025-12-21
**Status:** Configuration Guide
---
## Overview
This guide explains how to set up Cloudflare Tunnel for the RPC endpoints with Nginx SSL termination. This provides additional security, DDoS protection, and hides your origin server IPs.
---
## Architecture Options
### Option 1: Direct Tunnel to Nginx (Recommended)
```
Internet → Cloudflare → Tunnel → cloudflared → Nginx (443) → Besu RPC (8545/8546)
```
**Benefits:**
- Direct connection to Nginx on each RPC container
- SSL termination at Nginx level
- Simpler architecture
- Better performance (fewer hops)
### Option 2: Tunnel via nginx-proxy-manager
```
Internet → Cloudflare → Tunnel → cloudflared → nginx-proxy-manager → Nginx → Besu RPC
```
**Benefits:**
- Centralized management
- Additional routing layer
- Useful if you have many services
**This guide focuses on Option 1 (Direct Tunnel to Nginx).**
---
## Prerequisites
1.**Nginx installed** on RPC containers (2501, 2502) - Already done
2.**SSL certificates** configured - Already done
3. **Cloudflare account** with Zero Trust enabled
4. **Domain** `d-bis.org` managed by Cloudflare
5. **cloudflared container** (VMID 102 or create new one)
---
## Step 1: Create Cloudflare Tunnel
### 1.1 Create Tunnel in Cloudflare Dashboard
1. **Access Cloudflare Zero Trust:**
- Navigate to: https://one.dash.cloudflare.com
- Sign in with your Cloudflare account
2. **Create Tunnel:**
- Go to **Zero Trust****Networks****Tunnels**
- Click **Create a tunnel**
- Select **Cloudflared**
- Enter tunnel name: `rpc-tunnel` (or `proxmox-rpc`)
- Click **Save tunnel**
3. **Copy Tunnel Token:**
- After creation, you'll see installation instructions
- Copy the tunnel token (starts with `eyJ...`)
- Save it securely - you'll need it in Step 2
---
## Step 2: Deploy/Configure cloudflared
### 2.1 Check Existing cloudflared Container
```bash
# Check if cloudflared container exists (VMID 102)
ssh root@192.168.11.10 "pct status 102"
ssh root@192.168.11.10 "pct exec 102 -- which cloudflared"
```
### 2.2 Install cloudflared (if needed)
If cloudflared is not installed:
```bash
# Install cloudflared on VMID 102
ssh root@192.168.11.10 "pct exec 102 -- bash -c '
wget -q https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
dpkg -i cloudflared-linux-amd64.deb || apt-get install -f -y
cloudflared --version
'"
```
### 2.3 Configure Tunnel
**Option A: Using Tunnel Token (Easiest)**
```bash
# Install tunnel with token
ssh root@192.168.11.10 "pct exec 102 -- cloudflared service install <YOUR_TUNNEL_TOKEN>"
# Start service
ssh root@192.168.11.10 "pct exec 102 -- systemctl enable cloudflared"
ssh root@192.168.11.10 "pct exec 102 -- systemctl start cloudflared"
```
**Option B: Using Config File (More Control)**
Create tunnel configuration file:
```bash
ssh root@192.168.11.10 "pct exec 102 -- bash" <<'EOF'
cat > /etc/cloudflared/config.yml <<'CONFIG'
tunnel: <YOUR_TUNNEL_ID>
credentials-file: /etc/cloudflared/credentials.json
ingress:
# Public HTTP RPC
- hostname: rpc-http-pub.d-bis.org
service: https://192.168.11.251:443
originRequest:
noHappyEyeballs: true
connectTimeout: 30s
tcpKeepAlive: 30s
keepAliveConnections: 100
keepAliveTimeout: 90s
# Public WebSocket RPC
- hostname: rpc-ws-pub.d-bis.org
service: https://192.168.11.251:443
originRequest:
noHappyEyeballs: true
connectTimeout: 30s
tcpKeepAlive: 30s
keepAliveConnections: 100
keepAliveTimeout: 90s
# Private HTTP RPC
- hostname: rpc-http-prv.d-bis.org
service: https://192.168.11.252:443
originRequest:
noHappyEyeballs: true
connectTimeout: 30s
tcpKeepAlive: 30s
keepAliveConnections: 100
keepAliveTimeout: 90s
# Private WebSocket RPC
- hostname: rpc-ws-prv.d-bis.org
service: https://192.168.11.252:443
originRequest:
noHappyEyeballs: true
connectTimeout: 30s
tcpKeepAlive: 30s
keepAliveConnections: 100
keepAliveTimeout: 90s
# Catch-all (must be last)
- service: http_status:404
CONFIG
# Set permissions
chmod 600 /etc/cloudflared/config.yml
EOF
```
**Important Notes:**
- Use `https://` (not `http://`) because Nginx is listening on port 443 with SSL
- The tunnel will handle SSL termination at Cloudflare edge
- Nginx will still receive HTTPS traffic (or you can configure it to accept HTTP from tunnel)
---
## Step 3: Configure Tunnel in Cloudflare Dashboard
### 3.1 Add Public Hostnames
In Cloudflare Zero Trust → Networks → Tunnels → Your Tunnel → Configure:
**Add each hostname:**
1. **rpc-http-pub.d-bis.org**
- **Subdomain:** `rpc-http-pub`
- **Domain:** `d-bis.org`
- **Service:** `https://192.168.11.251:443`
- **Type:** HTTP
- Click **Save hostname**
2. **rpc-ws-pub.d-bis.org**
- **Subdomain:** `rpc-ws-pub`
- **Domain:** `d-bis.org`
- **Service:** `https://192.168.11.251:443`
- **Type:** HTTP
- **WebSocket:** Enable (if available)
- Click **Save hostname**
3. **rpc-http-prv.d-bis.org**
- **Subdomain:** `rpc-http-prv`
- **Domain:** `d-bis.org`
- **Service:** `https://192.168.11.252:443`
- **Type:** HTTP
- Click **Save hostname**
4. **rpc-ws-prv.d-bis.org**
- **Subdomain:** `rpc-ws-prv`
- **Domain:** `d-bis.org`
- **Service:** `https://192.168.11.252:443`
- **Type:** HTTP
- **WebSocket:** Enable (if available)
- Click **Save hostname**
---
## Step 4: Configure DNS Records
### 4.1 Update DNS Records to Use Tunnel
**Change from A records to CNAME records pointing to tunnel:**
In Cloudflare DNS Dashboard:
1. **Delete existing A records** (if any):
- `rpc-http-pub.d-bis.org` → A → 192.168.11.251
- `rpc-ws-pub.d-bis.org` → A → 192.168.11.251
- `rpc-http-prv.d-bis.org` → A → 192.168.11.252
- `rpc-ws-prv.d-bis.org` → A → 192.168.11.252
2. **Create CNAME records:**
| Type | Name | Target | Proxy | TTL |
|------|------|--------|-------|-----|
| CNAME | `rpc-http-pub` | `<tunnel-id>.cfargotunnel.com` | 🟠 Proxied | Auto |
| CNAME | `rpc-ws-pub` | `<tunnel-id>.cfargotunnel.com` | 🟠 Proxied | Auto |
| CNAME | `rpc-http-prv` | `<tunnel-id>.cfargotunnel.com` | 🟠 Proxied | Auto |
| CNAME | `rpc-ws-prv` | `<tunnel-id>.cfargotunnel.com` | 🟠 Proxied | Auto |
**Where `<tunnel-id>` is your tunnel ID (e.g., `abc123def456`).**
**Example:**
```
Type: CNAME
Name: rpc-http-pub
Target: abc123def456.cfargotunnel.com
Proxy: 🟠 Proxied (orange cloud)
TTL: Auto
```
**Important:**
-**Proxy must be enabled** (orange cloud) for tunnel to work
- ✅ Use CNAME records (not A records) when using tunnels
- ✅ Target format: `<tunnel-id>.cfargotunnel.com`
---
## Step 5: Update Nginx Configuration (Optional)
### 5.1 Option A: Keep HTTPS (Recommended)
Nginx continues to use HTTPS. The tunnel will:
- Terminate SSL at Cloudflare edge
- Forward HTTPS to Nginx
- Nginx handles SSL again (double SSL - acceptable but not optimal)
### 5.2 Option B: Use HTTP from Tunnel (More Efficient)
If you want to avoid double SSL, configure Nginx to accept HTTP from the tunnel:
**Update Nginx config on each container:**
```bash
# On VMID 2501 and 2502
ssh root@192.168.11.10 "pct exec 2501 -- bash" <<'EOF'
# Add HTTP server block for tunnel traffic
cat >> /etc/nginx/sites-available/rpc <<'NGINX_HTTP'
# HTTP server for Cloudflare Tunnel (no SSL needed)
server {
listen 80;
listen [::]:80;
server_name rpc-http-pub.d-bis.org rpc-ws-pub.d-bis.org;
# Trust Cloudflare IPs
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 104.16.0.0/13;
set_real_ip_from 104.24.0.0/14;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 131.0.72.0/22;
real_ip_header CF-Connecting-IP;
access_log /var/log/nginx/rpc-tunnel-access.log;
error_log /var/log/nginx/rpc-tunnel-error.log;
# HTTP RPC endpoint
location / {
if ($host = rpc-http-pub.d-bis.org) {
proxy_pass http://127.0.0.1:8545;
}
if ($host = rpc-ws-pub.d-bis.org) {
proxy_pass http://127.0.0.1:8546;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
}
}
NGINX_HTTP
nginx -t && systemctl reload nginx
EOF
```
**Then update tunnel config to use HTTP:**
```yaml
ingress:
- hostname: rpc-http-pub.d-bis.org
service: http://192.168.11.251:80 # Changed from https://443
```
**Recommendation:** Keep HTTPS (Option A) for simplicity and security.
---
## Step 6: Verify Configuration
### 6.1 Check Tunnel Status
```bash
# Check cloudflared service
ssh root@192.168.11.10 "pct exec 102 -- systemctl status cloudflared"
# View tunnel logs
ssh root@192.168.11.10 "pct exec 102 -- journalctl -u cloudflared -f"
```
**In Cloudflare Dashboard:**
- Go to Zero Trust → Networks → Tunnels
- Tunnel status should show "Healthy" (green)
### 6.2 Test DNS Resolution
```bash
# Test DNS resolution
dig rpc-http-pub.d-bis.org
nslookup rpc-http-pub.d-bis.org
# Should resolve to Cloudflare IPs (if proxied)
```
### 6.3 Test Endpoints
```bash
# Test HTTP RPC endpoint
curl https://rpc-http-pub.d-bis.org/health
curl -X POST https://rpc-http-pub.d-bis.org \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
# Test WebSocket RPC endpoint
wscat -c wss://rpc-ws-pub.d-bis.org
```
---
## Benefits of Using Cloudflare Tunnel
1. **🔒 Security:**
- Origin IPs hidden from public
- No need to expose ports on firewall
- DDoS protection at Cloudflare edge
2. **⚡ Performance:**
- Global CDN (though RPC responses shouldn't be cached)
- Reduced latency for global users
- Automatic SSL/TLS at edge
3. **🛡️ DDoS Protection:**
- Cloudflare automatically mitigates attacks
- Rate limiting available
- Bot protection
4. **📊 Analytics:**
- Traffic analytics in Cloudflare dashboard
- Request logs
- Security events
5. **🔧 Management:**
- Centralized tunnel management
- Easy to add/remove routes
- No firewall changes needed
---
## Troubleshooting
### Tunnel Not Connecting
**Symptoms:** Tunnel shows "Unhealthy" in dashboard
**Solutions:**
```bash
# Check cloudflared service
pct exec 102 -- systemctl status cloudflared
# View logs
pct exec 102 -- journalctl -u cloudflared -n 50
# Verify credentials
pct exec 102 -- cat /etc/cloudflared/credentials.json
# Test tunnel connection
pct exec 102 -- cloudflared tunnel info
```
### DNS Not Resolving
**Symptoms:** Domain doesn't resolve or resolves incorrectly
**Solutions:**
1. Verify DNS record type is CNAME (not A)
2. Verify proxy is enabled (orange cloud)
3. Verify target is correct: `<tunnel-id>.cfargotunnel.com`
4. Wait for DNS propagation (up to 5 minutes)
### Connection Timeout
**Symptoms:** DNS resolves but connection times out
**Solutions:**
```bash
# Check if Nginx is running
pct exec 2501 -- systemctl status nginx
# Check if port 443 is listening
pct exec 2501 -- ss -tuln | grep 443
# Test direct connection (bypassing tunnel)
curl -k https://192.168.11.251/health
# Check tunnel config
pct exec 102 -- cat /etc/cloudflared/config.yml
```
### SSL Certificate Errors
**Symptoms:** SSL certificate warnings
**Solutions:**
1. If using self-signed certs, clients will see warnings (expected)
2. Consider using Let's Encrypt certificates
3. Or rely on Cloudflare SSL (terminate at edge, use HTTP internally)
---
## Architecture Summary
### Request Flow with Tunnel
1. **Client**`https://rpc-http-pub.d-bis.org`
2. **DNS** → Resolves to Cloudflare IPs (via CNAME to tunnel)
3. **Cloudflare Edge** → SSL termination, DDoS protection
4. **Cloudflare Tunnel** → Encrypted connection to cloudflared
5. **cloudflared (VMID 102)** → Forwards to `https://192.168.11.251:443`
6. **Nginx (VMID 2501)** → Receives HTTPS, routes to `127.0.0.1:8545`
7. **Besu RPC** → Processes request, returns response
8. **Response** → Reverse path back to client
---
## Quick Reference
**Tunnel Configuration:**
```yaml
ingress:
- hostname: rpc-http-pub.d-bis.org
service: https://192.168.11.251:443
- hostname: rpc-ws-pub.d-bis.org
service: https://192.168.11.251:443
- hostname: rpc-http-prv.d-bis.org
service: https://192.168.11.252:443
- hostname: rpc-ws-prv.d-bis.org
service: https://192.168.11.252:443
- service: http_status:404
```
**DNS Records:**
```
rpc-http-pub.d-bis.org → CNAME → <tunnel-id>.cfargotunnel.com (🟠 Proxied)
rpc-ws-pub.d-bis.org → CNAME → <tunnel-id>.cfargotunnel.com (🟠 Proxied)
rpc-http-prv.d-bis.org → CNAME → <tunnel-id>.cfargotunnel.com (🟠 Proxied)
rpc-ws-prv.d-bis.org → CNAME → <tunnel-id>.cfargotunnel.com (🟠 Proxied)
```
---
## Related Documentation
- [RPC_DNS_CONFIGURATION.md](../RPC_DNS_CONFIGURATION.md) - Direct DNS configuration
- [CLOUDFLARE_DNS_TO_CONTAINERS.md](CLOUDFLARE_DNS_TO_CONTAINERS.md) - General tunnel setup
- [CLOUDFLARE_NGINX_INTEGRATION.md](../../05-network/CLOUDFLARE_NGINX_INTEGRATION.md) - Nginx integration