geoip_shop_manager.py aktualisiert

This commit is contained in:
2025-12-16 12:59:44 +01:00
parent 2e33bca4f6
commit 256ade31be

View File

@@ -771,7 +771,9 @@ $bot_hash = md5($detected_bot);
// === STEP 1: Check if this bot-type is banned ===
$ban_file = "$bans_dir/$bot_hash.ban";
if (file_exists($ban_file)) {{
$ban_until = (int)@file_get_contents($ban_file);
$ban_content = @file_get_contents($ban_file);
$ban_parts = explode('|', $ban_content, 2);
$ban_until = (int)$ban_parts[0];
if (time() < $ban_until) {{
// Bot-type is banned - log and block
$timestamp = date('Y-m-d H:i:s');
@@ -823,9 +825,9 @@ if (file_exists($count_file)) {{
// === STEP 3: Check if limit exceeded ===
if ($count > $rate_limit) {{
// Create ban for this bot-type
// Create ban for this bot-type (store timestamp|botname)
$ban_until = $current_time + $ban_duration;
@file_put_contents($ban_file, $ban_until, LOCK_EX);
@file_put_contents($ban_file, "$ban_until|$detected_bot", LOCK_EX);
// Log the ban
$timestamp = date('Y-m-d H:i:s');
@@ -847,7 +849,9 @@ $uri = $_SERVER['REQUEST_URI'] ?? '/';
if (rand(1, $cleanup_probability) === 1) {{
$now = time();
foreach (glob("$bans_dir/*.ban") as $f) {{
$ban_time = (int)@file_get_contents($f);
$ban_content = @file_get_contents($f);
$ban_parts = explode('|', $ban_content, 2);
$ban_time = (int)$ban_parts[0];
if ($now > $ban_time) @unlink($f);
}}
foreach (glob("$counts_dir/*.count") as $f) {{
@@ -1680,12 +1684,13 @@ def get_shop_log_stats(shop):
if ban_file.endswith('.ban'):
try:
with open(os.path.join(bans_dir, ban_file), 'r') as f:
ban_until = int(f.read().strip())
content = f.read().strip()
parts = content.split('|', 1)
ban_until = int(parts[0])
bot_name = parts[1] if len(parts) > 1 else "Unbekannt"
if now < ban_until:
active_bans += 1
# Try to find bot name from hash
bot_hash = ban_file.replace('.ban', '')
banned_bots.append(bot_hash[:8])
banned_bots.append(bot_name)
except:
pass
@@ -1723,6 +1728,8 @@ def show_logs(shop):
if rate_limit is not None and ban_duration is not None:
print(f"🚦 Rate-Limit: {rate_limit} req/min PRO BOT-TYP, Ban: {ban_duration // 60} min")
print(f"🚫 Bans: {total_bans} ausgelöst, {active_bans} Bot-Typen aktuell gebannt")
if banned_bots:
print(f" Gebannt: {', '.join(banned_bots)}")
if bots:
print(f"\n🤖 Bot-Statistik (nach Bot-Typ):")
@@ -1758,6 +1765,7 @@ def show_all_logs():
total_log_entries = 0
total_bans = 0
total_active_bans = 0
all_banned_bots = []
shop_stats = {}
all_ips = {}
all_bots = {}
@@ -1768,6 +1776,7 @@ def show_all_logs():
total_log_entries += entries
total_bans += bans
total_active_bans += active_bans
all_banned_bots.extend(banned_bots)
if activation_time:
runtime_minutes = (datetime.now() - activation_time).total_seconds() / 60
@@ -1783,7 +1792,8 @@ def show_all_logs():
'ips': ips,
'bots': bots,
'bans': bans,
'active_bans': active_bans
'active_bans': active_bans,
'banned_bots': banned_bots
}
if runtime_minutes > total_minutes:
@@ -1804,6 +1814,11 @@ def show_all_logs():
total_req_min = total_log_entries / total_minutes if total_minutes > 0 else 0
# Zeige aktuell gebannte Bot-Typen ganz oben
unique_banned_bots = list(set(all_banned_bots))
if unique_banned_bots:
print(f"\n🚫 AKTUELL GEBANNTE BOT-TYPEN: {', '.join(sorted(unique_banned_bots))}")
print(f"\n📝 Log-Einträge gesamt: {total_log_entries} (⌀ {total_req_min:.1f} req/min, Laufzeit: {format_duration(total_minutes)})")
if shop_stats:
for shop in sorted(shop_stats.keys()):
@@ -1827,21 +1842,14 @@ def show_all_logs():
print(f" ├─ {shop_colored} {geo_icon} {mode_icon}: {count} ({req_min:.1f} req/min, seit {runtime_str}) {bar}")
shop_ips = stats['ips']
if shop_ips and count > 0:
top_ip = max(shop_ips.items(), key=lambda x: x[1]['count'])
top_ip_addr = top_ip[0]
top_ip_count = top_ip[1]['count']
top_ip_ua = top_ip[1]['ua']
top_ip_bot = top_ip[1].get('bot') or detect_bot(top_ip_ua)
top_ip_req_min = top_ip_count / runtime if runtime > 0 else 0
if top_ip_bot == 'Unbekannt':
display_name = (top_ip_ua[:40] + '...') if len(top_ip_ua) > 43 else top_ip_ua
else:
display_name = top_ip_bot
print(f" │ └─➤ Top: {top_ip_addr} ({display_name}) - {top_ip_count}x, {top_ip_req_min:.1f} req/min")
# Top 3 Bot-Typen für diesen Shop
shop_bots = stats['bots']
if shop_bots and count > 0:
top_bots = sorted(shop_bots.items(), key=lambda x: x[1], reverse=True)[:3]
for i, (bot_name, bot_count) in enumerate(top_bots):
bot_req_min = bot_count / runtime if runtime > 0 else 0
prefix = "└─➤" if i == len(top_bots) - 1 else "├─➤"
print(f"{prefix} {bot_name}: {bot_count}x, {bot_req_min:.1f} req/min")
if total_bans > 0 or total_active_bans > 0:
print(f"\n🚫 Rate-Limit Bans: {total_bans} ausgelöst, {total_active_bans} Bot-Typen aktuell gebannt")
@@ -1857,6 +1865,11 @@ def show_all_logs():
bar = "" * min(stats['bans'] // 2, 20) if stats['bans'] > 0 else ""
print(f" ├─ {shop_colored}: {stats['bans']} bans ({stats['active_bans']} Bot-Typen aktiv) {bar}")
# Zeige gebannte Bot-Typen
if stats['banned_bots']:
for bot_name in stats['banned_bots']:
print(f" │ └─🚫 {bot_name}")
if all_bots:
print(f"\n🤖 Bot-Statistik nach Bot-Typ (alle Shops):")
for bot_name, count in sorted(all_bots.items(), key=lambda x: x[1], reverse=True)[:15]:
@@ -2005,7 +2018,7 @@ def main():
shop_mode = get_shop_mode(shop)
mode_icon = get_mode_icon(shop_mode)
bot_mode = is_bot_mode(shop_mode)
entries, _, bots, activation_time, total_bans, active_bans, _ = get_shop_log_stats(shop)
entries, _, bots, activation_time, total_bans, active_bans, banned_bots = get_shop_log_stats(shop)
runtime = (datetime.now() - activation_time).total_seconds() / 60 if activation_time else 0
httpdocs = os.path.join(VHOSTS_DIR, shop, 'httpdocs')
@@ -2015,7 +2028,12 @@ def main():
if bot_mode:
rate_limit, ban_duration = get_shop_rate_limit_config(shop)
rl_str = f", {rate_limit} req/min/Bot-Typ" if rate_limit else ""
ban_str = f", {active_bans} Bot-Typen gebannt" if active_bans > 0 else ""
ban_str = ""
if active_bans > 0:
if banned_bots:
ban_str = f", 🚫 {', '.join(banned_bots)}"
else:
ban_str = f", {active_bans} Bot-Typen gebannt"
print(f" {entries} log entries, {format_duration(runtime)}, {len(BOT_PATTERNS)} Patterns{rl_str}{ban_str}")
else:
valid, count, _ = validate_existing_cache(httpdocs, get_shop_geo_region(shop))