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)