---
title: "Tailscale Serve：在 tailnet 內分享本機服務"
description: "使用 Tailscale Serve 在 tailnet 內以 HTTPS 分享本機 HTTP、TCP 服務與靜態檔案"
---

> Documentation Index
> Fetch the complete documentation index at: https://tailscale.tw/llms.txt
> Use this file to discover all available pages before exploring further.

# Tailscale Serve：在 tailnet 內分享本機服務

本機跑了一個開發中的網站、後台或靜態檔案，想讓同一 tailnet 裡的其他裝置連進來，又不想開防火牆連接埠或上傳到公開主機，就用 [Tailscale Serve](https://tailscale.com/kb/1312/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` 以外會帶上連接埠號）：

```text
https://my-dev-machine.tailxxxxx.ts.net
https://my-dev-machine.tailxxxxx.ts.net:8443
```

Serve 收到 tailnet 來的請求時，會在轉給本機服務前加上身分標頭（`Tailscale-User-Login`、`Tailscale-User-Name` 等），後端可以用它識別是誰連進來的。例外：來自 tagged 裝置的請求不會帶這些標頭，只靠標頭做授權時要記得處理這個缺口。基於安全，後端服務建議只聽 `127.0.0.1`，避免有人繞過 Serve 直接偽造這些標頭。標頭的完整說明、剝除行為與 Grafana／Open WebUI／Dashy 範例，見 [Serve 的身分標頭](/features/serve-identity-headers/)。

## 前置條件

1. 裝置已加入 tailnet，且 MagicDNS 可以解析裝置名稱。
2. 在管理後台啟用 HTTPS 憑證（Admin console → DNS → 啟用 HTTPS）。Serve 依賴 tailnet 自動配發的 TLS 憑證。
3. 同一 tailnet 的存取控制（ACL）規則同樣適用於 Serve，而且是精確到連接埠的：對方能連你的裝置，不代表能連你的 Serve 網址。Serve 預設走 `443`，若 policy 只放行了特定連接埠（例如只開 `22`），對方能 SSH 但打不開你的 Serve 網址，需要額外放行 Serve 用的連接埠。
4. Linux 上 `tailscaled` 預設只接受 root 管理：一般使用者執行 `tailscale serve` 若看到 `Access denied`，改用 `sudo` 執行，或先跑一次 `sudo tailscale set --operator=$USER`，之後即可免 `sudo` 操作 Tailscale。

如果你還沒啟用 HTTPS，直接跑 `tailscale serve` 即可，CLI 會給你一個 consent 網址，照著點開同意，Tailscale 會幫你把缺少的設定補上。

## 快速開始

假設本機 `3000` 連接埠跑著開發伺服器，在該裝置上執行：

```bash
tailscale serve 3000
```

第一次會看到類似輸出：

```text
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 的監聽設定也會一起清掉。

其他實用旗標：

```bash
# 換一個 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` 裡處理：

```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"],
  },
});
```

```bash
# 開發伺服器照常跑起來
npm run dev

# 另開一個終端機分享出去
tailscale serve --bg 5173
```

用 `tailscale serve status` 查到你的網址後，把 `https://my-dev-machine.tailxxxxx.ts.net` 貼給同事，對方在 tailnet 內就能直接預覽，不用把程式碼推上測試機。

想一次對照前後端時，加上 `--set-path` 把 API 掛在同一個主機名稱下：

```bash
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/*` 的後端能正常運作。

## 範例二：分享一個資料夾

```bash
tailscale serve --bg /home/alice/demo
```

其他裝置打開你的 Serve 網址會看到目錄列表，點檔名即可下載。傳單一檔案就把路徑指到該檔案：

```bash
tailscale serve --bg /home/alice/demo/report.pdf
```

純文字公告最快，不用先建檔案：

```bash
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：把服務公開到網際網路](/features/funnel/)。

如果想分享的對象是「一個邏輯服務」而不是「某一台裝置」——例如資料庫背後有多台後端、想要一個固定名稱與虛擬 IP、後端可以隨時增減——那是 [Tailscale Services](/features/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 ...` 即可持久化。

## 參考資料

- [Tailscale Serve 官方文件](https://tailscale.com/kb/1312/serve)
- [`tailscale serve` 指令參考](https://tailscale.com/kb/1242/tailscale-serve)
- [Tailscale Funnel 官方文件](https://tailscale.com/kb/1223/funnel)
- [Vite Server Options（`server.host`、`server.allowedHosts`）](https://vite.dev/config/server-options.html)

Source: https://tailscale.tw/features/serve/index.mdx
