Proxmox server with a slick Cloudflare Tunnel using Zero Trust & TLS

Kunal YadavaaKunal Yadavaa
5 min read

Here's my step-by-step guide to get your Proxmox GUI accessible securely via your domain!


🛠️ Step-by-Step Guide: Proxmox + Cloudflare Tunnels with Zero Trust & TLS

What You’ll Need:

  • A Proxmox VE server (I’m on v8.2, but this works for most versions)

  • A Cloudflare account with a domain added

  • A sprinkle of patience and a cup of coffee ☕


Step 1: Prep Your Cloudflare Account

  • Log into your Cloudflare dashboard at cloudflare.com.

  • Add your domain (e.g., yourdomain.com) and switch its nameservers to Cloudflare’s. Wait for DNS propagation (usually quick, but grab that coffee just in case ☕).

  • Head to the Zero Trust section (find it in the sidebar or via dash.teams.cloudflare.com).

Pro Tip: You’ll need to pick a Zero Trust plan. The free tier works for this setup, but Cloudflare might ask for payment info. Don’t worry, no charges for the free plan


OR Step 2: Install cloudflared on Your Proxmox Server

  • SSH into your Proxmox server (e.g., ssh root@your-proxmox-ip).

  • Download and install the cloudflared daemon:

      wget -q https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
      dpkg -i cloudflared-linux-amd64.deb
    
  • Verify the installation:

      cloudflared --version
    

    You should see the version number. If not, double-check the download


Step 3: Authenticate cloudflared

  • Run the login command:

      cloudflared tunnel login
    
  • This spits out a URL. Copy it, paste it into your browser, and log into your Cloudflare account. Select your domain to generate a cert file (saved to /root/.cloudflared/cert.pem).

Fun Fact: This cert is your tunnel’s VIP pass to Cloudflare’s network! 🎟️


Step 4: Create Your Tunnel

  • In the Cloudflare Zero Trust dashboard, go to Access > Tunnels and click Create a Tunnel.

  • Name your tunnel (e.g., proxmox-tunnel) and click Save Tunnel.

  • Choose Debian (64-bit) for the connector installer. Copy the provided command (it’ll look like cloudflared service install <your-token>).

  • Back in your Proxmox SSH session, run the copied command to install the tunnel connector:

      cloudflared service install <your-token>
    
  • This starts the cloudflared daemon. Check its status:

      systemctl status cloudflared
    

    If it’s active, you’re golden! 🌟


Step 5: Configure the Tunnel for Proxmox

  • Create a config file at /root/.cloudflared/config.yml:

      nano /root/.cloudflared/config.yml
    
  • Add the following, replacing <UUID> with your tunnel’s UUID (find it in the Zero Trust dashboard) and <yourdomain.com> with your domain:

      tunnel: <UUID>
      credentials-file: /root/.cloudflared/<UUID>.json
      ingress:
        - hostname: proxmox.<yourdomain.com>
          service: https://localhost:8006
          originRequest:
            disableChunkedEncoding: true
            noTLSVerify: true
        - service: http_status:404
    
  • Save and exit (Ctrl+O, Enter, Ctrl+X).

  • Why disableChunkedEncoding and noTLSVerify? Proxmox’s web GUI uses chunked encoding, which Cloudflare Tunnels don’t love, and its self-signed cert needs bypassing for TLS.


Step 6: Set Up Public Hostname

  • In the Zero Trust dashboard, go to your tunnel (proxmox-tunnel) and click Configure > Public Hostname.

  • Add a new hostname:

    • Subdomain: proxmox

    • Domain: yourdomain.com

    • Type: HTTPS

    • URL: https://localhost:8006

  • Under Additional Application Settings > TLS, enable:

    • No TLS Verify: true (for Proxmox’s self-signed cert)

    • Disable Chunked Encoding: true

  • Save the hostname. Cloudflare auto-creates a CNAME record in your DNS settings. Check it in DNS > Records (should be proxmox.yourdomain.com pointing to <UUID>.cfargotunnel.com).


Step 7: Start the Tunnel

  • Run the tunnel:

      cloudflared tunnel run <UUID>
    
  • Or, if you set up the service, ensure it’s running:

      systemctl start cloudflared
      systemctl enable cloudflared
    
  • Test by visiting https://proxmox.yourdomain.com. You should see the Proxmox login page! 🎉


Step 8: Secure with Zero Trust (Optional but Awesome)

  • In Zero Trust, go to Access > Applications and click Add an Application.

  • Select Self-hosted, name it (e.g., Proxmox Access), and set the Application domain to proxmox.yourdomain.com.

  • Under Identity Providers, pick One-time PIN or your preferred method (e.g., Google, GitHub).

  • Set a policy to allow specific users (e.g., by email). Save it!

  • Now, accessing proxmox.yourdomain.com requires authentication. Super secure! 🔒


Step 9: Fix SPICE (Optional for VM Console Access)

  • Proxmox’s SPICE console uses port 3128, which Cloudflare doesn’t proxy by default. To fix:

    • Edit these files to change the SPICE port to 8880 (a Cloudflare-supported port):

        nano /usr/share/perl5/PVE/HTTPServer.pm
      

      Change my $remport = $remip ? 3128 : $spiceport; to my $remport = $remip ? 8880 : $spiceport;

        nano /usr/share/perl5/PVE/AccessControl.pm
      

      Change proxy => "http://$proxy:3128", to proxy => "http://$proxy:8880",

        nano /usr/share/perl5/PVE/Service/spiceproxy.pm
      

      Change my $socket = $self->create_reusable_socket(3128, undef, $family); to my $socket = $self->create_reusable_socket(8880, undef, $family);
      Change SPICE proxy server for Proxmox VE. Listens on port 3128. to SPICE proxy server for Proxmox VE. Listens on port 8880.

        nano /usr/share/perl5/PVE/API2Tools.pm
      

      Change my $port = $uri->port || 3128; to my $port = $uri->port || 8880;

    • Add a new public hostname in the Zero Trust dashboard for SPICE:

      • Subdomain: spice.proxmox.<yourdomain.com>

      • Type: HTTPS

      • URL: https://localhost:8880

      • No TLS Verify: true

    • Restart Proxmox services:

        systemctl restart pveproxy
      
  • Note: SPICE’s initial connection is plaintext, so set a Cloudflare Access rule to bypass for your home IP.


Step 10: Test & Celebrate!

  • Open https://proxmox.yourdomain.com and log in.

  • Try the SPICE console via spice.proxmox.yourdomain.com (if configured).

  • Everything works? You’re a homelab hero! 🦸‍♂️ Share your setup on X with #CloudflareTunnels!


Troubleshooting Tips:

  • Error 1033? Check if cloudflared is running (systemctl status cloudflared) and verify your tunnel UUID.

  • Can’t access VMs? Ensure disableChunkedEncoding and noTLSVerify are set in config.yml.

  • SPICE issues? Double-check port changes and Access rules.


0
Subscribe to my newsletter

Read articles from Kunal Yadavaa directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Kunal Yadavaa
Kunal Yadavaa

"Sudo-ing my way through clouds and containers."