Cloudflare Tunnels — SKILL.md
Raw skill file that agents receive when using this skill
---
name: "Cloudflare Tunnels"
description: "Skill for Cloudflare Tunnels — auto-generated from documentation"
version: "1.0.0"
author: "skynet"
category: "infrastructure"
agents: ["claude-code", "codex", "gemini"]
tags: ["cloudflare-tunnels", "infrastructure", "auto-generated"]
---
# Cloudflare Tunnels
---
name: Cloudflare Tunnels
description: Create secure connections between your local services and Cloudflare's network without opening inbound firewall ports. Use this skill when you need to expose local applications, bypass NAT/firewall restrictions, or create zero-trust network access.
metadata:
author: skynet
version: 1.0.0
category: infrastructure
---
# Cloudflare Tunnels
Securely expose local applications through Cloudflare's network without inbound ports or firewall changes.
## Prerequisites
- Cloudflare account with a domain
- `cloudflared` CLI installed
- Domain configured in Cloudflare Dashboard
## Installation
### Install cloudflared
**Linux/macOS:**
```bash
# Download and install
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
brew install cloudflare/cloudflare/cloudflared # macOS
```
**Windows:**
```powershell
# Download from releases or use winget
winget install --id Cloudflare.cloudflared
```
## Authentication
```bash
# Login to Cloudflare
cloudflared tunnel login
# This opens browser for authentication and downloads cert.pem
```
## Creating Tunnels
### Quick Start (Temporary Tunnel)
```bash
# Expose local service temporarily
cloudflared tunnel --url http://localhost:8080
# Custom hostname
cloudflared tunnel --url http://localhost:3000 --hostname myapp.example.com
```
### Persistent Named Tunnel
```bash
# 1. Create tunnel
cloudflared tunnel create my-tunnel
# 2. Configure tunnel (create config.yaml)
cat > ~/.cloudflared/config.yml << EOF
tunnel: my-tunnel
credentials-file: /home/user/.cloudflared/TUNNEL-UUID.json
ingress:
- hostname: api.example.com
service: http://localhost:8080
- hostname: app.example.com
service: http://localhost:3000
- service: http_status:404
EOF
# 3. Route DNS to tunnel
cloudflared tunnel route dns my-tunnel api.example.com
cloudflared tunnel route dns my-tunnel app.example.com
# 4. Run tunnel
cloudflared tunnel run my-tunnel
```
## Configuration Patterns
### Multi-Service Configuration
```yaml
# ~/.cloudflared/config.yml
tunnel: production-tunnel
credentials-file: /home/user/.cloudflared/UUID.json
ingress:
# Web application
- hostname: app.example.com
service: http://localhost:3000
# API service
- hostname: api.example.com
service: http://localhost:8080
originRequest:
httpHostHeader: api.internal
# SSH access
- hostname: ssh.example.com
service: ssh://localhost:22
# File server
- hostname: files.example.com
service: http://localhost:8000
originRequest:
noTLSVerify: true
# Catch-all
- service: http_status:404
```
### Path-Based Routing
```yaml
ingress:
- hostname: example.com
path: /api/*
service: http://localhost:8080
- hostname: example.com
path: /static/*
service: http://localhost:8081
- hostname: example.com
service: http://localhost:3000
- service: http_status:404
```
## Service Types Decision Tree
```
Local Service Type?
├── HTTP/HTTPS Web App → service: http://localhost:PORT
├── API Server → service: http://localhost:PORT + httpHostHeader
├── SSH/Terminal → service: ssh://localhost:22
├── TCP Service → service: tcp://localhost:PORT
├── Unix Socket → service: unix:/path/to/socket
├── Static Files → service: http_status:200 + file serving
└── Load Balancer → Multiple services with weights
```
## Advanced Configurations
### Origin Request Options
```yaml
ingress:
- hostname: secure-app.example.com
service: https://localhost:8443
originRequest:
noTLSVerify: true
caPool: /path/to/ca.pem
clientCert: /path/to/client.pem
clientKey: /path/to/client-key.pem
httpHostHeader: internal.service
originServerName: internal.example.com
connectTimeout: 30s
tlsTimeout: 10s
keepAliveTimeout: 90s
keepAliveConnections: 100
```
### Load Balancing
```yaml
ingress:
- hostname: lb.example.com
service: http://app1.local:8080
originRequest:
bastionMode: true
- hostname: lb.example.com
service: http://app2.local:8080
- service: http_status:404
```
## Management Commands
```bash
# List tunnels
cloudflared tunnel list
# Get tunnel info
cloudflared tunnel info my-tunnel
# Delete tunnel
cloudflared tunnel delete my-tunnel
# Clean up DNS records
cloudflared tunnel cleanup my-tunnel
# Test configuration
cloudflared tunnel ingress validate
# Check ingress rules
cloudflared tunnel ingress url https://app.example.com
```
## Running as Service
### Linux (systemd)
```bash
# Install service
sudo cloudflared service install
# Start service
sudo systemctl start cloudflared
sudo systemctl enable cloudflared
# Check status
sudo systemctl status cloudflared
```
### Docker
```bash
# Run tunnel in container
docker run -d \
--name cloudflared \
-v ~/.cloudflared:/etc/cloudflared \
--network host \
cloudflare/cloudflared:latest \
tunnel run my-tunnel
```
## Troubleshooting
### Common Errors and Fixes
**Error: "failed to request Cloudflare Tunnel connection"**
```bash
# Check tunnel status
cloudflared tunnel info my-tunnel
# Verify credentials
ls -la ~/.cloudflared/
cloudflared tunnel list
```
**Error: "connection refused"**
```bash
# Verify local service is running
curl http://localhost:8080
# Check ingress configuration
cloudflared tunnel ingress validate
cloudflared tunnel ingress url https://your-app.example.com
```
**Error: "certificate verify failed"**
```yaml
# Add to config.yml
originRequest:
noTLSVerify: true
```
**DNS not resolving:**
```bash
# Check DNS routing
nslookup app.example.com
# Re-add DNS route
cloudflared tunnel route dns my-tunnel app.example.com
# Check Cloudflare DNS settings in dashboard
```
### Debug Mode
```bash
# Run with debug logging
cloudflared tunnel --loglevel debug run my-tunnel
# Test specific URL
cloudflared tunnel ingress url https://app.example.com --config ~/.cloudflared/config.yml
```
### Health Checks
```bash
# Check tunnel metrics
curl http://localhost:60123/metrics
# Verify connectivity
cloudflared tunnel ingress validate --config ~/.cloudflared/config.yml
```
### Log Analysis
```bash
# Check logs
journalctl -u cloudflared -f
# Docker logs
docker logs cloudflared -f
# Common log patterns to watch:
# "connection established" - tunnel connected
# "error='dial tcp'" - backend service down
# "certificate verify failed" - TLS issues
```
This skill provides secure, reliable access to local services through Cloudflare's global network without complex networking or security concerns.
curl -s https://skills.skynet.ceo/api/skills/cloudflare-tunnels/skill.md