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

Tailscale 是什麼?運作方式與 WireGuard 原理

了解 Tailscale 如何以 WireGuard 建立加密通道,透過協調伺服器管理金鑰與 ACL,並使用 NAT 穿透或 DERP relay 連線,掌握其信任模型。

什麼是 Tailscale?

Tailscale 是一種 VPN,可讓您的機器直接彼此連線,而不是將所有網路流量都經由您執行的單一閘道。每個節點都執行 WireGuard,因此封包會從一台伺服器加密傳送到另一台伺服器,傳輸路徑上的任何元件都無法讀取內容。代管的協調伺服器會處理節點間的連線建立。它會儲存並分發公開金鑰,也會告知各節點其他節點的位置。它還會下發您撰寫的存取規則。

這種分離就是整體設計。資料平面採用點對點連線,並在節點之間加密。控制平面則是由 Tailscale 代為執行的服務。關於 Tailscale 的所有重要問題,包括信任方面較難回答的問題,都源自這兩項事實。如果您已經在 VPS 上手動建立 WireGuard VPN,那麼 Tailscale 就是相同的通道,只是由它代為處理金鑰分發與防火牆穿透。

Tailscale 如何運作?

由節點組成的私有網路稱為 tailnet。機器加入 tailnet 時,會發生以下 4 件事。

  1. tailscaled daemon 啟動,產生 WireGuard 金鑰組,並將狀態儲存在 /var/lib/tailscale/tailscaled.state。私密金鑰會留在該機器上。Tailscale 的說法很直接:「私密金鑰永遠不會離開其節點。」
  2. 節點登入協調伺服器,並上傳其公開金鑰,以及它認為可供連線的位址。Tailscale 將該伺服器描述為「供公開金鑰共用的投遞箱」。
  3. 協調伺服器傳回網路對映,其中包含公開金鑰、tailnet 位址、機器名稱,以及此節點獲准連線之所有節點的候選端點。
  4. 每一對節點接著嘗試在彼此之間建立直接的 WireGuard 通道。若失敗,則改由 relay 轉送封包。

每個節點都會從 100.64.0.0/10 取得穩定位址。這是從 100.64.0.0 到 100.127.255.255 的電信級 NAT 位址範圍。Tailscale 使用此範圍,是因為它保留供服務提供者的基礎設施使用,因此很少會與伺服器目前使用的私有位址衝突。在 Linux 上,該通道會顯示為名為 tailscale0 的介面。

WireGuard 實作位於使用者空間的 tailscaled 內,而不是核心模組中。因此,Tailscale 能在容器虛擬化環境中啟動,而 sudo modprobe wireguard 會因 Operation not supported 失敗。這也表示在特定主機上,其吞吐量上限低於核心中的 WireGuard。這是 Tailscale 與純 WireGuard 的比較所討論的取捨之一。

以下 2 個命令可顯示目前狀態。

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" 表示流量正經由位於 Frankfurt 的 Tailscale relay 傳送。- 表示目前沒有與該節點建立作用中的工作階段,這是正常情況。

協調伺服器能看見與不能看見的資訊

協調伺服器保存公開金鑰與中繼資料。它知道您的機器名稱、各節點所屬的使用者或標籤、各節點的 tailnet 位址、節點可從哪些公開位址連線、各節點上次上線的時間,以及您撰寫的政策檔案。這些資訊足以完整呈現您的伺服器群組。

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

它能做的是分發金鑰。無論是代管或自行執行的協調伺服器,您都必須信任它,讓它告知節點哪些公開金鑰屬於 tailnet。這正是後文威脅模型的關鍵,也是 Headscale,自行代管的開放原始碼協調伺服器 存在的原因。

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

NAT(網路位址轉換)讓多台機器共用一個公開位址。您的 VPS 通常有自己的公開位址,但您想加入 tailnet 的其他機器往往沒有,例如家用伺服器、辦公室網路中的建置執行器,或位於您無法修改之供應商防火牆後方的主機。

Tailscale 使用建構於 STUN(NAT 工作階段穿越公用程式)和 ICE 標準之上的技術尋找路徑。每個節點都會向 STUN 伺服器傳送小型 UDP 封包,並得知路由器為該 socket 指派的公開位址和連接埠。兩個節點都會將這些候選位址回報給協調伺服器,再由協調伺服器傳送給另一端。接著,兩個節點會同時開始互相傳送封包。每台路由器都會先看到輸出的封包,因此建立對映,並接受從相同位址送回的回應。兩端都不需要設定輸入防火牆規則。也因為如此,家中的 Synology 或 QNAP NAS 不必在路由器上設定連接埠轉送,就能從外部直接連線;在 Synology 或 QNAP NAS 上安裝 Tailscale 說明如何以此取代 QuickConnect 或 myQNAPcloud Link。

這些連接埠各有用途。直接 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。透過中繼的路徑仍可正常運作,但延遲會增加,因為每個封包都必須繞經第三台機器。如果您注意到的是傳輸速度變慢,而不是連線中斷,請參閱為何透過中繼的 Tailscale 連線比直接連線慢得多,以測量差異並瞭解如何讓 VPS 建立直接路徑。

將 VPS 加入 tailnet

安裝指令碼支援 Ubuntu 和 Debian。

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

sudo tailscale up 會輸出一個 URL。開啟該 URL 並完成驗證,節點就會出現在管理主控台中。接著確認 daemon 在重新開機後仍會恢復執行,因為這是最常被略過的步驟。

sudo systemctl is-enabled tailscaled
tailscale status

is-enabled 應輸出 enabled,而 tailscale status 應列出新節點及其 100.x 位址。對於透過指令碼建立的伺服器,互動式 URL 沒有用。請在管理主控台中產生 auth key,並傳入該金鑰及標記,以記錄這台機器的類型。

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

標記節點的擁有者是該標記,而不是執行指令的人。因此,即使該使用者帳號已刪除,節點仍可繼續運作。必須先在政策檔案的 tagOwners 下宣告該標記,否則指令會遭拒。標記也會改變機器計入方案的方式,因為標記資源的計費與使用者個人裝置分開,而免費方案實際涵蓋的內容會說明這些限制的範圍。

對於節點群組,有兩項設定很重要。Node key 預設會在 180 天後到期(截至 August 2026),而金鑰到期後,「與指定端點之間的連線將停止運作」,直到有人再次登入。因此,請在無人值守的伺服器上開啟管理主控台中的機器列,並選取 Disable Key Expiry。對於在 20 October 2022 當天或之後建立的 tailnet,MagicDNS 預設已啟用。它會為每個節點提供類似 db-1.yak-bebop.ts.net 的名稱,並由 100.100.100.100 的 stub resolver 解析。請使用名稱而非位址,因為重建節點後會取得新的位址,但名稱仍會保留。

如果安裝本身在 apt 或 repository 上失敗,Ubuntu 上常見的 Tailscale 安裝錯誤會說明修正方法。

連線至繫結 localhost 的服務

這正是 tailnet 發揮作用的地方,也是許多人卡住的地方。加入 tailnet 不會讓 loopback 服務變得可連線。

ss -tlnp | grep 3000

如果輸出 127.0.0.1:3000,表示 socket 只接受目的地為 127.0.0.1 的封包。來自其他節點的請求會以本節點的 100.x 位址為目的地送達,因此 kernel 找不到正在監聽的服務,並回覆 TCP reset。用戶端會顯示 Connection refused。tunnel 沒有問題,問題出在 listener。

有兩種直接的修正方式。將服務繫結至節點的 tailnet 位址。這樣不需要 proxy,也能避免服務暴露在公開介面上:傳入 --bind 100.101.102.104,或在設定檔中使用等效選項;若是容器,請將連接埠發布為 -p 100.101.102.104:3000:3000。或者讓服務維持在 loopback,並在前方放置 Tailscale。

tailscale serve 3000

這會將請求 proxy 至 http://127.0.0.1:3000,並在啟用 tailnet 的 HTTPS 憑證後,透過 ts.net 名稱在 tailnet 內提供服務。服務仍只對節點保持私有。相同概念的公開版本是 Funnel,而 Tailscale serve 與 funnel 的比較說明應使用哪一種。

另外兩項相關工作各有專頁。若要連線至未安裝 Tailscale 的完整私有網路,請參閱 VPS 上的 subnet router;若要將節點對外的網際網路流量經由另一個節點傳送,請參閱 exit node。

關閉不再需要的連接埠

當所有管理員都能透過 tailnet 連線到伺服器後,公開的 22 埠便不再有用途。這就是實際效益:關閉的連接埠無法遭受暴力破解,日誌也不會持續填滿嘗試連線的記錄。

操作順序很重要。先加入 tailnet 存取規則,從第二個工作階段確認可以透過 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 位址即可避開這個問題。如果應用程式由 Docker Compose 執行,在 Compose 堆疊中使用 Tailscale sidecar 可進一步完全移除已發布的埠,讓容器只能透過其 tailnet 名稱存取。

Tailscale 可防護的內容,以及無法防護的內容

這點值得直接說明,因為行銷說法容易模糊界線。

可防護的內容:兩個節點之間的流量會透過 WireGuard 進行端對端加密,中間的任何中繼器都無法讀取。私密金鑰不會離開產生它的機器。節點不需要公開的入站埠,因此網際網路無法掃描 22 或 5432。節點之間的存取由政策檔案決定,而不是由知道某個位址的人決定。

無法防護的內容:協調伺服器會看到你的裝置拓撲。這些中繼資料本身就很敏感,因為機器名稱、擁有者、位址和上線時間會描述你的基礎架構。協調伺服器也會分發金鑰,這是更直接的風險。Tailscale 直接說明:「如果 Tailscale 具備惡意,並偷偷將新節點插入你的網路,Tailscale 就能以明文向現有節點傳送流量,或從現有節點接收流量。」你的單一登入提供者也位於相同的信任路徑中,因為任何能在該處簽發身分的人都能加入節點。而遭入侵的節點是 tailnet 內的對等節點,因此它接下來能存取的內容,就是你的政策允許的內容。這是否構成可接受的風險,取決於你要防禦的對象;完整的信任模型會逐一說明這些情況,包括遭竊的身分帳戶實際上能做什麼。

金鑰分發風險有兩種應對方式。第一種是 tailnet lock。它要求現有的受信任節點以密碼編譯方式簽署新節點,其他節點才會接受該節點。若控制平面加入的節點沒有有效簽章,就會被忽略。管理主控台會為簽署節點產生確切的 tailscale lock init 行,每個節點都能確認自己看到的內容。

tailscale lock status

所有節點都應回報相同的一組受信任簽署金鑰。第二種方式是自行執行控制平面。自架 Headscale 協調伺服器會使用相同的通訊協定與相同的用戶端互通,將裝置拓撲與金鑰分發移至你擁有的硬體上。你也必須自行負責該伺服器的可用性。如果你仍在比較自架控制平面,而尚未決定採用這個方案,NetBird 是另一個 mesh 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 netcheck。UDP: false 表示對外 UDP 流量遭到封鎖,因此只能使用中繼。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 拒絕你的標籤。 政策檔案的 tagOwners 下未宣告該標籤。請在該處加入標籤,然後再次執行該命令。

FAQ

Tailscale 是 VPN 還是 mesh network?

這兩個詞都正確,但描述的是不同層次。通道使用 WireGuard,因此屬於 VPN。拓撲是 mesh,因為每個節點會直接與其通訊的其他節點建立通道,而不是將每個封包都經過單一中央伺服器。協調伺服器位於控制路徑,而非資料路徑,因此即使無法連線,現有通道仍會傳輸網路流量。中斷期間會停止的是新節點加入,以及金鑰或政策變更套用。

Tailscale 能讀取我的網路流量嗎?

無法讀取內容。節點之間的網路流量透過 WireGuard 進行端對端加密,私密金鑰不會離開節點,而 DERP relay 只會轉送無法解密的封包。Tailscale 仍會看見中繼資料:機器名稱、擁有者、公開金鑰、端點位址,以及各節點的上線時間。Tailscale 也會散布金鑰,因此遭入侵的協調伺服器可能嘗試加入一個你的節點群組會信任的節點。Tailnet lock 會要求你自己的受信任節點提供簽章,以阻擋這種情況;Headscale 則將代管的控制平面移除。

使用 Tailscale 需要開放防火牆連接埠嗎?

幾乎不需要開放輸入連線。Tailscale 的官方指引指出:「大多數情況下,不需要開放任何防火牆連接埠。」輸出連線方面,節點需要透過 TCP 443 連線至協調伺服器和 relay,並透過 UDP 3478 使用 STUN。直接通道會使用 UDP,來源連接埠預設為 41641。開放 UDP 41641 的輸入連線是選擇性的,只有在網路環境較特殊時,才有助於直接連線成功。

為什麼其他節點無法透過連接埠 3000 連線到我的服務?

先使用 ss -tlnp 檢查繫結位址。如果 listener 位於 127.0.0.1:3000,它會拒絕傳送至該節點 100.x tailnet 位址的連線,因為該 socket 只接受以 loopback 為目的地的連線,而用戶端會看到 Connection refused。請將服務繫結至 tailnet 位址,或執行 tailscale serve 3000 進行 proxy。如果 listener 已位於 0.0.0.0,且連線逾時而非遭拒絕,原因是政策規則或主機防火牆,而不是繫結位址。

我應該使用 Headscale,而不是 Tailscale 的協調伺服器嗎?

如果裝置拓撲或金鑰散布必須留在你控制的基礎架構上,或 tailnet 必須不依賴外部服務運作,請使用 Headscale。用戶端與通訊協定相同。代價是你必須自行營運協調伺服器;伺服器中斷時,新節點無法加入,政策變更也無法套用。對小型節點群組而言,啟用 tailnet lock 的代管控制平面通常是較佳的取捨。