Skip to main content

Guide to Set Up a Cloudflare Tunnel in Podman for SSH Access

Running a Cloudflare Tunnel container using Podman to expose a local SSH service is a great way to securely access your machine remotely without opening inbound firewall ports.

Here's a simple tutorial and an explanation of the command you provided.

Cloudflare Tunnel SSH Access Tutorial 🔐

This tutorial assumes you have Podman installed, an SSH server running on port 22 locally, and a Cloudflare account with a configured tunnel.

Step 1: Set Up Your Cloudflare Tunnel

Before running the container, you need to set up a tunnel in the Cloudflare Dashboard and obtain a Tunnel Token.

  1. Log in to Cloudflare and navigate to your domain.
  2. Go to Zero Trust $\rightarrow$ Access $\rightarrow$ Tunnels.
  3. Click Create a tunnel.
  4. Choose a Tunnel Name (e.g., ssh-access-tunnel).
  5. Select Docker (or cloudflared for the token type).
  6. Cloudflare will generate the cloudflared command, which contains your unique Tunnel Token (<YOUR_TOKEN>). Copy this token.
  7. In the same interface, click Next or Save tunnel.
  8. Define a Public Hostname:
    • Set the Subdomain (e.g., ssh).
    • Set the Domain (your domain, e.g., example.com).
    • Set the Service to ssh.
    • Set the URL to ssh://localhost:22 (this is the service the container will connect to).
  9. Save the hostname configuration.

Step 2: Run the Cloudflared Container (Podman)

Now, use the command you provided, replacing <> with your copied Tunnel Token.

podman run \
--restart always \
--network host \
cloudflare/cloudflared:latest \
tunnel --no-autoupdate run --token <YOUR_TOKEN> --url ssh://localhost:22

Replace <YOUR_TOKEN> with the token you got in Step 1.

This command will:

  1. Download the cloudflare/cloudflared:latest image (if not already present).
  2. Start the container.
  3. Establish a secure, outbound connection to Cloudflare's edge network using your token.
  4. Connect the defined Cloudflare Public Hostname (ssh.example.com) to your local SSH server running on localhost:22.

Step 3: Access Your Machine via SSH

You can now SSH into your machine from anywhere using the hostname you defined in Cloudflare.

ssh -p 22 <your_username>@ssh.<your_domain>

Example: ssh -p 22 johndoe@ssh.example.com

  • The Cloudflare network acts as the intermediary, securely routing traffic to your machine through the running tunnel container.
  • You are connecting to the standard SSH port (22) on the Cloudflare hostname, which is then forwarded to your local SSH server.

Command Explanation

The command you provided is a single, powerful line for deploying and running the cloudflared application in a containerized environment using Podman.

1. Podman Command Structure

  • podman run: The main command to create and start a container from an image.
  • --restart always: A container management option that ensures the container will automatically restart if it exits (due to an error, host reboot, etc.). This ensures persistent access.
  • --network host: This is crucial. It tells Podman to use the host's network stack directly. The container's localhost becomes the host machine's localhost. This allows the cloudflared process inside the container to connect to the SSH server running on the host's port 22, i.e., ssh://localhost:22.
  • cloudflare/cloudflared:latest: Specifies the Docker image to use, which is the official Cloudflare Tunnel daemon image.

2. Cloudflared Subcommand Structure

This part of the command is passed to the cloudflared application inside the container.

  • tunnel: The subcommand for managing tunnels.
  • --no-autoupdate: Prevents the cloudflared process from trying to update itself, which can sometimes cause issues in a containerized environment.
  • run: Tells the cloudflared process to start and run the tunnel.
  • --token <YOUR_TOKEN>: The authentication credential that links this container instance to your specific, named Cloudflare Tunnel. This token tells Cloudflare which tunnel settings (like the public hostname) to apply.
  • --url ssh://localhost:22: This is the service definition. It tells the tunnel what to connect to.
    • ssh://: Specifies the service protocol (SSH).
    • localhost:22: Specifies the target address and port. Because we used --network host, this points directly to the host machine's SSH server.