frp-tunnel

Share local development servers via self-hosted frp tunnel with custom domains and auto HTTPS. Use when you need to share localhost with others, demo to clients, or test on mobile. Replaces ngrok/localhost.run with a stable, unlimited, self-hosted solution.

Safety Notice

This listing is from the official public ClawHub registry. Review SKILL.md and referenced scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "frp-tunnel" with this command: npx skills add darwin7381/frp-tunnel

frp-tunnel — 自建內網穿透

用自建的 frp + Caddy + Hetzner VPS 分享本地開發中的網站。自訂域名、自動 HTTPS、無限 tunnel。

替代方案(無 VPS 時):見 old-share-local-site skill(ngrok/localhost.run)

⚙️ Config(自訂區塊)

使用此 skill 前,請將以下值替換成你自己的環境:

變數目前的值說明
VPS IP5.223.75.160你的 VPS 公網 IP
域名*.tunnel.fud.city你的 wildcard 子域名
DNS ProviderCloudflare (fud.city)管理你域名 DNS 的服務
GitHub 備份https://github.com/darwin7381/frp-tunnel你的 private repo(可選)

Dashboard 密碼:不記在這裡。在 VPS 的 frps.toml 裡設定你自己的密碼。

基礎資訊

項目
VPS IP5.223.75.160
VPS ProviderHetzner Cloud, Singapore, CPX12
域名*.tunnel.fud.city
DNSCloudflare (fud.city)
HTTPS 方式Wildcard cert (DNS-01 challenge via Cloudflare API)
frp Dashboardhttp://5.223.75.160:7500
GitHub 備份https://github.com/darwin7381/frp-tunnel (private)
本地 config~/.frp/frpc.toml
本地 tmux sessionfrpc
VPS servicesfrps (systemd) + caddy (systemd)

目前的 Tunnels

HTTPS 方式:Wildcard vs Per-Domain

VPS 上的 Caddy 有兩種方式為 tunnel 提供 HTTPS。目前使用 Wildcard(推薦)。

方式 A:Wildcard Certificate(目前使用 ✅)

原理:一張 *.tunnel.fud.city wildcard cert 涵蓋所有子域名。使用 DNS-01 challenge — Caddy 透過 Cloudflare API 自動加 TXT record 驗證。

Caddyfile:

*.tunnel.fud.city {
    tls {
        dns cloudflare {env.CF_API_TOKEN}
    }
    reverse_proxy localhost:8080
}

需要:

  • Caddy with Cloudflare DNS plugin(標準版沒有,需重新編譯或下載)
  • Cloudflare API Token(Zone:DNS:Edit 權限,只限 fud.city)
  • Token 設定在 /etc/systemd/system/caddy.service.d/override.conf

新增 tunnel 只需改本地 frpc.toml,不用動 VPS。

安裝步驟(已完成,僅供紀錄):

# 1. 下載帶 cloudflare plugin 的 Caddy
curl -s "https://caddyserver.com/api/download?os=linux&arch=amd64&p=github.com%2Fcaddy-dns%2Fcloudflare" -o /usr/bin/caddy
chmod +x /usr/bin/caddy

# 2. 驗證 module 存在
caddy list-modules | grep cloudflare

# 3. 設定 CF token
mkdir -p /etc/systemd/system/caddy.service.d
cat > /etc/systemd/system/caddy.service.d/override.conf << EOF
[Service]
Environment="CF_API_TOKEN=你的token"
EOF

# 4. 更新 Caddyfile
cat > /etc/caddy/Caddyfile << EOF
*.tunnel.fud.city {
    tls {
        dns cloudflare {env.CF_API_TOKEN}
    }
    reverse_proxy localhost:8080
}
EOF

# 5. 重啟
systemctl daemon-reload
systemctl restart caddy

方式 B:Per-Domain Certificate(備用)

原理:每個子域名獨立簽一張 cert。使用 HTTP-01 challenge — Let's Encrypt 訪問 http://xxx/.well-known/acme-challenge/ 驗證。

Caddyfile:

news.tunnel.fud.city {
    reverse_proxy localhost:8080
}

terminal.tunnel.fud.city {
    reverse_proxy localhost:8080
}

# 每加一個 tunnel 就加一段

需要:標準版 Caddy 即可,不需要 API token。

缺點:每次加 tunnel 都要 SSH 進 VPS 改 Caddyfile 再 reload Caddy。

適合場景

  • 不想給 Cloudflare API token
  • 需要不同子域名指向不同 upstream(不只是 frp)
  • 臨時測試

如何切換

Wildcard → Per-Domain:

ssh root@5.223.75.160
# 刪除 override.conf(或保留也無妨)
# 把 Caddyfile 改成逐一列出每個域名
systemctl restart caddy

Per-Domain → Wildcard: 按上面方式 A 的安裝步驟。

日常操作

啟動 frpc(Mac 重啟後需要)

SOCK=/tmp/openclaw-tmux/openclaw.sock
tmux -S $SOCK new-session -d -s frpc 'frpc -c ~/.frp/frpc.toml'

檢查 frpc 狀態

SOCK=/tmp/openclaw-tmux/openclaw.sock
tmux -S $SOCK capture-pane -t frpc -p -S -10

加新 tunnel(Wildcard 模式 — 只需改本地)

Step 1 — 本地 config

編輯 ~/.frp/frpc.toml,加一段:

[[proxies]]
name = "new-project"
type = "http"
localPort = 3000
customDomains = ["new.tunnel.fud.city"]

Step 2 — 重啟本地 frpc

SOCK=/tmp/openclaw-tmux/openclaw.sock
tmux -S $SOCK send-keys -t frpc C-c
sleep 2
tmux -S $SOCK send-keys -t frpc 'frpc -c ~/.frp/frpc.toml' Enter

Step 3 — 驗證(不需要動 VPS!Wildcard cert 自動涵蓋)

curl -sI https://new.tunnel.fud.city | head -5

確認回傳 HTTP/2 200 才告訴用戶。

Step 4 — 同步 GitHub 備份

cd ~/Projects/frp-tunnel
cp ~/.frp/frpc.toml ./frpc.toml
git add -A && git commit -m "Add tunnel: new-project" && git push

加新 tunnel(Per-Domain 模式 — 需改 VPS)

同上 Step 1-2,但在 Step 2 和 3 之間多一步:

ssh root@5.223.75.160
# 編輯 /etc/caddy/Caddyfile,加:
# new.tunnel.fud.city {
#     reverse_proxy localhost:8080
# }
systemctl reload caddy
# 等 30 秒讓 cert 簽發

前端 Vite 的 allowedHosts

Vite dev server 預設會拒絕非 localhost 的 Host header。加 tunnel 時前端 vite.config.ts 也要加:

server: {
  allowedHosts: ['xxx.tunnel.fud.city'],
}

臨時開一條(不改 config)

frpc http --server-addr 5.223.75.160:7000 --local-port 3000 --custom-domain temp.tunnel.fud.city

Wildcard 模式下,臨時 tunnel 也自動有 HTTPS。

發送 URL 前必做的檢查(SOP)

每次發送 tunnel URL 給用戶前:

  1. 確認 frpc 在跑tmux capture-pane -t frpc
  2. 確認 proxy 成功 — 看到 start proxy success
  3. 確認回傳 200 — 不是 502/404/連線失敗
  4. 確認內容正確curl -s https://xxx.tunnel.fud.city | grep "<title>",title 必須是預期的網站名稱
  5. 確認本地 server 是活的,不是僵屍進程ps aux | grep <port> 檢查進程啟動時間,如果是幾天前啟動的舊進程,很可能已經僵屍化(佔 port 但不正常服務,偶爾回 200 但頁面空白)。殺掉重啟。
  6. 瀏覽器驗證時禁止信任 cache — 用無痕模式或 curl --resolve 強制走 VPS IP,不要用已開過的 tab

⚠️ 已知 Failure Mode:僵屍進程(2026-03-04 事故)

本地 dev server(如 Vite)長時間不重啟會變成僵屍:佔著 port、偶爾回 HTTP 200,但實際頁面是空白。 curl 檢查看似正常,瀏覽器有 cache 也看似正常,但外部用戶(包含手機)打開是空白。

排查步驟

  1. ps aux | grep <port> — 看進程啟動時間,超過 1-2 天就該懷疑
  2. 殺掉舊進程,在 tmux 裡重新 npm run dev
  3. 重啟後再 curl + grep title 確認

VPS 故障排除

# SSH 進 VPS
ssh root@5.223.75.160

# 檢查 frps
systemctl status frps
journalctl -u frps --no-pager -n 20

# 檢查 Caddy
systemctl status caddy
journalctl -u caddy --no-pager -n 20

# 檢查 Caddy modules(確認有 cloudflare)
caddy list-modules | grep cloudflare

# 檢查 cert 狀態
caddy cert list 2>/dev/null || journalctl -u caddy | grep "certificate obtained"

# 重啟
systemctl restart frps
systemctl restart caddy

防火牆規則(VPS ufw)

Port用途
22SSH
80HTTP (Caddy + Let's Encrypt)
443HTTPS (Caddy)
7000frp client 連線
7500frp Web Dashboard

費用

  • VPS: $7.59/月(Hetzner CPX12 Singapore + IPv4)
  • 域名: 已有 fud.city
  • SSL: 免費(Let's Encrypt via Caddy)
  • 流量: 0.5 TB/月(實際用量約 10-15 GB/月)

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

Claude Chrome

Use Claude Code with Chrome browser extension for web browsing and automation tasks. Alternative to OpenClaw's built-in browser tools.

Registry SourceRecently Updated
Coding

App Builder

Build, edit, and deploy Instant-backed apps using npx instant-cli, create-instant-app (Next.js + Codex), GitHub (gh), and Vercel (vercel). Use when asked to create a new app, modify an existing app, fix bugs, add features, or deploy/update an app. Projects live under ~/apps; always work inside the relevant app folder.

Registry SourceRecently Updated
Coding

Opengraph Io

Extract web data, capture screenshots, scrape content, and generate AI images via OpenGraph.io. Use when working with URLs (unfurling, previews, metadata), capturing webpage screenshots, scraping HTML content, asking questions about webpages, or generating images (diagrams, icons, social cards, QR codes). Triggers: 'get the OG tags', 'screenshot this page', 'scrape this URL', 'generate a diagram', 'create a social card', 'what does this page say about'.

Registry SourceRecently Updated
Coding

Xlsx Pro

Compétence pour manipuler les fichiers Excel (.xlsx, .xlsm, .csv, .tsv). Utiliser quand l'utilisateur veut : ouvrir, lire, éditer ou créer un fichier tableur ; ajouter des colonnes, calculer des formules, formater, créer des graphiques, nettoyer des données ; convertir entre formats tabulaires. Le livrable doit être un fichier tableur. NE PAS utiliser si le livrable est un document Word, HTML, script Python standalone, ou intégration Google Sheets.

Registry SourceRecently Updated
2.1K0Profile unavailable