# Cloudflare Zero Trust Integration Guide

**Last Updated:** 2025-01-20  
**Document Version:** 1.0  
**Service:** Cloudflare Zero Trust + cloudflared

---

## Overview

This guide provides step-by-step configuration for Cloudflare Zero Trust integration, including:

- cloudflared tunnel setup (redundant)
- Application publishing via Cloudflare Access
- Security policies and access control
- Monitoring and troubleshooting

---

## Architecture

### cloudflared Gateway Pattern

Run **2 cloudflared LXCs** for redundancy:

- **cloudflared-1** on ML110 (192.168.11.10)
- **cloudflared-2** on an R630 (production compute)

Both run tunnels for:
- Blockscout (VLAN 120)
- FireFly (VLAN 141)
- Gitea (if deployed)
- Internal admin dashboards (Grafana) behind Cloudflare Access

---

## Prerequisites

1. **Cloudflare Account:**
   - Cloudflare account with Zero Trust enabled
   - Zero Trust subscription (free tier available)

2. **Domain:**
   - Domain managed by Cloudflare
   - DNS records can be managed via Cloudflare

3. **Access:**
   - Admin access to Cloudflare Zero Trust dashboard
   - SSH access to Proxmox hosts

---

## Step 1: Cloudflare Zero Trust Setup

### 1.1 Enable Zero Trust

1. **Access Cloudflare Dashboard:**
   - Navigate to: https://one.dash.cloudflare.com
   - Sign in with Cloudflare account

2. **Enable Zero Trust:**
   - Go to **Zero Trust** → **Overview**
   - Follow setup wizard if first time
   - Note your **Team Name** (e.g., `yourteam.cloudflareaccess.com`)

### 1.2 Create Tunnel

1. **Navigate to Tunnels:**
   - Go to **Zero Trust** → **Networks** → **Tunnels**
   - Click **Create a tunnel**

2. **Choose Tunnel Type:**
   - Select **Cloudflared**
   - Name: `proxmox-primary` (for cloudflared-1)
   - Click **Save tunnel**

3. **Install cloudflared:**
   - Follow instructions to install cloudflared on ML110
   - Copy the tunnel token (keep secure)

4. **Repeat for Second Tunnel:**
   - Create `proxmox-secondary` (for cloudflared-2)
   - Install cloudflared on R630
   - Copy the tunnel token

---

## Step 2: Deploy cloudflared LXCs

### 2.1 Create cloudflared-1 LXC (ML110)

**VMID:** (assign from available range, e.g., 8000)

**Configuration:**
```bash
pct create 8000 local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst \
  --hostname cloudflared-1 \
  --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:**
```bash
pct start 8000
```

**Install cloudflared:**
```bash
pct exec 8000 -- bash -c "
  wget -q https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
  dpkg -i cloudflared-linux-amd64.deb
  cloudflared --version
"
```

**Configure Tunnel:**
```bash
pct exec 8000 -- cloudflared service install <TUNNEL_TOKEN_FROM_STEP_1>
pct exec 8000 -- systemctl enable cloudflared
pct exec 8000 -- systemctl start cloudflared
```

### 2.2 Create cloudflared-2 LXC (R630)

Repeat the same process on an R630 node, using:
- VMID: 8001
- Hostname: cloudflared-2
- IP: 192.168.11.81/24
- Tunnel: `proxmox-secondary`

---

## Step 3: Configure Applications

### 3.1 Blockscout (VLAN 120)

**In Cloudflare Zero Trust Dashboard:**

1. **Navigate to Applications:**
   - Go to **Zero Trust** → **Access** → **Applications**
   - Click **Add an application**

2. **Configure Application:**
   - **Application Name:** Blockscout
   - **Application Domain:** `blockscout.yourdomain.com`
   - **Session Duration:** 24 hours
   - **Policy:** Create policy (see below)

3. **Configure Public Hostname:**
   - Go to **Zero Trust** → **Networks** → **Tunnels**
   - Select your tunnel → **Configure**
   - Click **Public Hostname** → **Add a public hostname**
   - **Subdomain:** `blockscout`
   - **Domain:** `yourdomain.com`
   - **Service:** `http://10.120.0.10:4000` (Blockscout IP:port)

4. **Access Policy:**
   ```
   Rule Name: Blockscout Access
   Action: Allow
   Include:
     - Email domain: @yourdomain.com
     - OR Email: admin@yourdomain.com
   Require:
     - MFA (if enabled)
   ```

### 3.2 FireFly (VLAN 141)

**Repeat for FireFly:**
- **Application Name:** FireFly
- **Application Domain:** `firefly.yourdomain.com`
- **Public Hostname:** `firefly.yourdomain.com`
- **Service:** `http://10.141.0.10:5000` (FireFly IP:port)
- **Access Policy:** Similar to Blockscout

### 3.3 Grafana (Monitoring)

**If Grafana is deployed:**
- **Application Name:** Grafana
- **Application Domain:** `grafana.yourdomain.com`
- **Public Hostname:** `grafana.yourdomain.com`
- **Service:** `http://10.130.0.10:3000` (Grafana IP:port)
- **Access Policy:** Restrict to admin users only

### 3.4 Gitea (if deployed)

**If Gitea is deployed:**
- **Application Name:** Gitea
- **Application Domain:** `git.yourdomain.com`
- **Public Hostname:** `git.yourdomain.com`
- **Service:** `http://10.130.0.20:3000` (Gitea IP:port)
- **Access Policy:** Similar to Blockscout

---

## Step 4: Security Policies

### 4.1 Access Policies

**Create Policies for Each Application:**

1. **Admin-Only Access:**
   ```
   Rule Name: Admin Only
   Action: Allow
   Include:
     - Email: admin@yourdomain.com
     - OR Group: admins
   Require:
     - MFA
   ```

2. **Team Access:**
   ```
   Rule Name: Team Access
   Action: Allow
   Include:
     - Email domain: @yourdomain.com
   Require:
     - MFA (optional)
   ```

3. **Device Posture (Optional):**
   ```
   Rule Name: Secure Device Only
   Action: Allow
   Include:
     - Email domain: @yourdomain.com
   Require:
     - Device posture: Secure (certificate installed)
   ```

### 4.2 WARP Client (Optional)

**For Enhanced Security:**

1. **Deploy WARP Client:**
   - Download WARP client for user devices
   - Configure with Zero Trust team name
   - Users connect via WARP for secure access

2. **Device Posture Checks:**
   - Enable device posture checks
   - Require certificates for access
   - Enforce security policies

---

## Step 5: DNS Configuration

### 5.1 Create DNS Records

**In Cloudflare DNS Dashboard:**

1. **Blockscout:**
   - Type: CNAME
   - Name: `blockscout`
   - Target: `proxmox-primary.yourteam.cloudflareaccess.com`
   - Proxy: Enabled (orange cloud)

2. **FireFly:**
   - Type: CNAME
   - Name: `firefly`
   - Target: `proxmox-primary.yourteam.cloudflareaccess.com`
   - Proxy: Enabled

3. **Grafana:**
   - Type: CNAME
   - Name: `grafana`
   - Target: `proxmox-primary.yourteam.cloudflareaccess.com`
   - Proxy: Enabled

---

## Step 6: Monitoring & Health Checks

### 6.1 Tunnel Health

**Check Tunnel Status:**
```bash
# On cloudflared-1 (ML110)
pct exec 8000 -- systemctl status cloudflared

# Check logs
pct exec 8000 -- journalctl -u cloudflared -f
```

**In Cloudflare Dashboard:**
- Go to **Zero Trust** → **Networks** → **Tunnels**
- Check tunnel status (should be "Healthy")

### 6.2 Application Health

**Test Access:**
1. Navigate to `https://blockscout.yourdomain.com`
2. Should redirect to Cloudflare Access login
3. After authentication, should access Blockscout

**Monitor Logs:**
- Cloudflare Zero Trust → **Analytics** → **Access Logs**
- Check for authentication failures
- Monitor access patterns

---

## Step 7: Proxmox UI Access (Optional)

### 7.1 Publish Proxmox via Cloudflare Access

**Important:** Proxmox UI should remain LAN-only by default. Only publish if absolutely necessary.

**If Publishing:**

1. **Create Application:**
   - **Application Name:** Proxmox
   - **Application Domain:** `proxmox.yourdomain.com`
   - **Public Hostname:** `proxmox.yourdomain.com`
   - **Service:** `https://192.168.11.10:8006` (Proxmox IP:port)

2. **Strict Access Policy:**
   ```
   Rule Name: Proxmox Admin Only
   Action: Allow
   Include:
     - Email: admin@yourdomain.com
   Require:
     - MFA
     - Device posture: Secure
   ```

3. **Security Considerations:**
   - Use IP allowlist in addition to Cloudflare Access
   - Enable audit logging
   - Monitor access logs closely
   - Consider VPN instead of public access

---

## Troubleshooting

### Common Issues

#### Tunnel Not Connecting

**Symptoms:** Tunnel shows as "Unhealthy" in dashboard

**Solutions:**
1. Check cloudflared service status: `systemctl status cloudflared`
2. Verify tunnel token is correct
3. Check network connectivity
4. Review cloudflared logs: `journalctl -u cloudflared -f`

#### Application Not Accessible

**Symptoms:** Can authenticate but application doesn't load

**Solutions:**
1. Verify service IP:port is correct
2. Check firewall rules allow traffic from cloudflared
3. Verify application is running
4. Check tunnel configuration in dashboard

#### Authentication Failures

**Symptoms:** Users can't authenticate

**Solutions:**
1. Check access policies are configured correctly
2. Verify user emails match policy
3. Check MFA requirements
4. Review access logs in dashboard

---

## Best Practices

1. **Redundancy:** Always run 2+ cloudflared instances
2. **Security:** Use MFA for all applications
3. **Monitoring:** Monitor tunnel health and access logs
4. **Updates:** Keep cloudflared updated
5. **Backup:** Backup tunnel configurations
6. **Documentation:** Document all published applications

---

## References

- **[NETWORK_ARCHITECTURE.md](NETWORK_ARCHITECTURE.md)** - Network architecture
- **[ORCHESTRATION_DEPLOYMENT_GUIDE.md](ORCHESTRATION_DEPLOYMENT_GUIDE.md)** - Deployment guide
- [Cloudflare Zero Trust Documentation](https://developers.cloudflare.com/cloudflare-one/)
- [cloudflared Documentation](https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/)

---

**Document Status:** Complete (v1.0)  
**Maintained By:** Infrastructure Team  
**Review Cycle:** Quarterly  
**Last Updated:** 2025-01-20

