Linuxの永続化と設定変更
サービス定義、cron、authorized_keysの差分から変更箇所を読み、所有者と変更時刻を確認します。所有者を変更者と誤認せず、自動実行の条件と実際の起動を分けて調べます。
説明
Linuxの設定ファイルは、保存された内容と実行中の状態が一致するとは限りません。systemdのユニット変更は、読み直しと起動の記録まで確認して評価します。
サービス定義、cron、authorized_keysの差分から変更箇所を読み、所有者と変更時刻を確認します。所有者を変更者と誤認せず、自動実行の条件と実際の起動を分けて調べます。
1設定の差分を読む
beforeとafterは保全済みの二時点の内容です。mtimeはファイルの変更時刻です。
from oplab import *
db=connect(4)
show(db, 'SELECT設定の差分を読む id,path,before,after,mtime FROM config ORDER BY mtime')起動コマンドの差替え、5分ごとのcron、SSH鍵の追加があります。いずれも保存内容の変化であり、そのまま実行の証拠にはなりません。
2所有者を確認する
所有者はファイル属性で、最後に書き換えた利用者を必ず示すものではありません。
show(db, 'SELECT所有者を確認する id,path,owner FROM config ORDER BY id')root所有のファイルを誰が更新したかは、auditや管理操作の記録で補います。属性と操作主体を分けて扱います。
3同じ処理を参照する設定を探す
report.pyを参照するサービスとcronを検索します。
show(db, 'SELECT同じ処理を参照する設定を探す id,path,after FROM config WHERE after LIKE "%/opt/report.py%"')二つの起動経路があります。一方だけを元に戻しても、もう一方から処理が実行される可能性が残ります。
4systemd側の反映と起動を調べる
daemon-reloadは定義の読み直しであり、サービス再起動とは別の操作です。
show(db, 'SELECTsystemd側の反映と起動を調べる * FROM service ORDER BY t')時刻23に読み直し、25に起動が記録されています。起動時のPID800は、後続のプロセス調査の手掛かりです。
5変更から起動までの間隔を調べる
report.serviceの変更時刻と起動記録を対応付けます。
show(db, 'SELECT変更から起動までの間隔を調べる c.id,s.id,s.t-c.mtime AS seconds FROM config c JOIN service s ON s.detail LIKE "%report.service%" WHERE c.id="c1" AND s.event="start"')変更から5秒後に起動しています。ただし、実行ファイルの内容や終了状態はプロセス記録と結果で追加確認します。
6鍵の追加とログインを分ける
authorized_keysの変化を再度抽出します。
show(db, 'SELECT鍵の追加とログインを分ける path,before,after FROM config WHERE id="c3"')key8の追加は、その鍵で認証した証拠ではありません。SSH側の鍵指紋や接続元の記録を照合する調査が残ります。
まとめ
key8の追加は、その鍵で認証した証拠ではありません。SSH側の鍵指紋や接続元の記録を照合する調査が残ります。
表示された証拠IDと検索条件を残すと、調査結果を元の記録までたどれます。
操作履歴と解説を振り返れます。
Python 3.15 / SQLite・固定の調査記録
from oplab import *
db=connect(4)
show(db, 'SELECT id,path,before,after,mtime FROM config ORDER BY mtime')id | path | before | after | mtime c1 | /etc/systemd/system/report.service | ExecStart=/usr/bin/true | ExecStart=/opt/report.py | 20 c2 | /etc/cron.d/report | absent | */5 * * * * alice /opt/report.py | 21 c3 | /home/alice/.ssh/authorized_keys | key7 | key7;key8 | 22
show(db, 'SELECT id,path,owner FROM config ORDER BY id')id | path | owner c1 | /etc/systemd/system/report.service | root c2 | /etc/cron.d/report | root c3 | /home/alice/.ssh/authorized_keys | alice
show(db, 'SELECT id,path,after FROM config WHERE after LIKE "%/opt/report.py%"')id | path | after c1 | /etc/systemd/system/report.service | ExecStart=/opt/report.py c2 | /etc/cron.d/report | */5 * * * * alice /opt/report.py
show(db, 'SELECT * FROM service ORDER BY t')id | t | event | detail s1 | 23 | daemon-reload | report.service s2 | 25 | start | report.service pid=800
show(db, 'SELECT c.id,s.id,s.t-c.mtime AS seconds FROM config c JOIN service s ON s.detail LIKE "%report.service%" WHERE c.id="c1" AND s.event="start"')id | id | seconds c1 | s2 | 5
show(db, 'SELECT path,before,after FROM config WHERE id="c3"')path | before | after /home/alice/.ssh/authorized_keys | key7 | key7;key8
演習完了