Skip to content

Cloudflare Tunnel (External Access)

Cloudflare Tunnel (cloudflared) enables secure external access to internal services without opening ports on the router.


1. Security Model

Access is governed by the following flow:

  1. Request: Request for subdomain.domain.com reaches Cloudflare Edge.
  2. Tunnel: Traffic is routed through an encrypted tunnel to the local cloudflared instance.
  3. Local Forward: cloudflared forwards the request to the internal Nginx Proxy Manager.
  4. Service: NPM routes traffic to the target application.

2. Installation on Proxmox

Standard Debian 12 LXC is used for the tunnel client.

A. Repository Setup

# Download and install GPG key
sudo mkdir -p --mode=0755 /usr/share/keyrings
curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null

# Add repository
echo 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudfare-main.gpg stable main' | sudo tee /etc/apt/sources.list.d/cloudflare-client.list

# Install agent
sudo apt update && sudo apt install cloudflared

3. Tunnel Configuration

A. Authentication

Execute the login command and follow the generated link to authorize the tunnel:

cloudflared tunnel login

B. Tunnel Creation

Create a new tunnel and note the assigned ID:

cloudflared tunnel create <TUNNEL_NAME>

C. Configuration File

Create /root/.cloudflared/config.yml:

tunnel: <TUNNEL_ID>
credentials-file: /root/.cloudflared/<TUNNEL_ID>.json

ingress:
  - hostname: "*.domain.com"
    service: http://<NPM_IP>:80
  - service: http_status:404

4. Execution as Service

Configure cloudflared to run on system startup:

cloudflared service install
systemctl start cloudflared
systemctl enable cloudflared

5. DNS Routing

Map the subdomain to the tunnel via the Cloudflare Dashboard (DNS Settings):

  • Type: CNAME
  • Name: subdomain (or @ for root)
  • Target: <TUNNEL_ID>.cfargotunnel.com
  • Proxy Status: Proxied (Orange Cloud)

6. Nginx Proxy Manager Setup

Traffic reaching Nginx from the tunnel is routed as follows:

  1. Access NPM Web UI (http://<NPM_IP>:81).
  2. Add a Proxy Host.
  3. Set Domain Names to match the Cloudflare hostname (e.g., service.domain.com).
  4. Set Forward Hostname/IP to the internal service IP.
  5. Set Forward Port to the application port.
  6. Enable Block Common Exploits.