#

networksecurity

(1 articles)

๐Ÿ›ก๏ธ Tutorial: Secure SSH Access over Cloudflare Tunnel (Docker Optional)

# ๐Ÿ›ก๏ธ Tutorial: Secure SSH Access over Cloudflare Tunnel (Docker Optional) ### ๐ŸŽฏ Objective Set up a **Cloudflare Tunnel** to securely expose **SSH access to your system** without revealing your home IP or requiring port forwarding. This enables secure remote access even behind NAT, CGNAT, or dynamic IP environments. This guide: * Uses **Cloudflare Tunnels** to proxy traffic * **Does not expose your home IP address** * Uses **Docker + Docker Compose** for orchestration (*optional*) * Can be adapted to run under **systemd** directly if preferred --- ## ๐Ÿ”ง Prerequisites * A domain managed via [Cloudflare DNS](https://dash.cloudflare.com) * SSH server running on your machine (default port `22`) * Temporary access to the `cloudflared` CLI (for tunnel creation) * Either: * **Docker and Docker Compose** *(used in this example)*, or * A native `systemd` service (alternative not covered here) --- ## ๐Ÿชœ Step-by-Step Instructions --- ### **1. Install and Authenticate `cloudflared`** Install `cloudflared` (temporary): ```bash curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 \ -o cloudflared && chmod +x cloudflared && sudo mv cloudflared /usr/local/bin/ ``` Login with your Cloudflare account: ```bash cloudflared tunnel login ``` This will open a browser and link the machine to your Cloudflare zone. --- ### **2. Create the Tunnel** Create a named tunnel: ```bash cloudflared tunnel create ssh-tunnel ``` This creates a credential file, e.g.: ``` ~/.cloudflared/5f84da12-e91b-4d2e-b4f0-7ca842f622f1.json ``` --- ### **3. Define the Tunnel Routing Configuration** Create the tunnel config: ```bash nano ~/.cloudflared/config.yml ``` Example: ```yaml tunnel: ssh-tunnel credentials-file: /etc/cloudflared/5f84da12-e91b-4d2e-b4f0-7ca842f622f1.json ingress: - hostname: secure-ssh.example.com service: ssh://localhost:22 - service: http_status:404 ``` Then bind the hostname to the tunnel: ```bash cloudflared tunnel route dns ssh-tunnel secure-ssh.example.com ``` > Replace `secure-ssh.example.com` with your own subdomain under Cloudflare management. --- ### **4. Prepare File Permissions for Docker Use (Optional)** If using Docker, `cloudflared` runs as a non-root user (`UID 65532`), so grant it access to your config and credentials: ```bash sudo chown 65532:65532 ~/.cloudflared sudo chown 65532:65532 ~/.cloudflared/* ``` --- ### **5. Define `docker-compose.yml` (Optional)** ```yaml version: "3.8" services: cloudflared: image: cloudflare/cloudflared:latest container_name: cloudflared-ssh-tunnel restart: unless-stopped volumes: - ${HOME}/.cloudflared:/etc/cloudflared:ro - ${HOME}/.cloudflared:/home/nonroot/.cloudflared:ro command: tunnel run ssh-tunnel network_mode: host ``` > ๐Ÿ“ Docker is used here for convenience and automation. You may alternatively run `cloudflared tunnel run ssh-tunnel` directly under `systemd` or a background process. --- ### **6. Start the Tunnel** Start the container: ```bash cd ~/docker/sshtunnel docker compose up -d docker logs -f cloudflared-ssh-tunnel ``` You should see `Registered tunnel connection` and other success logs. --- ### **7. Connect to the Tunnel from Remote Systems** #### Option A: Ad-hoc connection with `cloudflared access tcp` ```bash cloudflared access tcp --hostname secure-ssh.example.com --url localhost:2222 ``` In another terminal: ```bash ssh -p 2222 youruser@localhost ``` #### Option B: Permanent SSH Configuration Edit `~/.ssh/config`: ```ssh Host secure-home HostName secure-ssh.example.com User youruser IdentityFile ~/.ssh/id_rsa ProxyCommand cloudflared access ssh --hostname %h ``` Then connect with: ```bash ssh secure-home ``` --- ## โœ… Result * Secure SSH access via a public domain (e.g., `secure-ssh.example.com`) * No ports open to the public Internet * IP address of your machine remains hidden from Cloudflare clients * Easily extendable to expose other services in future --- ## ๐Ÿ” Optional Enhancements * Run as a `systemd` service instead of Docker for lower overhead * Use `autossh` or `systemd` to maintain persistent reverse tunnels * Expand to forward additional ports (e.g., Bitcoin RPC, application APIs) * Apply strict firewall rules to limit SSH access to `localhost` only