Secure Remote Access to Home Services with Cloudflare Tunnels

Introduction

There are plenty of options available to enable remote access from your home services, however with Cloudflare Zero trust it's now even easier to bring your home network services to the internet without too much risk on your home network.

In this article we'll cover the following

Speedtest Tracker

I personally use Portainer and prefer the usage of stacks to handle all of my containers rather than using compose or run cli.

The below is my personal stack using persistent storage (you may wish to change this to suit your needs).

version: '3.3'
services:
    speedtest:
        container_name: speedtest
        image: henrywhitaker3/speedtest-tracker
        ports:
            - 8765:80
        volumes:
            - /data/speedtest-tracker/:/config
        environment:
            - TZ=GMT
            - PGID=1000
            - PUID=1000
            - OOKLA_EULA_GDPR=true
        logging:
            driver: "json-file"
            options:
                max-file: "10"
                max-size: "200k"
        restart: unless-stopped
  • Navigate to your Portainer (usually https://localhost:9443)
  • Select 'Local' environment
  • Select 'Stacks' then 'Add Stack'
  • Provide a name e.g. 'speedtest-tracker' and paste the code above into the web editor section (ensuring you change any variables to suit your needs)
  • Deploy the stack

You should now be able to navigate to http://localhost:8765 and be provided with the below.

No data will be present initially, the above is my existing installation

Cloudflare Tunnels

Securely expose local web services (like your home server) to the internet without opening any inbound firewall ports. It creates an outbound-only connection to Cloudflare's network, which then routes traffic to your service. This protects your network from direct attacks and simplifies remote access.

Now that we've got our Speedtest Tracker up and running, which is great for analytics, I want to access it from anywhere in the world. This is where Cloudflare comes in. By creating an outbound-only connection to Cloudflare, we avoid having to open ports and offload some of the security to Cloudflare's network.

Getting Started

If you haven't already got a Cloudflare account, first port of call is to set one up over at https://www.cloudflare.com/plans/ (ensure you select 'Free' unless you require any of the paid plans).

After creating or logging into your account head over to Zero Trust;

  • Networks > Tunnels > Create a Tunnel
  • Select 'Cloudflared' as the tunnel type
  • Enter a name for your tunnel e.g. Home Tunnel(this is mainly for your own reference)
  • Select Docker as your operating system and run the docker command or use compose below in your compose or Portainer stack

I personally always prefer a stack than using the docker run commands, you can find my stack below that I use in my own deployment.

Cloudflare Tunnel Compose
version: '3.8'

services:
  cloudflared:
    image: cloudflare/cloudflared:latest
    container_name: cloudflared
    command: tunnel --no-autoupdate run --token YOUR_TOKEN_HERE
    restart: unless-stopped

Important: Replace YOUR_TOKEN_HERE with your actual token


  • Verify the tunnel status under connectors
  • Select 'Next' and you'll be presented with a public hostname section

Only the domain, type, and URL are required fields, meaning you can set this at the base domain, subpath, or subdomain, or a combination of all three, depending on your requirements.

In this instance I want to access my Speedtest tracker at https://speed.mywebsite.com

  • Enter 'Speed' as the subdomain
  • Select the domain you wish to use
  • In 'Type' field enter 'HTTP'

    (It's important to note HTTP is correct in this instance as we're targeting the protocol for the speedtest-tracker which only serves HTTP, Cloudflare will allow us to upgrade the protocol of our domain to HTTPS)
  • In 'URL' field type the local IP and port of your Speedtest or whichever service your running

Note: If you're unsure of the local IP address, you can obtain this from your portainer instance under 'Your Environment' > 'Containers' > "Speedtest-tracker" and under 'Published Ports' a link will be provided with the full IP and PORT.

Alternatively, you can typically find the IP in your router's administration interface or, if you have terminal access to your server, by using the ifconfig (Linux)

  • Select 'Save tunnel'
It can take time for the DNS records to be updated, ensure your clear your cache and flush DNS should you face any difficulties with access your domain

Wrapping up

Now if we navigate to https://speed.mywebsite.com our domain name will remain the same, however the page that is displayed will be that of our Speedtest tracker (if you're following this article or whichever service you have decided to host).

Warning - Cloudflare Tunnels protect your network. However, if your application has no authentication (such as the Speedtest tracker), anyone can access it.

In a future article I'll cover Cloudflare Access policies and a simple practice I employ to secure my network along with the ability to utilise Authentik's OAuth2 to further secure your remote services and apps.

End