Pangolin 安裝筆記

發布於 2026-07-28 00:00 5391 字 27 min read

丁丁 avatar

丁丁

隨意寫寫,筆記記錄,以免忘記,後悔莫及

Pangolin 安裝筆記 家裡放了一台 NAS、一台跑 Docker 的小主機,或是租了幾台散落各地的 VPS,接著問題就來了:要怎麼從外面連回去? 傳統做法不外乎那幾種:跟 ISP 要固定 IP、在路由器上開通訊埠轉發 (Port forwarding)、再自己架一套反向代理處理憑證。但只要遇上 CGNAT、浮動 IP,或是路由器根本不歸你管,這條路直接斷掉。就算通了,把 80、443、22...

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.comjellyfin.example.com…),所以網域是必需品,不是選配。

DNS 設定

到你的 DNS 供應商那邊加上這兩筆 A 記錄:

類型名稱TTL
A*你的 VPS IP300
A@你的 VPS IP300

第一筆萬用字元 (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協定用途
80TCPHTTP,Let's Encrypt 憑證驗證用
443TCPHTTPS,所有網頁流量跟管理介面
51820UDP站點隧道(Newt 連到 Gerbil)
21820UDP用戶端隧道(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

pangolingerbiltraefik 三個都是 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 還沒生效或防火牆沒開。回去檢查上面的準備步驟。

頁面上依序:

  1. 貼上剛剛複製的 Setup Token
  2. 輸入管理員 email
  3. 設定一組夠強的密碼 — 這是整個系統的最高權限帳號,別偷懶

建立組織 (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)httphttps — 這是指 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.1host.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:pass@domain.com。適合給程式或腳本用。

Email 一次性驗證碼 (OTP) — 先設定允許的信箱白名單(支援萬用字元如 *@example.com),使用者輸入信箱後收到驗證碼才能進。需要先設定好 SMTP。

分享連結 (Shareable Links) — 產生有時效的臨時連結,想收回權限就把連結刪掉。適合「幫我看一下這個」這種一次性需求。

IP / 地理位置規則 — 設定有優先順序的規則,依來源 IP、國家、URL 路徑決定放行或封鎖。例如「只允許台灣的 IP」。

這些可以組合使用,也可以做成共用的 Resource Policy 套用到多個資源上,避免每個服務都要重設一次。

建議至少對所有沒有自帶登入機制的服務開啟一種驗證。開了之後即使有人猜到你的子網域名稱,看到的也只是 Pangolin 的驗證頁面。

不開 22 port 的 SSH

這是 Pangolin 相當實用的功能之一:主機不用對外開 22 port。

在 Resources 新增一個 SSH 類型的資源。SSH 資源不使用 Target,而是直接:

  1. 指定哪些 Site 可以路由到這個資源
  2. 填入後端主機跟 port(例如 192.168.1.50:22
  3. 設定驗證方式(同上一節)

設定完成後,直接用瀏覽器打開這個資源的網址,就會看到一個完整的互動式終端機 — 不需要 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 目前是相當完整的選擇。

參考資料

© 2010 - 2026 丁丁 @ThanatosDi
Powered by theme astro-koharu · Inspired by Shoka