サーバーへの侵入が成功する多くの場合、使われるのは巧妙な exploit ではなく、数か月前にパッチが出ていた脆弱性です。理由はたいてい怠慢ではありません。稼働中のサーバーで手作業の更新をするのは怖いのです。apt upgrade が誰も頼んでいないものを再起動することがあるからです。自動更新はこの問題を片づけますが、評判はよくありません——そして、その評判は急いで設定された分だけ正当です。
セキュリティのパッチが自分で届き、PHP のバージョンが一晩で変わらないような組み方を見ていきましょう。
インストール
sudo apt install unattended-upgrades apt-listchanges
sudo dpkg-reconfigure -plow unattended-upgrades
この対話が /etc/apt/apt.conf.d/20auto-upgrades を作ります。何が出来上がったか確認してください。
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
1 は「毎日」を意味します。これらを動かすのは古典的な cron ではなく systemd のタイマーです。
systemctl list-timers | grep apt
いちばん大事なこと:セキュリティだけ
主要なファイルは /etc/apt/apt.conf.d/50unattended-upgrades です。そこには Allowed-Origins の一覧があり(Debian では Origins-Pattern)、既定ではセキュリティのリポジトリだけが有効になっています。そのままにしておいてください。
-updates の行のコメントを外したい誘惑——「全部更新させればいい」——は強いものです。やめてください。updates のリポジトリは修正だけでなく新しいバージョンを持ち込みます。そして夜中の不意打ちはまさにそこから来ます。セキュリティと新しさは別の仕事であり、後者はあなたがキーボードの前にいるときにやるほうがよいのです。
自動更新してはいけないパッケージがあるなら、そのための除外一覧があります。
Unattended-Upgrade::Package-Blacklist {
"mariadb-server";
"php8.3-fpm";
};
意識して使ってください。ここの各行は「これは自分で更新する」という意味であり——それは守らねばならない約束です。
再起動
鍵になる行:
Unattended-Upgrade::Automatic-Reboot "false";
サイトのあるサーバーではこれを false のままにするのが正解です。予告なしの午前三時の再起動は、一日遅れたパッチより悪いのですから。ただしこの判断には必須の後半があり、そして忘れられるのはまさにその後半です。
カーネル、libc、openssl が更新されると、システムはファイル /var/run/reboot-required を作ります。再起動されるまで、直った版はディスク上にあり、古い版はメモリで動き続けます——つまりパッケージは更新済みと数えられていても、脆弱性はどこへも行っていません。明示的に確認してください。
ls -l /var/run/reboot-required
cat /var/run/reboot-required.pkgs
二つ目のファイルには、何が原因で再起動が必要になったかが正確に書かれています。規則は単純です。印を見たら、「いつか」ではなく今後一日か二日のうちに時間枠を計画してください。
ライブラリは別の話です。openssl は更新され、nginx と PHP-FPM は古い版をメモリに抱えたまま動き続け、再起動の印はそもそも出ません。誰に再起動が要るかは needrestart が教えてくれます。
sudo apt install needrestart
sudo needrestart -b
ただし「報告せよ、尋ねるな」のモードにしておいてください。さもないと非対話のインストールの途中で質問を始め、それを止めてしまいます。そのために /etc/needrestart/conf.d/ へ $nrconf{restart} = 'l'; の一行を書いたファイルを置きます。
そもそも動いているか確認する
インストールせずに試し実行:
sudo unattended-upgrade --dry-run --debug
出力には、どのパッケージが規則に合致し、どれがなぜ弾かれたかが出ます。実際に何が起きたかはログに。
sudo tail -50 /var/log/unattended-upgrades/unattended-upgrades.log
いま何件の更新が待っているか:
apt list --upgradable 2>/dev/null | grep -i security
この最後のコマンドがいちばん役に立ちます。設定済みの自動更新には静かに壊れる癖があります。/boot の空きが尽きた、リポジトリが鍵を変えた、手作業の編集の後でタイマーが切れた。外からは万事順調に見え、パッチは何か月も入っていません。
/boot の空き
典型的な状況:古いカーネルが消されず、/boot パーティションが埋まり、新しいカーネルのインストールが失敗し、更新全体が止まります。数か月に一度は覗く価値があります。
df -h /boot
sudo apt autoremove --purge
あるいは同じ 50unattended-upgrades で自動整理を有効にします:Remove-Unused-Kernel-Packages "true" と Remove-Unused-Dependencies "true"。
人に残るもの
自動更新は決まりきった作業を取り除きますが、見張ることは取り除きません。いつでも答えられるべき問いが二つあります。セキュリティ更新が何件待っているか、そして再起動の印が立っているか。どちらの答えもページの一行であり、そしてすべての意味は、その一行が四半期に一度あなたの側から調べに行くのではなく、自分から目に入ってくることにあります。