Secure Remote Access to Your Raspberry Pi in 2025 (Updated Cloudflare Tunnel Guide)
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:
- Log in to your Cloudflare account (if not already logged in)
- Select the domain you want to use for this tunnel
- 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 (oftenpi)1a2b3c4d-5e6f-7g8h-9i0j-k1l2m3n4o5p6with your actual Tunnel IDssh.yourdomain.comwith your actual hostname
What this configuration does:
- Routes traffic from
ssh.yourdomain.comto 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
- Log in to the Cloudflare Dashboard
- Navigate to Zero Trust (in the left sidebar)
- Go to Access → Applications
- Click Add an application
- 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
- Subdomain:
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:
- Selector:
Emails - Value: Your email address (e.g.,
[email protected])
- Selector:
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:
- Scroll down to Advanced settings
- Find Enable automatic cloudflared authentication
- Toggle it ON
- 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
- In the Cloudflare dashboard, go to Zero Trust → Access → Service Auth
- Click on the SSH tab
- Click Generate certificate
- Copy the public key that appears (it starts with
ssh-rsaor 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:
-
Find the line
#PubkeyAuthentication yesand ensure it's uncommented (remove the#):PubkeyAuthentication yes -
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 bejohn.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:
piwith 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:
- Your browser will open automatically
- You'll be prompted to log in with your Cloudflare account
- After authenticating, a short-lived certificate is issued
- 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: