23.2. FreeBSD Update

Written by Tom Rhodes.
Based on notes provided by Colin Percival.

即時應用安全性更新與升級作業系統到新的發行版本對一個持續運作的系統是重要的。FreeBSD 包括一個叫 freebsd-update 的工具程式可以執行這兩項任務。

這個工具程式支援 FreeBSD 二進制安全性與和錯誤更新, 不需要手動編譯和安裝修復或新核心。 安全性團隊目前支援的所有架構和發行版都可以取得二進制更新。 目前支援的發行版列表和他們的支援期限都列於 http://www.FreeBSD.org/security/

這個工具程式也支援作業系統升級到次要的發行版本和升級到令一個發行版分支升級到新的發行版本前,要檢查他的發行宣告,因為他包含發行版本相關的重要資訊。發行公告可以由http://www.FreeBSD.org/releases/取得。

注意:

如果有使用crontab來執行 freebsd-update(8),那必須在升級作業系統前先停用。

這節描述 freebsd-update 使用的設定檔, 示範如何運用安全性修補和如何升級到主要或次要的作業系統發行版, 以及討論某些升級作業系統的考量。

23.2.1. 設定檔

freebsd-update預設的設定檔不需變更即可運作。 有些使用者可能想要調校預設的設定檔 /etc/freebsd-update.conf 來對程序有更好的控制。這個設定檔的註解說明了可以使用的選項, 但以下可能需要更多一些的解釋:

# Components of the base system which should be kept updated.
Components world kernel

這個參數控制 FreeBSD 的哪個部份將保持最新。 預設是將更新整個 base system 和核心。 個別元件可以被指定, 例如:src/basesrc/sys。 然而最好的選項是維持預設設定, 因為改變設定去包括特定項目,則每個需要的項目都必須要列出。 時間一久可能會因為原始碼和二進制檔案沒有更新而造成慘重的後果。

# Paths which start with anything matching an entry in an IgnorePaths
# statement will be ignored.
IgnorePaths /boot/kernel/linker.hints

保持特定的目錄,例如 /bin/sbin, 在更新過程不被更動,可以將他們的路徑加到此敘述中。 這個選項可以防止 freebsd-update覆蓋本機的修改。

# Paths which start with anything matching an entry in an UpdateIfUnmodified
# statement will only be updated if the contents of the file have not been
# modified by the user (unless changes are merged; see below).
UpdateIfUnmodified /etc/ /var/ /root/ /.cshrc /.profile

這個選項只會更新特定目錄中未修改的設定檔。 任何使用者修改的檔案都不會自動更新。 有另一個選項── KeepModifiedMetadata會指示 freebsd-update 在合併時將改變儲存下來

# When upgrading to a new FreeBSD release, files which match MergeChanges
# will have any local changes merged into the version from the new release.
MergeChanges /etc/ /var/named/etc/ /boot/device.hints

列出 freebsd-update應嘗試合併的設定檔目錄。 檔案合併過程是一系列類似mergemaster(8)diff(1)修補, 但是選項比較少。 合併可以接受,開啟編輯器,或是令freebsd-update中止。 如果有疑慮,備份 /etc,然後同意合併。 更多關於mergemaster的資訊, 參見 節 23.6.4, “Merging Configuration Files”

# Directory in which to store downloaded updates and temporary
# files used by FreeBSD Update.
# WorkDir /var/db/freebsd-update

這個目錄是所有修補檔和暫存檔放置處。 當使用者進行版本升級時,這個位置應該要有至少1GB的可用磁碟空間。

# When upgrading between releases, should the list of Components be
# read strictly (StrictComponents yes) or merely as a list of components
# which *might* be installed of which FreeBSD Update should figure out
# which actually are installed and upgrade those (StrictComponents no)?
# StrictComponents no

當這個選項設定為yesfreebsd-update 將會假設 Components 列表已完成,將不會嘗試做列表外的改變。 實際上 freebsd-update將嘗試更新每一個屬於 Components 列表的檔案。

23.2.2. 運用安全性修補

運用 FreeBSD 安全性修補的過程已經被簡化, 允許系統管理員使用freebsd-update保持系統更新。 更多關於FreeBSD 安全性報告的資訊可以參考 節 13.11, “FreeBSD Security Advisories”

FreeBSD 安全性修補可以使用以下指令下載與安裝。 第一個指令將決定是否有尚未完成的修補,如果有,將列出執行修補將會變更的檔案清單。第二個指令將會執行修補。

# freebsd-update fetch
# freebsd-update install

如果更新執行任何核心修補,系統將會重新開機以使用修補過的核心。 如果在任何執行中的二進位檔進行修補,被影響的應用程式將會重新啟動來使用修補過的二進位檔。

將以下項目加入 /etc/crontab 系統可以每天自動檢查是否有更新:

@daily                                  root    freebsd-update cron

如果有新的修補,它們將會自動下載,但是還不會執行。 管理者root 將會收到email來檢視修補然後手動執行 freebsd-update install 來安裝

如果有發生任何錯誤,freebsd-update 可以使用以下指令回溯最後的變更:

# freebsd-update rollback
Uninstalling updates... done.

再次,如果核心或任何核心模組有變更,系統將重新開機,受影響的二進位檔會重新執行。

只有 GENERIC 核心可以自動被 freebsd-update 更新。 如果有安裝自訂的核心,在freebsd-update 完成安裝更新後,將會被重新編譯和重新安裝。 然而,如果 /boot/GENERIC 存在, freebsd-update將會偵測和更新 GENERIC 核心, 即使他並非目前系統正在執行的核心。

注意:

永遠在 /boot/GENERIC 保留一份 GENERIC 核心的備份。這對於診斷不同的問題與版本的升級有幫助。 參考節 23.2.3.1, “ FreeBSD 9.X 以上自訂核心”節 23.2.3.2, “FreeBSD 8.X 自訂核心” 關於如何備份 GENERIC 核心的說明

除非 /etc/freebsd-update.conf 的預設設定被改變, freebsd-update將安裝更新過的核心原始碼和其餘的更新 然後就可以照平常的方式重新編譯和重新安裝新的自訂核心。

freebsd-update 發行的更新並非總是包含核心。 如果核心的原始碼沒有被 freebsd-update install 變更,並不需要重新編譯自訂核心。 然而 freebsd-update 總是會更新 /usr/src/sys/conf/newvers.sh。目前修補的程度, 如同執行 uname -r 顯示的 -p 數字是由這個檔案取得。 即使沒有做任何改變,重新編譯核心會讓 uname 正確地報告目前系統修補的程度。 這對於維護多個系統特別有幫助,可以讓你快速評估每個系統安裝的更新。

23.2.3. 執行主要和次要的版本升級

從FreeBSD的次要版本升級到另一個版本,例如從 FreeBSD 9.0 到 FreeBSD 9.1, 叫作 次要版本更新。 主要版本更新發生在當 FreeBSD 從一個主要版本升級到主要版本升級到另一個主要版本時 ,例如從 FreeBSD 9.X 到 FreeBSD 10.X。 兩種更新都可以透過提供 freebsd-update 發行版本來執行。

注意:

如果系統正在執行自訂的核心,開始升級前, 確定 GENERIC 核心的副本在 /boot/GENERIC。 參考節 23.2.3.1, “ FreeBSD 9.X 以上自訂核心”節 23.2.3.2, “FreeBSD 8.X 自訂核心” 關於如何製作 GENERIC核心副本的說明。

以下的指令執行在 FreeBSD 9.0 系統時, 將會把系統升級至 FreeBSD 9.1:

# freebsd-update -r 9.1-RELEASE upgrade

當收到這個指令後, freebsd-update 將會評估設定檔和目前的系統來收集升級需要的資訊。 螢幕上的清單會顯示偵測到或沒偵測到哪些元件。例如:

Looking up update.FreeBSD.org mirrors... 1 mirrors found.
Fetching metadata signature for 9.0-RELEASE from update1.FreeBSD.org... done.
Fetching metadata index... done.
Inspecting system... done.

The following components of FreeBSD seem to be installed:
kernel/smp src/base src/bin src/contrib src/crypto src/etc src/games
src/gnu src/include src/krb5 src/lib src/libexec src/release src/rescue
src/sbin src/secure src/share src/sys src/tools src/ubin src/usbin
world/base world/info world/lib32 world/manpages

The following components of FreeBSD do not seem to be installed:
kernel/generic world/catpages world/dict world/doc world/games
world/proflibs

Does this look reasonable (y/n)? y

此時,freebsd-update 將嘗試下載所有升級需要的檔案。 在某些案例,使用者會被提示一些關於安裝什麼或是如何進行的問題。

當使用自訂核心,上述的步驟將會產生如下列的警告:

WARNING: This system is running a "MYKERNEL" kernel, which is not a
kernel configuration distributed as part of FreeBSD 9.0-RELEASE.
This kernel will not be updated: you MUST update the kernel manually
before running "/usr/sbin/freebsd-update install"

這個警告可以安全地忽略,升級過程將會立即使用更新過的 GENERIC 核心

一旦所有的修補都被下載到本地的系統, 它們將會被運用。這個過程可能會花點時間,取決於機器的速度和工作量 設定檔將會被合併。 合併的過程中當檔案被合併或是手動合併螢幕上出現編輯器時需要使用者介入。 每一個成功合併的結果將會顯示給使用者。 失敗或是被忽略的合併將會使程序中斷。使用者稍候可能想要備份 /etc 和手動合併重要的檔案,例如: master.passwdgroup

注意:

當所有修補和合併在另一個目錄進行時,系統還不會被警告。 一旦所有修補都成功運用,所有設定檔都被合併,而且過程順利,使用者可以以下指令來將這些改變付諸於磁碟上:

# freebsd-update install

核心和核心模組將會先被修補。如果系統正在執行自訂核心,使用 nextboot(8) 指令設定下次開機的核心為更新過的 /boot/GENERIC

# nextboot -k GENERIC

警告:

如果機器以遠端遙控來更新, 使用GENERIC核心重新開機前, 確定他包含所有系統開機需要的驅動程式而且連接網路, 特別是當執行的自訂核心包含核心模組提供內建功能時, 確定暫時地使用 /boot/loader.conf 工具載入這些模組到 GENERIC 核心。 建議停用非必須的服務和磁碟與網路掛載直到升級程序完成。

機器現在應該更新過的核心重新開機:

# shutdown -r now

一旦系統重新上線,使用以下指令重新開始 freebsd-update。 因為程序的狀態已被儲存, freebsd-update 將不會重頭開始,他會進行到下一個階段 ,移除所有舊的共用程式庫和目標檔。

# freebsd-update install

注意:

根據程式庫版本編號, 可能有兩個而不是三個安裝階段。

升級程序現在完成了。如果這是主要的版本升級,參考 節 23.2.3.3, “主要版本更新後更新 Packages” 的描述重新安裝所有的ports和套件。

23.2.3.1. FreeBSD 9.X 以上自訂核心

使用 freebsd-update 前,確定有一份核心的副本, ensure that a copy of the GENERIC kernel exists in /boot/GENERIC. If a custom kernel has only been built once, the kernel in /boot/kernel.old is the GENERIC kernel. Simply rename this directory to /boot/kernel.

If a custom kernel has been built more than once or if it is unknown how many times the custom kernel has been built, obtain a copy of the GENERIC kernel that matches the current version of the operating system. If physical access to the system is available, a copy of the GENERIC kernel can be installed from the installation media:

# mount /cdrom
# cd /cdrom/usr/freebsd-dist
# tar -C/ -xvf kernel.txz boot/kernel/kernel

Alternately, the GENERIC kernel may be rebuilt and installed from source:

# cd /usr/src
# make kernel __MAKE_CONF=/dev/null SRCCONF=/dev/null

For this kernel to be identified as the GENERIC kernel by freebsd-update, the GENERIC configuration file must not have been modified in any way. It is also suggested that the kernel is built without any other special options.

Rebooting into the GENERIC kernel is not required as freebsd-update only needs /boot/GENERIC to exist.

23.2.3.2. FreeBSD 8.X 自訂核心

On an FreeBSD 8.X system, the instructions for obtaining or building a GENERIC kernel differ slightly.

Assuming physical access to the machine is possible, a copy of the GENERIC kernel can be installed from the installation media using the following commands:

# mount /cdrom
# cd /cdrom/X.Y-RELEASE/kernels
# ./install.sh GENERIC

Replace X.Y-RELEASE with the version of the release being used. The GENERIC kernel will be installed in /boot/GENERIC by default.

To instead build the GENERIC kernel from source:

# cd /usr/src
# env DESTDIR=/boot/GENERIC make kernel __MAKE_CONF=/dev/null SRCCONF=/dev/null
# mv /boot/GENERIC/boot/kernel/* /boot/GENERIC
# rm -rf /boot/GENERIC/boot

For this kernel to be picked up as GENERIC by freebsd-update, the GENERIC configuration file must not have been modified in any way. It is also suggested that it is built without any other special options.

Rebooting into the GENERIC kernel is not required.

23.2.3.3. 主要版本更新後更新 Packages

一般來說,次要版本更新後安裝的應用程式可以沒有問題地繼續執行。 主要版本間使用不同的應用程式二進位介面 Application Binary Interfaces (ABIs),會破壞大部份第三方應用程式。 主要版本更新後,所有安裝的套件和 ports 需要使用應用程式來升級,例如 ports-mgmt/portmaster 重新編譯所有應用程式,可以使用以下指令完成:

# portmaster -af

這個指令將會顯示每個程式的設定選項設定畫面,等待使用者的互動。 如果要使用預設的選項,可以在上述指令使用-G選項。

一旦軟體升級完成, 執行 freebsd-update 來完成所有升級過程的零碎事情 :

# freebsd-update install

如果是暫時使用 GENERIC 核心, 現在請使用 章 8, 設定 FreeBSD Kernel的說明編譯和安裝新的自訂核心。

重新開機進入新版的 FreeBSD。現在已經完成升級過程了。

23.2.4. 系統狀態比較

已安裝的 FreeBSD 版本可以使用 freebsd-update IDS 來跟另一個已知好的複製版本來做測試。 這個指令評估系統應用程式,程式庫和設定檔案目前的版本, 可以被當成內建的入侵偵測系統來使用 (IDS)。

警告:

這個指令不是取代真正的 IDS ,例如 security/snort。當 freebsd-update 儲存資料在磁碟裡,是有被竄改的可能性 可以使用 kern.securelevel 或是將沒有在使用的 freebsd-update 的資料儲存在唯讀檔案系統來減少這樣的可能性, 比較好的解決方法是將系統和安全的磁碟,例如 DVD 或是安全的外接 USB 磁碟裝置做比較。 另類的方法是使用在 節 13.2.6, “Binary Verification” 描述的內建應用程式提供的 IDS 功能

為了開始比較,先指定特定的輸出檔案來儲存結果:

# freebsd-update IDS >> outfile.ids

現在系統將會被檢查, 而包含已知發行版和現在安裝版的SHA256雜湊值 的冗長檔案清單將會被送至指定的輸出檔。

清單的項目相當長,但是輸出格式很容易被分析。 例如,要獲得一個和發行版不同的檔案清單,可以下以下指令:

# cat outfile.ids | awk '{ print $1 }' | more
/etc/master.passwd
/etc/motd
/etc/passwd
/etc/pf.conf

這個輸出範例已經被截短,原來有更多的檔案存在。 有些檔案自然會有修改。例如,如果有使用者被加入系統, /etc/passwd 會被修改 如果 freebsd-update 有更新過,核心模組可能會不同 為了要排除特定的檔案或目錄,把它們加到/etc/freebsd-update.conf 裡的 IDSIgnorePaths 選項。

本文及其他文件,可由此下載: ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/

若有 FreeBSD 方面疑問,請先閱讀 FreeBSD 相關文件,如不能解決的話,再洽詢 <questions@FreeBSD.org>。

關於本文件的問題,請洽詢 <doc@FreeBSD.org>。