| name | expose-local-services |
| description | Expose local HTTP/TCP services to the internet using tunneling tools. Use this skill whenever you need to make a local service accessible from the internet - for testing, demos, red teaming, or development. Covers free options (Serveo, Localtunnel, Cloudflare Quick Tunnels), paid options (Ngrok TCP, LocalXpose Pro), and self-hosted solutions (FRP). |
Expose Local Services to the Internet
This skill helps you expose local HTTP and TCP services to the internet using various tunneling tools. Choose the right tool based on your needs.
Quick Selection Guide
| Use Case | Recommended Tool |
|---|
| Quick HTTP demo (free) | Serveo, Localtunnel, Cloudflare Quick Tunnel |
| Quick TCP demo (free) | Serveo, Pinggy |
| Persistent HTTP/TCP | Cloudflare Named Tunnel, Tailscale Funnel |
| Self-hosted control | FRP |
| Behind captive proxy | Pinggy (SSH over 443) |
| Within tailnet only | Tailscale Serve |
Tool Commands
Serveo (Free, SSH-based)
From https://serveo.net/
ssh -R 0:localhost:4444 serveo.net
ssh -R 80:localhost:3000 serveo.net
Localtunnel (Free, HTTP only)
From https://github.com/localtunnel/localtunnel
npx localtunnel --port 8000
Cloudflare Tunnel (Free)
Cloudflare's cloudflared CLI supports both quick anonymous tunnels and named tunnels bound to your domain.
Quick Tunnel (ephemeral, random subdomain):
cloudflared tunnel --url http://localhost:8080
Named Tunnel (persistent, custom domain):
cloudflared tunnel login
cloudflared tunnel create my-tunnel
cloudflared tunnel route dns my-tunnel app.example.com
cloudflared tunnel run my-tunnel --config tunnel.yml
Named tunnels support multiple ingress rules (HTTP, SSH, RDP), per-service access policies via Cloudflare Access, and can run as systemd containers for persistence.
Tailscale Funnel / Serve (Free)
Tailscale v1.52+ provides tailscale serve (tailnet-only) and tailscale funnel (public internet).
sudo tailscale serve 3000
sudo tailscale funnel --https=443 localhost:3000
sudo tailscale funnel --tcp=10000 tcp://localhost:22
Use --bg to persist configuration without keeping a foreground process. Check status with tailscale funnel status.
FRP (Self-hosted)
frp is ideal when you control a VPS and want deterministic domains/ports.
Server (frps):
./frps -c frps.toml
Client (frpc):
./frpc -c <<'EOF'
serverAddr = "c2.example.com"
serverPort = 7000
[[proxies]]
name = "ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 6000
[[proxies]]
name = "panel"
type = "http"
localPort = 8080
customDomains = ["panel.example.com"]
EOF
Recent releases add QUIC transport, token/OIDC auth, bandwidth caps, and health checks.
Pinggy (Free, SSH over 443)
Works behind captive proxies that only allow HTTPS. Sessions last 60 minutes on free tier.
ssh -p 443 -R0:localhost:3000 a.pinggy.io
Ngrok (Free/Paid)
From https://ngrok.com/
ngrok http 8000
ngrok tcp 9000
LocalXpose (Free/Paid)
From https://localxpose.io/
loclx tunnel http -t 8989
loclx tunnel tcp --port 4545
Expose (Free/Paid)
From https://expose.dev/
./expose share http://localhost:3000
./expose share-port 4444
Telebit (Free/Paid)
From https://telebit.cloud/
/Users/username/Applications/telebit/bin/telebit http 3000
/Users/username/Applications/telebit/bin/telebit tcp 9000
SocketXP (Free/Paid)
From https://www.socketxp.com/download
socketxp connect tcp://localhost:22
socketxp connect http://localhost:8080
OPSEC Considerations
Adversaries have increasingly abused ephemeral tunneling (especially Cloudflare's unauthenticated trycloudflare.com endpoints) to stage RAT payloads and hide C2 infrastructure. Since February 2024, campaigns have used these tunnels to deliver AsyncRAT, Xworm, VenomRAT, GuLoader, and Remcos.
Best practices:
- Rotate tunnels and domains proactively
- Monitor for external DNS lookups to your tunneler to detect blue-team blocking
- Use custom domains for persistent operations
- Be aware that free tiers may have rate limits or uptime restrictions
- Self-hosted solutions give you full control but require maintenance
References