Linuxサーバー保守チェックリスト:週次・月次・更新
Linuxサーバーを毎週・毎月確認する項目と、リリースアップグレードの要点を整理します。各確認で防げる障害や、見落とされがちなリストアテストも具体的に説明します。
Linux サーバーの保守で実際に行うこと
Linux サーバーの保守は、終わりのないプロジェクトではなく、決めたスケジュールで実施する短い確認項目です。毎週、更新がインストールされたこと、ディスクに空きがあること、サービスが停止していないこと、バックアップジョブが完了したことを確認します。毎月、リストアをテストし、証明書の有効期限を確認し、アカウントと暗号鍵を監査し、古いカーネルとログを削除します。ディストリビューションのリリースごとに、バージョンアップグレードを計画し、先延ばしにしている再起動を実施します。
サーバーの構築は別の作業です。新しい VPS で最初の 10 分間に行うことでは、その部分を説明しています。このページでは、その後の 1 年間を扱います。以下の各項目では、それによって防げる障害を示します。結果を伴わないチェックリストは、利用者が気付かないうちに実行されなくなるためです。
ここで示すコマンドは説明用であり、実行する前に内容を確認してください。空き容量やプロセス数の正常値はサーバーの用途によって異なるため、出力を自分のサーバーと比較します。ディストリビューションによって確認方法が異なる場合は、その点を記載しています。例では Debian と Ubuntu の apt を使用します。RHEL 系ではツールが dnf になり、いくつかのパスも異なります。
継続できる Linux サーバーの保守頻度の決め方
週次の確認では、自分で操作しなくても変化する項目を確認します。パッケージ、ディスク使用量、サービスの状態、スケジュールされたジョブなどです。これらは自動的に変化するため、確認せずに放置できる期間は長くても 1 週間程度です。
月次の確認では、時間をかけて進む劣化を確認します。まもなく有効期限を迎える証明書、削除されていないアカウント、/boot に蓄積する古いカーネル、ローテーションの条件に合わなくなって増え続けるログファイルなどです。これらが明日すぐに問題になるとは限りません。ただし、いずれは問題になります。
リリースの確認は、カレンダーに基づいて行います。ディストリビューションのリリースは、外部の期限がある唯一の保守項目です。準備ができているかどうかに関係なく、現在のバージョンのサポートは終了するためです。
週次の確認は月曜日の朝、月次の確認は毎月 1 日というように、実施する時間を固定します。「時間ができたら」実施する確認は、チェックリストに基づく運用とはいえません。数台を超えるマシンを管理する場合は、手作業ではなく 1 か所からこれらを実行します。その方法については、複数の Linux サーバーを 1 か所から管理する方法で説明します。
週次確認: 更新は実際にインストールされたか
unattended-upgrades を有効にするだけでは、実行されたことを確認したことにはなりません。サービスが mask されている場合や、使用していない origin に設定が制限されている場合があります。また、1 つの hold されたパッケージによって、それ以降のすべての実行が失敗することもあります。インストール方法については、Ubuntu の自動セキュリティ更新で説明しています。週次ジョブでは、インストールした仕組みが実際に処理を完了したことを確認します。
systemctl status unattended-upgrades
journalctl -u unattended-upgrades --since "8 days ago" --no-pager
sudo tail -n 50 /var/log/unattended-upgrades/unattended-upgrades.log
apt list --upgradable
apt-mark showholdapt list --upgradable は、意図ではなく現在の状態を報告するため、実態を正確に示します。その一覧にセキュリティ更新が残っている場合、自動化は機能していません。マシンにパッチが適用済みだと判断する前に、ログを確認してください。apt-mark hold で固定されたパッケージは永久にスキップされ、何も報告しません。そのため、同じ確認の中で apt-mark showhold も確認します。
これにより、更新が自動で行われていると思い込み、既知の脆弱性があるパッケージを数か月間実行し続ける事態を防げます。
Weekly: ディスクと inode の余裕
root ファイルシステムが一杯になると、ディスク容量とは無関係に見える問題が発生します。データベースは書き込みを拒否し、ログ出力は停止し、パッケージのアップグレードは設定途中で失敗します。環境によっては、自身のファイルを書き込めないため、新しいセッションも開けなくなります。
df -h
df -i
sudo du -xh --max-depth=1 / | sort -h | tail -20df -i は、多くの人が確認を省略するもう半分の項目です。inode はファイルのメタデータを保持する数が固定された構造であり、df -h が数 GB の空きを示していても、ファイルシステムの inode を使い切ることがあります。その場合、空き容量が表示されているのに、書き込みは No space left on device で失敗します。初めて遭遇すると、原因の特定に 1 時間かかることもあります。停止したメールキューや、誰も整理しないセッションディレクトリなどにある大量の小さなファイルが、通常の原因です。
du -xh は 1 つのファイルシステム内にとどまります。bind mount や接続ストレージを使用するホストでは、この動作が適しています。Docker ホストでは、通常、原因はイメージレイヤーと不要なボリュームにあります。VPS で Docker のディスク使用量を削減する方法で説明している手順で削除できます。
空き容量から分かるのは容量の状況です。その下にあるストレージは別のタイミングで故障するため、別途確認が必要です。確認方法はVPS でディスクの健全性を監視する方法で説明しています。
週次確認: 通知なしで停止したものはありませんか?
systemctl list-units --state=failed
systemctl list-timers --all
journalctl -p err --since "8 days ago" --no-pagerクラッシュして再起動回数の上限に達した unit は failed 状態になり、そのまま静かに残ります。停止していても、メールで通知されることはありません。list-timers は、より有用な情報を表示します。各 timer が最後に実行された時刻と、次回の実行時刻を確認できます。そのため、LAST の値が timer 自身の間隔より古い場合、そのジョブはまったく実行されていません。
再起動する前に、journalctl -u <unit> -n 100 --no-pager で unit の journal を確認します。再起動すると症状は解消しますが、次に同じ問題がより悪い時間帯に発生するまで、再度確認する理由を失います。
この確認で防げるのは、3 週間前のメモリ急増以降、monitoring agent、queue worker、または backup service が停止したままになっている事態です。
Weekly: バックアップジョブは実際に完了しましたか?
スケジュールされたバックアップと、完了したバックアップは別の事実です。復元に使えるのは後者だけです。完了を確認してください。
systemctl list-timers --all | grep -i backup
journalctl -u <your-backup-unit> --since "8 days ago" --no-pager
ls -lh /path/to/backup/target | tail次の2点を確認します。直近の実行が終了コード 0 で終了していることと、最新のアーカイブが新しく、想定したサイズにおおむね一致していることです。通常の 10 分の 1 ほどのサイズしかないバックアップファイルは、ファイルの書き込み自体は行われたものの、ダンプに失敗した結果です。これは、後続の処理がすべて正常に見えるため、最も危険なバックアップ障害の形態です。
スクリプトでダンプをコンプレッサーにパイプしている場合は、先頭に set -o pipefail を追加してください。これがないと、パイプラインの終了ステータスはコンプレッサーのものになります。コンプレッサーは正常に終了します。エラーメッセージを圧縮したためです。その結果、ジョブは毎晩成功を報告しながら、中身のない小さなアーカイブを書き込みます。
月次: 別の場所にバックアップをリストアする
これは多くの人が省略する項目ですが、残りの項目に意味があったかどうかを決める項目です。
稼働中のデータに上書きせず、別のマシンまたは新しいコンテナにリストアします。次に、リストアしたデータを開き、実際に使用できることを確認します。テーブルの行数を数えます。ドキュメントを開きます。リストアしたアプリケーションにログインします。抽出処理が完了したことから分かるのは、アーカイブを読み取れるということだけです。
リポジトリツールには独自の検証機能があります。restic check --read-data-subset=5% と borg check --verify-data はインデックスではなく保存済みデータを読み取ります。実行してスモークテストとして扱いますが、リストアの代替にはなりません。検証で確認できるのは、バイト列が保持されていることです。リストアで確認できるのは、そのバイト列がアプリケーションに必要なものかどうかです。
後から厳しい形で学ぶことになる点が2つあります。まず、エージェントに鍵がすでに保持されていないマシンで復号用パスフレーズをテストします。復号できないバックアップは、バックアップとして機能しないためです。次に、リストアにかかる時間を計測します。その時間が実際の復旧時間であり、それを知るのが障害発生時になりがちです。
月次: 有効期限が近い証明書を確認する
更新の自動化は、問題が起きても何も表示せずに失敗することがあります。Web サーバーがメモリ上の古い証明書を提供し続けている一方で、certbot の timer がディスク上のファイルだけを更新する場合があります。サービスを reload する deploy hook が実行されなかったためです。そのため、サーバーの外部から、実行中のサーバーが実際に提供している証明書を確認します。
sudo certbot certificates
systemctl list-timers --all | grep -i certbot
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates-servername フラグは SNI (server name indication) を設定します。複数のサイトをホストするアドレスでは必須です。設定しないと、自分の証明書ではなくデフォルトの証明書が返されます。certbot を snap からインストールした場合、timer の名前は異なります。そのため、想定した unit ではなく、単語で一致させます。
自動化をまったく設定していない証明書も忘れないでください。メールサーバー、VPN、内部 certificate authority などです。これらは週末に期限切れになることがあります。ブラウザーやクライアントは警告を表示するのではなく、証明書を完全に拒否します。
月次: ユーザー、sudo アクセス、SSH キー
awk -F: '$3>=1000 && $3<65534 {print $1}' /etc/passwd
getent group sudo
sudo find /home /root -name authorized_keys -exec ls -l {} +
sudo sshd -T | grep -E 'permitrootlogin|passwordauthentication|pubkeyauthentication|port'
last -n 25sshd -Tは、すべてのIncludeをマージした後の実効設定を表示します。これはデーモンが実際に使用する設定です。最近の Ubuntu イメージには/etc/ssh/sshd_config.d/の drop-in ファイルが含まれており、メインファイルの設定を上書きする場合があります。そのため、sshd_configだけを読んでいると、実際とは逆の判断になることがあります。RHEL 系では管理用グループがsudoではなくwheelです。getentの行を調整してください。
次に、authorized_keysファイル自体を読みます。アクセスはアカウントではなくキーによって許可されます。そのため、6 か月前に契約を終えた委託業者のキーが残っていると、ユーザー一覧では検出できない有効なログイン手段になります。キーにはコメントフィールドがあります。これを活用し、所有者を特定できないものはすべて削除してください。
ログイン履歴を確認する場合、journalctl -t sshd --since "30 days ago" | grep -i acceptedは unit 名ではなく syslog 識別子で照合します。これは重要です。Ubuntu 24.04 は socket を通じて SSH を起動するため、各接続は接続ごとに生成された unit に記録されます。そのため、単純なjournalctl -u sshでは記録を見落とすことがあります。
毎月: 古いカーネルと容量がいっぱいになった /boot
/boot は、標準の VPS イメージでは数百メガバイト程度の独立したパーティションになっていることがよくあります。カーネルを更新するたびに、カーネルイメージと initramfs が追加されます。容量がいっぱいになると、次のアップグレードが途中で失敗し、パッケージが未設定のまま残ります。金曜日に突然この状態に遭遇するのは避けたい事態です。
uname -r
df -h /boot
dpkg -l 'linux-image-*' | grep '^ii'
sudo apt autoremove --purge最初に必ず uname -r を実行します。現在実行中のカーネルを表示するため、削除するカーネルの中に残しておく必要があります。Debian と Ubuntu の通常のケースでは apt autoremove を使用します。カーネルは自動インストールとして扱われ、現在のカーネルは保護されるためです。手動でインストールしたカーネルや、apt 自体の実行を妨げるほど容量が埋まった /boot などの例外については、Ubuntu で古いカーネルを削除するで説明します。
月次: ログの増加と systemd journal
journalctl --disk-usage
sudo du -xh --max-depth=1 /var/log | sort -h | tail
sudo logrotate --debug /etc/logrotate.conflogrotate --debug はドライランであり、何も書き込まないため、稼働中のサーバーでも安全に実行できます。実行する価値があるのは、ローテーション規則がパスに基づいて適用されるためです。アップグレード中にログの保存先を変更したアプリケーションは、以前の規則の対象外になります。そのファイルは、ディスクが満杯になるまで無制限に増加します。
journal は systemd によって上限が設定されます。ただし、上限は指定した数値ではなく、ファイルシステムに対する割合で決まります。特定の上限を設定する場合は、/etc/systemd/journald.conf に SystemMaxUse= を設定し、systemd-journald を再起動します。sudo journalctl --vacuum-time=14d は直ちに領域を解放します。これはポリシーではなく一度だけ実行する操作なので、設定変更と併用してください。
リリースごとに行う、先延ばしにしている再起動
ディスク上の更新済みカーネルパッケージは、実行中のカーネルではありません。再起動するまで、マシンは古いカーネルで動作します。利用可能な場合でも、ライブパッチが対応できるのは修正の一部だけです。
uname -r
ls -l /var/run/reboot-required
cat /var/run/reboot-required.pkgs
sudo needrestartこのフラグファイルは、パッケージスクリプトが作成する Debian および Ubuntu の慣例です。RHEL 系のシステムでは作成されません。そこで同等の確認を行うには needs-restarting -r を使用します。これは dnf-utils に由来します。最近の Ubuntu server イメージではデフォルトでインストールされている needrestart は、カーネルより下のレベルを確認します。ディスク上で置き換えられたライブラリを、まだプロセスがマッピングしているかを一覧表示します。そのため、パッチを適用した OpenSSL は、それを使用するサービスを再起動するまで有効になりません。
再起動を避けるのではなく、予定に組み込んでください。/etc/apt/apt.conf.d/50unattended-upgrades、Unattended-Upgrade::Automatic-Reboot "true";、Unattended-Upgrade::Automatic-Reboot-Time "03:00"; では、指定した時刻に再起動を実行するよう設定できます。計画的な再起動は、マシンが復旧するかどうかを確認する唯一のテストでもあります。壊れた fstab エントリや、有効化していないサービスは、起動時にだけ問題として現れるためです。
リリースごとの配布アップグレード計画
Ubuntu LTS リリースの標準サポート期間は 5 年、interim リリースは 9 か月です。そのため、この選択によって今後数年間のアップグレード作業量が決まります。この違いについては、サーバーにおける LTS と interim リリースの比較を参照してください。
lsb_release -a
cat /etc/update-manager/release-upgradesdo-release-upgrade はそのファイルを読み込み、Prompt=lts は LTS から LTS への移行に限定します。LTS から LTS への移行経路は通常、新しいバージョンのリリース日ではなく、最初のポイントリリースで利用可能になります。そのため、想定した日付を基準に計画せず、実際にマシンへ提示されている内容を確認してください。移行手順については、Ubuntu 24.04 から 26.04 へのアップグレードを参照してください。
3 か月の余裕を確保して計画します。復元テスト済みのスナップショットを取得し、サードパーティーの apt リポジトリを一覧化します。アップグレードによってこれらは無効になり、それぞれ新しいリリース用の移行先が必要です。開始前にロールバック方法も決めてください。2026 年 8 月時点で、Ubuntu 24.04 LTS の標準サポートは 2029 年 4 月まで続くため、これは緊急対応ではなくスケジュール管理の問題です。
自動化する作業と手動で残す作業
すでに決めた運用を自動化します。セキュリティ更新、ログローテーション、証明書の更新、バックアップジョブが対象です。アラートも自動化してください。自分が覚えていなければ実行されないチェックは、午前2時には実行されないためです。Uptime Kuma によるセルフホスト型ステータス監視などの外部モニターを使うと、サーバー上のスクリプトでは報告できない、サーバー自体に到達できない状態を検知できます。
手動で行う作業は2つ残します。リストアテストとアカウント監査です。どちらも、結果が正しいかを人が判断する必要があります。ターミナルではなくブラウザーでマシンの状態を確認したい場合は、サーバー管理における Cockpit と Webmin の比較で一般的な2つの Web コンソールを比較できます。
自動化にも確認が必要です。そのため、このリストの最初の週次項目はアップデーターの動作確認です。エラーを通知せずに失敗する自動化は、何もしないより悪い結果になります。失敗だけでなく、同じ項目を確認する習慣まで失われるためです。
チェックリスト全体
毎週および毎月実行するコマンドを、コピーしてすぐ使える形でまとめています
# weekly
systemctl list-units --state=failed
systemctl list-timers --all
journalctl -u unattended-upgrades --since "8 days ago" --no-pager
apt list --upgradable
apt-mark showhold
df -h
df -i# monthly
sudo certbot certificates
awk -F: '$3>=1000 && $3<65534 {print $1}' /etc/passwd
getent group sudo
sudo sshd -T | grep -E 'permitrootlogin|passwordauthentication'
uname -r
dpkg -l 'linux-image-*' | grep '^ii'
journalctl --disk-usageこのブロックにリストアテストを含めていないのは意図的です。リストアテストは 1 つのコマンドではなく、同じマシンで実施するものでもありません。別の場所にリストアし、データを開いて実際に復元できていることを確認してください。
FAQ
Linux サーバーのメンテナンスはどのくらいの頻度で実行すべきですか?
自動的に変化する項目は毎週確認します。更新状態、ディスクと inode の空き容量、failed 状態の unit、バックアップジョブの完了状況が対象です。時間をかけて劣化する項目は毎月確認します。リストアテスト、証明書の有効期限、アカウントと SSH key の監査、古い kernel、ログの増加量が対象です。ディストリビューションのリリースごとに 1 回、バージョンアップグレードと現在の kernel での再起動を実行します。正常なサーバーであれば、毎週の確認は数分で終わります。問題が見えてから実行するのではなく、毎週実行する目的はそこにあります。
バックアップジョブが成功を報告しているのに、なぜリストアをテストするのですか?
ジョブが報告するのは、そのジョブ自身の終了ステータスだからです。そのステータスが成功でも、アーカイブが使用できない場合があります。ダンプを set -o pipefail なしでコンプレッサーにパイプすると、返されるのはコンプレッサーのステータスです。そのため、エラーメッセージだけを出力したダンプが失敗していても、終了ステータスは 0 になり、小さなファイルが書き込まれます。別のマシンにリストアし、データを開いて、何らかの件数を確認します。リストアにかかった時間も測定します。その時間が実際の復旧時間です。
kernel を更新するたびに再起動する必要がありますか?
新しい kernel を実行中の kernel にするには、再起動が必要です。Debian と Ubuntu では、/var/run/reboot-required の存在が、パッケージから再起動を要求されたことを示します。どのパッケージが要求したかは /var/run/reboot-required.pkgs で確認できます。RHEL 系ではそのファイルは存在しません。dnf-utils の needs-restarting -r が同じ情報を示します。再起動を無期限に延期せず、/etc/apt/apt.conf.d/50unattended-upgrades に自動再起動の時間帯を設定します。1 年間再起動していないマシンでは、kernel が古いだけでなく、起動経路もテストされていないためです。
これらの確認のうち、安全に自動化できるものはどれですか?
実行するかどうかの判断がすでに決まっている処理を自動化します。セキュリティ更新、ログローテーション、証明書の更新、スケジュールされたバックアップが対象です。通知も自動化します。そうすれば、人がコマンドを実行しなくても、failed 状態の unit や容量が不足しつつあるディスクを把握できます。リストアテストと key の監査は手動で行います。どちらも、結果が正しいかを人が判断する必要があるためです。さらに、自動化処理自体を確認するチェックを 1 つ追加します。更新処理が無言で失敗すると、すべて正常に動作している場合と同じように見えるためです。