🎯 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
📚 References
Official Documentation
- Cloudflare Tunnel Documentation
- SSH with Access for Infrastructure
- Zero Trust Access Documentation
- Short-lived Certificates
Technical Specifications
- RFC 4253 - SSH Transport Layer Protocol
- RFC 4252 - SSH Authentication Protocol
- OpenSSH Certificate Documentation