Or: How I learned to forget port forwarding and love the cloud 🙂
Introduction
Dear radio amateurs! Tired of struggling with your router’s port forwarding settings? Annoyed by DynDNS services that give up at the most inopportune moment? Want to share your awesome OpenWebRX+ setup with the world without exposing your home network to the dark corners of the Internet?
Then grab your favorite drink (for me it’s the Braun tube, 73!), and let me show you how I set up a Cloudflare tunnel on my Raspberry Pi. It’s free, secure and best of all – no port forwarding required!
What you need:
- A Raspberry Pi with OpenWebRX+ (or another web service)
- A domain name registered with Cloudflare (free account works perfectly)
- SSH access to your Pi
- About 20 minutes time
- Patience (the same kind needed when waiting for better propagation conditions)
Why Cloudflare Tunnels?
Think of a Cloudflare Tunnel as a secure, encrypted “tube” between your Pi and Cloudflare’s servers. All traffic flows through this pipe, which means:
- ✅ No port forwarding – Your router remains tightly closed
- ✅ Free SSL/HTTPS – Automatic encryption for your site
- ✅ DDoS protection – Cloudflare protects you from attacks
- ✅ Static access – No more DynDNS headaches
- ✅ Multiple services – Different services on different subdomains
It’s like a permanent, secure QSO connection to your home station, only on the Internet!
Step 1: Install cloudflared
First we connect to the Raspberry Pi via SSH. Once you are logged in, we need to find out which architecture your Pi uses.
Check system architecture:
bash
uname -m
Most modern Pis display aarch64 (64-bit) or armv7l/armhf (32-bit).
For 32-bit ARM systems (armhf):
This is what I had to use. It requires downloading the binary directly, as the package repositories can be… let’s say “temperamental”.
bash
#Download ARM Binary
wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-arm
#Make executable
chmod +x cloudflared-linux-arm
# Move to system path
sudo mv cloudflared-linux-arm /usr/local/bin/cloudflared
# Check if it works
cloudflared --version
For 64-bit ARM systems (aarch64):
bash
# Download ARM64 Binary
wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-arm64
#Make executable
chmod +x cloudflared-linux-arm64
# Move to system path
sudo mv cloudflared-linux-arm64 /usr/local/bin/cloudflared
# Check if it works
cloudflared --version
You should see something like cloudflared version 2025.11.1 – the exact version doesn’t matter as long as it’s running!
Step 2: Authenticate with Cloudflare
Now comes the exciting part – logging into Cloudflare. Runs this command:
bash
cloudflared tunnel login
A long URL appears in the terminal. Since you’re connected via SSH, you can’t just click on it (well, you can try, but your terminal will look at you funny).
Copy the entire URL and paste it into a browser on your computer. You will be redirected to the Cloudflare dashboard where you:
- Logged into your Cloudflare account
- Select the domain you want to use (e.g.
webrx.at) - Click “Authorize”
After authorization go back to your SSH session. You should see a success message confirming that your credentials have been saved in /home/radio/.cloudflared/cert.pem.
Pro tip: If you later get an error message that the cert.pem file was not found, this step was not completed properly. Just run the login command again!
Step 3: Create tunnel
Time to create the actual tunnel! Think of it like establishing your call sign for this particular connection.
bash
cloudflared tunnel create my-pi-tunnel
You will see output that looks something like this:
Tunnel credentials written to /home/radio/.cloudflared/1d7cebf0-2297-4eb3-abba-5d9606d8e3cb.json
Created tunnel my-pi-tunnel with id 1d7cebf0-2297-4eb3-abba-5d9606d8e3cb
IMPORTANT: Copy this UUID (the long string of numbers and letters). You’ll need them in the next step. Mine was 1d7cebf0-2297-4eb3-abba-5d9606d8e3cb – yours will be different!
Step 4: Configure tunnel
Now we have to tell the tunnel where to direct the traffic. First we find out which port OpenWebRX is running on.
Check whether OpenWebRX is running on port 80:
bash
curl http://localhost:80
If you see HTML output, great! If not, try:
bash
curl http://localhost:8073
As soon as you know the port, we create the configuration file:
bash
# Create system configuration directory
sudo mkdir -p /etc/cloudflared
# Create and edit configuration file
sudo nano /etc/cloudflared/config.yml
Insert this configuration (Replace values as specified):
yaml
tunnel: YOUR-TUNNEL-UUID-HERE
credentials file: /etc/cloudflared/EURE-TUNNEL-UUID-HIER.json
ingress:
- hostname: your-subdomain.euredomain.com
service: http://localhost:80
- service: http_status:404
For example, this is what mine looked like:
yaml
tunnel: 1d7cebf0-2297-4eb3-abba-5d9606d8e3cb
credentials file: /etc/cloudflared/1d7cebf0-2297-4eb3-abba-5d9606d8e3cb.json
ingress:
- host name: oe8yml.webrx.at
service: http://localhost:80
- service: http_status:404
Replace:
YOUR-TUNNEL-UUID-HEREwith your actual tunnel UUID (in both places!)eure-subdomain.euredomain.comwith your actual domain/subdomainhttp://localhost:80with the correct port if yours is different
Save file (Ctrl+X, then Y, then Enter).
Now copy the credentials file to the system location:
bash
sudo cp ~/.cloudflared/EURE-TUNNEL-UUID-HIER.json /etc/cloudflared/
For example:
bash
sudo cp ~/.cloudflared/1d7cebf0-2297-4eb3-abba-5d9606d8e3cb.json /etc/cloudflared/
Step 5: Set up DNS
Now we need to point your domain to the tunnel. This creates a CNAME record in Cloudflare’s DNS that routes traffic to your tunnel.
bash
cloudflared tunnel route dns my-pi-tunnel meine-subdomain.euredomain.com
For example, I used:
bash
cloudflared tunnel route dns my-pi-tunnel oe8yml.webrx.at
You should see:
INF Added CNAME oe8yml.webrx.at which will route to this tunnel
If you get an error that the entry already exists, no problem! Simple:
- Go to https://dash.cloudflare.com
- Select your domain
- Go to DNS → Records
- Deletes the existing entry for your subdomain
- Try the command again
Step 6: Test the tunnel
Before we make it permanent, let’s test it first! Executes:
bash
cloudflared tunnel run my-pi-tunnel
You should see logs scrolling by, including lines like:
INF Connection registered
INF Registered tunnel connection
Now open a browser and visit your domain (e.g. https://oe8yml.webrx.at). You should see your OpenWebRX interface!
If it works: Congratulations! Press Ctrl+C to stop the tunnel and go to the next step.
If you see a Cloudflare error page: Check the following:
- Does OpenWebRX even run? (
sudo systemctl status openwebrx) - Did you use the correct port in your config?
- Can you access it locally? (
curl http://localhost:80)
Step 7: Install as system service
Now we make the tunnel permanent so that it starts automatically when the Pi boots. No more manual starting!
bash
# Install service
sudo cloudflared service install
#Start
sudo systemctl start cloudflared
#Start automatically when booting
sudo systemctl enable cloudflared
# Check whether it is running
sudo systemctl status cloudflared
You should see something like:
● cloudflared.service - cloudflared
Loaded: loaded (/etc/systemd/system/cloudflared.service; enabled)
Active: active (running) since...
This green “active (running)” is what you want to see!
Done! 🎉
Your OpenWebRX is now accessible worldwide via your own domain, with HTTPS encryption, no port forwarding and with automatic start at boot!
Share your link with other hams, add it to your QRZ page, and enjoy watching DX stations from around the world join in.
Your tunnel will be:
- Start automatically when the Pi boots
- Automatically restart if it crashes
- Continue running even if your home IP address changes
- Protect your network from direct exposure to the Internet
Useful commands for later
Here are some handy commands to remember:
View live logs:
bash
sudo journalctl -u cloudflared -f
Restart service:
bash
sudo systemctl restart cloudflared
Stop service:
bash
sudo systemctl stop cloudflared
Start service:
bash
sudo systemctl start cloudflared
Check tunnel status:
bash
sudo systemctl status cloudflared
List all tunnels:
bash
cloudflared tunnel list
Troubleshooting common problems
“Cannot determine default configuration path”
Your config file is in the wrong place. Make sure it is in /etc/cloudflared/config.yml and not in your home directory.
“Cloudflare Tunnel error” when visiting your domain
The tunnel service is not running. Check with sudo systemctl status cloudflared and look at the logs with sudo journalctl -u cloudflared -n 50.
Tunnel starts but page doesn’t load
- Check if your local service is running:
curl http://localhost:EUER-PORT - Check whether the port number in your config matches your service
- Check the tunnel logs for connection errors
“package architecture does not match system”
You downloaded the wrong binary. Use uname -m to check your architecture and download the appropriate version (arm vs arm64).
Add more services
Do you want to share multiple services? Simply! Simply add more entries to your config file:
yaml
tunnel: 1d7cebf0-2297-4eb3-abba-5d9606d8e3cb
credentials file: /etc/cloudflared/1d7cebf0-2297-4eb3-abba-5d9606d8e3cb.json
ingress:
- hostname: sdr.euredomain.com
service: http://localhost:80
- hostname: pihole.euredomain.com
service: http://localhost:8080
- hostname: homeassistant.euredomain.com
service: http://localhost:8123
- service: http_status:404
Then route DNS for each one individually:
bash
cloudflared tunnel route dns my-pi-tunnel sdr.euredomain.com
cloudflared tunnel route dns my-pi-tunnel pihole.euredomain.com
cloudflared tunnel route dns my-pi-tunnel homeassistant.euredomain.com
Restart service:
bash
sudo systemctl restart cloudflared
Safety information
Although Cloudflare tunnels are fairly secure, here are some additional tips:
- Consider Cloudflare Access for authentication when sharing sensitive services
- Keep your Pi up to date:
sudo apt update && sudo apt upgrade - Use strong passwords for your Pi and all web interfaces
- Monitor your tunnel logs occasionally for suspicious activity
- Do not release administrative interfaces without additional authentication
Final word
As radio amateurs, we love to tinker and share our stations with others. Cloudflare Tunnels make this easier and more secure than ever before. No more struggling with NAT, CGNAT or DynDNS services going down at 3am during a contest.
Now go out and share your SDR with the world! And remember: Just like in radio communications, sometimes the best DX comes from the most unexpected places.
My personal conclusion
These instructions are not just theory – I followed them step by step myself and thus set up https://oe8yml.webrx.at. My setup runs on Starlink, and the combination of Cloudflare Tunnel and satellite internet works great! No CGNAT (Carrier-Grade NAT) issues that would be common with Starlink, and the connection is stable and fast.
The best part? I didn’t have to worry about the constantly changing IP address or do complicated network configurations. The tunnel just runs, regardless of whether I’m connected via satellite, mobile or landline.
I hope this guide helps you as much as it helped me. Have fun setting up your own WebSDR!
73 de OE8YML Michael
P.S. – If this guide helped you, give me a signal on your favorite tape. I would love to hear about your setup! And of course:Listen to https://webrx.at – there you will find even more WebSDRs from our community!
Additional resources
Last updated: December 2025
Tested on: Raspberry Pi 3/4 with Raspberry Pi OS (Debian Bullseye)
License: Feel free to share and modify this guide. Credit is appreciated!

