SSD Nodes Learn Hosting plans →
指南 Matt Connor作者: Matt Connor · 已更新 2026-09-08

Tailscale 是什麼?運作原理與架構深度解析

深入解析 Tailscale 如何利用 WireGuard 建立點對點加密通道。本文說明協調伺服器、NAT 穿透、DERP 中繼機制,以及使用者空間實作與核心層級 WireGuard 的效能差異,協助您快速掌握其網路架構與安全模型。

什麼是 Tailscale?

Tailscale 是一種 VPN,它能將您的機器直接相互連接,而非將所有流量路由至您所維運的單一閘道。每個節點皆執行 WireGuard,因此封包會以加密形式從一台伺服器傳輸至另一台,路徑上的任何設備皆無法讀取內容。託管式的協調伺服器負責處理節點間的識別與介紹,它負責儲存並分發公開金鑰,並告知各節點其他節點的位置,同時也會下發您所編寫的存取規則。

這種分離架構即是其整體設計核心。資料平面採用點對點傳輸,並在節點間進行加密;控制平面則是由 Tailscale 為您運行的服務。關於 Tailscale 的所有重要問題,包括涉及信任的敏感議題,皆源自這兩個事實。如果您已經自行 在 VPS 上手動架設過 WireGuard VPN,那麼 Tailscale 就是同樣的通道,只是它為您處理了金鑰分發與防火牆穿透的作業。

Tailscale 如何運作?

您的節點私有網路稱為 tailnet。當機器加入時,會發生以下四件事。

  1. tailscaled daemon 啟動,產生一組 WireGuard 金鑰對,並將狀態保留在 /var/lib/tailscale/tailscaled.state 中。私鑰會留在該機器上。Tailscale 的官方說明非常直接:「私鑰絕不會離開其節點。」
  2. 節點登入協調伺服器並上傳其公鑰,以及它認為可被存取的位址。Tailscale 將該伺服器描述為「公鑰的共享投遞箱」。
  3. 協調伺服器會回傳一份網路地圖:包含該節點獲准存取之所有節點的公鑰、tailnet 位址、機器名稱以及候選端點。
  4. 隨後,每一對節點會嘗試在彼此之間建立直接的 WireGuard 通道。若無法建立,則會改透過中繼伺服器傳輸封包。

每個節點都會從 100.64.0.0/10 取得一個穩定位址,這是範圍從 100.64.0.0 到 100.127.255.255 的電信級 NAT (CGNAT) 區段。Tailscale 使用此範圍是因為它保留給供應商基礎設施使用,因此極少與您伺服器現有的私有位址衝突。在 Linux 上,該通道會顯示為名為 tailscale0 的介面。

WireGuard 的實作位於使用者空間的 tailscaled 中,而非核心模組。這就是為什麼 Tailscale 可以在容器虛擬化環境中啟動,而 sudo modprobe wireguard 會因 Operation not supported 而失敗的原因。這也意味著特定機器上的傳輸量上限會低於核心層級的 WireGuard,這是 Tailscale 與原生 WireGuard 的比較 中探討的權衡之一。

以下兩個指令可讓您確認連線狀態。

tailscale ip -4
tailscale status

tailscale status 會為每個節點列印一行資訊,最後一欄即為關鍵所在。

100.101.102.103  web-1      you@  linux  -
100.101.102.104  db-1       you@  linux  active; direct 198.51.100.24:41641
100.101.102.105  ci-runner  you@  linux  active; relay "fra"

direct 後接位址與埠號,表示兩台機器已找到彼此的路徑,流量為點對點傳輸。relay "fra" 表示流量正通過位於法蘭克福的 Tailscale 中繼伺服器。- 表示目前與該節點沒有活動連線,這是正常現象。

協調伺服器可見與不可見的資訊

協調伺服器持有公開金鑰與元資料。它知道您的機器名稱、每個節點的擁有者(使用者或標籤)、每個節點的 tailnet 位址、節點可被存取的公開位址、上次上線時間,以及您編寫的策略檔案。這構成了您整個節點群組的完整地圖。

它不持有任何私密金鑰,因此無法解密兩個節點之間的流量。加密是在 WireGuard 對等節點之間進行的端對端加密,而協調伺服器並非對等節點。

它能做的是分發金鑰。任何協調伺服器(無論是託管服務或自行架設)都被信任,負責告知您的節點哪些公開金鑰屬於該 tailnet。這是後續威脅模型的核心關鍵,也是 Headscale,一個您可以自行架設的開源協調伺服器 存在的原因。

如何讓位於不同防火牆後的兩台伺服器直接通訊

NAT (network address translation) 讓多台機器能共用一個公用 IP 位址。您的 VPS 通常擁有獨立的公用位址,但您希望加入 tailnet 的其他機器往往沒有:例如家用伺服器、辦公網路中的建置執行器,或是位於您無法編輯防火牆設定的供應商網路後的機器。

Tailscale 運用基於 STUN (session traversal utilities for NAT) 與 ICE 標準的技術來尋找路徑。每個節點會發送一個小型 UDP 封包至 STUN 伺服器,藉此得知路由器為該 socket 分配的公用位址與埠號。兩端節點將這些候選資訊回報給協調伺服器,再由伺服器轉達給對方。隨後,兩端節點同時向對方發送封包。由於各路由器會先偵測到外送封包,因此會建立對應規則,並接受來自相同位址的回應封包。此過程無需在任何一端設定入站防火牆規則。

這些埠號具有特定用途。直接的 WireGuard 通道使用 UDP,預設來源埠為 41641。STUN 透過 UDP 3478 運行於 Tailscale 的中繼伺服器。控制連線與任何中繼資料則使用 TCP 443 上的 HTTPS。大多數情況下,您無需開啟任何入站埠;但在 NAT 限制嚴格的網路中,允許 UDP 41641 入站能提高建立直接連線的機率。

tailscale netcheck

閱讀該報告的兩行內容。UDP: true 代表 UDP 封包確實能離開該機器,而 UDP: false 代表來自此節點的所有連線都將透過中繼傳輸。MappingVariesByDestIP: true 代表路由器針對不同目的地分配了不同的公用埠,導致上述的位址預測機制無法運作,這些節點通常會維持在中繼狀態。

當 Tailscale 使用 DERP 中繼時

DERP (designated encrypted relay for packets) 是備援機制。Tailscale 在多個區域運行中繼伺服器,可透過 TCP 443 連接;當節點無法建立直接路徑時,便會透過其中一台伺服器傳送 WireGuard 封包。

封包會保持加密狀態。Tailscale 明確指出:「DERP 伺服器無法解密您的流量。它只是盲目地將已加密的流量從一個節點轉發到另一個節點。」中繼伺服器僅能看到密文,以及哪些節點正在進行通訊。

中繼伺服器也會承載大多數連線的初始封包。由於尋找直接路徑需要時間,連線通常會先以中繼方式開始,待兩個節點互相定位後再升級為直接連線。您可以觀察此過程。

tailscale ping db-1

最初的回應會顯示 via DERP(fra),隨後的一行會報告類似 via 198.51.100.24:41641 的訊息。該變更即代表升級為直接通道。若狀態始終未變,請在兩端執行 tailscale netcheck。中繼路徑仍可運作,但會增加延遲,因為每個封包都必須繞經第三台機器。

將 VPS 加入您的 tailnet

安裝腳本支援 Ubuntu 與 Debian。

curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up

sudo tailscale up 會印出一個 URL。請開啟該連結並進行驗證,節點隨即會出現在您的管理控制台。接著請確認 daemon 在重新開機後能自動啟動,這是最常被忽略的步驟。

sudo systemctl is-enabled tailscaled
tailscale status

is-enabled 應顯示 enabled,且 tailscale status 應列出該新節點及其 100.x 位址。對於透過腳本建立的伺服器,互動式 URL 並不適用。請在管理控制台中產生驗證金鑰 (auth key),並在執行時帶入該金鑰與標籤 (tag),以記錄此機器的類型。

sudo tailscale up --auth-key=tskey-auth-REPLACE-ME --advertise-tags=tag:server

被標記的節點歸屬於該標籤,而非執行指令的使用者,因此即便該使用者的帳號被移除,節點仍能持續運作。標籤必須先在您的政策檔案中的 tagOwners 下宣告,否則指令將會被拒絕。標記也會影響機器在方案中的計算方式,因為被標記的資源計費方式與個人裝置不同,免費方案的實際涵蓋範圍 說明了這些限制的細節。

對於伺服器群組,有兩項設定至關重要。節點金鑰預設會在 180 天後過期(截至 2026 年 8 月),一旦金鑰過期,「與該端點之間的所有連線將會中斷」,直到有人重新登入為止。因此,請在管理控制台中開啟該機器的設定列,並針對無人值守的伺服器選擇 Disable Key Expiry。MagicDNS 預設為 2022 年 10 月 20 日(含)之後建立的 tailnet 啟用,它會為每個節點提供一個名稱(例如 db-1.yak-bebop.ts.net),並由 100.100.100.100 的 stub resolver 進行解析。建議使用名稱而非位址,因為重建後的節點會取得新位址,但名稱保持不變。

若安裝過程在 apt 或儲存庫階段失敗,Ubuntu 上常見的 Tailscale 安裝錯誤 提供了相關修正方法。

存取綁定於 localhost 的服務

這是 tailnet 發揮作用的地方,也是使用者最常卡關之處。加入 tailnet 並不會讓 loopback 服務自動變得可存取。

ss -tlnp | grep 3000

若該指令輸出 127.0.0.1:3000,代表該 socket 僅接受目的地為 127.0.0.1 的封包。當來自其他節點的請求抵達時,其目的地為該節點的 100.x 位址,核心因找不到對應的監聽程序,會以 TCP reset 回應。客戶端隨即回報 Connection refused。此時通道運作正常,問題在於監聽設定。

有兩種正確的解決方案。第一種是將服務綁定至節點的 tailnet 位址,這能確保服務不會暴露在公用介面上,且無需經過代理:請傳入 --bind 100.101.102.104 或設定檔中的對應選項;若為容器,則將連接埠發布為 -p 100.101.102.104:3000:3000。第二種則是維持服務在 loopback 上,並在前方部署 Tailscale。

tailscale serve 3000

一旦啟用 tailnet 的 HTTPS 憑證,該設定會將請求代理至 http://127.0.0.1:3000,並透過 ts.net 名稱在 tailnet 內部以 HTTPS 提供服務。此服務僅對您的節點保持私有。此概念的公開版本稱為 Funnel,Tailscale serve 與 Funnel 的比較 一文說明了您該選擇哪種方案。

兩項相關任務各有專屬頁面。若要存取未安裝 Tailscale 的完整私有網路,請參閱 在 VPS 上設定子網路由器;若要將節點的對外網際網路流量導向至另一個節點,請參閱 出口節點 (exit node)

關閉不再需要的連接埠

一旦管理員能透過 tailnet 連線至伺服器,公開的 22 埠便已完成任務。這是最實際的效益:關閉的連接埠無法被暴力破解,日誌也不會再被這些嘗試填滿。

順序至關重要。請先新增 tailnet 存取權限,並確認能透過第二個連線階段成功登入,最後再移除公開規則。

sudo ufw allow in on tailscale0
sudo ufw status verbose

完成後,刪除公開的 SSH 規則,並改用 MagicDNS 名稱重新連線。請注意 ufw allow in on tailscale0 的實際運作方式:它信任所有經由通道傳入的流量,因此存取控制將由 Tailscale 政策檔案取代 ufw。撰寫政策時請務必考量此點。

針對執行容器的使用者有一項警告。Docker 發布的連接埠會安裝專屬的 NAT 規則並繞過 ufw,因此 ufw deny 無法將其關閉。Docker 發布的連接埠繞過 ufw 一文解釋了其機制。如前所述,將服務發布至 tailnet 位址即可避開此問題。

Tailscale 保護的範圍與限制

這點值得明確說明,因為行銷文案往往會模糊界線。

受保護的範圍:兩節點間的流量透過 WireGuard 進行端對端加密,中間的轉發節點無法讀取內容。私鑰永遠不會離開產生它的機器。節點不需要開啟對外的公開連接埠,因此網際網路無法掃描到 22 或 5432 等埠。節點間的存取權限由原則檔案決定,而非取決於誰知道位址。

不受保護的範圍:協調伺服器(coordination server)會看到您的裝置拓撲。這些中繼資料本身就很敏感,因為機器名稱、擁有者、位址與上線時間描述了您的基礎架構。它同時負責分發金鑰,這是更嚴重的風險。Tailscale 直接說明:「若 Tailscale 惡意運作並隱密地將新節點插入您的網路,Tailscale 就能以明文傳送或接收您現有節點的流量。」您的單一登入(SSO)提供者處於相同的信任路徑上,因為任何能在該處建立身分的人都能新增節點。此外,若節點遭到入侵,它就是 tailnet 內部的對等節點,其後續能存取的範圍取決於您的原則設定。這是否構成可接受的風險,取決於您的防禦對象是誰。完整的信任模型 逐一分析了這些案例,包括遭竊的身分帳號實際能做什麼。

針對金鑰分發風險有兩種解決方案。第一種是 tailnet lock,它要求現有的受信任節點對新節點進行密碼學簽章,其他節點才會接受該新節點。若控制平面在沒有有效簽章的情況下新增節點,該節點將被忽略。管理控制台會為您的簽章節點產生精確的 tailscale lock init 指令,每個節點都能確認其所見內容。

tailscale lock status

所有節點應回報相同的受信任簽章金鑰集。第二種解決方案是自行運作控制平面。自架 Headscale 協調伺服器 使用相同的協定與用戶端溝通,這將裝置拓撲與金鑰分發轉移到您擁有的硬體上。您同時也需負責該伺服器的正常運作時間。如果您仍在比較自架控制平面而非決定使用此方案,NetBird 是另一個網狀 VPN,其伺服器可完整在單一 VPS 上執行

第一天就該修正的一個預設值:新的 tailnet 預設為寬鬆模式:「預設的 tailnet 原則檔案允許 tailnet 內所有裝置互相通訊。」一旦您新增了 acls 區段,模型就會轉變為預設拒絕,僅允許符合您規則的流量通過。

{
  "tagOwners": {
    "tag:server": ["autogroup:admin"]
  },
  "acls": [
    {"action": "accept", "src": ["autogroup:member"], "dst": ["tag:server:22"]}
  ]
}

該原則允許 tailnet 成員存取已標記伺服器上的 SSH,除此之外別無其他。請針對每個服務新增規則,而非保留萬用字元,因為萬用字元意味著一旦筆記型電腦金鑰遭竊,攻擊者就能存取您的資料庫。

故障模式與常見訊息

tailscale status 總是顯示 relay 兩個節點無法建立直接路徑。請在兩端執行 tailscale netcheckUDP: false 代表 UDP 對外連線受阻,因此僅能透過中繼(relay)運作。MappingVariesByDestIP: true 代表路徑中存在嚴格的 NAT,通常在您可控的一端開放 UDP 41641 入站連接埠即可解決。

運作數月的節點突然消失。 這是因為節點金鑰已達到 180 天的預設過期時間。該機器在管理控制台中會顯示為過期,在該機器上執行 sudo tailscale up 即可恢復。請在伺服器上停用金鑰過期功能,以避免此問題再次發生。

節點列表顯示對等端,但連線逾時。 這代表連線能力正常,但存取控制策略拒絕了該流量。請檢查 acls 區段,確認是否有規則涵蓋該來源、目的與連接埠。被拒絕的封包會直接被丟棄而非回應,這就是為何您會收到逾時錯誤而非 Connection refused 的原因。

MagicDNS 名稱無法解析。 ping db-1 失敗但 ping 100.101.102.104 運作正常。這表示有其他程式取代了 /etc/resolv.conf,導致查詢請求無法到達 100.100.100.100 的 stub resolver。請檢查 cat /etc/resolv.conf 是否包含 100.100.100.100,並檢查系統中是否有其他程式會寫入該檔案。這類問題與 WireGuard 通道內的 DNS 故障 屬於同一類型。

tailscale up 拒絕您的標籤(tag)。 該標籤未在策略檔案的 tagOwners 下宣告。請將其加入後,再次執行該指令。

FAQ

Tailscale 是 VPN 還是網狀網路 (mesh network)?

這兩個詞彙都正確,且分別描述了不同的層面。其隧道技術採用 WireGuard,因此它是一個 VPN。其拓撲結構屬於網狀網路,因為每個節點都會直接與通訊對象建立隧道,而非將所有封包經由單一中央伺服器轉送。協調伺服器 (coordination server) 位於控制路徑而非資料路徑上,因此即使該伺服器無法連線,現有的隧道仍能持續傳輸流量。中斷期間受影響的僅有新節點加入,以及金鑰或政策的更新。

Tailscale 能讀取我的流量嗎?

無法讀取內容。流量在節點間透過 WireGuard 進行端對端加密,私鑰絕不會離開節點,而 DERP 中繼站轉送的封包也無法解密。Tailscale 確實會看到元數據:機器名稱、擁有者、公鑰、端點位址以及各節點的在線狀態。此外,由於它負責分發金鑰,若協調伺服器遭到入侵,攻擊者可能會嘗試植入節點並使其被您的節點群信任。透過啟用 tailnet lock 可防止此類攻擊,因為它要求必須由您信任的節點進行簽章;或者,您也可以使用 Headscale 來移除託管的控制平面。

我需要為 Tailscale 開啟防火牆埠嗎?

幾乎不需要開啟入站埠。Tailscale 的官方建議是「大多數情況下,您不需要開啟任何防火牆埠」。在出站方面,節點需要 TCP 443 連線至協調伺服器與中繼站,以及 UDP 3478 用於 STUN。直接隧道使用 UDP,預設來源埠為 41641。允許 UDP 41641 入站是選用設定,這僅有助於在網路環境較受限時成功建立直接連線。

為什麼其他節點無法存取我服務的 3000 埠?

請先使用 ss -tlnp 檢查綁定位址。若監聽器綁定在 127.0.0.1:3000,它會拒絕發送至該節點 100.x tailnet 位址的連線,因為該 socket 僅接受來自 loopback 的目的地,客戶端會收到 Connection refused。請將服務綁定至 tailnet 位址,或執行 tailscale serve 3000 進行代理。若監聽器已綁定至 0.0.0.0 但連線逾時而非被拒絕,則問題出在政策規則或主機防火牆,而非綁定位址。

我應該執行 Headscale 而非 Tailscale 的協調伺服器嗎?

當裝置圖表或金鑰分發必須保留在您自行管理的基礎設施上,或者當 tailnet 必須在不依賴外部服務的情況下運作時,請執行 Headscale。其客戶端與協定皆相同。代價是您現在必須自行維運協調伺服器,若該伺服器故障,將導致新節點無法加入,且政策變更無法生效。對於小型節點群而言,使用已啟用 tailnet lock 的託管控制平面通常是較佳的選擇。