Introduction
When you enable Cloudflare's proxy (orange cloud icon) for a DNS record, Cloudflare only proxies HTTP (port 80) and HTTPS (port 443) traffic. All other ports, including SSH (port 22), are not proxied and will time out when accessed through the Cloudflare-proxied hostname. This confuses many administrators who enable the proxy for all DNS records and then find SSH connections hanging or timing out.
Symptoms
ssh user@example.comhangs and times out when example.com is proxied through Cloudflaretelnet example.com 22times out buttelnet example.com 443works- SSH works when using the server's direct IP address
ssh user@example.comworks when Cloudflare proxy is disabled (grey cloud)- Connection attempt shows no response at all (not a refused connection)
Common Causes
- DNS record for the server has Cloudflare proxy (orange cloud) enabled
- Cloudflare does not proxy port 22 (or any non-HTTP/HTTPS port)
- Using the same hostname for both web traffic (proxied) and SSH (needs direct)
- Cloudflare Spectrum (enterprise feature) not configured for SSH proxying
- SSH client resolving the Cloudflare edge IP instead of the origin IP
Step-by-Step Fix
- 1.Verify the DNS record is proxied through Cloudflare:
- 2.```bash
- 3.dig example.com A +short
- 4.# If the IP belongs to Cloudflare (check against https://www.cloudflare.com/ips-v4),
- 5.# then the proxy is enabled
- 6.
` - 7.Option A: Create a separate DNS record for SSH (grey cloud):
- 8.In the Cloudflare DNS dashboard:
- 9.- Keep
example.comwith orange cloud (proxied for HTTP/HTTPS) - 10.- Create
ssh.example.comwith grey cloud (DNS only, no proxy) - 11.- Point
ssh.example.comto the origin server's IP address - 12.```bash
- 13.# Now use:
- 14.ssh user@ssh.example.com
- 15.
` - 16.Option B: Disable proxy on the existing record:
- 17.In the Cloudflare DNS dashboard, click the orange cloud icon to turn it grey. This exposes the origin IP directly but removes DDoS protection for HTTP traffic.
- 18.Option C: Use Cloudflare Tunnel for SSH (recommended for security):
- 19.```bash
- 20.# Install cloudflared on the origin server
- 21.curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 -o /usr/local/bin/cloudflared
- 22.chmod +x /usr/local/bin/cloudflared
# Create a tunnel cloudflared tunnel create ssh-tunnel
# Route SSH through the tunnel cloudflared tunnel route dns ssh-tunnel ssh.example.com
# Run the tunnel cloudflared tunnel run ssh-tunnel ```
- 1.Option D: Use Cloudflare Spectrum (Enterprise plan):
- 2.Cloudflare Spectrum can proxy arbitrary TCP ports including SSH:
- 3.- Navigate to Traffic > Spectrum in the Cloudflare dashboard
- 4.- Create a new application for TCP port 22
- 5.- Point it to your origin server IP
- 6.Verify SSH connectivity:
- 7.```bash
- 8.ssh -v user@ssh.example.com
- 9.# Should connect directly to the origin server
- 10.
`
Prevention
- Use separate DNS records for HTTP (proxied) and SSH (DNS only) services
- Document which DNS records should be proxied vs DNS-only in a DNS management guide
- Use Cloudflare Tunnel for all non-HTTP services to avoid exposing origin IPs
- Include DNS proxy status verification in server setup checklists
- Use bastion hosts accessed via Cloudflare-proxified HTTPS (Cloudflare Access)