SSD Nodes Learn 🎉 VPS $5.50/月起
指南 Matt Connor作者: Matt Connor · 已更新 2026-08-13

FreeBSD 安全更新:freebsd-update 與 pkg audit

FreeBSD 的基礎系統與套件必須分開修補:使用 freebsd-update 更新 kernel 與 userland,再用 pkg audit 找出套件漏洞,兩套工具也要分別追蹤公告來源。

FreeBSD 如何處理安全更新

FreeBSD 使用兩個不同的工具處理安全更新,因為 FreeBSD 伺服器由兩個不同部分組成。基礎系統,也就是隨版本一同發布的 kernel 與 userland,使用 freebsd-update 修補。其上安裝的所有內容都是 package,使用 pkg 修補。只執行其中一個而略過另一個,主機就會有一半未套用修補,而且系統不會主動告訴你。

SSD Nodes 不提供 FreeBSD 映像檔。我們的方案執行 Linux。不過,這篇文章仍然有參考價值,因為讀者重疊度很高:使用我們 Ubuntu 與 Debian 伺服器的人,也會在防火牆上執行 FreeBSD,或維護一台繼承而來的 FreeBSD 主機。這種分開修補的模型最容易讓 Linux 管理員忽略,因此值得特別說明。以下所有指令、公告格式與支援日期,均已於 August 2026 依據 FreeBSD security page 與該專案的 manual pages 進行確認。

執行指令前先注意一點。FreeBSD 不會在基礎系統中安裝 sudo。以下所有操作都需要 root 權限。請使用 su -,或先從 packages 安裝 sudodoas

基礎系統與套件是兩個獨立的世界

在 Ubuntu 中,apt 管理整台機器。核心、opensslnginx 與您自行安裝的工具,全部由同一個工具以 .deb 檔案的形式提供,並由 apt upgrade 一併更新。

FreeBSD 將這部分一分為二。基礎系統以單一單位建置,也以單一單位進行版本管理:15.1-RELEASE-p3 是涵蓋核心、C 函式庫、sshd 以及 /usr/lib 中 OpenSSL 副本的單一版本號碼。其中沒有任何內容來自 pkg。其他所有內容都位於 /usr/local 下,由 ports tree 建置成 binary package 後提供,並擁有自己的版本。

因此,一台機器上可能同時存在兩份 OpenSSL:/usr/lib 中的基礎系統副本只能由 freebsd-update 修補,而 /usr/local/lib 中的套件副本只能由 pkg 修補。程式使用哪一份,取決於它連結的是哪一份;從套件安裝的軟體通常會連結套件副本。修補其中一份不會影響另一份。

以下 3 個指令可顯示目前的狀態:

freebsd-version -u
freebsd-version -k
uname -r

freebsd-version -u 會顯示已安裝 userland 的修補層級。freebsd-version -k 會顯示已安裝核心的修補層級,而 freebsd-version(1) 明確說明這為何不同於 uname:「如果已安裝新核心但系統尚未重新開機,freebsd-version 會顯示新核心的版本與修補層級。」uname -r 會顯示目前正在執行的核心。此外還有 freebsd-version -r,它會顯示正在執行的核心,但「不受環境變數影響」。這在 jail 內很重要,因為其中通常會將 UNAME_r 設為其他值。

安全公告與勘誤通知

FreeBSD Security Team 會發布兩種通知,兩者代表的事項不同。

Security Advisory 涵蓋 base system 中的安全性漏洞。其識別碼格式如下:FreeBSD-SA-26:55.elf。其中包含 SA 字母、兩位數年份、該年度依序遞增的編號,以及受影響的元件。FreeBSD-SA-26:52.if_wgFreeBSD-SA-26:50.kqueue 都發布於 2026-07-29。完整清單位於 FreeBSD 公告頁面

Errata Notice 涵蓋值得推送至 release branch 的正確性或穩定性問題,但不涉及安全性影響。格式相同,只是以 EN 取代 SAFreeBSD-EN-26:19.zfsFreeBSD-EN-26:18.tzdata。時區資料更新是典型範例。過時的時區資料不會讓攻擊者入侵你的系統,但在套用修正前,時間戳記會是錯誤的。勘誤通知列於 FreeBSD 勘誤通知頁面

這兩種通知都使用 Security Officer 的 PGP(pretty good privacy)金鑰簽署,並封存於 security.FreeBSD.org;兩者也都會透過 freebsd-update 傳送至你的機器。

以下是 Linux 管理員容易忽略的部分。這兩種通知都不涵蓋套件。安全性頁面已明確說明:FreeBSD Ports Collection 中的問題「會另外記載於 FreeBSD VuXML 文件」。nginx 套件中的遠端漏洞,永遠不會取得 SA 編號。如果你只監控公告來源,就永遠不會得知這類問題。

如何得知 FreeBSD 安全更新?

應加入的郵件清單是 freebsd-security-notifications。該清單由管理員審核,郵件量少,內容本身就是安全公告與勘誤通知。請在 lists.freebsd.org 訂閱。

freebsd-announce 同樣由管理員審核,除了安全公告也會發布版本公告。如果您希望使用一個清單取得所有資訊,這個選擇較為合適。freebsd-security 是討論清單,適合用來閱讀相關討論,但不應依賴它得知需要套用修補程式。

這些清單只提供 base system 的資訊。套件漏洞不會透過郵件寄送。您必須執行指令來查詢這些漏洞。

pkg audit 與其背後的資料庫

VuXML(Vulnerabilities and Exposures Markup Language,漏洞與暴露標記語言)是 FreeBSD 專案用來記錄 ports 與 packages 安全性問題的資料。每筆資料會列出受影響的 package、存在漏洞的版本範圍、CVE(common vulnerabilities and exposures)識別碼,以及簡短說明。完整資料可在 VuXML 索引 中瀏覽,並可依 package、CVE 或日期排序。

pkg audit 是用來讀取這些資料的工具:

pkg audit -F

-F 會在檢查前先取得資料庫的最新副本。每次都應使用它。若沒有 -F,比對時使用的就是機器現有副本,而該副本可能已經過時數個月,因此檢查結果為乾淨也沒有意義。此命令會將每個已安裝的 package 版本與每筆 VuXML 資料比對,列出每個相符項目及其 CVE 編號和 VuXML 頁面連結,最後輸出一行統計,說明在多少個已安裝 package 中發現多少個問題。

pkg-audit(8) 的另外兩個旗標也值得了解。pkg audit -r 也會「列出相依於有漏洞 package 的 packages,因此這些 packages 也可能存在漏洞」,讓你知道某個有漏洞的函式庫之所以重要,是因為有 6 個已安裝項目會連結它。pkg audit -R 會以 JSON 或其他機器可讀格式輸出相同結果,供監控檢查使用。

pkg package 會在 /usr/local/etc/periodic/security/410.pkg-audit 安裝週期性執行的 script。它會在每日安全性檢查中執行,並將結果寄送給 root。確認 /etc/periodic.conf 中有以下設定:

daily_status_security_pkgaudit_enable="YES"

這封每日郵件是 FreeBSD 最接近 Ubuntu 上的 unattended-upgrades 作法 的機制,而兩者的差異正是重點:unattended-upgrades 會在你休息時安裝修正程式,而 pkg audit 只會告知你需要修正。pkg audit 只會回報,不會修補。原始的 FreeBSD 系統不會在未經你操作的情況下安裝安全性更新。

修正有漏洞的套件

pkg update
pkg upgrade

FreeBSD 套件儲存庫沒有僅提供安全性更新的 pocket。Ubuntu 可以只從 noble-security 取得套件,並讓其他套件維持原狀。FreeBSD 沒有對等機制,因此修正單一有漏洞的套件時,必須採用儲存庫目前提供的版本,以及隨之變動的相依套件。請將套件修補視為變更,而不是背景工作。

你所使用的儲存庫分支,決定修正內容多久會到達系統。預設是 quarterly 分支;手冊 說明,這個分支只接受非功能性更新,因此「提供更可預測且穩定的使用體驗」。latest 分支則採用所有套件的最新版本。因此,當 pkg audit -F 回報套件有漏洞,而 pkg upgrade 顯示無事可做時,表示修正內容尚未進入你使用的分支,這就是造成混淆的原因。

若要將機器切換至 latest 分支,請複製系統隨附的儲存庫檔案,再編輯副本:

mkdir -p /usr/local/etc/pkg/repos
cp /etc/pkg/FreeBSD.conf /usr/local/etc/pkg/repos/FreeBSD.conf

在副本的 url 行中,將 quarterly 改為 latest,然後執行 pkg update -f 以取得新的套件目錄。請複製檔案,不要憑記憶輸入儲存庫名稱:/etc/pkg/FreeBSD.conf 內的名稱才是系統實際使用的名稱,而 /usr/local/etc/pkg/repos 下的檔案只會覆寫名稱完全相符的儲存庫。

套用基礎系統修補程式

freebsd-update fetch
freebsd-update install

fetch會下載目前版本的修補程式,並列出將變更的檔案。沒有需要處理的內容時,它會輸出 No updates needed to update system to 15.1-RELEASE-p3.後結束。有需要處理的內容時,它最後會提示你執行安裝命令。執行 freebsd-update install前,不會套用任何變更,因此隨時執行 fetch都很安全。

freebsd-update(8)會為 ALPHA、BETA、RC 與 RELEASE 版本提供二進位更新,但不適用於 PRERELEASE、STABLE 或 CURRENT。若你使用 stable/15,就必須從原始碼建置,而這項工具沒有可提供的內容。

自動化下載,但手動執行安裝。手冊中對 /etc/crontab的說明如下:

@daily                                  root    freebsd-update cron

freebsd-update cron會隨機等待 1 到 3600 秒,然後執行與 fetch完全相同的更新下載作業,並在有更新等待處理時寄信通知 root。隨機等待的目的,是避免網際網路上的所有 FreeBSD 電腦在同一秒連線到更新鏡像站。

輸出中有兩項內容常讓人困惑。在沒有原始碼樹的伺服器上,src component not installed, skipped是正常現象,不是錯誤。元件集合由 /etc/freebsd-update.conf中的 Components行控制,可選項目為 srcworldkernel

如果安裝失敗,freebsd-update rollback會解除安裝最近安裝的更新。使用 ZFS root 時,可以先建立 boot environment,提供更好的復原方式:

bectl create pre-patch
freebsd-update fetch install

如果套用修補程式後的系統無法開機,從 loader 選單選取舊的 boot environment,即可回到原本的狀態。這項復原機制是 使用 ZFS 作為 root 檔案系統的實際優點之一;在兩個環境產生差異前,幾乎不會額外佔用磁碟空間。

我的 FreeBSD 發行版本仍受支援嗎?

每個發行版本都有固定的支援期間,安全性頁面會以分支表格公布。截至 2026 年 8 月,該表格如下:

  • releng/15.1,即 15.1-RELEASE,支援至 31 March 2027
  • releng/15.0,即 15.0-RELEASE,支援至 30 September 2026
  • releng/14.4,即 14.4-RELEASE,支援至 31 December 2026
  • stable/15,支援至 31 December 2029
  • stable/14,支援至 30 November 2028

點版本的支援期間很短。15.0-RELEASE 在本文撰寫後約七週便停止支援,因為 15.1 已發布,並開始計算其支援期限。穩定分支的支援可持續數年,而且它們是 freebsd-update 不提供服務的原始碼分支。

使用 freebsd-version -u 檢查自己的版本,並與表格比對。freebsd-update 也會發出警告。接近期限時,fetch 會輸出:

WARNING: FreeBSD 15.0-RELEASE is approaching its End-of-Life date.
It is strongly recommended that you upgrade to a newer
release within the next 2 months.

期限過後,警告會變成 WARNING: FreeBSD 15.0-RELEASE HAS PASSED ITS END-OF-LIFE DATE.。不受支援的發行版本仍可運作,但不再收到安全性公告。這表示下一個 base 漏洞將永遠由你自行承擔。

升級至較新的發行版本時,先執行 freebsd-update -r 15.1-RELEASE upgrade,再執行 freebsd-update install,然後重新開機;接著再次執行 freebsd-update install,再執行 pkg-static upgrade -f,讓所有套件針對新的函式庫重新安裝,最後執行 freebsd-update install。手冊指出,視函式庫版本號是否變更而定,安裝階段可能只有 2 個,而不是 3 個。請安排維護時段,並在開始前閱讀FreeBSD 15 伺服器設定指南

重新開機,還是重新啟動服務就足夠?

FreeBSD 可透過一項比較回答這個問題:

freebsd-version -k
uname -r

freebsd-version -k 是磁碟上的 kernel。uname -r 是記憶體中的 kernel。字串不同,表示已安裝新的 kernel,但目前尚未使用,因此需要重新開機。字串相同,表示修補程式未修改 kernel,重新開機也不會帶來任何效果。

套用 userland 修補程式後,請重新啟動使用該程式碼的服務。修正 /usr/lib 中的 base OpenSSL,對於三週前啟動且仍將舊函式庫映射至其位址空間的 sshd 不會產生任何作用。磁碟上的檔案已更新,但執行中的程序尚未更新。

service sshd restart

相同規則也適用於套件。pkg upgrade 會取代磁碟上的 binary,但執行中的程序仍開啟舊版本,因此 service nginx restart 才是讓修正實際生效的步驟。

base system 沒有相當於 Debian needrestart 的機制,因此不會提示你,也不會維護清單。你必須追蹤哪些服務連結至哪些已修補的函式庫,或是在任何修改 base libraries 的修補程式後重新開機。對於設定納入版本控制的伺服器,重新開機是例行操作;這比誤以為系統已完成修補、實際上卻尚未生效便宜得多。

執行 jails 的機器修補

jail 共用主機核心,因此核心安全公告涉及主機問題,而該主機上的每個 jail 都會受到影響。修補主機並重新開機後,所有 jail 的核心部分就完成修補。每個 jail 內的 userland 都是獨立安裝,具有各自的修補層級;從主機執行 freebsd-version -j <jail> 即可回報相關資訊。jail 內的套件也彼此獨立,pkg -j <jail> audit -F 可在不進入 jail 的情況下稽核這些套件。這種共用核心與獨立 userland 的區分,也是影響 jail 與 Docker container 比較方式 的相同結構差異。

Ubuntu 的對應方式

每個 FreeBSD 操作習慣都有對應方式,因此可以在兩個系統之間沿用相同流程。

  • 基礎系統修補:先執行 freebsd-update fetch,再執行 freebsd-update install。在 Ubuntu 上,執行 apt update && apt upgrade 即可同時涵蓋基礎系統與其他套件。
  • 第三方軟體:在 FreeBSD 上執行 pkg update && pkg upgrade。在 Ubuntu 上再次執行 apt
  • 已知漏洞檢查:在 FreeBSD 上執行 pkg audit -F。在 Ubuntu 24.04 上,最接近的指令是 pro security-status,可顯示已安裝套件的安全性更新,包括 Expanded Security Maintenance 內容。
  • 自動安裝:Ubuntu 上的 unattended-upgrades 會代為套用安全性更新。FreeBSD 沒有完全等效的功能,因此 freebsd-update cron 會負責下載並寄送郵件,你仍須手動安裝。
  • 安全公告來源:freebsd-security-notifications 提供 FreeBSD-SA 與 FreeBSD-EN 項目。ubuntu-security-announce 提供 Ubuntu Security Notices。
  • 漏洞資料庫:FreeBSD ports 與套件使用 VuXML;Ubuntu 套件使用 Ubuntu CVE tracker。
  • 重新啟動檢查:在 FreeBSD 上,比對 freebsd-version -kuname -r。在 Ubuntu 上,則檢查是否存在 /var/run/reboot-required
  • 支援期間:FreeBSD security page 上的分支表格;Ubuntu 則參考 release schedule 與 pro security-status

兩個系統的基本流程相同:訂閱公告來源、依排程執行稽核,然後決定要安裝哪些更新,以及何時重新啟動。FreeBSD 不會代你完成後半段,因此你必須明確執行這些步驟。Linux 與 FreeBSD 作為伺服器平台的完整比較說明了在兩者之間搬移工作負載時,還有哪些部分會改變。

FAQ

freebsd-update 也會修補我的套件嗎?

不會。freebsd-update 只涵蓋基礎系統,也就是該版本隨附的 kernel 與 userland。安裝在 /usr/local 下的軟體來自套件,會由 pkg upgrade 進行修補。執行 pkg audit -F,找出已安裝且具有已知漏洞的套件,因為基礎系統的安全公告不會提及這些漏洞,安全性郵件清單也不會發布相關通知。

如何知道 FreeBSD 更新是否需要重新開機?

比較 freebsd-version -kuname -r。前者會顯示磁碟上已安裝的 kernel,包括剛寫入但尚未開機載入的版本。後者會顯示目前正在執行的 kernel。兩者字串不同表示需要重新開機。若字串相同,表示這次只修補了 userland,因此只需重新啟動受影響的服務,例如 service sshd restart,因為執行中的程序會持續對映舊的函式庫,直到程序重新啟動。

Security Advisory 與 Errata Notice 有何差異?

Security Advisory(例如 FreeBSD-SA-26:55.elf)會修正基礎系統中的安全漏洞。Errata Notice(例如 FreeBSD-EN-26:18.tzdata)會修正不影響安全性的正確性或穩定性問題,例如過時的時區資料。兩者都採用「年份、冒號、序號、元件」的格式。兩者都由 Security Officer 簽署,並透過 freebsd-update 發布;兩者都不涵蓋從 ports 或套件安裝的軟體。

FreeBSD 有 unattended-upgrades 的替代方案嗎?

基礎系統沒有。freebsd-update cron 會下載待處理的基礎系統修補程式並寄信給 root,但不會安裝。pkg 安裝的 periodic script 會每日執行 pkg audit 並寄送結果,也不會升級任何內容。若要無人值守安裝,必須自行使用 cron job 建立機制。此外,FreeBSD 套件升級會安裝最新版本,而不是只套用安全性 backport,因此多數管理員會先閱讀郵件,再手動安裝。

如何確認我的 FreeBSD 版本仍受支援?

執行 freebsd-version -u 取得 userland 版本,然後與 FreeBSD security page 上的支援分支表比較。點版本的支援期間很短:截至 August 2026,15.0-RELEASE 將於 30 September 2026 結束支援,而 15.1-RELEASE 支援至 31 March 2027。freebsd-update fetch 會在日期接近時發出警告;日期過後,會輸出一行表示該版本 HAS PASSED ITS END-OF-LIFE DATE。自此之後,任何新增的公告都不適用於該版本。

#freebsd#security#patching#advisories#pkg