Загрузка данных


import time, os, subprocess

INTEL_LOG   = "/tmp/zeek_block_intel.log"
RULES_FILE  = "/usr/local/var/lib/suricata/rules/dynamic_block.rules"
SEEN_FILE   = "/usr/local/var/lib/suricata/rules/dynamic_block_seen.txt"
SID_START   = 2000000

# --- Шаблоны правил под каждый тип индикатора ---
def make_rule(itype, value, sid):
    if itype == "HTTP_HOST":
        return (
            f'drop http any any -> any 80 ('
            f'msg:"BLOCK HTTP HOST {value}"; '
            f'flow:to_server,established; '
            f'http.header; content:"Host: {value}"; nocase; '
            f'sid:{sid}; rev:1;)\n'
        )
    elif itype == "HTTP_USERAGENT":
        return (
            f'drop http any any -> any any ('
            f'msg:"BLOCK HTTP User-Agent {value}"; '
            f'flow:to_server,established; '
            f'http.user_agent; content:"{value}"; nocase; '
            f'sid:{sid}; rev:1;)\n'
        )
    elif itype == "FTP_PORT":
        # FTP блокируем двумя правилами — USER и PASS отдельно
        rule_user = (
            f'drop tcp any any -> any 21 ('
            f'msg:"BLOCK FTP USER command"; '
            f'flow:to_server,established; '
            f'content:"USER"; nocase; depth:10; '
            f'sid:{sid}; rev:1;)\n'
        )
        rule_pass = (
            f'drop tcp any any -> any 21 ('
            f'msg:"BLOCK FTP PASS command"; '
            f'flow:to_server,established; '
            f'content:"PASS"; nocase; depth:10; '
            f'sid:{sid + 1}; rev:1;)\n'
        )
        return rule_user + rule_pass
    return None

# --- Загрузка уже обработанных индикаторов ---
seen = set()
if os.path.exists(SEEN_FILE):
    with open(SEEN_FILE) as f:
        seen = set(line.strip() for line in f if line.strip())
    print(f"[*] Загружено {len(seen)} существующих индикаторов")

# Определяем следующий свободный SID
sid = SID_START + len(seen)

print("[*] Zeek→Suricata мост запущен. Ожидание индикаторов...")

while True:
    if os.path.exists(INTEL_LOG):
        with open(INTEL_LOG) as f:
            for line in f:
                indicator = line.strip()
                if not indicator or indicator in seen:
                    continue
                # Разбираем формат ТИП:значение
                if ':' not in indicator:
                    continue
                itype, value = indicator.split(':', 1)
                rule = make_rule(itype, value, sid)
                if not rule:
                    print(f"[!] Неизвестный тип: {itype}")
                    continue
                # Записываем правило
                with open(RULES_FILE, 'a') as rf:
                    rf.write(rule)
                # Сохраняем индикатор
                with open(SEEN_FILE, 'a') as sf:
                    sf.write(indicator + '\n')
                seen.add(indicator)
                sid += 2 if itype == "FTP_PORT" else 1
                result = subprocess.run(
                    ["sudo", "suricatasc", "-c", "reload-rules", 
                     "/usr/var/run/suricata/suricata-command.socket"],
                    capture_output=True, text=True
                )
                if '"return": "OK"' in result.stdout:
                    print("[+] Suricata перезагрузила правила")
                else:
                    print(f"[!] Ошибка перезагрузки: {result.stdout}")
                print(f"[+] Новое правило: {rule.strip()}")

    time.sleep(2)