Rocky AlmaLinux dnf-automatic 安全性更新設定
了解 Rocky Linux 9 與 AlmaLinux 9 如何設定 dnf-automatic,啟用僅限安全性更新、systemd timer、電子郵件通知,以及避免意外重啟的重開機政策。
Rocky Linux 與 AlmaLinux 上的 dnf-automatic 功能
dnf-automatic 是在 Rocky Linux 與 AlmaLinux 上取得無人值守安全性更新的方式。它是一個由 systemd timer 啟動的小型程式,會讀取 /etc/dnf/automatic.conf,並套用該檔案允許的內容。安裝只需執行一個命令。本指南其餘內容將說明各項設定如何決定它會保護伺服器,或在沒有明顯訊息的情況下完全不執行任何動作。
如果你使用過 Debian 或 Ubuntu,這項功能相當於 unattended-upgrades 在 Ubuntu VPS 上提供的功能。其中一項差異比其他差異都更重要:套件管理程式如何定義「安全性」。在 Ubuntu 上,安全性更新位於獨立的 archive pocket。在 RHEL 系列中,安全性是附加在已發布 advisory 上的中繼資料,而這些中繼資料可能遺失或過期。若將 dnf-automatic 指向沒有 advisory 資料的 repository,它會回報成功,但不會安裝任何內容。
本指南以 Rocky Linux 9 與 AlmaLinux 9 為基準;截至 August 2026,這些系統使用 DNF 4(DNF 是 RHEL 系列的套件管理程式)。10 版本已改用 DNF5,名稱也有所變更,因此本指南會在接近結尾處另設一節說明。以下每個命令都可直接在你自己的伺服器上執行,預期輸出會列在命令旁邊。
安裝 dnf-automatic 並閱讀套件附帶的設定檔
啟用自動更新應該列入 新 VPS 的前十分鐘設定,時機是在建立非 root 使用者並設定防火牆之後。
sudo dnf install -y dnf-automatic
rpm -q dnf dnf-automatic
systemctl is-enabled dnf-automatic.timer全新安裝上執行 systemctl is-enabled 會輸出 disabled,因為安裝套件不會啟動任何服務。這是伺服器「已安裝 dnf-automatic」卻從未套用任何更新的最常見原因。
DNF 版本會影響其中一個選項。reboot 設定在 DNF 4.15 中由上游加入;Red Hat 於 November 2023 透過公告 RHBA-2023:6645,將此設定回移植到 dnf-4.14.0-6.el9。Rocky 9 和 AlmaLinux 9 會重新建置該套件,因此目前的系統通常已包含此設定,而自 2023 年起未更新的系統則沒有。
設定檔位於 /etc/dnf/automatic.conf。套件附帶的檔案會列出此版本支援的所有選項,並以註解標示預設值。編輯前先閱讀一次,因為該檔案才是此版本的準確依據。
決定行為的兩個開關
download_updates 和 apply_updates 位於 [commands] 區段中,決定服務的行為。在 EL9(enterprise Linux 9,Rocky 9 和 AlmaLinux 9 共用的基礎版本)中,兩者預設都設為 no。因此,啟用後未經修改的 dnf-automatic 只會告知你有哪些更新可用。
- 兩者都是
no:dnf-automatic 會回報可用更新,但不會變更系統。 download_updates = yes搭配apply_updates = no:套件會下載至 DNF 快取。之後安裝時速度較快,且不需要網路,但當晚不會套用任何變更。- 兩者都是
yes搭配upgrade_type = default:會安裝所有可用更新,不論是否為安全性更新。 - 兩者都是
yes搭配upgrade_type = security:只會安裝安全性公告中列出的套件。
對外提供服務的 VPS,可以從以下設定開始:
[commands]
upgrade_type = security
download_updates = yes
apply_updates = yes
random_sleep = 0
network_online_timeout = 60
reboot = nevernetwork_online_timeout 是執行程序在放棄前等待可用網路的秒數。對剛完成開機的伺服器而言,這項設定很重要。random_sleep 是過去用來分散多台機器負載的方式,而現在由 timer 負責這項工作。執行 systemctl cat dnf-automatic.service 可查看已隨套件提供的服務實際傳入哪些旗標。
無須等到 06:00,即可確認檔案是否會按照預期運作:
sudo systemctl start dnf-automatic.service
sudo journalctl -u dnf-automatic.service -n 50 --no-pagerjournal 會顯示執行程序檢查了哪些項目,以及實際執行了哪些操作。你也可以從命令列強制指定一種行為;這只會覆寫該次執行的設定:
sudo dnf-automatic --downloadupdates --no-installupdatesRocky 和 Alma 中 upgrade_type = security 的實際意義
DNF 不會透過比較版本號碼來判斷更新是否屬於安全性更新。它會讀取勘誤中繼資料:這是發佈在儲存庫中的檔案,名稱為 updateinfo.xml,其中每則公告都會列出修正該問題的套件。AlmaLinux 將這些公告發佈為 ALSA 公告,Rocky 則發佈為 RLSA。upgrade_type = security 會根據這些中繼資料建立篩選條件,只升級符合條件的套件。
這會帶來兩個結果,而且都容易讓人意外。
第一,沒有中繼資料就不會有更新。如果儲存庫沒有 updateinfo.xml,篩選條件就不會符合任何項目,執行結果會以下列這行日誌結束:
No security updates needed, but 3 updates available系統並未完成修補,而且沒有回報失敗。請自行確認:
dnf updateinfo list --security
dnf check-update如果 dnf check-update 列出套件,而 dnf updateinfo list --security 完全沒有輸出,可能是目前沒有任何待處理套件具備公告,也可能是儲存庫沒有可讀取的公告資料。Rocky 和 AlmaLinux 都會發佈這些資料,因此在這兩個系統上,空清單通常代表實際情況。CentOS Stream 完全不會發佈這些資料。
第二,安全性模式不是最小幅度的變更。dnf-automatic 會加入安全性篩選條件,然後執行一般的升級流程。因此,公告中列出的套件會升級到儲存庫中的最新版本,並一併帶入相依套件。若只升級到能修正該公告的最早版本,變更幅度會較小;這需要手動執行 dnf upgrade-minimal --security。dnf-automatic 沒有對應的設定。
Rocky 還有一項注意事項。Rocky 會透過自己的流程,使用 Red Hat 資料產生勘誤;但該流程曾經落後。2025 年 9 月,使用者回報 Rocky 9 BaseOS updateinfo.xml 自 2024 年 12 月起就沒有更新,因此 --security 缺少近期公告;Rocky 維護人員也確認這是已知問題。如果你依賴 upgrade_type = security,請不時將公告清單與近期的 RLSA 公告互相比對。若系統更重視涵蓋率而非變更控管,則在你選定的排程上執行 upgrade_type = default 會是較安全的設定。
實際執行該工作的 systemd timer
sudo systemctl enable --now dnf-automatic.timer
systemctl list-timers dnf-automatic.timerlist-timers 應列出一列,其中的 NEXT 時間約在一天後。表格為空表示 timer 未啟用,因此永遠不會執行。
隨附的 timer 會在 *-*-* 6:00 執行,並使用 RandomizedDelaySec=60m 與 Persistent=true。隨機延遲會將整個伺服器群分散在一小時內執行,避免所有伺服器在同一秒存取 mirror。Persistent=true 表示如果機器在 06:00 關機,開機後不久就會執行錯過的工作,而不是跳過當天。
請使用 drop-in 變更排程。不要編輯隨附的 unit,因為套件升級會替換 /usr/lib/systemd/system 下的檔案。
sudo systemctl edit dnf-automatic.timer[Timer]
OnCalendar=
OnCalendar=*-*-* 03:30
RandomizedDelaySec=30m空白的 OnCalendar= 行是必要的。OnCalendar 會累加,因此若未先重設,就會保留 06:00 的項目並加入第二個項目,導致工作每天執行兩次。使用 systemctl list-timers dnf-automatic.timer 確認結果,並讀取 NEXT 欄。相同的 drop-in 規則也適用於其他排程項目,詳見 撰寫 systemd service 與 timer unit。
接下來是容易踩到的問題。套件另外提供 3 個 timer:dnf-automatic-notifyonly.timer、dnf-automatic-download.timer 與 dnf-automatic-install.timer。每個 timer 都會使用命令列旗標啟動相同的程式,而這些旗標會覆寫設定檔中的 download_updates 與 apply_updates。如果在 dnf-automatic.timer 旁啟用其中一個,工作就會以兩種不同的行為執行兩次,看起來就像設定檔被忽略。啟用一個 timer,然後檢查:
systemctl list-unit-files 'dnf-automatic*'如何知道某項目何時安裝?
emit_via 區段中的 [emitters] 會控制回報方式。在 systemd 下,stdio 發送器會將內容寫入 journal。這是最可靠的選項,因為不需要安裝其他元件:
sudo journalctl -u dnf-automatic.service --since -7d --no-pagermotd 發送器會將報告寫入 /etc/motd,並覆寫該檔案的內容。如果您在該檔案中保留登入訊息,請不要啟用此發送器。
email 發送器會透過 SMTP(simple mail transfer protocol)連線到 email_host 的 email_port。兩者預設分別為 localhost 與 25。全新的 VPS 通常沒有程式在該處監聽,因此連線會遭拒,且不會寄出郵件。依賴此功能前,先執行 ss -lnt | grep ':25'。如果輸出為空,請設定僅轉送郵件的 Postfix。郵件功能正常時,主旨會顯示 Updates applied on 'web01'.,名稱取自 system_name。
其他情況下,command 發送器會將報告透過標準輸入傳給您指定的程式:
[emitters]
emit_via = stdio, command
system_name = web01.example.com
send_error_messages = yes
[command]
command_format = /usr/local/bin/notify-ops
stdin_format = {body}send_error_messages 預設為 no,這表示執行失敗時完全不會產生報告。請將它啟用。只回報成功結果的修補系統反而比完全沒有修補系統更糟,因為沒有訊息會被解讀為系統正常。
dnf-automatic 不會重新啟動服務
安裝套件會取代磁碟上的檔案。已在執行中的程序會繼續使用記憶體中的舊程式碼,因此,已修補的函式庫對上個月啟動的 daemon 不會產生作用。已安裝與實際生效之間的落差,正是無人值守修補需要重新啟動政策,而不只是安裝政策的原因。
sudo dnf install -y dnf-plugins-core
dnf needs-restarting -s
dnf needs-restarting -r-s 會列出服務啟動後其檔案曾變更的 systemd 服務。-r 只回答一個問題,並輸出以下兩個區塊之一:
Core libraries or services have been updated since boot-up:
* kernel
Reboot is required to fully utilize these updates.No core libraries or services have been updated since boot-up.
Reboot should not be necessary.-r 並不是深度分析。它會檢查固定的套件清單:kernel、kernel-core、kernel-rt、glibc、linux-firmware、systemd、dbus、dbus-broker、dbus-daemon 和 microcode_ctl。如果其中一個套件是在上次開機後安裝,便會得到第一個答案。當主機上的其他元件也需要重新開機才能生效時,請將自訂套件名稱加入 /etc/dnf/plugins/needs-restarting.d/ 下以 .conf 結尾的檔案。
對指令碼而言,還有一項注意事項:dnf needs-restarting -r 在需要重新開機以及指令本身執行失敗時都會傳回非零狀態,因此不能只依靠結束狀態區分這兩種情況。請讀取輸出文字。
重新啟動服務是影響較小的處理方式,通常也是正確選擇。請從已經開啟的第二個 SSH 工作階段重新啟動 SSH daemon,這樣即使設定錯誤,也不會把自己鎖在系統外。若是新核心,則只有重新開機才能解決,因為執行中的核心無法直接替換。
主機應該自行重新開機嗎?
[commands]
reboot = when-needed
reboot_command = shutdown -r +5 'Rebooting after applying package updates'reboot = never 是預設值。when-changed 會在套用任何更新後重新開機。when-needed 只有在 needs-restarting -r 背後的檢查判定核心套件已被替換時才會重新開機;這通常是單一伺服器管理者想要的設定,再搭配自行選定的計時器時段。預設的 reboot_command 會透過 shutdown 提前 5 分鐘通知已登入的使用者;你也可以延長這段時間。
啟用這項功能前,請先確認兩件事。所有相依服務都必須能在開機時自行啟動;手動啟動的 Docker Compose 堆疊通常就是缺少這項設定。你也需要透過服務供應商提供的主控台或救援存取功能進行管理,因為無法開機的核心無法透過 SSH 修復。若缺少其中任一項,請保留 reboot = never,並在閱讀 journal 後自行重新開機。
Rocky、AlmaLinux 與 CentOS Stream 的差異
在 Rocky 9 與 AlmaLinux 9 上,上述內容完全相同,包括設定檔路徑與 unit 名稱。兩者都會發布 errata,因此 upgrade_type = security 有可供篩選的資料。
CentOS Stream 是例外,而且差異很大。Stream 的套件庫不包含 updateinfo.xml,因此安全性篩選條件永遠不會符合,每次執行都會回報 No security updates needed。在 Stream 上,請使用 upgrade_type = default,並接受這會套用所有更新。Stream 的版本也領先 RHEL,因此相同設定在 Stream 主機上的變動會比 Rocky 或 AlmaLinux 更頻繁。
Rocky 10 與 AlmaLinux 10 已改用 DNF5,因此部分名稱有所變更。上游 DNF5 文件將計時器列為 dnf5-automatic.timer,將隨套件提供的預設值放在 /usr/share/dnf5/dnf5-plugins/automatic.conf,而你的覆寫設定仍放在 /etc/dnf/automatic.conf;預設值 download_updates 為 yes,而非 no,並新增 distro-sync 作為 upgrade_type。公告查詢指令為 dnf advisory list,updateinfo 則保留作為別名。在從針對 9 撰寫的指南複製套件或 unit 名稱前,請先確認你的版本實際安裝了哪些內容:
dnf list --available '*automatic*'
systemctl list-unit-files '*automatic*'許多針對此主題發布的指南仍僅涵蓋 Rocky 8。自這些指南撰寫後,可用選項已增加,因此請檢查你自己主機上的註解檔案,不要直接信任舊文章。
失效情況與你會看到的字串
完全沒有執行任何工作。 systemctl list-timers dnf-automatic.timer 顯示空白表格,而 systemctl is-enabled dnf-automatic.timer 顯示 disabled。套件已安裝,但計時器從未安裝。
工作有執行,但沒有安裝任何內容。 journal 中包含 No security updates needed, but 3 updates available。安全性篩選器沒有符合任何項目,原因可能是目前沒有待處理項目附帶 advisory,也可能是套件庫未發布 advisory 資料。
某項設定似乎未生效。 DNF 會在 debug 層級於 automatic.conf 記錄未知選項,接著使用預設值。因此,拼錯的 key 不會造成任何變更,也不會發出警告。設定 apply_update = yes 後,apply_updates 仍維持 no,因此伺服器會持續下載,但永遠不會安裝。每次編輯後,執行 sudo systemctl start dnf-automatic.service 並查看 journal,不要只相信設定檔。
工作每天執行 2 次。 有 2 個計時器已啟用。systemctl list-unit-files 'dnf-automatic*' 會顯示是哪幾個計時器,額外的計時器可能會傳入優先於設定檔的 flags。
沒有收到郵件。 可能是沒有任何程式在 port 25 上接收 email emitter 的郵件,也可能是 send_error_messages 仍為 no,而唯一值得回報的項目是錯誤。
已套用修補程式的服務仍回報舊版本。 磁碟上的檔案已更新,但記憶體中的程序仍是舊版本。dnf needs-restarting -s 會列出需要重新啟動的服務。
FAQ
dnf-automatic 在 Rocky Linux 上是否只會安裝安全性更新?
只有在 /etc/dnf/automatic.conf 中設定 upgrade_type = security,且您的套件庫發布勘誤中繼資料時才會如此。Rocky Linux 和 AlmaLinux 都會發布這類中繼資料,因此篩選器有可比對的安全性公告。隨附的預設值是 upgrade_type = default;一旦 apply_updates = yes,就會安裝所有可用的更新。
為什麼 dnf-automatic 顯示「不需要安全性更新,但有 3 個可用更新」?
DNF 會從套件庫讀取 updateinfo.xml,藉此判定哪些項目屬於安全性更新;每則公告都會列出修正該問題的套件。當這些中繼資料遺失或過期時,安全性篩選器會找不到任何符合項目,但一般更新仍在等待安裝,因此就會產生這段訊息。在完全不發布勘誤資料的 CentOS Stream 上,這是預期行為。在 Rocky 或 AlmaLinux 上,請比較 dnf updateinfo list --security 與 dnf check-update,並確認中繼資料為最新版本。
dnf-automatic 會在 kernel 更新後重新啟動伺服器嗎?
除非您要求,否則不會。reboot 選項的預設值是 never。設定 reboot = when-needed 後,只有當 dnf needs-restarting -r 背後的檢查發現自開機後替換了 kernel 或 glibc 等核心套件時,執行工作才會重新啟動伺服器。reboot = when-changed 則會在套用任何更新後重新啟動。兩者都使用 reboot_command;其預設值為 shutdown -r +5,並會向已登入的使用者顯示警告訊息。
如何變更 dnf-automatic 的執行時間?
執行 sudo systemctl edit dnf-automatic.timer,並加入 [Timer] 區段,在空白的 OnCalendar= 行之後輸入排程,例如 OnCalendar=*-*-* 03:30。空白行是必要的,因為 OnCalendar 會累積設定;省略空白行會保留隨附的 06:00 執行時間,並再加入第二個排程。使用 systemctl list-timers dnf-automatic.timer 驗證,並查看 NEXT 欄位。
伺服器會自行安裝修補程式後,我還需要檢查它嗎?
需要。dnf-automatic 只會安裝套件,完成後即停止。它不會重新啟動 daemon;除非 emit_via 指定了您實際讀取的 emitter,否則您不會看到任何報告。至少將 emit_via 設為 stdio,並啟用 send_error_messages,讓失敗情況也會回報。修補時段結束後執行 dnf needs-restarting -s,以找出仍在執行舊版程式碼的服務。