Pangolin 安裝筆記
前言
家裡放了一台 NAS、一台跑 Docker 的小主機,或是租了幾台散落各地的 VPS,接著問題就來了:要怎麼從外面連回去?
傳統做法不外乎那幾種:跟 ISP 要固定 IP、在路由器上開通訊埠轉發 (Port forwarding)、再自己架一套反向代理處理憑證。但只要遇上 CGNAT、浮動 IP,或是路由器根本不歸你管,這條路直接斷掉。就算通了,把 80、443、22 port 曝露在網際網路上,也等於每天被掃描機器人敲門問候。
Pangolin 就是來解這個問題的。
Pangolin 是什麼?Tailscale 或多或少應該有聽過,那 Cloudflare Tunnel 呢?其實這三者是相似的產品,差別在於 Pangolin 是開源專案,可以完全自架在自己的 VPS 上,資料不用經過第三方。
那 Pangolin 能幹嘛?
- 反向代理:內建 Traefik,自動申請與續期 Let's Encrypt 憑證,設定都在 Web UI 上點一點就好
- 穿透防火牆:透過 WireGuard 建立 tunnel,內網機器主動往外連,完全不需要通訊埠轉發,CGNAT 環境照樣能用
- 零信任驗證 (Zero Trust):在服務前面加上一層身分驗證,支援 PIN、一次性密碼、OIDC SSO,未通過驗證的請求根本碰不到後端服務
- 安全 SSH:主機不用對外開 22 port,一樣能從外面安全地連進去操作
簡單說,就是用一台便宜的有 public IP 的 VPS 當入口,把散落各處的內網服務通通串起來,並且統一管理誰能存取什麼。
Pangolin 比較適合了解 Linux 系統的使用者,或者平時有在管理雲端主機的使用者
如果一般使用者比較推薦使用 Tailscale 或 Cloudflare 兩者
這篇筆記記錄 Pangolin 的安裝與設定過程。
Pangolin 是怎麼運作的
在動手裝之前,先花三分鐘搞懂它的架構,後面設定會順很多。整套東西拆成兩邊:
一台有 public IP 的 VPS,跑 Pangolin 本體。這台是唯一對網際網路曝露的機器,也是所有流量的入口。
你想要被存取的那些機器(家裡的 NAS、公司的伺服器、朋友家的 Raspberry Pi),各自跑一個叫 Newt 的小連接器。Newt 會主動往 VPS 建立一條 WireGuard 加密隧道 — 注意是「主動往外連」,所以這些機器完全不需要固定 IP、不需要開通訊埠、在 CGNAT 底下也照樣能用。
VPS 上實際跑起來的容器有這幾個,知道名字就好:
| 元件 | 角色 | 白話解釋 |
|---|---|---|
| Pangolin | 控制平面 | 資料庫、Web 管理介面、API。你所有的設定都存在這 |
| Traefik | 反向代理 | 負責 HTTPS 憑證、把網域名稱對應到正確的後端服務 |
| Gerbil | 隧道管理員 | 管理所有 WireGuard 連線,Newt 和用戶端都是連到它 |
| Badger | 驗證中介層 | Traefik 的外掛,在請求進入後端前先擋下來檢查身分 |
| Newt | 站點連接器 | 裝在你的機器上,負責建立隧道跟轉發流量 |
流量走向長這樣:
公開資源: 瀏覽器 → Traefik → Badger(驗證)→ Gerbil → Newt → 你的服務
私有資源: Pangolin 用戶端 ←─ WireGuard ─→ Newt → 你的服務
三個一定要搞懂的名詞
Pangolin 的管理介面圍繞著三個概念在轉,這三個沒搞清楚就會一直卡住:
Site(站點) — 一個「網路」。通常等於一台跑著 Newt 的機器,或者說「家裡那個網段」。你有幾個地點的機器要接進來,就建幾個 Site。
Resource(資源) — 一個「你要開放出去的服務」。例如「家裡的 Jellyfin」、「NAS 的管理介面」、「開發機的 SSH」。資源分兩種:
- 公開資源 (Public):透過網域名稱從瀏覽器直接存取,前面有 Pangolin 的驗證關卡擋著。不用裝任何用戶端。
- 私有資源 (Private):真正的零信任 VPN,完全不對外曝露,必須裝 Pangolin 用戶端才連得到。
Target(目標) — 資源實際指向的後端位址,也就是 IP:Port。例如 192.168.1.50:8096。一個資源可以掛多個 Target 做負載平衡。
理解成這樣就對了:Site 是通道,Resource 是門,Target 是門後面的房間。
Pangolin 的預設是「全部拒絕」。裝好之後你的內網不會突然對外開放,每一個要能被存取的服務,都得由你手動建立成 Resource 才會通。
開始之前的準備
一台 VPS
規格不用高,Pangolin 本身很輕量:
| 用途 | 建議規格 |
|---|---|
| 最低可跑 | 1 vCPU / 2GB RAM / 8GB SSD |
| 一般自架(推薦) | 2 vCPU / 2GB RAM / 20GB SSD |
| 多站點、流量較大 | 4 vCPU / 4GB RAM / 40GB SSD |
作業系統建議 Ubuntu 20.04 以上或 Debian 11 以上,需要 root 權限跟一個 public IP。
真正要留意的不是 CPU 跟記憶體,是流量。所有經過隧道的資料都會過這台 VPS,如果你要串流 4K 影片,月流量很容易破表。一般 VPS 方案含 1~2TB/月,超過通常要另外收費。挑機房也盡量挑離你近的,延遲直接影響體感。
一個網域
要有一個自己的網域,例如 example.com。Pangolin 會用子網域來區分不同的服務(nas.example.com、jellyfin.example.com…),所以網域是必需品,不是選配。
DNS 設定
到你的 DNS 供應商那邊加上這兩筆 A 記錄:
| 類型 | 名稱 | 值 | TTL |
|---|---|---|---|
| A | * | 你的 VPS IP | 300 |
| A | @ | 你的 VPS IP | 300 |
第一筆萬用字元 (wildcard) 記錄是關鍵 — 它讓任何子網域都指向你的 VPS。這樣以後每加一個新服務,你只要在 Pangolin 介面裡填個子網域名稱就好,不用再回 DNS 加記錄。第二筆根網域是選配。
如果你用 Cloudflare 管理 DNS,這兩筆記錄請先設成 DNS only(灰色雲朵),不要開橘色雲朵的 Proxy。Proxy 開著會擋掉 Let's Encrypt 的驗證流程,也會干擾 WireGuard。等一切都跑起來之後再看官方的 Cloudflare Proxy 文件決定要不要開。
設定完可以等個幾分鐘,用這個指令確認 DNS 生效了沒:
dig +short test.example.com
有回傳你的 VPS IP 就對了。
防火牆
VPS 上要放行這四個 port:
| Port | 協定 | 用途 |
|---|---|---|
| 80 | TCP | HTTP,Let's Encrypt 憑證驗證用 |
| 443 | TCP | HTTPS,所有網頁流量跟管理介面 |
| 51820 | UDP | 站點隧道(Newt 連到 Gerbil) |
| 21820 | UDP | 用戶端隧道(Pangolin 用戶端連進來) |
以 ufw 為例:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 51820/udp
sudo ufw allow 21820/udp
sudo ufw enable
如果你的 VPS 供應商有另外一層雲端防火牆(DigitalOcean、AWS 安全群組之類的),記得那邊也要開。
SSH 的 22 port 在設定好 Pangolin 之前都先綁定家裡特定 IP 才能通過防火牆,不要設定成 0.0.0.0/0 都可以訪問到 22 port。等 Pangolin 設定完成後再改走 Pangolin 。
安裝 Pangolin
安裝腳本會幫你把 Docker、Docker Compose 跟所有設定檔都準備好,實際上你只要跑兩行指令。
先切到你想安裝的目錄(設定檔跟資料都會放在這,建議找個好記的地方):
sudo mkdir -p /opt/pangolin && cd /opt/pangolin
下載安裝程式:
curl -fsSL https://static.pangolin.net/get-installer.sh | bash
這支腳本會自動判斷你的架構(AMD64 / ARM64)抓對應的執行檔,跑完會在當前目錄留下一個 installer。
執行安裝:
sudo ./installer
安裝過程會問的問題
安裝程式是互動式的,會依序問你這幾件事:
1. 選擇版本 — 選 Community(社群版,免費開源)。Enterprise 是商業授權版,個人自架用不到。
2. Base Domain(根網域) — 填你的根網域,不要帶子網域。例如 example.com,不是 www.example.com。
3. Dashboard Domain(管理介面網域) — 管理後台要用的網址,預設是 pangolin.example.com。可以改成你喜歡的,例如 admin.example.com。直接按 Enter 用預設值也行。
4. Let's Encrypt Email — 填一個真實信箱。這個信箱有兩個用途:一是憑證即將到期時 Let's Encrypt 會寄通知,二是這也會是你之後登入管理後台的帳號,所以別亂填。
5. 是否安裝 Gerbil — 選 是。Gerbil 是負責 WireGuard 隧道的元件,不裝的話就沒有穿透防火牆的能力,Pangolin 就退化成一個普通的反向代理了。除非你所有服務都跑在這台 VPS 上,否則一定要裝。
6. Email(SMTP)設定 — 這個是選配,預設關閉,可以先跳過。之後想開通「email 一次性驗證碼」或「密碼重設信」等功能,再回頭改設定檔就好。
7. 確認安裝 — 確認後開始拉 Docker 映像檔(pangolin、gerbil、traefik)並啟動容器,大概 2~3 分鐘。
跑完之後檢查一下容器狀態:
sudo docker compose ps
pangolin、gerbil、traefik 三個都是 Up 就成功了。
初始設定
取得 Setup Token
第一次登入需要一組安全權杖,它印在 pangolin 容器的日誌裡:
sudo docker compose logs pangolin
在輸出裡找類似 Setup token: xxxxxxxx 的字樣,把它複製起來。
如果日誌太長翻不到,可以用 sudo docker compose logs pangolin | grep -i token 過濾。
建立管理員帳號
瀏覽器打開:
https://<你的管理介面網域>/auth/initial-setup
例如 https://pangolin.example.com/auth/initial-setup。
如果這頁打不開,先別急著懷疑 Pangolin,八成是 DNS 還沒生效或防火牆沒開。回去檢查上面的準備步驟。
頁面上依序:
- 貼上剛剛複製的 Setup Token
- 輸入管理員 email
- 設定一組夠強的密碼 — 這是整個系統的最高權限帳號,別偷懶
建立組織 (Organization)
建好帳號後會要你建立第一個 Organization,填個名稱跟說明就好,例如「我家」。組織是 Pangolin 用來分隔資源跟權限的最上層容器,個人自架通常一個就夠。
到這裡你已經有一個能用的 Pangolin 了,但它現在還沒有任何東西可以連 — 因為還沒有 Site。
建立第一個 Site
Site 代表「你的服務所在的那個網路」。假設現在要把家裡 NAS 上的服務接進來,那就得在 NAS(或家裡任何一台常開的機器)上裝 Newt。
在後台建立 Site
在 Pangolin 後台側邊欄找到 Sites → 新增。
需要選擇 Site 類型,有三種:
| 類型 | 什麼時候用 |
|---|---|
| Newt(推薦) | 絕大多數情況。功能最完整,支援公開資源、私有資源、SSH/RDP/VNC、健康檢查、負載平衡 |
| Local | 服務就跑在 Pangolin 這台 VPS 上,不需要隧道。不支援私有資源跟健康檢查 |
| Basic WireGuard | 進階場景,手動設定原生 WireGuard,不用 Newt。功能限制多,一般不建議 |
選 Newt,取個名字(例如「家裡」),建立。
建立完成後,Pangolin 會顯示一組連線憑證:
Newt ID: 31fsdasdasp721
Newt Secret: h51mmlkasdsadasdasdagrwumt6isgbpyavxodibx1k2d6
Endpoint: https://pangolin.example.com
Secret 只會完整顯示這一次,關掉視窗就看不到了。先複製到安全的地方。真的忘了也不用慌,可以回後台重新產生一組,只是要重設 Newt 那邊的設定。
在內網機器上安裝 Newt
Pangolin 通常會直接把指令產好給你複製。以下是幾種常見的安裝方式,挑一種用就好。
方法一:Docker Compose(最推薦)
在你的內網機器上建立 compose.yml:
services:
newt:
image: fosrl/newt
container_name: newt
restart: unless-stopped
network_mode: host
environment:
- PANGOLIN_ENDPOINT=https://pangolin.example.com
- NEWT_ID=31fsdasdasp721
- NEWT_SECRET=h51mmlkasdsadasdasdagrwumt6isgbpyavxodibx1k2d6
啟動:
docker compose up -d
用 network_mode: host 是為了讓 Newt 能直接存取同一台機器上的其他服務跟整個區域網路。如果你的環境不方便用 host 模式,就得另外處理容器間的網路互通,會麻煩不少。
或者可以移除 network_mode: host 另外增加
extra_hosts:
- "host.docker.internal:host-gateway"
這樣就可以隔離網路且讓資源是透過 host.docker.internal 來訪問 host 網路
方法二:Docker 單行指令(快速測試用)
docker run -d --name newt --restart unless-stopped --network host \
fosrl/newt \
--id 31fsdasdasp721 \
--secret h51mmlkasdsadasdasdagrwumt6isgbpyavxodibx1k2d6 \
--endpoint https://pangolin.example.com
方法三:直接裝二進位執行檔
沒有 Docker 的環境(例如某些 NAS 或路由器)可以裝原生執行檔:
curl -fsSL https://static.pangolin.net/get-newt.sh | bash
然後執行:
newt --id 31fsdasdasp721 \
--secret h51mmlkasdsadasdasdagrwumt6isgbpyavxodibx1k2d6 \
--endpoint https://pangolin.example.com
要讓它開機自動啟動,寫成 systemd 服務。先把憑證放進環境變數檔 /etc/newt/newt.env:
NEWT_ID=31fsdasdasp721
NEWT_SECRET=h51mmlkasdsadasdasdagrwumt6isgbpyavxodibx1k2d6
PANGOLIN_ENDPOINT=https://pangolin.example.com
建立 /etc/systemd/system/newt.service:
[Unit]
Description=Newt Connector
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
EnvironmentFile=/etc/newt/newt.env
ExecStart=/usr/local/bin/newt
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
啟用:
sudo systemctl daemon-reload
sudo systemctl enable --now newt
sudo systemctl status newt
確認連線成功
回到 Pangolin 後台的 Sites 頁面,剛剛建立的 Site 狀態應該從 Offline 變成 Online(可能要等個十幾秒)。
沒變綠燈的話,先看 Newt 那邊的日誌:
docker compose logs -f newt
# 或
sudo journalctl -u newt -f
發布第一個服務
Site 通了,現在來把一個實際的服務開放出去。這裡以家裡的 Jellyfin(跑在 192.168.1.50:8096)為例。
建立 Resource
後台側邊欄 Resources → 新增,選擇 HTTP / HTTPS 類型。
要填的東西:
- 名稱:自己看得懂就好,例如
Jellyfin - 子網域:例如
jellyfin,完整網址就會是https://jellyfin.example.com。因為你 DNS 設了萬用字元記錄,這裡填什麼都會自動生效,不用回去改 DNS - Site:選剛剛建立的「家裡」
設定 Target
建立完資源後,進去設定 Target,也就是流量最終要送到哪。
- 方式 (Method):
http或https— 這是指 Pangolin 用什麼協定去連你的後端服務,跟外面看到的網址無關。外部一律是 HTTPS - IP / 主機名稱:
192.168.1.50 - 通訊埠:
8096
Target 位址怎麼填,看你的服務跑在哪:
| 服務位置 | Target 填什麼 |
|---|---|
| 內網另一台機器 | 那台機器的區域網路 IP,例如 192.168.1.50 |
| 跟 Newt 同一台機器(Newt 用 host 網路) | 127.0.0.1 |
| 跟 Newt 同一個 Docker Compose | 容器的服務名稱,例如 jellyfin |
| Newt 容器要連到宿主機 | 172.17.0.1 或 host.docker.internal |
存檔後等個十幾秒讓 Traefik 申請憑證,然後打開 https://jellyfin.example.com — 應該就看到你的服務了,而且是有效的 HTTPS 憑證。
到這一步為止,你家的路由器完全沒有動過任何設定,一個 port 都沒轉。所有流量都是走 Newt 主動建立的那條加密隧道進來的。
想加第二、第三個服務,就重複這一節:建 Resource、填子網域、指 Target。不用再碰 DNS、不用再碰防火牆。
加上身分驗證
現在這個服務是「有網址就能進」的狀態。Jellyfin 自己有登入頁面還好,但如果是那種沒有驗證機制的內部工具,等於直接裸奔在網際網路上。
Pangolin 的價值就在這 — 在服務前面再加一層關卡,沒通過的請求根本碰不到後端。
進入該 Resource 的設定頁,找到驗證 (Authentication) 相關選項:
Pangolin SSO — 必須用 Pangolin 帳號登入。可以指定哪些使用者或角色能存取這個資源。最完整的做法,適合給家人朋友各自開帳號。
外部身分提供者 (OIDC) — 接 Google、Microsoft Entra ID、Okta 等等。想用 Google 帳號登入就用這個。
PIN 碼 — 最簡單粗暴,設一組數字密碼,進去之前要先輸入。適合臨時分享。
密碼 — 類似 HTTP Basic Auth,支援在 Authorization: Basic 標頭帶帳密,或直接寫在網址裡 user:[email protected]。適合給程式或腳本用。
Email 一次性驗證碼 (OTP) — 先設定允許的信箱白名單(支援萬用字元如 *@example.com),使用者輸入信箱後收到驗證碼才能進。需要先設定好 SMTP。
分享連結 (Shareable Links) — 產生有時效的臨時連結,想收回權限就把連結刪掉。適合「幫我看一下這個」這種一次性需求。
IP / 地理位置規則 — 設定有優先順序的規則,依來源 IP、國家、URL 路徑決定放行或封鎖。例如「只允許台灣的 IP」。
這些可以組合使用,也可以做成共用的 Resource Policy 套用到多個資源上,避免每個服務都要重設一次。
建議至少對所有沒有自帶登入機制的服務開啟一種驗證。開了之後即使有人猜到你的子網域名稱,看到的也只是 Pangolin 的驗證頁面。
不開 22 port 的 SSH
這是 Pangolin 相當實用的功能之一:主機不用對外開 22 port。
在 Resources 新增一個 SSH 類型的資源。SSH 資源不使用 Target,而是直接:
- 指定哪些 Site 可以路由到這個資源
- 填入後端主機跟 port(例如
192.168.1.50:22) - 設定驗證方式(同上一節)
設定完成後,直接用瀏覽器打開這個資源的網址,就會看到一個完整的互動式終端機 — 不需要 SSH 用戶端,不需要裝 Pangolin 桌面程式,手機瀏覽器也能用。
Pangolin 的驗證會在 SSH 連線建立之前擋一次,通過之後才會進到主機自己的登入流程。等於多了一層完全獨立的防護。
如果要用 Pangolin SSH 模式(直接連到執行 Newt 的那台主機本身),Newt 必須以 root 權限執行。
確認能從瀏覽器連進去之後,就可以把 VPS 跟內網機器的 22 port 從對外防火牆規則裡拿掉了。
防火牆禁用 22 port 之前,務必先確認 Pangolin 的 SSH 資源真的能連進去,而且你有其他救援手段(VPS 供應商的 Console、實體機器旁邊的鍵盤)。不然一旦 Pangolin 出事,你就把自己鎖在門外了。
日常維護
更新
Pangolin 更新沒有一鍵指令,要手動改版號。步驟如下:
1. 先備份 — 把 config 目錄複製到安全的地方:
sudo cp -r /opt/pangolin/config /opt/pangolin/config.bak.$(date +%F)
2. 停止服務:
cd /opt/pangolin
sudo docker compose down
3. 查最新版號 — 到 GitHub Releases 看 Pangolin、Gerbil、Badger 的版本,Traefik 則看 Docker Hub。
4. 改版號 — 編輯 docker-compose.yml 裡各服務的映像檔版本;Badger 的版本在 config/traefik/traefik_config.yml 裡。
5. 拉映像檔並啟動:
sudo docker compose pull
sudo docker compose up -d
6. 看日誌確認:
sudo docker compose logs -f
7. 驗證 — 開管理後台、確認 Site 還是 Online、測試幾個資源連得上。
跨大版本升級請一個一個版本升上去,不要從 v1.0 直接跳 v1.5。中間可能有資料庫 migration,跳版容易出事。
Newt 那邊也要記得更新,Docker 的話:
docker compose pull && docker compose up -d
網段衝突
Pangolin 預設使用 100.89.137.0/20 這個 CGNAT 網段給隧道用,每個 Site 分配一個 /30 子網(4 個 IP)。
如果這個網段跟你家或公司的網路撞到,必須在註冊第一個 Site 之前先改設定檔。已經跑起來之後才改會很麻煩。一般家用網路是 192.168.x.x,通常不會撞。
常見問題
管理介面打不開
DNS 還沒生效,或 80/443 沒開。用 dig +short pangolin.example.com 確認解析,用 sudo docker compose ps 確認容器有起來。別忘了 VPS 供應商的雲端防火牆也要開。
憑證申請失敗
Let's Encrypt 需要透過 80 port 驗證網域擁有權。檢查 80 port 有沒有被別的程式(Apache、nginx)佔用,以及 Cloudflare 的橘色雲朵有沒有關掉。看 Traefik 日誌:sudo docker compose logs traefik。
Site 一直顯示 Offline
Newt 連不到 Gerbil。檢查 51820/udp 有沒有開(UDP 不是 TCP,這是最常踩的雷),確認 PANGOLIN_ENDPOINT 填的是完整網址含 https://,看 Newt 日誌找錯誤訊息。
Site 是 Online 但資源連不上 問題出在 Target。從 Newt 所在的那台機器手動測試一下後端通不通:
curl -v http://192.168.1.50:8096
連不上就是內網路由或防火牆問題,跟 Pangolin 無關。另外檢查 Target 的協定(http/https)跟 port 有沒有填對。
服務可以開但版面跑掉、資源載入失敗 某些應用程式需要知道自己被反向代理,得在該應用的設定裡指定對外的 base URL,或是在 Pangolin 這邊調整轉發標頭 (Forwarded Headers)。
結語
Pangolin 的核心價值是把三件本來要分開處理的事情合成一套:反向代理 + 憑證管理、隧道穿透、身分驗證。對於手上有幾台散落各地機器的人來說,管理成本降低很多。
代價是你得自己維護那台 VPS。它是整套系統的單點 — VPS 掛了所有服務都連不上,VPS 被打進去就是全面淪陷。所以該做的基本功一樣不能少:定期更新、SSH 金鑰登入、關掉不必要的服務。
如果只是想在自己的幾台裝置之間互連,不需要對外公開任何東西,Tailscale 那類方案設定更簡單。但如果你想要「用網域名稱公開存取 + 統一的身分驗證 + 資料不經過第三方」,Pangolin 目前是相當完整的選擇。