# Cloudflare Tunnel Setup Guide ## Overview Cloudflare Tunnels (formerly Argo Tunnels) provide secure, outbound-only connections from your infrastructure to Cloudflare's edge, eliminating the need for public IP addresses or open firewall ports. ## Prerequisites ### Required - Cloudflare account (free tier works) - Domain added to Cloudflare DNS - `cloudflared` CLI installed ### Installation (Linux) ```bash # Debian/Ubuntu curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb -o cloudflared.deb sudo dpkg -i cloudflared.deb # Or via package manager (if available) sudo apt install cloudflared ``` ### Installation (Termux/Android) ```bash pkg install cloudflared ``` ## Authentication Before creating tunnels, authenticate with Cloudflare: ```bash cloudflared tunnel login ``` This opens a browser for authentication and stores a certificate at `~/.cloudflared/cert.pem`. ## Tunnel Lifecycle ### Create Tunnel ```bash cloudflared tunnel create my-tunnel ``` Creates credentials at `~/.cloudflared/.json`. ### Configure Tunnel Create `~/.cloudflared/config.yml`: ```yaml tunnel: my-tunnel credentials-file: /path/to/credentials.json ingress: - hostname: ssh.example.com service: ssh://localhost:22 - hostname: web.example.com service: http://localhost:8080 - service: http_status:404 ``` ### Route DNS ```bash cloudflared tunnel route dns my-tunnel ssh.example.com ``` ### Run Tunnel ```bash cloudflared tunnel run my-tunnel ``` Or with explicit config: ```bash cloudflared tunnel --config ~/.cloudflared/config.yml run ``` ## SSH Access via Tunnel ### Server Side Tunnel config includes SSH service: ```yaml ingress: - hostname: ssh.example.com service: ssh://localhost:22 ``` ### Client Side Option 1: Using ProxyCommand: ``` Host my-server HostName ssh.example.com ProxyCommand cloudflared access ssh --hostname %h ``` Option 2: Using `cloudflared access`: ```bash cloudflared access ssh --hostname ssh.example.com ``` ## Cloudflare Access (Optional) For additional authentication: 1. Go to Cloudflare Zero Trust dashboard 2. Create an Access Application 3. Define authentication policies (email, SSO, etc.) 4. Apply to SSH hostname ## systemd Service ### User Service ```ini [Unit] Description=Cloudflare Tunnel After=network-online.target [Service] Type=simple ExecStart=/usr/bin/cloudflared tunnel --config /path/to/config.yml run Restart=on-failure RestartSec=5 [Install] WantedBy=default.target ``` Enable: ```bash systemctl --user enable cloudflared-tunnel systemctl --user start cloudflared-tunnel ``` ### System Service ```bash sudo cloudflared service install ``` ## Troubleshooting ### Check Tunnel Status ```bash cloudflared tunnel info my-tunnel ``` ### View Logs ```bash journalctl --user -u cloudflared-tunnel -f ``` ### Test Connectivity ```bash curl -v https://ssh.example.com ``` ### Common Issues 1. **Certificate expired**: Re-run `cloudflared tunnel login` 2. **DNS not resolving**: Check Cloudflare DNS for CNAME record 3. **Connection refused**: Verify local service is running ## Security Considerations - Tunnel credentials (`*.json`) are sensitive - protect like SSH keys - Use Cloudflare Access for authentication on sensitive services - Regularly rotate tunnel credentials - Monitor tunnel connections in Cloudflare dashboard ## References - [Cloudflare Tunnel Docs](https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/) - [cloudflared GitHub](https://github.com/cloudflare/cloudflared) - [Zero Trust Dashboard](https://one.dash.cloudflare.com/)