#
# auditd_parser.py
#
# 2024/11/02
#
# Claude 3.5 Sonnetにて以下で作成
# RHEL 9.2のLinuxマシンにAuditdを導入して、/share/data への読取りアクセスを
# /var/log/audit/audit.log に記録するようにしました。
# このログから、各回のアクセスに対して、以下の項目を抽出して1行ずつまとめてテキスト形式で出力したいです。
# ログをどのように見ればこれらの項目が抽出できますか?
#
# - アクセス日時
# - アクセスしたLinuxユーザー
# - アクセスした際のLinuxユーザーのカレントディレクトリ
# - アクセスに際して実行したコマンド
# - 参照されたファイルの名前
#
import re
from datetime import datetime
import sys
def parse_audit_log(log_file):
"""
Auditdのログファイルから指定された項目を抽出して整形するパーサー
"""
# イベントをまとめるための辞書
current_event = {}
events = []
try:
with open(log_file, 'r') as f:
for line in f:
# タイムスタンプの抽出
timestamp_match = re.search(r'msg=audit\((\d+\.\d+):(\d+)\):', line)
if timestamp_match:
epoch_time = float(timestamp_match.group(1))
# 新しいイベントの開始
if 'type=SYSCALL' in line:
if current_event:
events.append(current_event)
current_event = {
'timestamp': datetime.fromtimestamp(epoch_time).strftime('%Y-%m-%d %H:%M:%S'),
'user': '',
'cwd': '',
'cmd': '',
'file': ''
}
# ユーザー情報の抽出
auid_match = re.search(r'auid=(\S+)', line)
if auid_match:
current_event['user'] = auid_match.group(1)
# コマンド情報の抽出
exe_match = re.search(r'exe="([^"]+)"', line)
if exe_match:
current_event['cmd'] = exe_match.group(1)
# CWD情報の抽出
elif 'type=CWD' in line:
cwd_match = re.search(r'cwd="([^"]+)"', line)
if cwd_match:
current_event['cwd'] = cwd_match.group(1)
# PATH情報からファイル名の抽出
elif 'type=PATH' in line:
## パスを限定したい場合
##elif 'type=PATH' in line and 'name="/share/data/' in line:
name_match = re.search(r'name="([^"]+)"', line)
if name_match:
current_event['file'] = name_match.group(1)
# 最後のイベントを追加
if current_event:
events.append(current_event)
except FileNotFoundError:
print(f"Error: ログファイル {log_file} が見つかりません。")
return
except Exception as e:
print(f"Error: ログの解析中にエラーが発生しました: {str(e)}")
return
# 結果の出力
for event in events:
if event['file']: # ファイルアクセスが含まれるイベントのみ出力
print(f"{event['timestamp']} | {event['user']} | {event['cwd']} | {event['cmd']} | {event['file']}")
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: python audit_log_parser.py /var/log/audit/audit.log")
sys.exit(1)
parse_audit_log(sys.argv[1])
# end.
|