Overview
IronClaw’s tunnel system wraps external tunnel binaries (cloudflared, ngrok, tailscale, etc.) behind a common trait. The gateway starts a tunnel after binding its local port and stops it on shutdown.Supported Providers
Configuration
Environment Variables
Provider Setup
None (Local Only)
No tunnel. Agent is only accessible on localhost.- Local development
- Single-user setups
- Behind existing reverse proxy
Cloudflare Zero Trust
Secure, authenticated tunnel via Cloudflare’s network.Setup
- Create Cloudflare account at cloudflare.com
-
Install cloudflared:
-
Create tunnel in Zero Trust dashboard:
- Navigate to Networks > Tunnels
- Click “Create a tunnel”
- Choose “Cloudflared”
- Copy the tunnel token
-
Configure IronClaw:
-
Start IronClaw:
The tunnel URL will be displayed in logs:
- Zero Trust authentication
- Automatic HTTPS
- DDoS protection
- Access control policies
- No firewall configuration needed
Tailscale
Private mesh VPN with optional public access.Setup (Tailnet-Only)
-
Install Tailscale:
-
Authenticate:
-
Configure IronClaw:
-
Start IronClaw:
Access via:
https://<machine-name>.<tailnet-name>.ts.net
Setup (Public Funnel)
-
Enable Funnel (requires Tailscale account):
-
Start IronClaw:
Public URL:
https://<machine-name>.<tailnet-name>.ts.net
- Private mesh network
- Automatic HTTPS (via Let’s Encrypt)
- ACLs for access control
- Optional public access (Funnel)
- Magic DNS
ngrok
Instant public URLs for testing and demos.Setup
- Create account at ngrok.com
-
Install ngrok:
- Get auth token from dashboard
-
Configure IronClaw:
-
Start IronClaw:
URL:
https://random-string.ngrok.app
Custom Domain (Paid)
- Instant public URLs
- Web inspection UI
- Replay requests
- Custom domains (paid)
- Edge routing
Custom Tunnel
Use any tunnel binary with placeholders.Example: bore.pub
Example: localtunnel
Example: Custom cloudflared
{host}- Local bind address (e.g.,127.0.0.1){port}- Local bind port (e.g.,3000)
Tunnel Lifecycle
Startup
Shutdown
Health Checks
URL Extraction
Cloudflare
Parsescloudflared output:
https://.*cfargotunnel.com
Tailscale
Queriestailscale status --json:
https://<DNSName> (strips trailing dot)
ngrok
Parses ngrok output:https://.*ngrok.app
Custom
Matchesurl_pattern in stdout:
Programmatic API
Creating Tunnels
Tunnel Trait
Security Considerations
Tunnel Authentication
- Cloudflare: Zero Trust policies (IP restrictions, auth providers)
- Tailscale: ACLs, MagicDNS, device authorization
- ngrok: Basic auth, OAuth, SAML (paid plans)
- Custom: Depends on provider
Gateway Authentication
In addition to tunnel auth, IronClaw gateway has:- API key authentication (
GATEWAY_API_KEY) - Rate limiting
- Request validation
- CORS configuration
Recommended Setup
Production:Troubleshooting
Tunnel Process Dies
- Check binary is installed:
which cloudflared - Check logs for tunnel errors
- Verify credentials are valid
- Ensure port is not already in use
URL Not Extracted
- Check tunnel binary output format hasn’t changed
- For custom tunnels, verify
url_patternmatches - Increase startup timeout
- Check logs for tunnel startup errors
Connection Refused
- Tunnel not fully started (takes 10-30s)
- Gateway not listening on correct port
- Firewall blocking outbound tunnel connection
- Wait 30 seconds and retry
- Check gateway is running:
lsof -i :3000 - Verify
GATEWAY_PORTmatches tunnel forwarding
Cloudflare 502 Bad Gateway
- Gateway crashed after tunnel started
- Port mismatch between gateway and tunnel
- Network connectivity issues
- Restart IronClaw
- Verify
GATEWAY_PORTconfiguration - Check gateway health:
curl localhost:3000/health
Performance
Latency
Throughput
- Cloudflare: Unlimited bandwidth
- Tailscale: Full network speed (P2P)
- ngrok: Rate limited on free plan
Recommendations
- Low latency: Tailscale (P2P) or None (local)
- High throughput: Cloudflare or Tailscale
- Quick setup: ngrok
- Production: Cloudflare (Zero Trust) or Tailscale (team)
Source Code
Key files:src/tunnel/mod.rs- Tunnel trait and factorysrc/tunnel/cloudflare.rs- Cloudflare implementationsrc/tunnel/tailscale.rs- Tailscale implementationsrc/tunnel/ngrok.rs- ngrok implementationsrc/tunnel/custom.rs- Custom tunnel implementationsrc/tunnel/none.rs- No-tunnel implementation