「サーバーに変な形跡があるけど、肝心のログを見たら何も残っていない」——これは侵入者が最初にやる典型的な行動です。MITRE ATT&CKではT1070.002(Indicator Removal: Clear Linux or Mac System Logs)として分類されている、証拠隠滅の定番手口です。この記事では、Ubuntu/Debianのsystemdジャーナル(journalctlで見るログ)が改ざん・削除されていないかをjournalctl --verifyで確認する方法を、出力例つきで解説します。

journalctlのログがなぜ改ざんの標的になるのか

Ubuntu/Debianの標準的なログ管理はsystemd-journaldが担っており、SSHログイン・sudo実行・サービスの起動停止などが/var/log/journal/以下のバイナリファイルに記録されます。侵入した攻撃者が居座ろうとするとき、自分の痕跡を消すために最初に狙うのがこのログです。手口としては大きく2つあります。

  • ログファイルの中身を書き換える——特定のエントリだけを消したり改変したりする
  • ログファイルごと削除・ローテーションさせる——journalctl --vacuum-timeのような正規のコマンドを悪用し、痕跡ごと消す

この2つは検知方法が異なるため、この記事では両方をカバーします。

journalctl --verifyでハッシュチェーンの破損を確認する

systemdのジャーナルファイルは、エントリ同士がハッシュでつながった構造になっています。journalctl --verifyはこのハッシュのつながりが壊れていないかを1エントリずつ検証するコマンドです。root権限のログファイルを読むため、sudoが必要です。設定は何も変更しないので、実行しても環境に影響はありません。

sudo journalctl --verify

出力例と正常/異常の見分け方

正常な場合は、ジャーナルファイルごとにPASSが並びます。

PASS: /var/log/journal/b3e1a9c7d8f4e2a1b9c7d8f4e2a1b9c7/system.journal
PASS: /var/log/journal/b3e1a9c7d8f4e2a1b9c7d8f4e2a1b9c7/user-1000.journal

異常があると、該当ファイルがFAILになり、どのオフセット(ファイル内の位置)で不整合が起きたかが示されます。

FAIL: /var/log/journal/b3e1a9c7d8f4e2a1b9c7d8f4e2a1b9c7/system.journal
File corruption detected at offset 1048576

見るべきポイントはPASS/FAILの1点だけです。すべてPASSならハッシュチェーンの改ざんは無い状態、FAILが1つでもあれば、そのファイル内のエントリが不正に書き換えられたか、ディスク障害で壊れたかのどちらかです。ディスク障害との切り分けは、dmesg | grep -i -E 'error|fail'でストレージ関連のエラーが出ていないかを合わせて見ると判断しやすくなります。

--verifyだけでは見抜けないケースに注意

ここが初心者が誤解しやすい点です。--verifyが検知できるのは「残っているファイルの中身が壊れているか」だけです。攻撃者がroot権限を奪った上でjournalctl --vacuum-time=1sのような正規コマンドでファイルごと消してしまった場合、壊れたファイルは存在しないため--verifyは全部PASSのまま、つまり「異常なし」に見えてしまいます。ファイルごとの削除を疑うときは、次のセクションの手順もあわせて確認してください。

ファイルごと消されていないかを別の角度から確認する

起動履歴に抜けがないか(journalctl --list-boots)

journalctl --list-boots

過去の起動(boot)ごとに一覧が出ます。

-2 8f2c1a4e9b7d4c3e8a1f2b9c7d8e4f3a Mon 2026-09-08 09:12:03 JST—Mon 2026-09-08 18:44:11 JST
-1 3a7c9e1b2d4f8a6c9e1b2d4f8a6c9e1b Tue 2026-09-09 07:03:22 JST—Tue 2026-09-09 23:58:01 JST
 0 c4d8f2a6b9e1c4d8f2a6b9e1c4d8f2a6 Fri 2026-09-26 06:00:15 JST—Fri 2026-09-26 12:30:00 JST

ここでは時系列に不自然な穴がないかを見ます。サーバーを稼働させたまま何日も再起動していないはずなのに一覧に見覚えのない起動が挟まっている、逆に稼働しているはずの期間の起動が丸ごと無い、といった場合は要注意です。

ジャーナルファイルの保存状況を直接見る

sudo ls -la /var/log/journal/$(cat /etc/machine-id)/
journalctl --disk-usage

ls -laでファイルの更新日時が飛び飛びになっていないか、--disk-usageで「ジャーナルが使用中のディスク容量」が普段の運用感覚より極端に少なくなっていないかを確認します。数十MBあるはずのログが数百KBしか無い場合、直近でまとめて消された可能性があります。

もう1つの独立した記録と突き合わせる

last -Fx

これはjournaldとは別に/var/log/wtmpに記録されているログイン履歴を見るコマンドです。journalctl側の記録と食い違いがあれば(例えばlastには残っているログインがjournalctlには無い)、journald側だけが改ざんされた強い証拠になります。

異常が見つかったときにやること

--verifyがFAILを返した、または上記の突き合わせで矛盾が見つかった場合は、次の順で対応します。

  1. そのサーバーでのsudoパスワード・SSH鍵をすべて変更する(改ざんできた時点でroot権限を奪われている前提で動く)
  2. last -Fx・w・ss -tulpnで現在ログイン中のユーザーと開いている通信を確認し、覚えのない接続があれば切断する
  3. クラウド/VPSのプロバイダ側に残るアクセスログ(コンソールログ等、サーバー内部からは改ざんできない記録)と突き合わせる
  4. 重要なデータを退避した上で、OSの再インストールを検討する——root権限を奪われた形跡がある環境は、ログを直すより作り直す方が確実

自動実行される不審なジョブが残っていないかも合わせて確認すると安心です。crontab点検で不正な自動実行ジョブを見つける2026年9月の手順が使えます。

ログを消されにくくする設定(任意・sudo要)

ここは環境を変更する内容なので、必要と感じた場合だけ実施してください。デフォルトのUbuntu/Debianでは/etc/systemd/journald.confのStorage=が未設定(自動判定)になっていることが多く、環境によっては再起動でログが消える揮発設定になっている場合があります。

sudo nano /etc/systemd/journald.conf
# Storage=persistent に変更(先頭の#を外す)
sudo systemctl restart systemd-journald

これで/var/log/journal/にログが永続的に残るようになります。元に戻す場合は該当行をコメントアウトして同じコマンドで再起動すれば既定の動作に戻ります。より強固にしたい場合、sudo journalctl --setup-keysでForward Secure Sealing(FSS)という仕組みを有効にすると、ログを事後改ざんしたこと自体を暗号的に検出できるようになります。ただし鍵の管理が別途必要になるため、まずは--verifyによる定期点検から始めるのがおすすめです。もっとも確実なのはログを別のサーバーに転送しておくことです。ローカルに残るログはroot権限があれば理論上いくらでも改変できるため、rsyslogの転送設定やsystemd-journal-remoteで別ホストにも同じログを送っておくと、改ざんの検知精度が大きく上がります。

関連する選択肢

毎日決まった時刻にスクリプトを動かすだけなら、共有のレンタルサーバーでも足ります。cronが使えるプランを選べば、自分でOSを管理する必要はありません。

レンタルサーバー エックスサーバー

※ 広告を含みます(A8.net)。リンク経由でお申し込みがあった場合、手数料を受け取ることがあります。

まとめ

journalctl --verifyは、systemdジャーナルのハッシュチェーンが壊れていないかをsudoだけで手軽に確認できるコマンドです。ただしファイルごと消される手口までは検知できないため、--list-bootsでの起動履歴の抜け・ジャーナルファイルの容量・last -Fxとの突き合わせを組み合わせて点検するのが実務的です。異常を見つけたら直すより先に鍵とパスワードを変え、再インストールも選択肢に入れて判断してください。