はじめに
「カーネルの脆弱性対応、後回しになっていませんか?」
小規模な環境ほど、サーバーの更新は「気づいたときに手で当てる」運用になりがちです。でもカーネルのセキュリティ更新は、適用後に再起動しないと有効になりません。つまり「パッケージは新しいのに、動いているカーネルは古いまま」という状態が静かに続きます。
この記事では、Rocky Linux 9 の標準機能 dnf-automatic を使って、セキュリティ更新の適用と「必要なときだけ自動再起動」までを自動化します。検証は実際に契約した VPS(WebARENA Indigo)の Rocky Linux 9.3 で行い、途中で出た警告の切り分けまで含めて実測ベースでまとめました。
対象読者:Rocky Linux 9 系を運用している方、更新の手作業から解放されたい情シス・サーバー管理者の方。
結論(先に要点)
dnf-automaticの設定ファイル/etc/dnf/automatic.confで、セキュリティ更新だけを対象にできる- いきなり自動再起動まで有効にせず、①通知(ダウンロード)のみ → ②適用のみ → ③自動再起動 の3段階で進めると安全
reboot = when-neededにすると、カーネルや systemd など再起動が要る更新のときだけ再起動する(Rocky Linux 9 の dnf-automatic にある設定。8 にはないので注意)- 再起動のタイミングはタイマーの実行時刻で決まる。実行時刻はドロップインで変更でき、冗長構成では台ごとにずらして同時再起動を避ける
- 適用の確認は
dnf history、再起動の要否はdnf needs-restarting -rで見る
検証環境
- VPS:WebARENA Indigo
- OS:Rocky Linux release 9.3 (Blue Onyx)
[root@server ~]# cat /etc/rocky-release
Rocky Linux release 9.3 (Blue Onyx)
[root@server ~]# uname -r
5.14.0-362.8.1.el9_3.x86_64
この時点で止まっていたセキュリティ更新は、NetworkManager だけでも複数件ありました(抜粋)。
[root@server ~]# sudo dnf updateinfo list --security
RLSA-2025:0377 Moderate/Sec. NetworkManager-1:1.48.10-5.el9_5.x86_64
RLSA-2026:18597 Low/Sec. NetworkManager-1:1.54.3-2.el9.x86_64
RLSA-2026:58572 Moderate/Sec. NetworkManager-1:1.54.3-5.el9_8.x86_64
手順① 通知のみ(ダウンロードだけさせる)
まずインストール。
sudo dnf install -y dnf-automatic
/etc/dnf/automatic.conf の [commands] セクションを、最初は「ダウンロードのみ・適用しない」にします。
upgrade_type = security
download_updates = yes
apply_updates = no
タイマーを有効化。
sudo systemctl enable --now dnf-automatic.timer
systemctl list-timers dnf-automatic.timer
実行結果(実測):
NEXT LEFT LAST PASSED UNIT ACTIVATES
Wed 2026-11-04 06:27:36 UTC 16h left - - dnf-automatic.timer dnf-automatic.service
1 timers listed.
次回実行時刻が表示されれば OK です。なお時刻表示はサーバーのタイムゾーンに従います。この検証機は UTC 表示だったので、日本時間では 15:27 の実行です。自宅サーバー等で夜間に当てたい場合は、表示が自拠点の時刻になっているか確認しておきましょう。
しばらくこの段階で運用し、「毎回どのくらいの更新が来るのか」を眺めるのがおすすめです。
手順② 適用のみ(再起動はしない)
慣れてきたら、適用まで自動化します。ただし再起動はまだしません。
/etc/dnf/automatic.conf を変更:
apply_updates = yes
reboot = never
タイマー任せでも動きますが、動作確認のため手動で1回実行します。
sudo systemctl start dnf-automatic.service
実行後の確認(実測):
[root@server ~]# dnf history
ID | Command line | Date and time | Action(s) | Altered
----------------------------------------------------------------------------------------
6 | | 2026-11-03 13:48 | I, U | 171
171パッケージがインストール/アップグレードされました。所要時間は約5分(296秒)、dnf history info 6 の Return-Code は Success でした。
続いて「再起動が要る状態か」を確認します。
[root@server ~]# sudo dnf needs-restarting -r
Core libraries or services have been updated since boot-up:
* dbus-broker
* glibc
* kernel
* systemd
Reboot is required to fully utilize these updates.
カーネルが含まれているので、再起動が必要です。この状態が「パッケージは新しいが、まだ古いカーネルで動いている」状態です。手順③でここを自動化します。
コラム:
systemctl startで D-Bus 警告が出ても、失敗とは限らない(→ 本文中コラム参照)
手順③ 自動再起動を有効化する
/etc/dnf/automatic.conf を変更:
reboot = when-needed
when-needed は「再起動が必要な更新(カーネル、systemd、glibc など)が含まれるときだけ再起動する」設定です。再起動しても問題ない時間帯にタイマーが動くよう、実行時刻との兼ね合いは事前に確認しておきましょう。
なおデフォルトでは、再起動は即時ではありません。設定ファイルの reboot_command は次のようになっています。
reboot_command = "shutdown -r +5 'Rebooting after applying package updates'"
更新適用の5分後に再起動され、ログイン中のユーザーには再起動予告のメッセージも表示されます。
実行時刻を決める(タイマーの上書き)
自動再起動まで有効にすると、タイマーの実行時刻がそのまま「再起動が起きうる時刻」になります。デフォルトのタイマーは毎日 6:00 に、RandomizedDelaySec=60m(最大60分のランダム遅延)付きで実行される設定です。手順①の実測で次回実行が 06:27 や 06:01 と日によってバラついていたのは、この遅延のためです。
業務に合わせて時刻を変えるときは、ユニットファイル本体ではなくドロップインで上書きします。
sudo systemctl edit dnf-automatic.timer
エディタで次の内容を書きます(例:10時に実行)。
[Timer]
OnCalendar=
OnCalendar=*-*-* 10:00:00
RandomizedDelaySec=0
注意点は3つです。
OnCalendar=の空行が必須です。この設定は「追加」として効くため、空行で一度リセットしないと、デフォルトの朝6時台と新しい時刻の両方で実行されてしまいます- 時刻を厳密に合わせたい場合は
RandomizedDelaySec=0を加えます。検証機でも、設定後にsystemctl list-timers dnf-automatic.timerの NEXT が翌日の 10:00:00 ちょうどに変わり、ランダム遅延が無効化されたことを確認できました OnCalendarの時刻はサーバーのローカルタイムで解釈されます。タイムゾーンがUTCのままのサーバーに日本時間のつもりで書くと9時間ずれるので、timedatectlで確認してから設定しましょう(検証機はUTCだったため、10:00 UTC=日本時間19時の実行です)
そして冗長構成では、この時刻を台ごとにずらすのが基本です。権威DNSサーバーのように2台で冗長化している構成では、同じ更新が来れば両台とも「再起動が必要」になります。1台目を10時、2台目を22時(OnCalendar=*-*-* 22:00:00)のように離しておけば、片方が再起動している間も、もう片方がサービスを継続できます。
今回は検証のため手動で再起動し、効果を確認します。
sudo reboot
再接続後:
[root@server ~]# uname -r
5.14.0-687.64.1.el9_8.x86_64
[root@server ~]# dnf updateinfo list --security
Last metadata expiration check: 0:18:01 ago on Tue Nov 3 13:40:21 2026.
カーネルは 5.14.0-362.8.1.el9_3 から 5.14.0-687.64.1.el9_8 に上がり、セキュリティ更新の一覧も空になりました。適用から再起動後の確認まで、一通りの動作が確認できました。
戻し方について
この記事では、実機で検証したことだけを書く方針にしています。dnf history undo によるロールバックは今回検証していないため、手順としては紹介しません。
検証済みの範囲で言える備えは、次の2点です。
- 更新前のカーネルは削除されずに残ります。今回も
rpm -q kernelで、更新前のkernel-5.14.0-362.8.1.el9_3と更新後のkernel-5.14.0-687.64.1.el9_8の両方が入っていることを確認しました。新しいカーネルで起動に失敗した場合は、起動時にGRUBメニューから旧カーネルを選ぶのが最初の切り分けになります - 自動化を始める前に VPS のスナップショットを取っておけば、問題があれば丸ごと戻せます
コラム:D-Bus 警告と dnf history の ## は「実行中」のサインだった
手順②で sudo systemctl start dnf-automatic.service を実行したとき、次の警告が出ました。
Warning! D-Bus connection terminated.
Failed to wait for response: Connection reset by peer
さらに実行直後の dnf history では、トランザクションの Altered 欄に ## が付き、dnf history info 6 を見ると
End time : Thu Jan 1 00:00:00 1970
Return-Code : Failure: 1
と、あたかも失敗したかのような表示でした。
結論から言うと、これは**失敗ではなく「まだ実行中」**でした。実際の systemctl status dnf-automatic.service は activating のままで、カーネル更新に伴う dracut(initramfs 生成)が動いている最中だったのです。
では D-Bus 警告の正体は何か。ジャーナルを確認すると、更新開始の直後に systemd が再実行(reexec)された記録が残っていました。
[root@server ~]# journalctl -b 0 | grep -i reexecut
Nov 03 13:48:21 i-52100000801882 systemd[1]: Reexecuting.
Nov 03 13:48:41 i-52100000801882 systemd[1]: Reexecuting.
今回の更新には systemd と dbus-broker 自体の更新が含まれていました。更新途中で systemd が再実行されると、完了を監視していた systemctl クライアントの D-Bus 接続が切れます。切れたのは監視役だけで、サービス本体は裏で動き続け、最終的に Return-Code: Success で完了しました。
教訓は3つです。
dnf historyの#は「完了したが終了ステータスが非ゼロ」の印。ただし実行中はEnd timeが 1970 年表示になり、Failureと出ることがある(参考:DNF 公式ドキュメントの history 記号説明)- 警告が出たら結論を急がず、
systemctl status/systemctl is-activeでサービス本体の状態を先に見る - 更新の実行中に再起動すると、トランザクションを壊しかねない。終わるまで触らない
まとめ
dnf-automaticで、セキュリティ更新の適用と「必要なときだけ再起動」まで自動化できた- 導入は ①ダウンロードのみ → ②適用のみ → ③自動再起動 の順で。段階を踏めば本番でも怖くない
- 実行時刻はドロップインで変更できる。冗長構成では台ごとにずらして同時再起動を避ける
- 警告や見慣れない記号が出ても、ジャーナルとサービスの状態を見れば正体は追える
