geoip_shop_manager.py aktualisiert
This commit is contained in:
@@ -10,7 +10,7 @@ Supports three modes:
|
|||||||
- php-only: GeoIP blocking without CrowdSec
|
- php-only: GeoIP blocking without CrowdSec
|
||||||
- bot-only: Block only bots, shop remains globally accessible
|
- bot-only: Block only bots, shop remains globally accessible
|
||||||
|
|
||||||
v3.4.0: Added file-based rate-limiting for bot blocking
|
v3.4.2: Fixed directory permissions for rate-limit (777 for PHP access)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
@@ -1158,9 +1158,13 @@ def activate_blocking(shop, silent=False, mode="php+crowdsec", geo_region="dach"
|
|||||||
|
|
||||||
# Select appropriate template
|
# Select appropriate template
|
||||||
if is_bot_mode:
|
if is_bot_mode:
|
||||||
# Create rate-limit directories
|
# Create rate-limit directories with open permissions (PHP runs as different user)
|
||||||
os.makedirs(os.path.join(ratelimit_path, 'bans'), exist_ok=True)
|
os.makedirs(os.path.join(ratelimit_path, 'bans'), mode=0o777, exist_ok=True)
|
||||||
os.makedirs(os.path.join(ratelimit_path, 'counts'), exist_ok=True)
|
os.makedirs(os.path.join(ratelimit_path, 'counts'), mode=0o777, exist_ok=True)
|
||||||
|
# Ensure parent dir also has correct permissions
|
||||||
|
os.chmod(ratelimit_path, 0o777)
|
||||||
|
os.chmod(os.path.join(ratelimit_path, 'bans'), 0o777)
|
||||||
|
os.chmod(os.path.join(ratelimit_path, 'counts'), 0o777)
|
||||||
|
|
||||||
# Use defaults if not specified
|
# Use defaults if not specified
|
||||||
if rate_limit is None:
|
if rate_limit is None:
|
||||||
@@ -1399,9 +1403,12 @@ def activate_all_shops():
|
|||||||
expiry = datetime.now() + timedelta(hours=72)
|
expiry = datetime.now() + timedelta(hours=72)
|
||||||
|
|
||||||
if is_bot_mode:
|
if is_bot_mode:
|
||||||
# Create rate-limit directories
|
# Create rate-limit directories with open permissions (PHP runs as different user)
|
||||||
os.makedirs(os.path.join(ratelimit_path, 'bans'), exist_ok=True)
|
os.makedirs(os.path.join(ratelimit_path, 'bans'), mode=0o777, exist_ok=True)
|
||||||
os.makedirs(os.path.join(ratelimit_path, 'counts'), exist_ok=True)
|
os.makedirs(os.path.join(ratelimit_path, 'counts'), mode=0o777, exist_ok=True)
|
||||||
|
os.chmod(ratelimit_path, 0o777)
|
||||||
|
os.chmod(os.path.join(ratelimit_path, 'bans'), 0o777)
|
||||||
|
os.chmod(os.path.join(ratelimit_path, 'counts'), 0o777)
|
||||||
|
|
||||||
if uses_crowdsec(mode):
|
if uses_crowdsec(mode):
|
||||||
template = BOT_ONLY_SCRIPT_TEMPLATE
|
template = BOT_ONLY_SCRIPT_TEMPLATE
|
||||||
@@ -1559,9 +1566,12 @@ def activate_direct_shops_only():
|
|||||||
expiry = datetime.now() + timedelta(hours=72)
|
expiry = datetime.now() + timedelta(hours=72)
|
||||||
|
|
||||||
if is_bot_mode:
|
if is_bot_mode:
|
||||||
# Create rate-limit directories
|
# Create rate-limit directories with open permissions (PHP runs as different user)
|
||||||
os.makedirs(os.path.join(ratelimit_path, 'bans'), exist_ok=True)
|
os.makedirs(os.path.join(ratelimit_path, 'bans'), mode=0o777, exist_ok=True)
|
||||||
os.makedirs(os.path.join(ratelimit_path, 'counts'), exist_ok=True)
|
os.makedirs(os.path.join(ratelimit_path, 'counts'), mode=0o777, exist_ok=True)
|
||||||
|
os.chmod(ratelimit_path, 0o777)
|
||||||
|
os.chmod(os.path.join(ratelimit_path, 'bans'), 0o777)
|
||||||
|
os.chmod(os.path.join(ratelimit_path, 'counts'), 0o777)
|
||||||
|
|
||||||
if uses_crowdsec(mode):
|
if uses_crowdsec(mode):
|
||||||
template = BOT_ONLY_SCRIPT_TEMPLATE
|
template = BOT_ONLY_SCRIPT_TEMPLATE
|
||||||
@@ -1714,8 +1724,12 @@ def get_shop_log_stats(shop):
|
|||||||
|
|
||||||
if ip:
|
if ip:
|
||||||
if ip not in ips:
|
if ip not in ips:
|
||||||
ips[ip] = {'count': 0, 'ua': ua}
|
ips[ip] = {'count': 0, 'ua': ua, 'bot': None}
|
||||||
ips[ip]['count'] += 1
|
ips[ip]['count'] += 1
|
||||||
|
# Store bot name if detected (from BOT: or BANNED: in log)
|
||||||
|
if detected_bot and not ips[ip]['bot']:
|
||||||
|
ips[ip]['bot'] = detected_bot
|
||||||
|
# Fallback: try to detect from UA if we have one
|
||||||
if ua != 'Unknown' and ips[ip]['ua'] == 'Unknown':
|
if ua != 'Unknown' and ips[ip]['ua'] == 'Unknown':
|
||||||
ips[ip]['ua'] = ua
|
ips[ip]['ua'] = ua
|
||||||
|
|
||||||
@@ -1793,7 +1807,8 @@ def show_logs(shop):
|
|||||||
if ips:
|
if ips:
|
||||||
print(f"\n🔥 Top 10 IPs:")
|
print(f"\n🔥 Top 10 IPs:")
|
||||||
for ip, data in sorted(ips.items(), key=lambda x: x[1]['count'], reverse=True)[:10]:
|
for ip, data in sorted(ips.items(), key=lambda x: x[1]['count'], reverse=True)[:10]:
|
||||||
bot = detect_bot(data['ua'])
|
# Use stored bot name first, fallback to UA detection
|
||||||
|
bot = data.get('bot') or detect_bot(data['ua'])
|
||||||
print(f" {ip} ({bot}): {data['count']}x")
|
print(f" {ip} ({bot}): {data['count']}x")
|
||||||
|
|
||||||
|
|
||||||
@@ -1848,11 +1863,14 @@ def show_all_logs():
|
|||||||
|
|
||||||
for ip, data in ips.items():
|
for ip, data in ips.items():
|
||||||
if ip not in all_ips:
|
if ip not in all_ips:
|
||||||
all_ips[ip] = {'count': 0, 'ua': data['ua'], 'shops': {}}
|
all_ips[ip] = {'count': 0, 'ua': data['ua'], 'bot': data.get('bot'), 'shops': {}}
|
||||||
all_ips[ip]['count'] += data['count']
|
all_ips[ip]['count'] += data['count']
|
||||||
all_ips[ip]['shops'][shop] = data['count']
|
all_ips[ip]['shops'][shop] = data['count']
|
||||||
if data['ua'] != 'Unknown' and all_ips[ip]['ua'] == 'Unknown':
|
if data['ua'] != 'Unknown' and all_ips[ip]['ua'] == 'Unknown':
|
||||||
all_ips[ip]['ua'] = data['ua']
|
all_ips[ip]['ua'] = data['ua']
|
||||||
|
# Update bot name if we have one
|
||||||
|
if data.get('bot') and not all_ips[ip].get('bot'):
|
||||||
|
all_ips[ip]['bot'] = data.get('bot')
|
||||||
|
|
||||||
for bot_name, count in bots.items():
|
for bot_name, count in bots.items():
|
||||||
all_bots[bot_name] = all_bots.get(bot_name, 0) + count
|
all_bots[bot_name] = all_bots.get(bot_name, 0) + count
|
||||||
@@ -1905,7 +1923,8 @@ def show_all_logs():
|
|||||||
top_ip_addr = top_ip[0]
|
top_ip_addr = top_ip[0]
|
||||||
top_ip_count = top_ip[1]['count']
|
top_ip_count = top_ip[1]['count']
|
||||||
top_ip_ua = top_ip[1]['ua']
|
top_ip_ua = top_ip[1]['ua']
|
||||||
top_ip_bot = detect_bot(top_ip_ua)
|
# Use stored bot name first, fallback to UA detection
|
||||||
|
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
|
top_ip_req_min = top_ip_count / runtime if runtime > 0 else 0
|
||||||
|
|
||||||
if top_ip_bot == 'Unbekannt':
|
if top_ip_bot == 'Unbekannt':
|
||||||
@@ -1973,7 +1992,8 @@ def show_all_logs():
|
|||||||
for ip, data in sorted_ips:
|
for ip, data in sorted_ips:
|
||||||
count = data['count']
|
count = data['count']
|
||||||
ua = data['ua']
|
ua = data['ua']
|
||||||
bot_name = detect_bot(ua)
|
# Use stored bot name first, fallback to UA detection
|
||||||
|
bot_name = data.get('bot') or detect_bot(ua)
|
||||||
shops_data = data['shops']
|
shops_data = data['shops']
|
||||||
|
|
||||||
# Calculate req/min for this IP
|
# Calculate req/min for this IP
|
||||||
@@ -2014,7 +2034,7 @@ def show_all_logs():
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
print("\n" + "=" * 60)
|
print("\n" + "=" * 60)
|
||||||
print(" GeoIP Shop Blocker Manager v3.4.0")
|
print(" GeoIP Shop Blocker Manager v3.4.2")
|
||||||
print(" 🇩🇪🇦🇹🇨🇭 DACH | 🇪🇺 Eurozone+GB | 🤖 Bot-Only")
|
print(" 🇩🇪🇦🇹🇨🇭 DACH | 🇪🇺 Eurozone+GB | 🤖 Bot-Only")
|
||||||
print(" 🛡️ Mit Cache-Validierung und Fail-Open")
|
print(" 🛡️ Mit Cache-Validierung und Fail-Open")
|
||||||
print(" 🚦 Mit File-basiertem Rate-Limiting")
|
print(" 🚦 Mit File-basiertem Rate-Limiting")
|
||||||
|
|||||||
Reference in New Issue
Block a user