CentOS Stream 9でdnf-automaticを使ったAutomatic Security Updatesの設定ガイド:セキュリティパッチの自動適用とメール通知の実現

CentOS tutorial - IT technology blog
CentOS tutorial - IT technology blog

セキュリティパッチを後回しにするリスク

小規模なDevOpsチームによく見られる光景がある。サーバーが数ヶ月間安定して動いているうちに、誰もセキュリティパッチの適用を忘れてしまう。そしてインシデントが発生してからログを確認すると、3ヶ月前にすでに公表されていた脆弱性にパッチも出ていたことに気づく。

自分もこの状況を経験したことがある。会社にはまだCentOS 7で動いているサーバーが数台あり、AlmaLinuxへの移行作業は進めているものの、移行完了までの間、毎週SSHで各マシンに入らなくてもセキュリティパッチを自動適用できる仕組みが必要だった。いくつか試した結果、dnf-automaticがRHELベースのサーバー、特にCentOS Stream 9において最も信頼できる選択肢だとわかった。

この記事では、インストールから設定まで完全なセットアップ方法を紹介する。セキュリティアップデートのみを適用する設定と、毎日何がパッチされたかをメールで知らせる通知機能の有効化についても解説する。

dnf-automaticとは何か、なぜ使うのか

dnf-automaticDNFエコシステムの公式ツールで、パッケージのアップデートを自動化するために設計されている。dnf updateを手動で実行するのとは異なり、このツールはsystemdタイマーと直接統合されているため、cronジョブを自前で設定したり、複雑なラッパースクリプトを書いたりする必要がない。

他のソリューションと比較したときの強みは以下の通りだ:

  • Granular control:ダウンロードのみ、セキュリティアップデートのみの適用、または全体のアップデートを柔軟に選択できる
  • メール通知が組み込み済み:出力を外部にパイプする必要がない
  • Systemdタイマー:正確な時刻に実行され、ログが残り、システムがオフラインだった場合はリトライも行われる
  • ランダム遅延:複数のサーバーが同時にミラーリポジトリにアクセスするのを防ぐ

普段はapply security updates onlyモードで使っている。これが本番環境において最も安全で、あるパッケージのアップデートがアプリケーションを壊すリスクを避けられる。

実践:ステップごとのインストールと設定

ステップ1:dnf-automaticのインストール

このパッケージはCentOS Stream 9のデフォルトリポジトリに含まれているため、直接インストールできる:

sudo dnf install -y dnf-automatic

バージョンとデフォルトの設定ファイルを確認する:

dnf-automatic --version
cat /etc/dnf/automatic.conf

ステップ2:automatic.confの設定

メインの設定ファイルは/etc/dnf/automatic.confにある。各セクションの重要な項目を順に調整していこう:

sudo cp /etc/dnf/automatic.conf /etc/dnf/automatic.conf.bak
sudo nano /etc/dnf/automatic.conf

[commands]セクションで変更が必要な内容:

[commands]
# セキュリティアップデートのみダウンロード、即時適用しない
# 事前にレビューが必要な環境向け
# upgrade_type = security
# download_updates = yes
# apply_updates = no

# --- または: セキュリティアップデートを自動適用(本番環境向け推奨) ---
upgrade_type = security
download_updates = yes
apply_updates = yes

# 最大60分のランダム遅延 — 全サーバーが同時にアップデートするのを防ぐ
random_sleep = 3600

[emitters]セクション — 通知方法の設定:

[emitters]
# メールで通知を送る(SMTPまたはローカルMTAが必要)
emit_via = email

# アップデートがある場合のみメールを送る(毎日のスパム防止)
# available: always, never, only-if-updated
email_to = [email protected]
email_from = [email protected]
email_host = localhost
# 別のポートを使う場合(例:Gmail SMTP):
# email_host = smtp.gmail.com
# email_port = 587

[base]セクション — 全般的な設定:

[base]
debuglevel = 1
# ログのパス
# /var/log/dnf.log がdnfの出力を自動的にキャプチャする

ステップ3:systemdタイマーの有効化

dnf-automaticには3種類のタイマーが付属しているため、用途に合ったものを選ぶ:

# 利用可能なタイマーを表示
ls /usr/lib/systemd/system/dnf-automatic*.timer

# dnf-automatic.timer          — アップデートを適用(こちらを使用)
# dnf-automatic-download.timer — ダウンロードのみ、適用しない
# dnf-automatic-install.timer  — 最初のものの別名

セキュリティアップデートを適用するタイマーを有効にする:

# タイマーを有効化して起動
sudo systemctl enable --now dnf-automatic.timer

# 状態を確認
systemctl status dnf-automatic.timer
systemctl list-timers dnf-automatic*

タイマーが正常に動作しているときの出力例:

NEXT                         LEFT     LAST                         PASSED  UNIT
Wed 2026-07-02 06:42:15 JST  18h left Tue 2026-07-01 06:12:03 JST  5h ago  dnf-automatic.timer

ステップ4:Postfix(ローカルMTA)を使ったメール通知の設定

サーバーにMTAがない場合は、リレー経由でメールを送るためにPostfixをインストールする:

sudo dnf install -y postfix mailx
sudo systemctl enable --now postfix

メール送信の簡易テスト:

echo "Test from CentOS Stream 9" | mail -s "dnf-automatic test" [email protected]

GmailなどのSMTPを経由するリレーが必要な場合は、/etc/postfix/main.cfにリレー設定を追加する:

# /etc/postfix/main.cf の末尾に追加
relayhost = [smtp.gmail.com]:587
smtp_use_tls = yes
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_tls_CAfile = /etc/ssl/certs/ca-bundle.crt
# 認証情報ファイルを作成
echo "[smtp.gmail.com]:587 [email protected]:app-password" | sudo tee /etc/postfix/sasl_passwd
sudo postmap /etc/postfix/sasl_passwd
sudo chmod 600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db
sudo systemctl restart postfix

注意:Gmailの場合はアプリパスワードを使用する(通常のパスワードではない)。Googleアカウント → セキュリティ → アプリパスワードから作成できる。

ステップ5:自動実行前の手動テスト

必ず一度手動でテストして、設定が正しいことを確認しよう:

# タイマーを待たずに今すぐdnf-automaticを実行
sudo dnf-automatic /etc/dnf/automatic.conf

# 詳細ログを確認
sudo journalctl -u dnf-automatic -f

# またはタイマーを今すぐトリガー
sudo systemctl start dnf-automatic

ログを確認して、アップデートが適用されたかどうかを確認する:

sudo cat /var/log/dnf.log | grep -E "(Upgraded|Installed|security)"

# アップデート履歴を確認
sudo dnf history list | head -20

ステップ6:実行スケジュールの調整(オプション)

デフォルトでは、タイマーは午前6時+ランダム遅延で実行される。時間を変更するには、タイマーをオーバーライドする:

sudo systemctl edit dnf-automatic.timer

オーバーライドの内容を追加する(例:午前3時に実行):

[Timer]
OnCalendar=
OnCalendar=*-*-* 03:00:00
RandomizedDelaySec=1800
sudo systemctl daemon-reload
sudo systemctl restart dnf-automatic.timer

実践から得たtips

  • カーネルのアップデート:セキュリティアップデートにカーネルが含まれる場合がある。自動再起動を避けたい場合は、kernel-livepatchの利用を検討するか、カーネルを除外する。automatic.confの[base]セクションにexclude=kernel*を追加し、カーネルのアップデートはメンテナンスウィンドウで手動対応する。
  • 事前のステージング:重要な本番環境ではdownload_updates = yes, apply_updates = noモードを使う。アップデートが事前にダウンロードされるため、メンテナンスウィンドウ中にdnf update --cacheonlyを実行するだけでよい。
  • モニタリング:メール以外にも、dnf-automaticの実行後にwebhookを送信するsystemdサービスラッパーを作成することで、Slack/Telegram経由のアラートを追加できる。
  • 複数サーバーへの対応:大規模なフリートでは、各マシンにSSHする代わりに、Ansibleと組み合わせてautomatic.confの設定を一括同期することを推奨する。

まとめ

dnf-automaticのセットアップには約15分しかかからないが、その後の手間を大幅に削減できる。最も重要なのはupgrade_type = securityを正しく設定することだ。これによりセキュリティ脆弱性のみにパッチを当て、breaking changesを引き起こす可能性のある機能アップデートには手を加えない。

有効化した後は、数週間そのままにしておいてからログを確認することが多い。何か起きた場合はメール通知が自動的に知らせてくれる。これは、定期的に手動でパッチを当てる時間がないチームの本番サーバーに対する、最も実用的なアプローチだ。

Share: