🖥️ SSH Browser Tunnel

Cloudflare Zero Trust Implementation - Complete Technical Documentation

🎯 Purpose & Use Cases

Primary Purpose

Enable SSH access from any device with a web browser, providing secure terminal access without requiring SSH client software installation or key management.

Top 3 Use Cases

  • Cross-Platform SSH Access
    Enable SSH access from any device with a web browser, regardless of operating system
  • Corporate Environment Access
    Provide SSH access in environments where SSH clients are restricted or unavailable
  • Guest/Temporary Access
    Allow temporary SSH access without requiring client software installation or key management

Key Benefits

  • No SSH client software required
  • Cross-platform compatibility
  • Automatic certificate management
  • Secure WebSocket-based connection
  • Real-time terminal interaction

📋 Prerequisites

Required Accounts & Services

  • Cloudflare Account with domain management
  • Cloudflare Zero Trust subscription (free tier available)
  • AWS Account with EC2 instance running Ubuntu
  • Domain registered and managed through Cloudflare
  • OpenSSH Server configured for certificate authentication

Server Requirements

  • Ubuntu 20.04+ (other Linux distributions supported)
  • cloudflared binary (latest version)
  • OpenSSH Server with certificate authentication
  • SSH CA certificate from Cloudflare Zero Trust
  • sudo access on target server

Client Requirements

  • Web browser (Chrome, Firefox, Safari, Edge)
  • JavaScript enabled
  • WebSocket support
  • No SSH client software required

🚦 Detailed Traffic Flow

SSH Browser Access Flow

Step 1: Browser SSH Request

  • User navigates to https://ssh.ztn.*****.com
  • Cloudflare edge identifies SSH browser tunnel
  • Self-hosted Access application triggered

Step 2: Authentication & Certificate Generation

  • User authenticates via Access policy
  • Cloudflare generates short-lived SSH certificate
  • Certificate contains user principal (ubuntu)
  • Certificate valid for current session
  • Web SSH interface loaded

Step 3: SSH Session Establishment

  • Browser establishes WebSocket connection
  • Tunnel converts HTTPS to SSH protocol
  • SSH daemon receives connection on port 22
  • Certificate validation against ca-browser.pub
  • SSH session established without password

Step 4: Command Execution

  • User types command in web terminal
  • Command sent via WebSocket → Tunnel → SSH
  • SSH daemon executes command
  • Output: SSH → Tunnel → WebSocket → Browser
  • Real-time terminal interaction
Timeline: ~2-3s for initial connection, real-time for commands

Example Terminal Session

ubuntu@ssh-server:~$
ls -la
total 48 drwxr-xr-x 5 ubuntu ubuntu 4096 Jan 15 16:45 . drwxr-xr-x 3 root root 4096 Jan 15 14:30 .. -rw------- 1 ubuntu ubuntu 220 Jan 15 14:30 .bash_logout -rw------- 1 ubuntu ubuntu 3771 Jan 15 14:30 .bashrc -rw------- 1 ubuntu ubuntu 807 Jan 15 14:30 .profile drwx------ 2 ubuntu ubuntu 4096 Jan 15 16:45 .ssh drwxr-xr-x 2 ubuntu ubuntu 4096 Jan 15 16:45 .cloudflared
ubuntu@ssh-server:~$
whoami
ubuntu
ubuntu@ssh-server:~$
pwd
/home/ubuntu

⚙️ Configuration

Tunnel Configuration

Tunnel Config (~/.cloudflared/tunnels/ssh-browser/config.yml):

tunnel: <ssh-browser-tunnel-id> credentials-file: /home/ubuntu/.cloudflared/<ssh-browser-tunnel-id>.json logfile: /home/ubuntu/.cloudflared/logs/ssh-browser.log loglevel: info ingress: - hostname: ssh.ztn.*****.com service: ssh://localhost:22 - service: http_status:404

Self-hosted Access Application

Application Configuration:

Application Details: name: SSH Browser Terminal domain: ssh.ztn.*****.com session_duration: 24h Policy Configuration: name: SSH Browser Access action: allow include: - email: ubuntu@oskarcode.com Browser Rendering: enabled: true type: SSH

SSH CA Certificate Configuration

Certificate Generation:

# Generate via Zero Trust Dashboard # Access > Service Auth > SSH > Select Application > Generate Certificate # Example certificate format: # ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK... open-ssh-ca@cloudflareaccess.org

🔧 SSH Server Configuration

SSH Daemon Configuration

SSH Daemon Config (/etc/ssh/sshd_config):

# Core SSH settings Port 22 Protocol 2 PermitRootLogin no PasswordAuthentication no PubkeyAuthentication yes # Cloudflare Zero Trust integration TrustedUserCAKeys /etc/ssh/ca.pub /etc/ssh/ca-browser.pub # Security settings MaxAuthTries 3 MaxSessions 10 ClientAliveInterval 300 ClientAliveCountMax 2 # Logging SyslogFacility AUTH LogLevel INFO

Certificate Authority Files

Certificate Locations:

# Infrastructure Access CA (/etc/ssh/ca.pub) ecdsa-sha2-nistp256 AAAAE2VjZHNhLX... open-ssh-ca@cloudflareaccess.org # Browser SSH CA (/etc/ssh/ca-browser.pub) ecdsa-sha2-nistp256 AAAAE2VjZHNhLX... open-ssh-ca@cloudflareaccess.org

Systemd Service

Service File (/etc/systemd/system/cloudflared-ssh-browser.service):

[Unit] Description=Cloudflare Tunnel - SSH Browser After=network.target Wants=network.target [Service] Type=simple User=ubuntu Group=ubuntu ExecStart=/usr/local/bin/cloudflared tunnel --config /home/ubuntu/.cloudflared/tunnels/ssh-browser/config.yml run Restart=always RestartSec=5 TimeoutStartSec=0 KillMode=mixed StandardOutput=journal StandardError=journal SyslogIdentifier=cloudflared-ssh-browser [Install] WantedBy=multi-user.target

🔧 Common Issues & Solutions

Issue 1: Browser SSH Password Prompt

Problem:

Web SSH terminal prompts for password instead of using certificates.

Solution:

# Verify Access application exists # Zero Trust > Access > Applications > Look for SSH browser app # Regenerate SSH certificate # Zero Trust > Access > Service Auth > SSH > Select App > Generate Certificate # Update server SSH configuration sudo cp /etc/ssh/ca-browser.pub /etc/ssh/ca-browser.pub.backup # Paste new certificate content sudo vim /etc/ssh/ca-browser.pub # Test SSH configuration sudo sshd -t # Restart SSH service sudo systemctl restart ssh # Monitor SSH logs during connection attempt sudo journalctl -u ssh -f

Issue 2: WebSocket Connection Failures

Problem:

Browser cannot establish WebSocket connection to SSH tunnel.

Solution:

# Check tunnel status cloudflared tunnel info <ssh-browser-tunnel-id> # Verify tunnel configuration cloudflared tunnel --config ~/.cloudflared/tunnels/ssh-browser/config.yml validate # Check service status sudo systemctl status cloudflared-ssh-browser # Monitor tunnel logs sudo journalctl -u cloudflared-ssh-browser -f # Test manual tunnel start cloudflared tunnel --config ~/.cloudflared/tunnels/ssh-browser/config.yml run

Issue 3: Certificate Validation Errors

Problem:

SSH certificate validation fails during browser connection.

Solution:

# Check which CAs are trusted grep TrustedUserCAKeys /etc/ssh/sshd_config # Verify CA files exist and contain valid keys ls -la /etc/ssh/ca*.pub cat /etc/ssh/ca-browser.pub # Check certificate format ssh-keygen -L -f /etc/ssh/ca-browser.pub # Monitor SSH authentication logs sudo journalctl -u ssh -f # Look for certificate validation messages # Regenerate certificate from Zero Trust dashboard # Access > Service Auth > SSH > Select Application > Generate Certificate