Skip to main content

Secure Remote Access to Your Raspberry Pi in 2025 (Updated Cloudflare Tunnel Guide)

mhrsntrk

mhrsntrk / November 12, 2025

If you've been following along with my original guide on accessing your Raspberry Pi remotely using Cloudflare, first of all thank you! That post has helped thousands of people set up secure remote access to their devices. However, Cloudflare has made significant improvements to their tunnel infrastructure, and the setup process has evolved considerably since I first published that guide.

I'm writing this updated version to ensure you have the most current, secure, and streamlined instructions for 2025. Whether you're setting up a tunnel for the first time or updating an existing configuration, this guide will walk you through everything step-by-step.

Why This Update Matters

Since my original post, several important changes have occurred:

  • Simplified installation process: The repository setup now uses a universal "any" distribution approach rather than version-specific repositories.
  • Improved tunnel management: Cloudflare has streamlined the dashboard experience in Zero Trust, making tunnel creation more intuitive.
  • Enhanced SSH security: Short-lived certificates now replace traditional SSH keys more elegantly, with better integration into the Access for Infrastructure features.
  • Better systemd integration: The service installation process is more robust and reliable.

Why Choose Cloudflare Tunnel Over Traditional Methods?

Before we dive in, let's revisit why Cloudflare Tunnel remains the best choice for secure remote access:

  • No port forwarding: Unlike traditional methods that expose your device directly to the internet, Cloudflare creates an encrypted tunnel that keeps your Raspberry Pi hidden behind Cloudflare's network.
  • Zero Trust security: Every connection is authenticated and verified, reducing the risk of unauthorized access.
  • No public IP needed: Works perfectly behind NAT, CGNAT, or dynamic IPs—no need for DDNS services.
  • Built-in DDoS protection: Cloudflare's network protects your device from attacks.
  • Browser-based access: Optionally access your Pi through a web browser without any client software.

Prerequisites

Before starting, make sure you have:

  • A Raspberry Pi with Raspberry Pi OS (or any Debian-based distribution) installed and updated
  • A Cloudflare account (free tier works perfectly)
  • A domain name registered and managed through Cloudflare
  • Basic command-line knowledge
  • SSH access to your Raspberry Pi (at least initially)

Part 1: Installing cloudflared on Raspberry Pi

Step 1: Update Your System

Always start with a clean, updated system to avoid compatibility issues.

sudo apt update
sudo apt upgrade -y

Step 2: Install Required Prerequisites

Install the necessary packages for adding the Cloudflare repository:

sudo apt install curl lsb-release -y

Step 3: Add Cloudflare's GPG Key

Create the keyrings directory and add Cloudflare's package signing 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

This ensures that packages from Cloudflare are verified and authentic.

Step 4: Add the Cloudflare Repository

Note: This is one of the key changes from my original guide. The repository now uses any instead of the specific distribution codename:

echo "deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared any main" | sudo tee /etc/apt/sources.list.d/cloudflared.list

This universal approach means the same command works across different Debian-based distributions and versions.

Step 5: Update Package Cache and Install cloudflared

sudo apt update
sudo apt install cloudflared -y

Step 6: Verify Installation

Check that cloudflared is installed correctly:

cloudflared --version

You should see the version number displayed.

Part 2: Creating and Configuring Your Cloudflare Tunnel

Step 7: Authenticate with Cloudflare

Start the authentication process:

cloudflared tunnel login

You'll see output similar to this:

Please open the following URL and log in with your Cloudflare account:

https://dash.cloudflare.com/argotunnel?aud=...

Leave cloudflared running to download the cert automatically.

Important: Keep the terminal window open while you complete the next step.

Step 8: Authorize in Your Browser

Copy the URL from your terminal and paste it into your web browser. You'll be prompted to:

  1. Log in to your Cloudflare account (if not already logged in)
  2. Select the domain you want to use for this tunnel
  3. Click "Authorize"

Once authorized, you'll see a success message in your browser, and the terminal will confirm:

You have successfully logged in.
If you wish to copy your credentials to a server, they have been saved to:
/home/{YOUR_USERNAME}/.cloudflared/cert.pem

Step 9: Create a Named Tunnel

Now create your tunnel with a meaningful name (I'll use raspi-tunnel in this example):

cloudflared tunnel create raspi-tunnel

You'll receive important output that includes your Tunnel ID:

Tunnel credentials written to /home/{YOUR_USERNAME}/.cloudflared/1a2b3c4d-5e6f-7g8h-9i0j-k1l2m3n4o5p6.json. 
cloudflared chose this file based on where your origin certificate was found. 
Keep this file secret. To revoke these credentials, delete the tunnel.

Created tunnel raspi-tunnel with id 1a2b3c4d-5e6f-7g8h-9i0j-k1l2m3n4o5p6

Important: Copy and save your Tunnel ID—you'll need it in the configuration file.

Step 10: Route DNS Through the Tunnel

Create a DNS record that routes traffic through your tunnel:

cloudflared tunnel route dns raspi-tunnel ssh.yourdomain.com

Replace ssh.yourdomain.com with your actual subdomain and domain. Upon success, you'll see:

Added CNAME ssh.yourdomain.com which will route to this tunnel tunnelID=1a2b3c4d-5e6f-7g8h-9i0j-k1l2m3n4o5p6

This automatically creates a CNAME record in your Cloudflare DNS settings.

Step 11: Create the Configuration File

Create a configuration file to define how your tunnel operates:

sudo nano ~/.cloudflared/config.yml

Important Update: The configuration format remains similar, but make sure you use the exact tunnel ID from Step 9:

tunnel: raspi-tunnel
credentials-file: /home/{YOUR_USERNAME}/.cloudflared/1a2b3c4d-5e6f-7g8h-9i0j-k1l2m3n4o5p6.json

ingress:
  - hostname: ssh.yourdomain.com
    service: ssh://localhost:22
  - service: http_status:404

Replace:

  • {YOUR_USERNAME} with your actual username (often pi)
  • 1a2b3c4d-5e6f-7g8h-9i0j-k1l2m3n4o5p6 with your actual Tunnel ID
  • ssh.yourdomain.com with your actual hostname

What this configuration does:

  • Routes traffic from ssh.yourdomain.com to SSH on port 22
  • Returns a 404 error for any unmatched traffic (security best practice)

Save the file with Ctrl+X, then Y, then Enter.

Step 12: Validate Your Configuration

Before installing the service, validate your configuration file:

cloudflared tunnel ingress validate

If everything is correct, you'll see a confirmation. If there are errors, carefully check your YAML syntax (spacing matters!).

Step 13: Install cloudflared as a System Service

Install the tunnel as a systemd service so it starts automatically:

sudo cloudflared --config /home/{YOUR_USERNAME}/.cloudflared/config.yml service install

Replace {YOUR_USERNAME} with your actual username.

Step 14: Enable and Start the Service

Enable the service to start on boot:

sudo systemctl enable cloudflared

Start the service now:

sudo systemctl start cloudflared

Step 15: Verify the Service is Running

Check the status:

sudo systemctl status cloudflared

You should see active (running) in the output. If you see any errors, check:

  • Your configuration file syntax
  • That the Tunnel ID matches your credentials file
  • That the credentials file path is correct

Part 3: Setting Up Cloudflare Zero Trust for SSH Access

Step 16: Create a Zero Trust Application

  1. Log in to the Cloudflare Dashboard
  2. Navigate to Zero Trust (in the left sidebar)
  3. Go to AccessApplications
  4. Click Add an application
  5. Select Self-hosted

Step 17: Configure Application Details

Fill in the application settings:

  • Application name: Raspberry Pi SSH (or any name you prefer)
  • Session duration: Choose based on your security preference (e.g., 24 hours)
  • Application domain:
    • Subdomain: ssh (or whatever you chose earlier)
    • Domain: yourdomain.com

Click Next.

Step 18: Create an Access Policy

Now define who can access your Raspberry Pi:

  • Policy name: Allow My Email (or any descriptive name)
  • Action: Allow
  • Session duration: Match your application setting
  • Configure rules:

You can add multiple emails or use other criteria like IP ranges, countries, or identity providers.

Click Next.

Step 19: Enable SSH Authentication

On the additional settings page:

  1. Scroll down to Advanced settings
  2. Find Enable automatic cloudflared authentication
  3. Toggle it ON
  4. Select SSH from the dropdown

Click Add application to save.

Part 4: Configuring SSH Short-Lived Certificates

This section replaces traditional SSH keys with ephemeral certificates for enhanced security.

Step 20: Generate the SSH Certificate Authority

  1. In the Cloudflare dashboard, go to Zero TrustAccessService Auth
  2. Click on the SSH tab
  3. Click Generate certificate
  4. Copy the public key that appears (it starts with ssh-rsa or similar)

Step 21: Add the Certificate Authority to Your Raspberry Pi

Create the CA public key file on your Raspberry Pi:

sudo nano /etc/ssh/ca.pub

Paste the public key you copied from the Cloudflare dashboard, then save the file (Ctrl+X, Y, Enter).

Step 22: Configure SSH to Trust the Certificate Authority

Open the SSH daemon configuration file:

sudo nano /etc/ssh/sshd_config

Make the following changes:

  1. Find the line #PubkeyAuthentication yes and ensure it's uncommented (remove the #):

    PubkeyAuthentication yes
    
  2. Add this line at the end of the file:

    TrustedUserCAKeys /etc/ssh/ca.pub
    

Step 23: Handle Username Mapping (Critical Step!)

Important: The username in your SSH connection must match the email identity you use to authenticate. For example:

  • If your email is [email protected], your SSH username should be john.smith
  • If your Raspberry Pi username is different, you need to add a mapping

Add the following to /etc/ssh/sshd_config (adjust the username and email accordingly):

Match user pi
  AuthorizedPrincipalsCommand /bin/echo '[email protected]'
  AuthorizedPrincipalsCommandUser nobody

Replace:

  • pi with your actual Raspberry Pi username
  • [email protected] with the email you configured in the Access policy

This tells SSH to accept your email address as a valid principal for the pi user.

Step 24: Restart the SSH Service

Apply all the changes by restarting SSH:

sudo systemctl restart ssh

Verify SSH is still running:

sudo systemctl status ssh

Part 5: Configuring Your Client Computer

Step 25: Install cloudflared on Your Client

You'll need cloudflared on the computer you're connecting from as well.

For macOS (using Homebrew):

brew install cloudflare/cloudflare/cloudflared

For Windows: Download from Cloudflare's releases page

For Linux: Follow the same repository steps as on the Raspberry Pi (Steps 2-5).

Step 26: Generate SSH Configuration

On your client computer, run:

cloudflared access ssh-config --hostname ssh.yourdomain.com --short-lived-cert

Replace ssh.yourdomain.com with your actual hostname. You'll get output similar to:

Host ssh.yourdomain.com
  ProxyCommand /usr/local/bin/cloudflared access ssh --hostname %h
  IdentityFile ~/.cloudflared/ssh-cert.pub
  CertificateFile ~/.cloudflared/ssh-cert-cert.pub

Copy this entire output.

Step 27: Update Your SSH Config

Open or create your SSH config file:

nano ~/.ssh/config

Paste the configuration you copied. You can also customize it:

Host raspi
  Hostname ssh.yourdomain.com
  User pi
  ProxyCommand /usr/local/bin/cloudflared access ssh --hostname %h
  IdentityFile ~/.cloudflared/ssh-cert.pub
  CertificateFile ~/.cloudflared/ssh-cert-cert.pub

By adding Host raspi, you can now just type ssh raspi instead of the full hostname.

Save the file (Ctrl+X, Y, Enter).

Step 28: Test Your Connection!

Now for the moment of truth. Connect to your Raspberry Pi:

ssh [email protected]

Or if you set up the alias:

ssh raspi

What happens:

  1. Your browser will open automatically
  2. You'll be prompted to log in with your Cloudflare account
  3. After authenticating, a short-lived certificate is issued
  4. You'll be connected to your Raspberry Pi via SSH

The first time may take a few seconds while the certificate is generated. Subsequent connections within the session duration are faster.

Troubleshooting Common Issues

Tunnel Won't Start

  • Check the service logs: sudo journalctl -u cloudflared -f
  • Verify your config.yml syntax (YAML is whitespace-sensitive)
  • Ensure the Tunnel ID in config.yml matches the credentials file name

SSH Connection Refused

  • Verify the tunnel is running: sudo systemctl status cloudflared
  • Check that port 22 is open: sudo netstat -tlnp | grep :22
  • Ensure SSH service is running: sudo systemctl status ssh

Authentication Fails

  • Double-check the Access policy includes your email
  • Verify the CA public key is correctly pasted in /etc/ssh/ca.pub
  • Check the username mapping in sshd_config
  • Review Access logs in the Cloudflare dashboard

Browser Doesn't Open

  • Manually authenticate: cloudflared access login ssh.yourdomain.com
  • Check your SSH config path to cloudflared is correct
  • Try clearing browser cache and cookies for Cloudflare

Advanced: Adding Additional Services

You can route multiple services through the same tunnel. Edit ~/.cloudflared/config.yml:

tunnel: raspi-tunnel
credentials-file: /home/pi/.cloudflared/1a2b3c4d-5e6f-7g8h-9i0j-k1l2m3n4o5p6.json

ingress:
  - hostname: ssh.yourdomain.com
    service: ssh://localhost:22
  - hostname: web.yourdomain.com
    service: http://localhost:80
  - hostname: home.yourdomain.com
    service: http://localhost:8123
  - service: http_status:404

After editing, restart the service:

sudo systemctl restart cloudflared

Don't forget to route each new hostname:

cloudflared tunnel route dns raspi-tunnel web.yourdomain.com
cloudflared tunnel route dns raspi-tunnel home.yourdomain.com

Conclusion

Congratulations! You've successfully set up secure remote access to your Raspberry Pi using Cloudflare Tunnel with the latest 2025 configuration. This setup provides enterprise-grade security without the complexity or cost of traditional VPN solutions.

Your Raspberry Pi is now:

  • ✅ Accessible from anywhere in the world
  • ✅ Protected by Cloudflare's network and DDoS protection
  • ✅ Using ephemeral SSH certificates instead of long-lived keys
  • ✅ Hidden behind Zero Trust authentication
  • ✅ Running automatically on boot

Whether you're managing home automation, running personal projects, or accessing your lab environment, this secure tunnel ensures your connection is both convenient and safe. The beauty of this approach is that your Raspberry Pi never exposes any ports to the internet—all connections are outbound-only to Cloudflare's network.

If you found this guide helpful, feel free to share it with others who might benefit. And if you run into any issues not covered in the troubleshooting section, the Cloudflare Community Forums are an excellent resource.

Happy tinkering!


Related Resources: