This is the shape of tunnel.dtwin.uz: localhost:3000 on a laptop becomes https://demo.tunnel.example.com.
#1. Server: frps
frps.toml on the server:
bindPort = 7000
vhostHTTPPort = 8080
subDomainHost = "tunnel.example.com"
auth.token = "use-a-long-random-secret"Open port 7000 for frp clients. Keep 8080 private: only the reverse proxy talks to it.
#2. Reverse proxy: Caddy
*.tunnel.example.com {
tls {
dns <your-dns-provider> {env.DNS_API_TOKEN}
}
reverse_proxy 127.0.0.1:8080
}A wildcard certificate needs the DNS-01 challenge, so build Caddy with your DNS provider's plugin. The alternative is on-demand TLS with an ask endpoint that only approves names you issued.
Point a wildcard DNS record *.tunnel.example.com to the server.
#3. Laptop: frpc
frpc.toml:
serverAddr = "tunnel.example.com"
serverPort = 7000
auth.token = "use-a-long-random-secret"
[[proxies]]
name = "demo"
type = "http"
localPort = 3000
subdomain = "demo"frpc -c frpc.toml#Checklist
- One token per person, so you can revoke one without touching the others.
- Log requests at the proxy; a public URL gets scanned within minutes.
- Do not tunnel admin panels without their own authentication.