如何自架 NetBird VPN 伺服器:VPS 部署教學
在 VPS 上自架 NetBird VPN 控制平面。本文涵蓋 v0.76.2 快速啟動腳本、TLS 與 DNS 設定、Setup Keys 自動化部署,並分析其與 Headscale 的架構差異,協助您評估自架效益。
自架 NetBird VPN 伺服器的優勢
自架 NetBird VPN 伺服器意味著將控制平面(Control Plane)部署在您擁有的 VPS 上。該組件負責維護節點清單、決定節點間的存取權限,並協助兩個節點在 NAT(網路位址轉譯)後建立連線。隧道本身仍採用 WireGuard 技術,流量直接在您的機器間加密傳輸。此舉的差異在於,沒有外部公司能掌握您的裝置清單或登入流程。請務必釐清這帶來的實際效益,因為託管式控制平面同樣無法取得加密您流量的密鑰,且 協調伺服器遭入侵時的實際影響 範圍,通常比多數人在閱讀前所預想的還要小。
NetBird 的定位介於您可能已熟悉的兩種技術之間。它是一種網狀覆蓋網路(Mesh Overlay),節點間可直接連線,無須將所有流量經由單一閘道轉發。它同時支援端到端自架,這使其與 Headscale(Tailscale 的自架控制伺服器) 處於相同領域。若您過去僅使用過單一閘道隧道,請先閱讀 純 WireGuard 與網狀覆蓋網路的差異,因為該概念模型是理解本頁後續內容的基礎。
若您的需求僅是將所有流量導向單一伺服器出口,網狀網路的架構將顯得過於複雜。在單一 VPS 上架設純 WireGuard VPN 或 使用 Tailscale 出口節點(Exit Node) 即可達成,且維護成本更低。若目標僅是存取單一私有網路,而非將多台機器互連,在 VPS 上部署 Tailscale 子網路由器(Subnet Router) 即可將該網段廣播至現有的 tailnet,無須建置下方所述的完整堆疊。
實際運行的堆疊架構
佈局近期已變更,大多數舊版教學文件描述的是舊架構。截至 2026 年 8 月,在 v0.76.2 版本中,快速啟動腳本預設會寫入包含三個服務的 Compose 檔案。
netbird-server承載管理 API、訊號服務、內建 STUN 監聽器的轉送服務,以及內建的身分識別提供者。在舊版本中,這些是獨立的容器,且身分識別提供者必須先自行建置獨立的 Zitadel 安裝。dashboard是管理員網頁控制台。traefik負責終止 TLS (transport layer security),並在首次啟動時向 Let's Encrypt 請求憑證。
另外還有兩個服務,除非您在提示中選擇確認,否則預設為關閉。NetBird Proxy 服務負責將內部服務發布至公開主機名稱。CrowdSec 則負責過濾惡意流量。建置可運作的 mesh 並不需要這兩者,且兩者都會在小型伺服器上佔用記憶體。
如果您是從 單一 Docker 容器中的 wg-easy 遷移而來,這在組件數量上是一個顯著的增加。它為您帶來的好處是存取原則、使用者帳號,以及讓節點直接互連,而非透過單一閘道轉送。
開始前的準備工作
公開網域名稱是必要條件。儀表板、API 與中繼伺服器(relay)皆透過 443 埠的 HTTPS 運作,且 Traefik 需透過 HTTP challenge 向 Let's Encrypt 申請憑證,這要求網域名稱必須能從公網解析至此 VPS。單純使用 IP 位址無法完成此流程。
請建立一筆 A 記錄,netbird.example.com 指向該 VPS 的公開 IPv4 位址,並在執行任何操作前等待 DNS 生效。
dig +short netbird.example.com上述指令必須正確顯示伺服器的 IP 位址。若在 DNS 生效前執行安裝程式,憑證申請會在首次啟動時失敗;若重複失敗,將觸發 Let's Encrypt 的速率限制,導致您必須等待一小時後才能重試。
必須確保以下三個埠可從網際網路存取:TCP 80 用於憑證驗證與 HTTPS 重新導向、TCP 443 用於儀表板、API、訊號與中繼流量,以及 UDP 3478 用於 STUN。
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 3478/udp
sudo ufw reload
sudo ufw status請同時在雲端服務商的網路防火牆中開啟這些埠。多數 VPS 控制面板將此設為獨立控制項,這也是為何伺服器本身的 ufw status 設定正確,連線卻仍被拒絕的主因。
STUN (session traversal utilities for NAT) 是讓節點得知其 NAT 所分配之公開位址與埠號的機制,藉此嘗試建立直接通道。若封鎖 UDP 3478,節點仍會透過 TCP 443 上的中繼伺服器連線,表面上運作正常,但實際上所有節點都會顯示 Connection type: Relayed,導致所有流量皆經過您的 VPS,而非節點間直接傳輸。
軟體方面,您需要安裝具備 Compose v2 外掛的 Docker,以及 jq 與 curl。安裝腳本會自動檢查這些項目,若缺少任何一項將會停止執行。若此伺服器尚未安裝 Docker,請先參考 在 VPS 上設定 Docker Compose。
若不使用內建反向代理所需的埠
若不使用 Traefik,各項服務將直接暴露,所需的埠列表如下:
- TCP 80,HTTP 重新導向
- TCP 443,HTTPS
- TCP 33073,管理用 gRPC
- TCP 10000,訊號用 gRPC
- TCP 33080,透過 WebSocket 或 QUIC 的中繼服務
- UDP 3478,STUN
僅在伺服器已由其他服務處理 TLS 終止時才選擇此方式。否則,使用內建的 Traefik 可減少防火牆規則並降低設定錯誤的風險。
使用快速啟動腳本安裝 NetBird 伺服器
官方文件提供的單行指令會直接將最新版本導向至 shell 執行:
curl -fsSL https://github.com/netbirdio/netbird/releases/latest/download/getting-started.sh | bash請改用鎖定版本的方式。latest 會隨時間變動,導致兩週內執行兩次相同的指令會產生不同的安裝結果,且磁碟上沒有任何紀錄能說明是哪個版本寫入了您的設定。請下載標記過的發行版本,閱讀內容後再執行。
mkdir -p ~/netbird
cd ~/netbird
curl -fsSL -o getting-started.sh \
https://github.com/netbirdio/netbird/releases/download/v0.76.2/getting-started.sh
less getting-started.sh
bash getting-started.sh腳本會先要求輸入網域名稱:
Enter the domain you want to use for NetBird (e.g. netbird.my-domain.com):接著詢問 TLS 的處理方式:
Which reverse proxy will you use?
[0] Traefik (recommended - automatic TLS, included in Docker Compose)
[1] Existing Traefik (labels for external Traefik instance)
[2] Nginx (generates config template)
[3] Nginx Proxy Manager (generates config + instructions)
[4] External Caddy (generates Caddyfile snippet)
[5] Other/Manual (displays setup documentation)
Enter choice [0-5] (default: 0):請選擇 [0]。選項 2 到 5 會寫入設定片段並將連線設定留給您處理,這對於已經運行反向代理的伺服器是正確的,但對於全新的伺服器則不適用。選項 0 隨後會要求輸入 Let's Encrypt 的電子郵件地址,用於接收憑證過期通知。
首次安裝時,請拒絕安裝 NetBird Proxy 服務。它需要額外兩個 DNS 紀錄,即 proxy.netbird.example.com 與萬用字元 *.proxy.netbird.example.com,且對於單純的網狀網路(mesh)並無幫助。同樣地,也請拒絕安裝 CrowdSec。這兩者皆可日後再行加入。
腳本會將檔案寫入當前目錄:docker-compose.yml、權限為 600 的 config.yaml、dashboard.env,以及選擇內建 Traefik 時產生的 traefik-dynamic.yaml。請將該目錄視為必須保留的狀態資料,因為 config.yaml 存放著加密儲存資料的金鑰。一旦遺失,重新安裝也無法修復。
docker compose ps
docker compose logs -f netbird-server每個服務都應讀取 running,且伺服器日誌應趨於穩定,而非陷入重啟迴圈。請另外監控憑證狀態:
docker compose logs traefik | grep -i acmeACME (automatic certificate management environment) 是 Traefik 用於取得憑證的協定。此處若發生錯誤,通常是因為 DNS 設定問題或 80 埠未開啟所致。
建立第一個管理員帳號
開啟 https://netbird.example.com。全新安裝時,系統會進入設定頁面而非登入表單。輸入電子郵件地址、名稱與密碼,接著點擊 Create Account。該帳號將成為第一個管理員,頁面隨後會重新導向至登入表單。
該帳號儲存於 NetBird 自身的用戶儲存庫中,由內建於 netbird-server 容器的識別提供者(identity provider)驅動,無需任何外部服務。這與一年前的自架版 NetBird 有顯著差異;當時若要完成安裝,必須先架設 Zitadel 或 Keycloak,並將四個 OIDC (OpenID Connect) 數值複製到 setup.env 才能啟動服務。
若瀏覽器顯示憑證警告而非設定頁面,代表憑證未成功簽發。請務必先解決此問題再繼續,因為儀表板會透過相同的主機名稱與 API 通訊,若憑證異常,將導致難以排查的連線失敗。
加入您的第一個節點
在任何 Linux 機器上安裝客戶端,若您希望將 VPS 本身納入網狀網路(mesh),也可以在該 VPS 上安裝:
curl -fsSL https://pkgs.netbird.io/install.sh | sh在 Debian 與 Ubuntu 上,該腳本會設定 NetBird 的軟體套件庫,隨後透過 apt 安裝客戶端,因此軟體套件管理器會接管後續的維護。若您不希望直接將腳本導向至 shell 執行,可先使用 curl -fsSL -o install.sh https://pkgs.netbird.io/install.sh 儲存檔案,並在執行 sh install.sh 前先行閱讀。無論採取何種方式,請確認安裝結果:
apt-cache policy netbirdnetbird 是命令列客戶端與背景服務(daemon)。netbird-ui 是桌面系統匣應用程式,無頭(headless)伺服器無需使用。
現在將客戶端指向您的伺服器:
sudo netbird up --management-url https://netbird.example.com若省略 --management-url,客戶端會預設註冊至 NetBird 的託管服務,因為這是編譯時的預設值。此時指令仍會成功,機器也會取得位址,但您的自架儀表板將保持空白。這是初學者最常遇到的問題。
該指令會顯示一個 URL,請在瀏覽器中開啟以完成登入。完成後:
netbird status
ip addr show wt0從 netbird status 讀取四行資訊:Management: Connected、Signal: Connected、一行報告所有可用轉送節點的 Relays:,以及一個位於覆蓋網路(overlay)範圍內的 NetBird IP:。wt0 是 NetBird 建立的 WireGuard 介面,它應具備相同的位址。
使用 setup key 以無人值守方式加入第二台機器
若機器沒有瀏覽器且無人操作,則無法使用瀏覽器登入。setup key 是一種預先驗證權杖,可在無需互動步驟的情況下註冊機器。請在儀表板的 Setup Keys 頁面中建立此權杖。
權杖分為兩種。一次性金鑰僅能驗證一台機器,使用後即失效。可重複使用金鑰則可註冊多台機器,並可選擇設定註冊上限。兩者皆需設定過期時間,且皆可將新節點自動指派至特定群組,讓該群組的存取規則在機器出現時立即生效。
sudo netbird up --setup-key <SETUP-KEY> \
--management-url https://netbird.example.com \
--hostname build-runner-01--hostname 可設定儀表板中顯示的名稱。若未設定,節點將使用機器自身的名稱;若有一堆名稱皆為 ubuntu 的項目,將無法有效管理。
針對容器與短暫存在的建置代理程式,請在建立金鑰時將其標記為 ephemeral。使用 ephemeral 金鑰註冊的節點若離線超過 10 分鐘,系統將自動移除該節點,以避免節點清單中出現無效項目。
在規劃使用 setup key 前,請務必理解一項限制:過期或刪除金鑰僅會停止新的註冊,並不會中斷已使用該金鑰註冊的機器連線。若要移除機器的存取權,必須直接移除該節點。
您是否仍需要獨立的身份提供者?
對於小型安裝而言,不需要。內建的使用者儲存庫可處理從儀表板建立的帳號,這對少數使用者來說已足夠。
若您已有現成的身份提供者,且不想維護第二份使用者清單,則需要外部身份提供者。NetBird 支援任何採用 OIDC 協定的提供者。請在您的提供者中註冊一個機密型 OIDC 用戶端(confidential OIDC client),接著在 NetBird 儀表板中填入四項數值:名稱、client ID、client secret 與 issuer。NetBird 會提供一組重新導向 URL,請將其貼回至提供者設定中。系統已針對 Google、Microsoft Entra ID、Okta、Zitadel、Keycloak、Authentik 與 Pocket ID 提供整合設定,其他服務則可透過通用 OIDC 方式接入。如果您已經部署了 作為自架單一登入系統的 Authentik,這是維持單一帳號清單的最佳路徑。
新增身份提供者後,本機登入功能依然有效,且所有已設定的提供者都會顯示在登入頁面上。請務必保留一個具備強密碼的本機管理員帳號。如此一來,即使 OIDC 設定損毀,您仍有管道可以進入系統。
NetBird 或 Headscale:您該執行哪一個控制平面?
兩者都能移除相同的依賴項目,即客戶端原本必須連線回報的託管控制伺服器。但這兩者的專案架構並不相同。
Headscale 重新實作了 Tailscale 控制伺服器,讓您能繼續使用官方的 Tailscale 客戶端。該專案沒有官方的網頁控制台。您需透過 headscale 指令針對設定檔來管理使用者與預先驗證金鑰。雖然社群開發了網頁介面,但它們並非專案的一部分。這適合偏好將狀態儲存於檔案中,並透過版本控制系統管理變更的使用者。
NetBird 則提供完整產品:包含自有的客戶端、儀表板、內建身分提供者,以及可在瀏覽器中編輯的存取原則。這意味著您的 VPS 上會有較多運作中的組件,但對於不常使用終端機的同事來說,這套方案的管理負擔遠低於前者。
如果您已深度使用 Tailscale 客戶端,或希望控制平面越精簡越好,請選擇 Headscale。若有多人需要管理節點,且您希望在不自行組裝的情況下擁有控制台與 SSO 功能,請選擇 NetBird。在決定採用任一方案前,請先確認 Tailscale 免費方案的實際涵蓋範圍,因為若您的群組人數在 6 人以內且裝置數量不限,使用託管控制平面是免費的,可能完全沒有自行架設的必要。一旦超過此上限,費用將隨人數而非機器數量增加,因此 計算 Tailscale 對您群組的收費 能讓您評估該金額與維護 VPS 所需的時間成本是否划算。
執行此服務所需的 VPS 最小規格為何?
文件記載的最低需求為 1 CPU 與 2 GB 記憶體。由於目前使用者管理已改為本地端,NetBird 官方說明指出目前的記憶體下限約為 1 GB,相較於舊架構中包含完整 Zitadel 部署時所需的 2 GB 至 4 GB 已大幅降低。建議購買 2 GB 規格。額外的記憶體空間能確保在升級時,舊映像檔尚未移除前,系統仍有足夠資源下載新映像檔。
在小型伺服器上,有三項功能可選擇不安裝。您可以捨棄 NetBird Proxy 服務,該服務僅用於將內部服務發布至公開主機名稱,與節點間的連線無關。您可以捨棄 CrowdSec,建議待伺服器正式對外開放後再行安裝,而非首日即部署。請保留 netbird_data 磁碟區中的預設 SQLite 儲存庫,僅在將部署拆分至多台機器或遇到實際高併發需求時,再遷移至 PostgreSQL;此遷移過程已有相關文件說明,日後執行即可。
Relay 是唯一不可捨棄的元件。若兩個節點的 NAT 對每個目的地都分配不同的連接埠,它們將無法建立直接通道,此時 Relay 是確保連線成功的唯一途徑。停用 Relay 僅能節省極少量的記憶體,卻會導致難以追蹤的連線中斷問題。
當單台伺服器效能不足時,應優先將 Relay 移出。獨立的 Relay 執行時需設定 NB_LISTEN_ADDRESS、NB_EXPOSED_ADDRESS、NB_AUTH_SECRET 與 NB_ENABLE_STUN。Relay 與主伺服器上的共用密鑰(shared secret)必須完全一致,否則用戶端將無法通過驗證。
故障模式與現象說明
儀表板顯示憑證警告。 Traefik 未能取得憑證。請執行 docker compose logs traefik | grep -i acme。原因有二:一是 dig +short netbird.example.com 尚未指向此 VPS;二是 TCP 80 埠在 Let's Encrypt 與容器之間的某處被阻擋,通常是雲端服務商的網路防火牆,而非 ufw 本身的設定。請先排除故障原因再重試,否則驗證失敗會觸發速率限制,導致您在一小時內無法再次嘗試。
客戶端顯示已連線,但儀表板為空。 客戶端註冊到了 NetBird 的託管服務,因為缺少了 --management-url。請執行 netbird status --detail 並查看 Management: 行,該行會顯示客戶端實際連線的伺服器。若看到 Management: Connected to https://api.netbird.io:443,代表連線已導向雲端。請執行 sudo netbird down,然後再次執行 sudo netbird up --management-url https://netbird.example.com。
所有節點均顯示 Connection type: Relayed。 這代表無法建立直接通道,所有流量皆須經過您的 VPS,導致延遲增加。請檢查 VPS 防火牆與服務商防火牆是否開放 UDP 3478 埠,因為 STUN 是節點取得自身公用 IP 與埠號的關鍵。netbird status --detail 也會輸出 Direct: false 以及各節點的 ICE (Interactive Connectivity Establishment) 候選類型,藉此判斷連線嘗試的進度。在某些網路環境下,relayed 是唯一可行的連線方式,此時並非系統故障。
節點加入後無法存取任何資源。 加入網狀網路並不代表節點間即可通訊。存取政策決定了連線權限,若群組未設定任何政策,則無法存取任何資源。在開始除錯路由與防火牆之前,請先檢查儀表板中的政策設定。
netbird status 回報 daemon 問題。 服務未執行。請使用 sudo netbird service status 與 sudo netbird service start。客戶端日誌位於 /var/log/netbird/client.log。若遇到無法判斷的問題,請使用 netbird debug bundle --anonymize --system-info,此指令會將日誌、狀態、路由、DNS 設定與防火牆狀態收集至單一封存檔中。
備份與升級
整個安裝僅需依賴兩項內容:存放 docker-compose.yml 與 config.yaml 的目錄,以及存放資料庫與加密金鑰的 Docker volume。請務必將兩者一併備份。config.yaml 內含用於加密儲存資料的金鑰,若缺少此檔案,備份的資料庫將無法還原為可讀取的內容。
docker volume ls
docker compose down
sudo tar czf netbird-config.tgz -C ~ netbird
docker run --rm -v netbird_netbird_data:/data -v "$PWD":/backup \
alpine tar czf /backup/netbird-data.tgz -C /data .
docker compose up -dCompose 會在 volume 名稱前加上專案目錄作為前綴,因此文件中標示為 netbird_data 的 volume,實際名稱通常為 netbird_netbird_data。請先執行 docker volume ls 並使用其輸出的名稱,否則上述的 docker run 會因自動建立空的 volume 而導致備份失敗,最終無法歸檔任何資料。請將備份檔存放在 VPS 之外。若您已有備份工具,可使用 restic 或 BorgBackup 處理異地備份。
升級伺服器的方式為拉取映像檔並重建容器:
docker compose pull
docker compose up -d
docker compose ps在執行上述操作前,請先執行 docker compose config | grep image:。任何標記為 latest 的 tag 都應鎖定特定版本,理由與鎖定安裝腳本相同:您需要明確掌握執行中的版本,並在升級發生異常時有版本可供回退。客戶端程式則透過當初安裝時所使用的套件管理工具進行升級。
FAQ
自架 NetBird 是否需要自備身份提供者(Identity Provider)?
不需要。目前的軟體版本已內建使用者儲存庫,您可以在瀏覽器中透過 https://netbird.example.com 建立第一個管理員帳號,隨後即可從儀表板新增使用者。外部 OIDC 提供者為選用項目,日後可隨時透過名稱、Client ID、Client secret 與 Issuer 這四項數值進行整合。若教學文件建議在 NetBird 之前先部署 Zitadel 或 Keycloak,該設定方式已不再必要,且會導致您必須額外維護一項服務。
為何所有節點都顯示 Connection type: Relayed?
因為無法建立直接連線,流量正透過您 VPS 上的轉發器(relay)傳輸。常見原因是 UDP 3478 埠被阻擋,該埠為 STUN 協定所用,供節點偵測自身的公開位址與埠號。請在 VPS 防火牆及雲端服務商的網路防火牆上開啟此埠,接著再次執行 netbird status --detail 並查看 Direct: 這一行。若您所在的網路環境中,NAT 會針對不同目的地分配不同埠號,則顯示 relayed 為正常現象,並非設定錯誤。
客戶端已連線,但儀表板卻看不到節點,發生了什麼事?
客戶端註冊到了 NetBird 的託管服務,而非您的伺服器,這是因為遺漏了 --management-url 參數。netbird status --detail 會在 Management: 這一行顯示目前連線的伺服器,若數值為 https://api.netbird.io:443 即代表連線錯誤。請執行 sudo netbird down,接著執行 sudo netbird up --management-url https://netbird.example.com,該節點就會出現在您的儀表板中。
自架 NetBird 與 Headscale 有何不同?
兩者皆可將託管控制伺服器替換為您自行運行的伺服器。Headscale 僅提供控制平面:您需透過 headscale 指令與設定檔進行管理,且無官方網頁控制台,其運作對象為官方的 Tailscale 客戶端。NetBird 則在同一套堆疊中提供專屬客戶端、管理儀表板與身份提供者整合。Headscale 資源佔用較小且以檔案儲存狀態;NetBird 則更適合提供給不熟悉終端機操作的使用者。
自架 NetBird 伺服器需要多大規格的 VPS?
官方文件建議的最低規格為 1 CPU 與 2 GB 記憶體,建議購買 2 GB 規格。由於身份提供者現已內建而非獨立部署,近期版本的實際需求門檻已降至約 1 GB。安裝時可選擇不啟用選配的 Proxy 與 CrowdSec 服務,並維持使用預設的 SQLite 儲存庫,直到您確實有使用 PostgreSQL 的需求為止。