Initial backup commit
This commit is contained in:
24
firehol-sync.sh
Executable file
24
firehol-sync.sh
Executable file
@@ -0,0 +1,24 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
MIKROTIK="10.10.10.1"
|
||||||
|
USER="fail2ban"
|
||||||
|
LIST="firehol_l1"
|
||||||
|
TIMEOUT="7d"
|
||||||
|
TMP="/tmp/firehol_l1.txt"
|
||||||
|
LOG="/var/log/firehol-sync.log"
|
||||||
|
|
||||||
|
echo "[$(date)] FireHOL sync started" >> $LOG
|
||||||
|
|
||||||
|
curl -s https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/firehol_level1.netset \
|
||||||
|
| grep -E '^[0-9]' \
|
||||||
|
| grep -v ':' \
|
||||||
|
| grep -Ev '^(0\.|10\.|127\.|169\.254\.|172\.(1[6-9]|2[0-9]|3[0-1])\.|192\.168\.|224\.|240\.)' \
|
||||||
|
> $TMP
|
||||||
|
|
||||||
|
while read ip; do
|
||||||
|
ssh -o ConnectTimeout=3 $USER@$MIKROTIK \
|
||||||
|
"/ip firewall address-list add list=$LIST address=$ip timeout=$TIMEOUT comment=FireHOL" \
|
||||||
|
2>/dev/null
|
||||||
|
done < $TMP
|
||||||
|
|
||||||
|
echo "[$(date)] FireHOL sync finished" >> $LOG
|
||||||
139
firehol_diff_sync.py
Executable file
139
firehol_diff_sync.py
Executable file
@@ -0,0 +1,139 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from routeros_api import RouterOsApiPool
|
||||||
|
import requests
|
||||||
|
import ipaddress
|
||||||
|
import datetime
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# =======================
|
||||||
|
# CONFIGURATION
|
||||||
|
# =======================
|
||||||
|
|
||||||
|
MIKROTIK_IP = "10.10.10.1"
|
||||||
|
USER = "fail2ban"
|
||||||
|
PASSWORD = "password"
|
||||||
|
|
||||||
|
ADDRESS_LIST = "firehol_l1"
|
||||||
|
TIMEOUT = "7d"
|
||||||
|
|
||||||
|
FIREHOL_URL = "https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/firehol_level1.netset"
|
||||||
|
|
||||||
|
# Whitelist (ALWAYS CIDR)
|
||||||
|
WHITELIST = {
|
||||||
|
"100.64.0.0/10" # Apartment CGNAT
|
||||||
|
}
|
||||||
|
|
||||||
|
# Safety cap
|
||||||
|
MAX_NEW_ENTRIES = 5000
|
||||||
|
|
||||||
|
# =======================
|
||||||
|
# FUNCTIONS
|
||||||
|
# =======================
|
||||||
|
|
||||||
|
def valid_net(net):
|
||||||
|
try:
|
||||||
|
n = ipaddress.ip_network(net, strict=False)
|
||||||
|
|
||||||
|
if n.version != 4:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if n.prefixlen < 10:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if (
|
||||||
|
n.is_private
|
||||||
|
or n.is_loopback
|
||||||
|
or n.is_multicast
|
||||||
|
or n.is_reserved
|
||||||
|
or n.is_link_local
|
||||||
|
):
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def is_whitelisted(net):
|
||||||
|
try:
|
||||||
|
n = ipaddress.ip_network(net, strict=False)
|
||||||
|
for w in WHITELIST:
|
||||||
|
wnet = ipaddress.ip_network(w, strict=False)
|
||||||
|
if n.subnet_of(wnet) or n == wnet:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
# =======================
|
||||||
|
# MAIN
|
||||||
|
# =======================
|
||||||
|
|
||||||
|
print(f"[{datetime.datetime.now()}] FireHOL diff sync start")
|
||||||
|
|
||||||
|
# Fetch FireHOL
|
||||||
|
try:
|
||||||
|
response = requests.get(FIREHOL_URL, timeout=30)
|
||||||
|
response.raise_for_status()
|
||||||
|
firehol_raw = response.text.splitlines()
|
||||||
|
except Exception as e:
|
||||||
|
print(f"ERROR: Failed to fetch FireHOL list: {e}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Parse & filter FireHOL
|
||||||
|
firehol = {
|
||||||
|
net.strip()
|
||||||
|
for net in firehol_raw
|
||||||
|
if valid_net(net.strip()) and not is_whitelisted(net.strip())
|
||||||
|
}
|
||||||
|
|
||||||
|
print(f"Parsed FireHOL entries after filtering: {len(firehol)}")
|
||||||
|
|
||||||
|
# Connect to MikroTik API (RouterOS v7)
|
||||||
|
try:
|
||||||
|
api_pool = RouterOsApiPool(
|
||||||
|
MIKROTIK_IP,
|
||||||
|
username=USER,
|
||||||
|
password=PASSWORD,
|
||||||
|
plaintext_login=True
|
||||||
|
)
|
||||||
|
api = api_pool.get_api()
|
||||||
|
except Exception as e:
|
||||||
|
print(f"ERROR: Failed to connect to MikroTik API: {e}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
address_list = api.get_resource("/ip/firewall/address-list")
|
||||||
|
|
||||||
|
# Fetch existing MikroTik entries
|
||||||
|
current = {
|
||||||
|
entry["address"]
|
||||||
|
for entry in address_list.get(list=ADDRESS_LIST)
|
||||||
|
}
|
||||||
|
|
||||||
|
print(f"Current MikroTik entries: {len(current)}")
|
||||||
|
|
||||||
|
# Diff calculation
|
||||||
|
to_add = firehol - current
|
||||||
|
|
||||||
|
print(f"New entries to add: {len(to_add)}")
|
||||||
|
|
||||||
|
# Safety check
|
||||||
|
if len(to_add) > MAX_NEW_ENTRIES:
|
||||||
|
print("ERROR: Safety stop — too many new entries")
|
||||||
|
api_pool.disconnect()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Add missing entries
|
||||||
|
for net in sorted(to_add):
|
||||||
|
address_list.add(
|
||||||
|
list=ADDRESS_LIST,
|
||||||
|
address=net,
|
||||||
|
timeout=TIMEOUT,
|
||||||
|
comment="FireHOL L1"
|
||||||
|
)
|
||||||
|
|
||||||
|
api_pool.disconnect()
|
||||||
|
|
||||||
|
print("FireHOL diff sync complete")
|
||||||
Reference in New Issue
Block a user