Files
intrusion-detection/app/utils/constants.py
T

148 lines
6.1 KiB
Python

#!/usr/bin/env python3
"""Central configuration constants for the intrusion-detection system.
All tunable values (paths, router credentials, whitelist sources, scan
thresholds) live here so they can be maintained and overridden from a
single place. Values that make sense per-deployment are read from
environment variables; see ``.env.example`` for the supported keys.
"""
from __future__ import annotations
import os
# ---------------------------------------------------------------------------
# Project root + .env loading
# ---------------------------------------------------------------------------
PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Load `.env` for local development (python-dotenv, optional dependency).
# `load_dotenv` does NOT override variables already present in the system
# environment, so production deployments that set these via the OS keep
# working without a `.env` file (or even without python-dotenv installed).
try:
from dotenv import load_dotenv
load_dotenv(os.path.join(PROJECT_ROOT, ".env"))
except ImportError:
pass
# ---------------------------------------------------------------------------
# Project paths
# ---------------------------------------------------------------------------
DATA_DIR = os.path.join(PROJECT_ROOT, "data")
REPORT_DIR = os.path.join(PROJECT_ROOT, "reports")
# Per-analyzer report directories
COPYPARTY_REPORT_DIR = os.path.join(REPORT_DIR, "copyparty")
NPM_REPORT_DIR = os.path.join(REPORT_DIR, "npm")
# Consolidated application outputs (blocklists, shared data)
APP_REPORT_DIR = os.path.join(REPORT_DIR, "app")
APP_REPORT_DATA_DIR = os.path.join(APP_REPORT_DIR, "data")
# MikroTik reports + structured snapshots from each run
MIKROTIK_REPORT_DIR = os.path.join(REPORT_DIR, "mikrotik")
MIKROTIK_REPORT_DATA_DIR = os.path.join(MIKROTIK_REPORT_DIR, "data")
# Common MikroTik state (latest snapshot; overwritten each run, used for
# git diffing / auditing changes to firewall rules and address lists).
MIKROTIK_DATA_DIR = os.path.join(DATA_DIR, "mikrotik")
WHOIS_CACHE_PATH = os.path.join(DATA_DIR, "whois_cache.json")
# Incremental-scan state: absolute log path -> last processed byte offset
SCAN_STATE_PATH = os.path.join(DATA_DIR, "scan_state.json")
# Web UI scan-job history (web_scan.py): persisted so the dashboard keeps
# showing recent scans across server restarts. Oldest entries are pruned
# once SCAN_JOBS_MAX is exceeded.
SCAN_JOBS_PATH = os.path.join(DATA_DIR, "scan_jobs.json")
SCAN_JOBS_MAX = 50
# Report retention: per-directory cleanup of generated files under /reports/.
# Each directory keeps at most REPORT_RETENTION_MAX_FILES files, all newer
# than REPORT_RETENTION_DAYS days (see app/retention.py).
REPORT_RETENTION_DAYS = int(os.environ.get("REPORT_RETENTION_DAYS", "30"))
REPORT_RETENTION_MAX_FILES = int(
os.environ.get("REPORT_RETENTION_MAX_FILES", "10"))
# ---------------------------------------------------------------------------
# Log sources (configurable via environment)
# ---------------------------------------------------------------------------
COPYPARTY_LOG_PATH = os.environ.get(
"COPYPARTY_LOG_PATH", "/srv/projects/copyparty")
NPM_LOG_PATH = os.environ.get("NPM_LOG_PATH", "/mnt/backups/npm/logs")
# ---------------------------------------------------------------------------
# MikroTik router connection (configurable via environment)
# ---------------------------------------------------------------------------
SSH_PORT = 22
SSH_TIMEOUT = 10 # seconds
ROUTER_IP = os.environ.get("ROUTER_IP", "192.168.88.1")
ROUTER_USER = os.environ.get("ROUTER_USER", "admin")
ROUTER_PASSWORD = os.environ.get("ROUTER_PASSWORD", "M11ffpgm")
BLOCKLIST_NAME = os.environ.get("BLOCKLIST_NAME", "Blocked")
WHITELIST_NAMES = [
name.strip()
for name in os.environ.get(
"WHITELIST_NAMES", "Cloudflare,Init7").split(",")
if name.strip()
]
# ---------------------------------------------------------------------------
# WHOIS subnet consolidation
# ---------------------------------------------------------------------------
WHOIS_SERVER = os.environ.get("WHOIS_SERVER", "whois.radb.net")
WHOIS_PORT = int(os.environ.get("WHOIS_PORT", "43"))
WHOIS_TIMEOUT = float(os.environ.get("WHOIS_TIMEOUT", "3.0")) # seconds
# Minimum number of same-subnet IPs before blocking the whole subnet
SUBNET_THRESHOLD = int(os.environ.get("SUBNET_THRESHOLD", "3"))
# ---------------------------------------------------------------------------
# Scan / flagging defaults
# ---------------------------------------------------------------------------
DEFAULT_TOP = int(os.environ.get("DEFAULT_TOP", "30")
) # top-IP table rows
DEFAULT_MIN_DENIED = int(os.environ.get(
"DEFAULT_MIN_DENIED", "1")) # copyparty
DEFAULT_MIN_ERRORS = int(os.environ.get("DEFAULT_MIN_ERRORS", "5")) # npm
DEFAULT_ERROR_RATIO = float(os.environ.get(
"DEFAULT_ERROR_RATIO", "0.4")) # npm
DEFAULT_TOP_PATHS = int(os.environ.get("DEFAULT_TOP_PATHS", "20"))
# ---------------------------------------------------------------------------
# Web server (localhost only)
# ---------------------------------------------------------------------------
# The Flask web UI binds to localhost on a very high port so it is only
# reachable from this machine. Do not expose WEB_HOST beyond 127.0.0.1.
WEB_HOST = os.environ.get("WEB_HOST", "127.0.0.1")
WEB_PORT = int(os.environ.get("WEB_PORT", "54666"))
# ---------------------------------------------------------------------------
# Whitelist sources (configurable via environment)
# ---------------------------------------------------------------------------
CLOUDFLARE_URL_V4 = os.environ.get(
"CLOUDFLARE_URL_V4", "https://www.cloudflare.com/ips-v4")
CLOUDFLARE_URL_V6 = os.environ.get(
"CLOUDFLARE_URL_V6", "https://www.cloudflare.com/ips-v6")
PALOALTO_URL = os.environ.get(
"PALOALTO_URL",
"https://docs-cortex.paloaltonetworks.com/r/1/Cortex-Xpanse/Scanning-activity",
)
# Local whitelist files (checked before remote download)
CLOUDFLARE_V4_FILE = os.path.join(DATA_DIR, "cloudflare", "ips-v4.txt")
CLOUDFLARE_V6_FILE = os.path.join(DATA_DIR, "cloudflare", "ips-v6.txt")
PALOALTO_FILE = os.path.join(DATA_DIR, "paloalto", "scanner-ips.txt")