Files
autoban/config.py
2026-01-01 02:13:34 +01:00

433 lines
14 KiB
Python

import os
SKIP_BACKUP_PREFIXES = (
"redirectlog",
"stats:ip",
"stats:user_agent",
"stats:referrer",
"stats:host:",
"sequence:", # per-IP sekwencje żądań (ltrim, ale bez TTL)
"requests:", # per-IP ostatnie requesty (ltrim, ale bez TTL)
)
CONFIG = {
"basic_auth": {
"username": "admin",
"password": "admin"
},
"api_keys": {
"default": "d844X5w4GJ7X29tvp3bQ48"
},
"api_trusted_networks": [
"127.0.0.1/32",
"::1/128",
"10.87.0.0/16",
"172.16.0.0/24"
],
"trusted_proxies": ["127.0.0.1", "::1"],
"sqlite_db": os.path.join(os.path.dirname(__file__), "redis_backup.sqlite3"),
"webserver_bin": "/usr/sbin/angie",
"log_files": [
"/var/log/angie/unitraklub.pl_access.log",
"/var/log/angie/unitra.eu.org_access.log",
"/var/log/angie/unitrafan.pl_access.log",
],
"redis_host": "localhost",
"redis_port": 6379,
"redis_db": 8,
"thresholds": {
"requests": 25000,
"errors": 10,
"success_requests": 20000,
"error_codes": [404, 500, 410],
"requests_time_window": 3600,
"ban_duration": 15552000,
"request_size": 256000000,
},
"deny_file": "/etc/angie/conf.d/deny_auto.conf",
#'deny_file': 'deny_auto.conf',
"geoip_db": "GeoIP/GeoLite2-City.mmdb",
"api_port": 5002,
"prometheus_port": 9502,
"pushover": {
"token": "afh4yqrybtf7jnznyapq2bs1wcdmiq",
"user_key": "u629MYggcYdRs6UM3TdYJviHWmcdKe",
"enabled": True,
},
"whitelist_endpoints": [
"/customerror/404",
"/block_refresh/quicktabs/3",
"/block_refresh/block/10",
"/block_refresh/views/apk_user_tracker_page-block_1",
"/klubowyczat/includes/json/receive/receive_core.php",
"/klubowyczat/includes/json/receive/receive_buddylist.php",
],
"notification_batching": {
"enabled": True,
"batch_window": 43200, # X minut w sekundach
"threshold": 25, # minimum banów do wysłania powiadomienia
"max_window": 21600, # maksymalny czas oczekiwania
"summary_limit": 10, # ile najczęstszych IP pokazać w podsumowaniu
},
"attack_patterns": {
"path_traversal": [
r"\.\./",
r"\.\.\\",
r"%2e%2e%2f", # ../
r"%2e%2e%5c", # ..\
r"%252e%252e%252f", # podwójnie kodowane ../
r"%c0%ae%c0%ae%c0%af", # UTF-8 overlong ../
r"%uff0e%uff0e%u2215", # Unicode fullwidth
r"/etc/passwd",
r"/etc/shadow",
r"/proc/self/environ",
r"c:\\windows\\system32",
r"c:\\boot\\.ini",
r"web\.config",
r"\.\./\.\./", # ../../
r"\\..\\", # UNC style
],
"command_injection": [
r";\s*cat\s+/etc/passwd",
r";\s*ls\s+",
r";\s*id\s*;",
r";\s*whoami\s*;",
r"&&\s*cat\s+",
r"\|\s*cat\s+",
r"`cat\s+/etc/passwd`",
r"\$\(cat\s+/etc/passwd\)",
r";\s*wget\s+",
r";\s*curl\s+",
r";\s*nc\s+",
r";\s*bash\s*;",
],
"nosql_injection": [
r"\$ne:",
r"\$gt:",
r"\$lt:",
r"\$where:",
r"\$regex:",
r"\$exists:",
r'{"username":\s*{"?\$ne',
r'{"password":\s*{"?\$ne',
r";\s*db\.dropDatabase\(\)",
r"MapReduce",
r"\$eval:",
],
"ldap_injection": [
r"\*\)\(cn=\*",
r"\)\(\|",
r"\(\|\(",
r"\)\(uid=\*",
r"\(\&\(",
r"admin\)\(\|",
r"\*\)\(userPassword=\*",
r"\(\!\(",
r"\)%00",
],
"xxe": [
r"<!ENTITY.*?SYSTEM",
r"<!ENTITY.*?file://",
r"<!ENTITY.*?http://",
r"<!ENTITY.*?https://",
r"<!ENTITY.*?ftp://",
r"<!ENTITY.*?expect://",
r"&xxe;",
r"<!DOCTYPE.*?\[",
r'SYSTEM\s+["\']file://',
],
"ssti": [
r"\{\{.*?\}\}",
r"\{\%.*?\%\}",
r"\$\{.*?\}",
r"\{\{7\*7\}\}",
r"\{\{config\}\}",
r"\{\{request\}\}",
r"\{\{self\}\}",
r"<%.*?%>",
r"\{\{.*?\.\_\_class\_\_.*?\}\}",
],
"csrf": [
r'<form.*?action=["\']https?://(?!.*?example\.com)',
r'<img.*?src=["\']https?://(?!.*?example\.com).*?\.php',
r'<iframe.*?src=["\']https?://(?!.*?example\.com)',
r"XMLHttpRequest.*?open.*?POST",
r'fetch.*?method:\s*["\']POST["\']',
],
"deserialization": [
r"O:\d+:",
r"a:\d+:\{",
r"java\.io\.Serializable",
r"rO0AB",
r"H4sIA",
r"__reduce__",
r"__setstate__",
r"pickle\.loads",
r"cPickle\.loads",
r"yaml\.load",
r"unserialize\(",
],
"host_header_injection": [
r"Host:\s*[^.\r\n]+\.[^.\r\n]+\.[^.\r\n]+",
r"X-Forwarded-Host:\s*[^.\r\n]+\.[^.\r\n]+",
r"X-Host:\s*[^.\r\n]+\.[^.\r\n]+",
r"Host:\s*localhost:\d{4,5}",
r"Host:\s*127\.0\.0\.1:\d+",
],
"open_redirect": [
r"(redirect|url|return|next|target)=https?://",
r"(redirect|url|return|next|target)=%2F%2F",
r"(redirect|url|return|next|target)=//[^/]",
r"Location:\s*https?://(?!.*?example\.com)",
r"window\.location.*?=.*?http://",
r"document\.location.*?=.*?http://",
],
"information_disclosure": [
r'(password|passwd|pwd|secret|key|token)[\s]*[:=][\s]*["\'][^"\']{8,}',
r"mysql_connect\(",
r"pg_connect\(",
r"stack trace",
r"Fatal error:",
r"Warning:.*?on line",
r"Error:.*?at line",
r"\.git/",
r"\.env",
r"config\.php",
r"backup\.",
r"\.bak",
r"\.old",
],
"business_logic": [
r"(price|amount|quantity|discount)=0",
r"(price|amount|quantity|discount)=-\d+",
r"(role|privilege|level|type)=admin",
r"(role|privilege|level|type)=administrator",
r"bypass=true",
r"test=true",
r"debug=true",
r"admin=true",
],
"session_attacks": [
r"PHPSESSID=.*?\w{26,}",
r"JSESSIONID=.*?\w{32,}",
r"session_id=.*?\w{32,}",
r"sid=.*?\w{16,}",
r"Cookie:.*?sessionid=fixed",
r"Set-Cookie:.*?secure=false",
r"Set-Cookie:.*?httponly=false",
],
"sqli_extended": [
# MongoDB NoSQL
r"\$where:\s*function\(\)",
r'ObjectId\(["\'][^"\']*["\']\)',
# PostgreSQL specific
r"pg_sleep\(\d+\)",
r"COPY.*?FROM.*?PROGRAM",
# Oracle specific
r"UTL_HTTP\.REQUEST",
r"SYS\.DBMS_EXPORT_EXTENSION",
],
"xss_extended": [
# DOM-based XSS
r"document\.write\(",
r"innerHTML\s*=",
r"outerHTML\s*=",
# Event handlers
r'on\w+\s*=\s*["\'][^"\']*script',
# Data URIs
r"data:text/html,",
r"data:image/svg\+xml",
# JavaScript protocols
r"vbscript:",
r"livescript:",
],
"clickjacking": [
r"<iframe.*?opacity\s*:\s*0",
r"<iframe.*?visibility\s*:\s*hidden",
r"<iframe.*?display\s*:\s*none",
r"position\s*:\s*absolute.*?top\s*:\s*-\d+",
r"z-index\s*:\s*-?\d+",
],
"sqli": [
r"\b(UNION\s+SELECT|SELECT\s+.*?\s+FROM|INSERT\s+INTO|UPDATE\s+.*?\s+SET|DELETE\s+FROM)\b",
r"\bOR\s+1=1\b",
r"\bEXEC\(.*\)",
r"\bWAITFOR\s+DELAY\b",
r"\b(SLEEP\(\d+\)|BENCHMARK\(\d+\))",
r"\b(CAST|CONVERT)\(.*AS.*\)",
r"\bINFORMATION_SCHEMA\.TABLES\b",
r"\b0x[0-9a-fA-F]+\b",
r"\b(;--|#|/\*)\s*$",
],
"xss": [r"<script.*?>", r"javascript:", r"onerror=", r"alert\(.*\)"],
"drupal": [
r"/user/register\?element_parents=account/mail/%23value&.*_wrapper_format=drupal_ajax",
r"/file/ajax/.*/upload",
r"POST\s+/node/\d+/?_format=hal_json",
r"POST\s+/user/.*?_format=hal_json",
r"_drupal_ajax=1&form_id=.*_form",
r"/_entity_embed/.*?/embed",
r"linkit/match\?search=.*<script",
r"/_jsonapi\?.*filter\[.*\]\[condition\]\[path\]=.*",
r"/admin/config/development/configuration/single/export",
r"rest_export=1",
r"/taxonomy/term/\d+/edit",
],
"rce": [
r"\b(passthru|shell_exec|phpinfo|proc_open|popen)\b",
r"\.\./\.\./\.\./\.\./",
r"/\$(?:\\$\$)+/",
],
"lfi": [
r"\.\./\.\./\.\./\.\./",
r"(etc/passwd|proc/self/environ)",
r"php://filter/convert.base64-encode/resource=",
],
"ssrf": [
r"(127\.0\.0\.1|localhost|169\.254\.169\.254)",
r"(\?|&)url=(http|https|ftp|file)",
r"/(metadata|instance-data)/",
r"accesskeyid|secretkey",
],
"xxe": [r"<!ENTITY.*SYSTEM.*>", r"%xxe;", r"DOCTYPE.*ENTITY", r"jar:file:/"],
"ci_cd": [
r"/(\.git|\.svn|\.hg)/",
r"/(Jenkinsfile|\.travis\.yml|circleci/config\.yml)",
r"/(docker-compose\.yml|Dockerfile)",
r"/(package\.json|requirements\.txt)",
r"/_apis/build",
r"/api/v4/ci",
r"/(github|gitlab)-webhook",
r"/(bitbucket-pipelines\.yml)",
],
},
"bruteforce": {
"login_urls": [
# klasyczne
"/user/login",
"/login",
"/signin",
"/users/login",
"/account/login",
"/auth/login",
"/admin/login",
"/admin.php",
"/admin/index.php",
"/administrator/",
"/administrator/index.php",
"/cpanel",
"/phpmyadmin",
# WordPress / CMS
"/wp-login.php",
"/wp-login.php?action=lostpassword",
"/xmlrpc.php",
"/wp-admin/",
"/wp-admin/admin-ajax.php",
"/wp-content/",
"/typo3/index.php",
"/joomla/administrator/",
# API loginy
"/oauth/token",
"/graphql",
"/api/login",
"/api/auth",
"/api/v1/login",
"/rest/user/login",
"/rest/auth/login",
"/admin/auth/login",
# podejrzane / backdoory
"/makeasmtp.php",
"/updates.php",
"/yanz.php",
"/pwnd.php",
"/wp-l0gin.php",
"/wlwmanifest.xml",
"/classwithtostring.php",
"/0x.php",
"/shell.php",
"/cmd.php",
"/login.php",
"/logon.php",
"/portal/redlion",
],
"attempts_threshold": 15,
"time_window": 300,
"rate_limits": {
"api": {"path_regex": r"^/klubowyczat/.*", "limit": 250, "window": 60},
"assets": {
"path_regex": r"\.(js|css|png|jpg|jpeg)$",
"limit": 750,
"window": 60,
},
},
},
"sequence": {
"window_size": 15,
"suspicious_patterns": [
{
"pattern": ["/user/password", "/user/login", "/user/register"],
"score": 10,
},
{"pattern": ["/node/add", "/admin/content", "/admin/users"], "score": 8},
{"pattern": ["/wp-admin", "/wp-login.php", "/xmlrpc.php"], "score": 12},
{"pattern": ["/.env", "/config.php", "/database.ini"], "score": 15},
{"pattern": ["/v1/api", "/v1/admin", "/v1/user"], "score": 7},
{"pattern": ["/phpinfo.php", "/info.php", "/test.php"], "score": 10},
],
"threshold": 15,
"time_based_sequences": [
{
"pattern": ["/api/auth/token", "/api/user/me"],
"time_window": 2,
"threshold": 10,
},
{
"pattern": ["/password/reset", "/login"],
"time_window": 30,
"threshold": 5,
},
],
},
"api_abuse": {
"graphql": [
r"(__schema|introspection)",
r"mutation\s+\{",
r"query\s+\{\s+__typename",
],
"rest": [r"/(v1|api)/.*(\$|\|)", r"%24%7B.*%7D", r"/api/.*%0A"],
},
"scanner_signatures": [
r"(nmap|acunetix|nessus|nikto)",
r"(sqlmap|w3af|zap|burp)",
r"libwww-perl|curl|python-requests",
r"(zgrab|masscan|metasploit)",
],
"whitelist": {
"user_agents": [
r"Googlebot",
r"Bingbot",
r"DuckDuckBot",
r"YandexBot",
r"Twitterbot",
r"Applebot",
r"LinkedInBot",
r"AdsBot-Google",
r"SeznamBot",
r"facebot",
],
"ip_ranges": [
"66.249.64.0/19",
"157.55.39.0/24",
"207.46.0.0/16",
"146.75.0.0/16",
"141.144.232.95/32",
],
"log_lines_limit": 50,
},
"stats_retention": {"week": 4, "month": 1, "year": 0},
}