Приведу пример Python скрипта который считает хеши SHA-256 всех файлов в указанной директории и сообщает на email список файлов которые изменились, создались или удалились, а также записывает в log файл.
Скрипт я запускал на Ubuntu Server, по этому убедимся что установлен python3:
python3 --version
apt install python3 python3-pip
Понадобилось однажды следить за состоянием www файлов, по этому сделал такой скрипт:
#!/usr/bin/env python3
import os
import hashlib
import json
import time
import subprocess
WATCH_DIR = "/var/www"
HASH_DB = "/root/www_hashes.json"
LOG_FILE = "/root/www_changes.log"
EMAIL_TO = "root"
EMAIL_SUBJECT = "FILE MODIFIED"
EXCLUDE_FILES = [
"/var/www/logs/1.log",
"/var/www/logs/2.log",
]
def file_hash(path):
sha = hashlib.sha256()
try:
with open(path, "rb") as f:
for chunk in iter(lambda: f.read(4096), b""):
sha.update(chunk)
return sha.hexdigest()
except Exception:
return None
def load_db():
if os.path.exists(HASH_DB):
with open(HASH_DB, "r") as f:
return json.load(f)
return {}
def save_db(db):
with open(HASH_DB, "w") as f:
json.dump(db, f, indent=2)
def scan():
hashes = {}
for root, dirs, files in os.walk(WATCH_DIR):
for name in files:
path = os.path.join(root, name)
if path in EXCLUDE_FILES:
continue
h = file_hash(path)
if h:
hashes[path] = h
return hashes
def log_changes(changes):
if not changes:
return
timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
with open(LOG_FILE, "a") as f:
f.write(f"\n[{timestamp}] Changes:\n")
for line in changes:
f.write(line + "\n")
def send_email(changes):
if not changes:
return
body = "\n".join(changes)
try:
proc = subprocess.Popen(
["/usr/sbin/sendmail", EMAIL_TO],
stdin=subprocess.PIPE
)
proc.communicate(input=f"Subject: {EMAIL_SUBJECT}\n\n{body}".encode("utf-8"))
print("[EMAIL] notification sent")
except Exception as e:
print("[EMAIL ERROR]:", e)
def main():
old_hashes = load_db()
new_hashes = scan()
changes = []
for path, new_h in new_hashes.items():
old_h = old_hashes.get(path)
if old_h and old_h != new_h:
changes.append(f"File modified: {path}")
for path in old_hashes:
if path not in new_hashes:
changes.append(f"File deleted: {path}")
for path in new_hashes:
if path not in old_hashes:
changes.append(f"New file: {path}")
if changes:
log_changes(changes)
send_email(changes)
save_db(new_hashes)
if __name__ == "__main__":
main()
Сделаем файл исполняемым и запустим, на NVMe рейдах подсчет делается очень быстро, чем больше размер файла, тем дольше, если файлов десятки тысяч и они маленькие, то это займет секунды:
chmod +x ixnfo.com.py
./ixnfo.com.py
Осталось добавить в cron, например ежедневно в 7 утра:
02 7 * * * root /dir/ixnfo.com.py > /dev/null 2>&1
Смотрите также мои статьи:
Использование и настройка CRON
Скрипт проверки целостности файлов (size+mtime)
Скрипты