本機跑了一個開發中的網站、後台或靜態檔案,想讓同一 tailnet 裡的其他裝置連進來,又不想開防火牆連接埠或上傳到公開主機,就用 Tailscale Serve。
本文以 Tailscale v1.102(2026 年 10 月)為準,指令為 v1.52 改版後的新語法:旗標在前、目標在後(例如
tailscale serve --bg 3000)。
Serve 是什麼
Tailscale Serve 會在你的裝置上啟一個 HTTPS(或 HTTP、TCP)服務,把流量轉給本機的服務。其他裝置用你的 MagicDNS 名稱連線,全程走 tailnet,不會暴露到網際網路。
一個 Serve 目標(target)可以是以下四種:
- 本機服務:連接埠號碼(如
3000)、localhost:3000,或完整 URL。最常用來分享開發中的網站。注意反向代理永遠轉給http://127.0.0.1,本機服務必須聽在 IPv4 迴路位址,只聽[::1]的會被拒絕(見範例一)。 - 檔案或資料夾:絕對路徑(如
/home/alice/demo)。分享資料夾時會自動產生目錄列表。 - 靜態文字:
text:"...",適合放維護公告或快速測試。 - TCP 轉發:
--tcp或--tls-terminated-tcp,轉發 SSH、RDP 這類非 HTTP 的 TCP 服務。
預設走 HTTPS 443 連接埠,對外網址長這樣(443 以外會帶上連接埠號):
https://my-dev-machine.tailxxxxx.ts.net
https://my-dev-machine.tailxxxxx.ts.net:8443Serve 收到 tailnet 來的請求時,會在轉給本機服務前加上身分標頭(Tailscale-User-Login、Tailscale-User-Name 等),後端可以用它識別是誰連進來的。例外:來自 tagged 裝置的請求不會帶這些標頭,只靠標頭做授權時要記得處理這個缺口。基於安全,後端服務建議只聽 127.0.0.1,避免有人繞過 Serve 直接偽造這些標頭。標頭的完整說明、剝除行為與 Grafana/Open WebUI/Dashy 範例,見 Serve 的身分標頭。
前置條件
- 裝置已加入 tailnet,且 MagicDNS 可以解析裝置名稱。
- 在管理後台啟用 HTTPS 憑證(Admin console → DNS → 啟用 HTTPS)。Serve 依賴 tailnet 自動配發的 TLS 憑證。
- 同一 tailnet 的存取控制(ACL)規則同樣適用於 Serve,而且是精確到連接埠的:對方能連你的裝置,不代表能連你的 Serve 網址。Serve 預設走
443,若 policy 只放行了特定連接埠(例如只開22),對方能 SSH 但打不開你的 Serve 網址,需要額外放行 Serve 用的連接埠。 - Linux 上
tailscaled預設只接受 root 管理:一般使用者執行tailscale serve若看到Access denied,改用sudo執行,或先跑一次sudo tailscale set --operator=$USER,之後即可免sudo操作 Tailscale。
如果你還沒啟用 HTTPS,直接跑 tailscale serve 即可,CLI 會給你一個 consent 網址,照著點開同意,Tailscale 會幫你把缺少的設定補上。
快速開始
假設本機 3000 連接埠跑著開發伺服器,在該裝置上執行:
tailscale serve 3000第一次會看到類似輸出:
Available within your tailnet:
https://my-dev-machine.tailxxxxx.ts.net
|-- / proxy http://127.0.0.1:3000
Press Ctrl+C to exit.接著在同一 tailnet 的另一台裝置上,用瀏覽器打開 https://my-dev-machine.tailxxxxx.ts.net 就能看到你的網站。不加旗標是前景執行,按 Ctrl+C 就停止分享。
常用指令
| 指令 | 用途 |
|---|---|
tailscale serve 3000 |
前景分享本機 3000 連接埠(預設 HTTPS 443) |
tailscale serve --bg 3000 |
背景執行,重開機、tailscale down/up 後自動恢復 |
tailscale serve status |
查看目前分享了哪些服務(加 --json 看 JSON 版) |
tailscale serve --https=443 off |
關掉 443 上的 HTTPS 分享(off 前要帶原本的旗標) |
tailscale serve reset |
清空本機所有 Serve 設定(含 Funnel 監聽) |
幾個重點:
--bg會把設定寫進節點的 serve config 並持續生效;沒加--bg的前景分享在重開機或tailscale down/up後要手動重跑。- 關閉單一分享時,
off指令的旗標要和當初啟用時一致。--bg輸出的最後一行會直接告訴你該跑哪一行off指令,建議先跑tailscale serve status確認連接埠與路徑再關。 reset不會印出任何訊息,跑完用status確認,會顯示No serve config。注意它連 Funnel 的監聽設定也會一起清掉。
其他實用旗標:
# 換一個 HTTPS 連接埠(Serve 可用任意連接埠,不限 443 / 8443 / 10000)
tailscale serve --bg --https=8443 3000
# tailnet 內用純 HTTP(不需要憑證)
tailscale serve --bg --http=80 3000
# 同一台主機用路徑區分多個服務(前綴會被去掉,見範例一)
tailscale serve --bg 3000
tailscale serve --bg --set-path=/api http://127.0.0.1:8080/api
# 轉發本機 TCP 服務(例如 SSH)
tailscale serve --bg --tcp=2222 tcp://localhost:22範例一:分享本機開發中的網站
以 Vite(預設 5173)為例。有兩個坑要先避開:Serve 永遠轉給 http://127.0.0.1,而 Vite 預設聽的 localhost 在 Node 17+ 常只綁到 IPv6 的 [::1],轉發會被拒絕;而且 Vite 6.0.9 / 5.4.12 之後預設擋掉非 localhost 的 Host(DNS rebinding 防護),Serve 轉發帶的是 *.ts.net 的 Host,不處理會看到「Blocked request」。兩個都在 vite.config.js 裡處理:
// vite.config.js
import { defineConfig } from "vite";
export default defineConfig({
server: {
// 明確聽在 127.0.0.1(仍是本機迴路,不會暴露到區網)
host: "127.0.0.1",
// 允許 tailnet 網址的 Host;開頭的 . 表示包含所有子網域
allowedHosts: [".ts.net"],
},
});# 開發伺服器照常跑起來
npm run dev
# 另開一個終端機分享出去
tailscale serve --bg 5173用 tailscale serve status 查到你的網址後,把 https://my-dev-machine.tailxxxxx.ts.net 貼給同事,對方在 tailnet 內就能直接預覽,不用把程式碼推上測試機。
想一次對照前後端時,加上 --set-path 把 API 掛在同一個主機名稱下:
tailscale serve --bg 5173
tailscale serve --bg --set-path=/api http://127.0.0.1:8080/api這樣前端走 /,後端走 /api,共用同一個 HTTPS 網址。注意 --set-path 的前綴不會原樣轉給後端:請求 /api/users 時,Tailscale 會先去掉 /api 再轉發。上面把目標寫成含 /api 的完整 URL,就是為了把前綴補回去,讓路由註冊在 /api/* 的後端能正常運作。
範例二:分享一個資料夾
tailscale serve --bg /home/alice/demo其他裝置打開你的 Serve 網址會看到目錄列表,點檔名即可下載。傳單一檔案就把路徑指到該檔案:
tailscale serve --bg /home/alice/demo/report.pdf純文字公告最快,不用先建檔案:
tailscale serve --bg text:"網站維護中,09:00 UTC 回來"macOS 有沙盒限制:從 Mac App Store 或 Standalone 版安裝的 Tailscale 只能分享連接埠,不能分享檔案或資料夾;要用檔案分享請改用開源版用戶端。
與 Funnel 的差異
| Serve | Funnel | |
|---|---|---|
| 看得到的人 | 只有同一 tailnet 內的裝置 | 整個網際網路都能連 |
| 典型用途 | 內部分享開發站、後台、檔案 | 公開 demo、webhook 接收、對外服務 |
| 連接埠限制 | 任意連接埠皆可 | 只能用 443、8443、10000 |
| 身分標頭 | 有(tagged 裝置的請求不帶) | 沒有(公開流量不帶身分) |
同一個連接埠不能同時是 Serve 又是 Funnel,以最後下的那道指令為準。如果你下了 Funnel 指令,該連接埠就變成公開的;要收回來就重下一次 serve。怎麼把服務公開到網際網路、要注意哪些限制與安全問題,見 Tailscale Funnel:把服務公開到網際網路。
如果想分享的對象是「一個邏輯服務」而不是「某一台裝置」——例如資料庫背後有多台後端、想要一個固定名稱與虛擬 IP、後端可以隨時增減——那是 Tailscale Services 的領域:它一樣用 tailscale serve 指令,只是多一個 --service 旗標,把服務和特定裝置解耦,同一台裝置也能同時當多個 Service 的後端。
常見問題
- 跑
tailscale serve被導去開網頁? 表示 HTTPS 或相關設定還沒啟用,照著 CLI 給的 consent 網址點開同意即可。 status顯示No serve config? 表示本機目前沒有任何分享,或剛跑完reset。重下一道serve指令即可。- 確定在分享,對方卻連不上? 先檢查對方裝置是否在同一 tailnet,再檢查 ACL 是否放行了 Serve 用的連接埠(預設
443),最後用tailscale serve status確認網址、連接埠與路徑有沒有打錯。 - Linux 上看到
Access denied?tailscaled預設只接受 root 管理,改用sudo tailscale serve ...,或先跑一次sudo tailscale set --operator=$USER之後免sudo操作。 - 重開機後分享消失? 前景執行的分享不會自動回來,改用
tailscale serve --bg ...即可持久化。