Cockpit 與 Webmin:Ubuntu VPS 該選哪個?
比較 Cockpit 與 Webmin 在 Ubuntu VPS 可變更的內容、登入方式與安全風險,說明為何不應公開密碼登入連接埠,以及何時 SSH 搭配 Ansible 反而更適合。
Cockpit 與 Webmin:簡短結論
Cockpit 與 Webmin 都是可透過瀏覽器管理 Linux 伺服器的 Web 管理面板,但兩者解決的是不同問題。Cockpit 由發行版自己的套件庫提供,透過 systemd、journald、polkit 與 udisks 讀取主機狀態,因此呈現的是一台仍可透過 SSH 管理的伺服器。Webmin 的歷史較久,涵蓋範圍也廣得多:它會寫入 Apache、BIND、Postfix、MariaDB 及數十種其他服務的設定檔,而 Cockpit 不會處理這些服務;此外,Webmin 會以 root 身分執行自己的 Web 伺服器。
如果你需要查看單一主機的即時狀態、讀取日誌及使用緊急終端機,請安裝 Cockpit。如果你需要以表單編輯不想手動設定的服務,請安裝 Webmin。不要讓任何一者以密碼登入方式暴露在公開連接埠上。如果你已經執行超過兩或三台伺服器,誠實的答案通常是兩者皆不選;相較於任何管理面板,SSH 搭配 Ansible 的方式更容易擴充。
每個面板實際上能變更的內容
Cockpit 的基本安裝很小,多數功能區都是可省略的獨立套件:
- systemd 服務與計時器:啟動、停止、啟用,以及讀取 unit 檔案
- 依 unit 與優先級篩選的 journal,其中
journalctl可搭配日期選擇器 - 本機帳號、群組成員資格,以及已授權的 SSH 金鑰
- 使用
cockpit-storaged管理儲存設備:分割區、LVM volume group、檔案系統與掛載點 - 使用
cockpit-podman管理容器;它只管理 Podman - 使用
cockpit-packagekit管理套件更新 - 使用
cockpit-pcp顯示 CPU、記憶體、磁碟與網路的圖表 - 瀏覽器分頁中的 root 終端機
在 Ubuntu VPS 上,有兩個區域看似故障,但實際上並不是。Cockpit 的 Networking 頁面是 NetworkManager 的前端,而 Ubuntu server 映像檔使用 netplan 搭配 systemd-networkd,因此該頁面會缺少內容或顯示空白。不要為了恢復該頁面而在遠端主機安裝 NetworkManager,因為它會接管網路介面,設定錯誤也會讓 SSH 連線中斷。Cockpit 的防火牆控制項是 firewalld 的前端,而 Ubuntu 使用 ufw,因此完全不會顯示防火牆控制項。你仍需在終端機執行 sudo ufw status。
Webmin 涵蓋的範圍大得多,因為它是由各服務模組組成的集合,而不是單一程式:
- 透過表單設定 Apache、nginx、BIND、Postfix、Dovecot、MariaDB、PostgreSQL 與 Samba
- 使用者、群組與磁碟配額
- cron 工作與系統時鐘
- 套件更新,以及可上傳與下載檔案的檔案管理器
- 防火牆前端,包括 iptables 與 firewalld 的前端
- 設定檔備份,以及可將變更推送到其他 Webmin 伺服器的叢集模組
Webmin 會編輯 /etc 下的實際檔案。表單背後沒有隱藏的資料庫,因此如果 /etc 受到版本控制,儲存表單後的 sudo git -C /etc diff 會準確顯示該模組寫入的內容。這是了解任何 Webmin 頁面實際作用的最快方式。Webmin 安裝與首次登入導覽會詳細介紹模組樹狀結構。Virtualmin 與 Usermin 是使用相同引擎建置的獨立產品,分別用於 shared hosting 與終端使用者;本文對暴露風險的所有說明同樣適用於這兩項產品。
每個工具的驗證方式
Cockpit 沒有自己的使用者資料庫。其登入頁面會在 /etc/pam.d/cockpit 中執行 PAM(可插拔驗證模組)堆疊,因此使用的是 Unix 帳號與 Unix 密碼。預設會拒絕 root,因為 /etc/cockpit/disallowed-users 將其列入其中。需要權限的操作會透過 polkit 執行;介面在變更設定前也會再次要求輸入密碼。因此,在提升權限前,頁首可能會顯示「Limited access」。
這項設計在強化過的伺服器上會帶來一個常見結果。如果你依照 停用密碼驗證的僅限金鑰 SSH 登入 設定,帳號可能完全沒有可用的密碼。此時 Cockpit 登入會遭拒,但 ssh 仍可運作。請在伺服器上檢查:
sudo passwd -S deploy以 deploy L 開頭的輸出表示密碼已鎖定,因此 PAM 沒有可接受的密碼,你輸入的任何密碼都無法使用。P 表示已設定可用的密碼。Cockpit 自己的登入頁面不接受 SSH 金鑰。只有當 Cockpit 從你登入的機器連線到另一部主機時,才會使用金鑰。
Webmin 將自己的使用者儲存在 /etc/webmin/miniserv.users,與 /etc/passwd 分開;它也可以設定為使用 Unix 帳號進行驗證。獲授予所有模組權限的 Webmin 使用者,在該機器上等同於 root,與其登入 shell 的設定無關。Webmin 內建 TOTP(以時間為基礎的一次性密碼)支援,也能在多次登入失敗後封鎖主機;這兩項功能都可在 Webmin Configuration 中啟用。Cockpit 只有在你將第二因素加入 PAM 後,才會取得多因素驗證,例如使用 libpam-google-authenticator。
每個元件的更新方式
Cockpit 由發行版打包。在 Ubuntu 24.04 中,它來自套件庫;上游專案建議使用 backports pocket,以取得較新的版本:
. /etc/os-release
sudo apt update
sudo apt install -t ${VERSION_CODENAME}-backports cockpit
sudo systemctl status cockpit.socket
apt policy cockpitapt policy會顯示已安裝的版本,以及其來源套件庫。如果 backports 沒有較新的版本,apt 會退回使用套件庫中的版本,這沒有問題。cockpit.socket應顯示 active (listening)。之後,安全性修正會和 kernel 一起透過相同的 unattended-upgrades 執行取得,來源是你已信任的發行者。
Webmin 不在 Ubuntu 的套件庫中。官方安裝程序會先加入 Webmin 自己的套件庫與簽署金鑰:
curl -o webmin-setup-repo.sh https://raw.githubusercontent.com/webmin/webmin/master/webmin-setup-repo.sh
sudo sh webmin-setup-repo.sh
sudo apt-get install webmin --install-recommends執行前請先閱讀該 script,因為它會以 root 身分執行。此後,伺服器上的每次 apt upgrade 也會從 Webmin 的套件庫取得更新。因此,你已在這台主機上加入另一個具備 root 層級信任的發行者。這就是使用 Webmin 的實際代價,值得用一個明確的例子說明:CVE-2019-15107 是數個 1.9x 套件中的後門,可在未經驗證的情況下執行命令。它之所以影響使用者,是因為專案的 build host 遭到入侵,而不是 source repository 遭到入侵。發行版打包無法完全排除這種情況,但會增加一個由你以外的人員維護的建置與審查步驟。
為什麼兩者都不應監聽公開埠
Cockpit 監聽 TCP 9090,而 Webmin 監聽 TCP 10000,兩者都透過 TLS(transport layer security)搭配自簽憑證,因此首先看到的是瀏覽器警告。建立並信任自簽憑證說明這項警告能告訴你什麼,以及不能告訴你什麼。這兩個埠都持續遭到掃描,而且兩個面板都能取得 root 權限,因此只要密碼遭到猜測或重複使用,就可能完全入侵伺服器。
安全的做法是讓面板繫結至 localhost,再透過 SSH tunnel 存取。對 Cockpit 而言,請覆寫 socket unit:
sudo systemctl edit cockpit.socket[Socket]
ListenStream=
ListenStream=127.0.0.1:9090單獨佔一行的空白 ListenStream= 是必要設定。systemd 會將清單型設定附加到原值,因此沒有這一行時,unit 會保留原本的 0.0.0.0:9090,並加入新的位址,面板仍會公開監聽。套用覆寫設定,並確認目前的監聽狀態:
sudo systemctl daemon-reload
sudo systemctl restart cockpit.socket
sudo ss -lntp | grep 9090輸出必須顯示 127.0.0.1:9090。若位址顯示為 *:9090 或 0.0.0.0:9090,表示覆寫設定尚未生效。接著從自己的電腦建立 tunnel,並瀏覽 https://localhost:9090:
ssh -N -L 9090:127.0.0.1:9090 deploy@203.0.113.10讓本機埠與遠端埠相同。Cockpit 會將瀏覽器的 Origin 標頭,與它認為自己提供服務的位址進行比對,因此使用本機埠 9999 建立 tunnel 時,登入頁面雖然會載入,登入時卻會失敗,而 journalctl -u cockpit 會記錄遭拒絕的來源。若需要不同的本機埠,請在 /etc/cockpit/cockpit.conf 中指定:
[WebService]
Origins = https://localhost:9999 https://127.0.0.1:9999使用 sudo systemctl restart cockpit.socket 重新啟動,讓這項設定生效。Webmin 的對應設定位於 /etc/webmin/miniserv.conf:
bind=127.0.0.1sudo systemctl restart webmin
sudo ss -lntp | grep 10000
ssh -N -L 10000:127.0.0.1:10000 deploy@203.0.113.10Webmin 也會檢查表單提交中的 Referer 標頭,並拒絕看似來自其他主機的請求;這正是第一次嘗試使用反向代理時會失敗的原因。同一檔案中的 referers= 行可用來允許代理的主機名稱,而 webprefix= 可用來指定 Webmin 所在的路徑。
另一個選項是使用需要驗證的反向代理:前方使用 nginx,並由 Authentik 單一登入層處理登入。這種方式可行,但次於 SSH tunnel。面板在代理後方仍以 root 身分執行,而且你現在必須維護兩個對外入口,而不是一個。Tunnel 完全不會在網際網路上新增監聽服務,並且可重複使用你已經妥善保護的 SSH key。
已執行正式服務的伺服器應選用哪個面板
Cockpit,理由有兩項,適用於其他人依賴這台機器的情境。它採用 socket activation,因此 cockpit-ws 只會在工作階段開啟時執行,不會有永久執行且等待連接埠的 root daemon。Cockpit 也不會接管任何設定:移除套件後,所有服務仍會完全按照原狀執行,因為 Cockpit 不會儲存自己的設定。無論是否有人登入,Webmin 的 miniserv.pl 都會持續常駐。使用 systemctl status webmin 檢查其成本;此命令會輸出執行中程序的常駐記憶體使用量。
如果需要 Webmin 的 DNS 或 mail 模組,請為它們配置專用伺服器。只執行單一工作並繫結至 127.0.0.1 的 Webmin 伺服器,風險較容易控制。Webmin 與面向客戶的應用程式共用主機則不是如此。安裝任一面板前,先完成基礎設定:新 VPS 的前 10 分鐘涵蓋兩個面板都預期已存在的非 root 使用者與防火牆。
何時不應選擇上述任一方案
面板是以伺服器為單位手動操作,且不會記錄變更內容或原因。只有一台主機時這樣做沒有問題。到了 5 台主機,您會不斷重複相同操作;到了 20 台,則很難確認是哪台伺服器漏了變更。Cockpit 可透過 SSH 將其他主機加入同一個工作階段,但近期版本預設停用此功能,並要求在 /etc/cockpit/cockpit.conf 中設定 AllowMultiHost=yes;而且您仍然需要在面板中將相同變更點擊 5 次。
另一種方式是使用一般的 SSH,並將設定放在 git repository 中。從單一位置管理多台 Linux 伺服器說明這種架構;第一個 Ansible playbook則能從單一檔案將相同的防火牆規則套用到所有主機,並可透過 diff 審查變更。容器管理也是相同做法:如Docker Compose 基礎指南所示,從 git 中的檔案透過 SSH 執行 docker compose up -d,比在任何面板中逐步點選更有效率;而且 Cockpit 原本就不管理 Docker。
面板適合處理終端機不擅長的工作,例如閱讀 metrics graph,或找出 40 個 unit 中哪些啟動失敗。凡是會執行超過 2 次的工作,都應改用程式碼。
失敗情況與您會看到的字串
Cockpit 拒絕 SSH 可接受的密碼。 該帳戶僅能使用 cryptographic key 登入。sudo passwd -S alice 會在第二個欄位輸出 L,因此 PAM 沒有可供驗證的密碼。使用 sudo passwd alice 設定密碼,或保留該帳戶供 SSH 使用,改以其他使用者登入 Cockpit。
即使密碼正確,Cockpit 仍拒絕 root。 /etc/cockpit/disallowed-users 會列出 root。請使用具備 sudo 權限的一般使用者登入。這是預期的操作方式,因為 polkit 會記錄是哪位使用者提升了權限。
Cockpit 沒有 Networking 或 Firewall 頁面。 這些頁面需要 NetworkManager 和 firewalld。Ubuntu VPS 使用 netplan 搭配 systemd-networkd 和 ufw,因此不會顯示這些頁面。系統沒有故障,請繼續透過 SSH 使用 ufw。
透過 tunnel 載入 Cockpit 登入頁面,但登入失敗。 本機埠與遠端埠不同,因此 Origin 檢查失敗,journalctl -u cockpit 會顯示相關資訊。請使兩端使用相同的埠,或在 /etc/cockpit/cockpit.conf 中設定 Origins。
將 Webmin 放在 proxy 後方後,表單提交失敗。 Referer 檢查會拒絕這些請求。請在 /etc/webmin/miniserv.conf 的 referers= 中加入 proxy 主機名稱;如果控制面板是透過路徑提供服務,也請設定 webprefix=。
不確定控制面板是否對外公開。 sudo ss -lntp | grep -E '9090|10000' 可從伺服器本身確認此資訊。Webmin 會將每次登入嘗試寫入 /var/webmin/miniserv.log;每次變更監聽方式後,都應查看一次該日誌。
FAQ
對單一 Ubuntu VPS 而言,Cockpit 或 Webmin 哪個比較好?
對多數人而言,Cockpit 較適合,因為它來自 Ubuntu 自己的套件庫,會與系統一同套用修補程式,而且只在瀏覽器工作階段開啟時執行。若需要以表單編輯 Cockpit 不支援的服務,例如 BIND 或 Postfix,請選擇 Webmin;但要接受其代價:Webmin 的網頁伺服器會持續以 root 身分執行,更新也來自 Webmin 自己的套件庫。
可以在同一台伺服器上執行 Cockpit 和 Webmin 嗎?
可以。兩者使用不同的連接埠,分別是 9090 和 10000,因此不會衝突,因為它們都是直接編輯系統,而不是各自接管系統。不過,這仍不是理想的取捨。兩個管理面板都會在同一台機器上提供可取得 root 權限的獨立登入,因此只是多幾次點擊,卻讓暴露面增加一倍。若同時安裝兩者,請將兩者繫結至 127.0.0.1,再透過 SSH tunnel 連線。
將連接埠 9090 或 10000 開放至網際網路安全嗎?
若使用密碼登入,並不安全。兩個管理面板都能通往 root,而這兩個連接埠通常在開放後數小時內就會被例行掃描發現。請將管理面板繫結至 127.0.0.1,然後執行 ssh -N -L 9090:127.0.0.1:9090 user@host,並瀏覽至 https://localhost:9090。使用 sudo ss -lntp | grep 9090 確認;其輸出必須顯示 127.0.0.1:9090,而不是 0.0.0.0:9090。經驗證的反向代理是另一個可接受的選項。
為什麼使用 key 的 SSH 可以登入,但 Cockpit 登入失敗?
Cockpit 透過 PAM 使用 Unix password 進行驗證,其登入頁面不接受 SSH keys。在強化安全性的伺服器上,帳號通常沒有可用的 password。請執行 sudo passwd -S youruser:第二個欄位若為 L,表示 password 已鎖定,因此 PAM 沒有可接受的 password,所有嘗試都會遭拒。使用 sudo passwd youruser 設定 password,或改用其他帳號登入管理面板。
Cockpit 能管理 Docker containers 嗎?
不能。Cockpit 的 container 頁面來自 cockpit-podman,管理的是 Podman。舊版 Docker module 多年前已移除,不會恢復。如果服務執行於 Docker,請透過 SSH 使用版本控制中的 compose file 管理,並讓 Cockpit 處理周邊的系統工作,例如 journal 和 disks。