From f78faf8f8af1a5782734eb92bb8cf4acfefe3ae9 Mon Sep 17 00:00:00 2001 From: zwitschi Date: Tue, 4 Aug 2026 22:23:59 +0200 Subject: [PATCH] Restructure sources into app package with unified entry point and update documentation --- README.md | 192 +++++++++++++------------ app.py | 18 +++ app/__init__.py | 1 + analyzer.py => app/analyzer.py | 16 +-- bad_patterns.py => app/bad_patterns.py | 0 copyparty.py => app/copyparty.py | 14 +- files.py => app/files.py | 0 firewall.py => app/firewall.py | 8 +- flags.py => app/flags.py | 4 +- ip_utils.py => app/ip_utils.py | 2 +- mikrotik.py => app/mikrotik.py | 4 +- models.py => app/models.py | 4 +- npm.py => app/npm.py | 12 +- reporting.py => app/reporting.py | 0 scan.py => app/scan.py | 14 +- utils.py => app/utils.py | 0 whitelists.py => app/whitelists.py | 2 +- whois.py => app/whois.py | 5 +- 18 files changed, 167 insertions(+), 129 deletions(-) create mode 100644 app.py create mode 100644 app/__init__.py rename analyzer.py => app/analyzer.py (95%) rename bad_patterns.py => app/bad_patterns.py (100%) rename copyparty.py => app/copyparty.py (95%) rename files.py => app/files.py (100%) rename firewall.py => app/firewall.py (98%) rename flags.py => app/flags.py (96%) rename ip_utils.py => app/ip_utils.py (96%) rename mikrotik.py => app/mikrotik.py (97%) rename models.py => app/models.py (98%) rename npm.py => app/npm.py (96%) rename reporting.py => app/reporting.py (100%) rename scan.py => app/scan.py (92%) rename utils.py => app/utils.py (100%) rename whitelists.py => app/whitelists.py (99%) rename whois.py => app/whois.py (95%) diff --git a/README.md b/README.md index 7a81b3a..fe8eba2 100644 --- a/README.md +++ b/README.md @@ -2,53 +2,59 @@ Local-development intrusion detection / log analysis for two log sources: -| Script | Source | Detection rule | -| ----------------- | --------------------------------------------------------------- | -------------------------------------------------------------------------- | -| `scan.py` | both sources | consolidated scan + unified MikroTik export | -| `copyparty.py` | [copyparty](https://github.com/9001/copyparty) server logs | denied-only IPs + copyparty auto-bans | -| `npm.py` | [Nginx Proxy Manager](https://nginxproxymanager.com) proxy logs | high error-rate IPs (scanners) | -| `utils.py` | re-export layer | thin barrel — imports from sub-modules below | -| `models.py` | data model | `Request`, `IPStats`, `aggregate()` | -| `ip_utils.py` | IP helpers | `parse_ip`, `whitelist_of`, `is_whitelisted`, `sort_ips`, `split_versions` | -| `flags.py` | detection rules | `flag_scanners`, `flag_denied_only`, `flag_malicious_patterns`, `by_total` | -| `analyzer.py` | pipeline | `Analyzer` — discover → load → analyze → report → write | -| `whitelists.py` | whitelist module | provider CIDR constants, local/remote load, CIDR extraction | -| `bad_patterns.py` | pattern detection | malicious URL/file regex classification | -| `whois.py` | WHOIS query | `query_whois_subnet`, `consolidate_by_subnet` | -| `mikrotik.py` | RouterOS export | `mikrotik_script`, `write_mikrotik`, `split_cidr_versions` | -| `files.py` | I/O helpers | `read_lines`, `find_logs`, `write_csv`, `write_json`, etc. | -| `reporting.py` | text rendering | `Column`, `render_table`, `render_kv`, `timestamp_name` | +| Script | Source | Detection rule | +| --------------------- | --------------------------------------------------------------- | -------------------------------------------------------------------------- | +| `app.py` | unified entry point | runs both analyzers + optional firewall sync | +| `app/scan.py` | consolidated scanner | runs both analyzers, merges blocklists, syncs firewall | +| `app/copyparty.py` | [copyparty](https://github.com/9001/copyparty) server logs | denied-only IPs + copyparty auto-bans | +| `app/npm.py` | [Nginx Proxy Manager](https://nginxproxymanager.com) proxy logs | high error-rate IPs (scanners) | +| `app/utils.py` | re-export layer | thin barrel — imports from sub-modules below | +| `app/models.py` | data model | `Request`, `IPStats`, `aggregate()` | +| `app/ip_utils.py` | IP helpers | `parse_ip`, `whitelist_of`, `is_whitelisted`, `sort_ips`, `split_versions` | +| `app/flags.py` | detection rules | `flag_scanners`, `flag_denied_only`, `flag_malicious_patterns`, `by_total` | +| `app/analyzer.py` | pipeline | `Analyzer` — discover → load → analyze → report → write | +| `app/whitelists.py` | whitelist module | provider CIDR constants, local/remote load, CIDR extraction | +| `app/bad_patterns.py` | pattern detection | malicious URL/file regex classification | +| `app/whois.py` | WHOIS query | `query_whois_subnet`, `consolidate_by_subnet` | +| `app/mikrotik.py` | RouterOS export | `mikrotik_script`, `write_mikrotik`, `split_cidr_versions` | +| `app/firewall.py` | RouterOS SSH client | `MikrotikFirewall` — connect, sync blocklist, audit state | +| `app/files.py` | I/O helpers | `read_lines`, `find_logs`, `write_csv`, `write_json`, etc. | +| `app/reporting.py` | text rendering | `Column`, `render_table`, `render_kv`, `timestamp_name` | Both per-source scripts parse logs, aggregate per-IP behaviour, split IPv4/IPv6, skip whitelisted provider ranges, detect malicious path patterns, group flagged IPs into WHOIS subnets, and emit a ready-to-import MikroTik RouterOS firewall script. -`scan.py` runs both analyzers, merges their blocklists, and writes a single -consolidated `.rsc`. +`app.py` runs both analyzers, merges their blocklists, and optionally +synchronizes the MikroTik RouterOS firewall via SSH. -> Status: **local dev**. Runs offline against log files on disk. It does not -> talk to the router, does not run as a service, and blocks nothing by itself. -> You review the generated `.rsc` and import it manually. +> Status: **local dev**. Runs offline against log files on disk. Use +> `--update-firewall` to push changes to the router, or `--dry-run` to +> preview without applying. ## Architecture ```text intrusion-detection/ -├── scan.py consolidated scanner entry point -├── copyparty.py copyparty log adapter (~150 lines) -├── npm.py NPM proxy log adapter (~150 lines) -├── utils.py thin re-export barrel (~90 lines) -├── models.py Request, IPStats, aggregate() -├── ip_utils.py IP parsing, whitelist lookups, sorting -├── flags.py flag_scanners, flag_denied_only, flag_malicious_patterns -├── analyzer.py Analyzer pipeline base class -├── whitelists.py provider CIDR constants, local/remote load -├── bad_patterns.py malicious URL/file regex patterns -├── whois.py query_whois_subnet, consolidate_by_subnet -├── mikrotik.py RouterOS .rsc script generation -├── files.py read_lines, find_logs, write_csv/json/lines -├── reporting.py Column, render_table, render_kv, timestamp_name +├── app.py unified entry point +├── app/ application package +│ ├── __init__.py +│ ├── scan.py consolidated scanner +│ ├── copyparty.py copyparty log adapter (~150 lines) +│ ├── npm.py NPM proxy log adapter (~150 lines) +│ ├── firewall.py MikroTik RouterOS SSH client +│ ├── utils.py thin re-export barrel (~90 lines) +│ ├── models.py Request, IPStats, aggregate() +│ ├── ip_utils.py IP parsing, whitelist lookups, sorting +│ ├── flags.py flag_scanners, flag_denied_only, flag_malicious_patterns +│ ├── analyzer.py Analyzer pipeline base class +│ ├── whitelists.py provider CIDR constants, local/remote load +│ ├── bad_patterns.py malicious URL/file regex patterns +│ ├── whois.py query_whois_subnet, consolidate_by_subnet +│ ├── mikrotik.py RouterOS .rsc script generation +│ ├── files.py read_lines, find_logs, write_csv/json/lines +│ └── reporting.py Column, render_table, render_kv, timestamp_name ├── data/ whitelist source files (cached locally) │ ├── openfactory/ │ │ └── geofeed.csv @@ -60,29 +66,28 @@ intrusion-detection/ ├── reports/ generated reports (per-run + per-source) │ ├── copyparty/ │ ├── npm/ -│ └── mikrotik-block.rsc consolidated .rsc (scan.py only) +│ └── mikrotik/ firewall audit snapshots └── README.md ``` -`copyparty.py` and `npm.py` are thin adapters. Each supplies a log matcher, -a line parser, a flagging rule, and column definitions. `utils.py` is a barrel -module that re-exports everything from the sub-modules so callers only need -`import utils`. +`app/copyparty.py` and `app/npm.py` are thin adapters. Each supplies a log +matcher, a line parser, a flagging rule, and column definitions. Core responsibilities by module: -| Module | Owns | -| ----------------- | -------------------------------------------------------------------------------- | -| `models.py` | `Request`, `IPStats`, `aggregate()` | -| `ip_utils.py` | `parse_ip`, `whitelist_of`, `is_whitelisted`, `sort_ips`, `split_versions` | -| `flags.py` | `flag_scanners`, `flag_denied_only`, `flag_malicious_patterns`, `by_total` | -| `analyzer.py` | `Analyzer` — discover → load → analyze → report → write | -| `whitelists.py` | provider CIDR constants, local-file / remote / built-in loading | -| `bad_patterns.py` | malicious URL/file regex classification | -| `whois.py` | `query_whois_subnet`, `consolidate_by_subnet` | -| `mikrotik.py` | `mikrotik_script`, `write_mikrotik`, `split_cidr_versions` | -| `files.py` | `read_lines`, `find_logs`, `validate_dir`, `ensure_dirs`, `write_csv/json/lines` | -| `reporting.py` | `Column`, `render_table`, `render_kv`, `timestamp_name` | +| Module | Owns | +| --------------------- | -------------------------------------------------------------------------------- | +| `app/models.py` | `Request`, `IPStats`, `aggregate()` | +| `app/ip_utils.py` | `parse_ip`, `whitelist_of`, `is_whitelisted`, `sort_ips`, `split_versions` | +| `app/flags.py` | `flag_scanners`, `flag_denied_only`, `flag_malicious_patterns`, `by_total` | +| `app/analyzer.py` | `Analyzer` — discover → load → analyze → report → write | +| `app/whitelists.py` | provider CIDR constants, local-file / remote / built-in loading | +| `app/bad_patterns.py` | malicious URL/file regex classification | +| `app/whois.py` | `query_whois_subnet`, `consolidate_by_subnet` | +| `app/mikrotik.py` | `mikrotik_script`, `write_mikrotik`, `split_cidr_versions` | +| `app/firewall.py` | `MikrotikFirewall` — SSH connect, sync blocklist, audit state | +| `app/files.py` | `read_lines`, `find_logs`, `validate_dir`, `ensure_dirs`, `write_csv/json/lines` | +| `app/reporting.py` | `Column`, `render_table`, `render_kv`, `timestamp_name` | Console output and saved reports are the **same string** (`Analyzer.text_report()`). @@ -94,50 +99,57 @@ Console output and saved reports are the **same string** (`Analyzer.text_report( ## Usage ```powershell -# individual scanners -python copyparty.py -python npm.py +# unified entry point (both sources, optional firewall sync) +python app.py +python app.py --quiet +python app.py --update-firewall --dry-run +python app.py --update-firewall -# consolidated (both sources, unified blocklist) -python scan.py +# individual scanners (still runnable directly) +python -m app.copyparty +python -m app.npm ``` All scripts accept CLI overrides: -| Flag | Default | Meaning | -| ----------------- | -------------------- | ----------------------------- | -| `--log-path` | see below | log directory | -| `--report-dir` | `reports/` | output directory | -| `--top N` | `30` | rows in the top-IP table | -| `--quiet` | off | write files, print only paths | -| `--no-rsc` | off | skip MikroTik export | -| `--min-errors N` | `5` (`npm.py`) | error count threshold | -| `--error-ratio F` | `0.5` (`npm.py`) | error ratio threshold | -| `--min-denied N` | `1` (`copyparty.py`) | denied-hit threshold | +| Flag | Default | Meaning | +| ------------------- | -------------------- | ---------------------------------- | +| `--log-path` | see below | log directory | +| `--report-dir` | `reports/` | output directory | +| `--top N` | `30` | rows in the top-IP table | +| `--quiet` | off | write files, print only paths | +| `--min-errors N` | `5` (`npm.py`) | error count threshold | +| `--error-ratio F` | `0.5` (`npm.py`) | error ratio threshold | +| `--min-denied N` | `1` (`copyparty.py`) | denied-hit threshold | +| `--update-firewall` | off | sync blocklist to MikroTik via SSH | +| `--dry-run` | off | preview firewall changes, no apply | -`scan.py` accepts all flags from both scanners plus `--copyparty-log-path`, +`app.py` accepts all flags from both scanners plus `--copyparty-log-path`, `--copyparty-report-dir`, `--npm-log-path`, `--npm-report-dir`, and `--report-dir` for the consolidated output. Default log paths (overridable by `.env`): -| Script | Env var | Default | -| -------------- | -------------------- | -------------- | -| `copyparty.py` | `COPYPARTY_LOG_PATH` | `P:\copyparty` | -| `npm.py` | `NPM_LOG_PATH` | `Y:\npm\logs` | +| Script | Env var | Default | +| ------------------ | -------------------- | --------------- | +| `app/copyparty.py` | `COPYPARTY_LOG_PATH` | `P:\copyparty` | +| `app/npm.py` | `NPM_LOG_PATH` | `Y:\npm\logs` | +| `app/firewall.py` | `ROUTER_IP` | `192.168.88.1` | +| | `ROUTER_USER` | `admin` | +| | `ROUTER_PASSWORD` | _(set in .env)_ | Examples: ```powershell -python npm.py --log-path D:\logs\npm --min-errors 10 --error-ratio 0.8 -python copyparty.py --top 100 --no-rsc -python scan.py --quiet --no-rsc +python -m app.npm --log-path D:\logs\npm --min-errors 10 --error-ratio 0.8 +python -m app.copyparty --top 100 +python app.py --quiet --update-firewall --dry-run ``` ## Output -Each script writes to its own report directory. `scan.py` also writes a -consolidated `.rsc`: +Each script writes to its own report directory. `app.py` also writes +firewall audit snapshots: ```text reports/ @@ -154,8 +166,7 @@ reports/ │ │ ├── blocked_ipv4.txt final block set (non-whitelisted) │ │ ├── blocked_ipv6.txt │ │ ├── authed_users.json authenticated user counts -│ │ ├── requests.csv every parsed request -│ │ └── mikrotik-block.rsc +│ │ └── requests.csv every parsed request │ └── 2026-08-02-12-00-00.txt timestamped report ├── npm/ │ ├── data/ @@ -169,10 +180,15 @@ reports/ │ │ ├── blocked_ipv6.txt │ │ ├── ua_summary.csv user agent breakdown │ │ ├── host_summary.csv virtual host breakdown -│ │ ├── requests.csv -│ │ └── mikrotik-block.rsc +│ │ └── requests.csv │ └── 2026-08-02-12-00-00.txt -└── mikrotik-block.rsc consolidated (scan.py only) +└── mikrotik/ + ├── data/ + │ ├── address_list_ipv4.json + │ ├── address_list_ipv6.json + │ ├── firewall_ipv4.json + │ └── firewall_ipv6.json + └── 2026-08-04-18-30-28.json firewall audit snapshot ``` ## Detection @@ -259,13 +275,13 @@ Fields: `[datetime]`, upstream status, proxy status, method, scheme, host, ## Extending - **new whitelist provider** → add URLs, local file paths, and fallback CIDRs - to `whitelists.py` -- **new detection pattern** → add a `BadPattern` to `bad_patterns.py` -- **new detection rule** → add a `flag_*()` function to `flags.py`, return it + to `app/whitelists.py` +- **new detection pattern** → add a `BadPattern` to `app/bad_patterns.py` +- **new detection rule** → add a `flag_*()` function to `app/flags.py`, return it from the analyzer's `flag()` method -- **new log source** → subclass `analyzer.Analyzer`, implement `parse_line()` + +- **new log source** → subclass `app.analyzer.Analyzer`, implement `parse_line()` + `flag()`, declare `ip_columns` / `request_columns` - **new output file** → override `write_extra(data_dir)` and return the paths written -- **new I/O format** → add writer to `files.py` -- **new report section** → add rendering logic to `reporting.py` +- **new I/O format** → add writer to `app/files.py` +- **new report section** → add rendering logic to `app/reporting.py` diff --git a/app.py b/app.py new file mode 100644 index 0000000..58f7281 --- /dev/null +++ b/app.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +"""Intrusion Detection System — unified entry point. + +Runs both copyparty and NPM log analyzers, consolidates blocklist +candidates, and optionally synchronizes the MikroTik RouterOS firewall. + +Usage: + python app.py --quiet + python app.py --update-firewall --dry-run + python app.py --update-firewall +""" + +from __future__ import annotations + +from app.scan import main + +if __name__ == "__main__": + main() diff --git a/app/__init__.py b/app/__init__.py new file mode 100644 index 0000000..359b58f --- /dev/null +++ b/app/__init__.py @@ -0,0 +1 @@ +# Intrusion Detection System — app package diff --git a/analyzer.py b/app/analyzer.py similarity index 95% rename from analyzer.py rename to app/analyzer.py index 04791ec..c14e834 100644 --- a/analyzer.py +++ b/app/analyzer.py @@ -13,13 +13,13 @@ from collections import Counter from datetime import datetime from typing import Any, Sequence -from files import ensure_dirs, find_logs, read_lines, validate_dir, write_csv, write_json, write_lines -from flags import by_total, flag_malicious_patterns -from ip_utils import is_whitelisted, split_versions -from mikrotik import write_mikrotik -from models import IPStats, Request, aggregate -from reporting import Column, columns_header, columns_row, render_kv, render_table, timestamp_name -from whitelists import refresh_whitelists +from .files import ensure_dirs, find_logs, read_lines, validate_dir, write_csv, write_json, write_lines +from .flags import by_total, flag_malicious_patterns +from .ip_utils import is_whitelisted, split_versions +from .mikrotik import write_mikrotik +from .models import IPStats, Request, aggregate +from .reporting import Column, columns_header, columns_row, render_kv, render_table, timestamp_name +from .whitelists import refresh_whitelists class Analyzer: @@ -251,4 +251,4 @@ class Analyzer: f"{n_whitelisted} CIDR ranges whitelisted") result.update(rsc=rsc, blocked=n_blocked, whitelisted=n_whitelisted) - return result \ No newline at end of file + return result diff --git a/bad_patterns.py b/app/bad_patterns.py similarity index 100% rename from bad_patterns.py rename to app/bad_patterns.py diff --git a/copyparty.py b/app/copyparty.py similarity index 95% rename from copyparty.py rename to app/copyparty.py index bae91aa..353995a 100644 --- a/copyparty.py +++ b/app/copyparty.py @@ -12,17 +12,17 @@ from __future__ import annotations import os import re -from analyzer import Analyzer -from ip_utils import split_versions -from files import write_json, write_lines -from flags import flag_denied_only -from models import IPStats, Request -from utils import arg_parser +from .analyzer import Analyzer +from .ip_utils import split_versions +from .files import write_json, write_lines +from .flags import flag_denied_only +from .models import IPStats, Request +from .utils import arg_parser DEFAULT_LOG_PATH = os.environ.get("COPYPARTY_LOG_PATH", r"P:\copyparty") DEFAULT_REPORT_DIR = os.path.join( - os.path.dirname(os.path.abspath(__file__)), "reports", "copyparty") + os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "reports", "copyparty") # "HH:MM:SS.mmm LEVEL: message" # System lines ("hsrv", "root", ...) have no port and are skipped. diff --git a/files.py b/app/files.py similarity index 100% rename from files.py rename to app/files.py diff --git a/firewall.py b/app/firewall.py similarity index 98% rename from firewall.py rename to app/firewall.py index d380178..beba20a 100644 --- a/firewall.py +++ b/app/firewall.py @@ -13,10 +13,12 @@ import paramiko from datetime import datetime import shlex from typing import Iterable -from ip_utils import is_whitelisted +from .ip_utils import is_whitelisted -DATA_DIR = os.path.join(os.path.dirname(__file__), "data", "mikrotik") -REPORT_DIR = os.path.join(os.path.dirname(__file__), "reports") +DATA_DIR = os.path.join(os.path.dirname(os.path.dirname( + os.path.abspath(__file__))), "data", "mikrotik") +REPORT_DIR = os.path.join(os.path.dirname( + os.path.dirname(os.path.abspath(__file__))), "reports") MIKROTIK_DATA_DIR = os.path.join(REPORT_DIR, "mikrotik", "data") SSH_TIMEOUT = 10 # seconds diff --git a/flags.py b/app/flags.py similarity index 96% rename from flags.py rename to app/flags.py index 321b629..065f2ca 100644 --- a/flags.py +++ b/app/flags.py @@ -6,8 +6,8 @@ Detection functions that identify hostile IPs based on aggregated stats. from __future__ import annotations -import bad_patterns -from models import IPStats +from . import bad_patterns +from .models import IPStats def flag_scanners(stats: dict[str, IPStats], min_errors: int = 5, diff --git a/ip_utils.py b/app/ip_utils.py similarity index 96% rename from ip_utils.py rename to app/ip_utils.py index 9698a95..3e5e9de 100644 --- a/ip_utils.py +++ b/app/ip_utils.py @@ -6,7 +6,7 @@ from __future__ import annotations import ipaddress from typing import Iterable -from whitelists import WHITELIST_NETS as _WHITELIST_NETS +from .whitelists import WHITELIST_NETS as _WHITELIST_NETS def parse_ip(value: str): diff --git a/mikrotik.py b/app/mikrotik.py similarity index 97% rename from mikrotik.py rename to app/mikrotik.py index 5721411..b66db61 100644 --- a/mikrotik.py +++ b/app/mikrotik.py @@ -7,8 +7,8 @@ import ipaddress from datetime import datetime from typing import Iterable -from ip_utils import is_ipv4, is_ipv6, is_whitelisted, parse_ip -from whitelists import WHITELISTS +from .ip_utils import is_ipv4, is_ipv6, is_whitelisted, parse_ip +from .whitelists import WHITELISTS def split_cidr_versions(targets: Iterable[str]) -> tuple[list[str], list[str]]: diff --git a/models.py b/app/models.py similarity index 98% rename from models.py rename to app/models.py index 76f109a..0f9831a 100644 --- a/models.py +++ b/app/models.py @@ -10,8 +10,8 @@ from collections import Counter from dataclasses import dataclass, field from typing import Iterable -import bad_patterns -from ip_utils import ip_version, whitelist_of +from . import bad_patterns +from .ip_utils import ip_version, whitelist_of @dataclass(slots=True) diff --git a/npm.py b/app/npm.py similarity index 96% rename from npm.py rename to app/npm.py index 1c6aec1..47ee18e 100644 --- a/npm.py +++ b/app/npm.py @@ -12,16 +12,16 @@ import os import re from collections import Counter -from analyzer import Analyzer -from files import write_csv -from flags import flag_scanners -from models import Request -from utils import arg_parser +from .analyzer import Analyzer +from .files import write_csv +from .flags import flag_scanners +from .models import Request +from .utils import arg_parser DEFAULT_LOG_PATH = os.environ.get("NPM_LOG_PATH", r"Y:\npm\logs") DEFAULT_REPORT_DIR = os.path.join( - os.path.dirname(os.path.abspath(__file__)), "reports", "npm") + os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "reports", "npm") # [02/Aug/2026:05:01:31 +0200] - 401 401 - GET https host "/path" # [Client IP] [Length N] [Gzip X] [Sent-to IP] "UA" "Referer" diff --git a/reporting.py b/app/reporting.py similarity index 100% rename from reporting.py rename to app/reporting.py diff --git a/scan.py b/app/scan.py similarity index 92% rename from scan.py rename to app/scan.py index 3575429..72f49b4 100644 --- a/scan.py +++ b/app/scan.py @@ -11,15 +11,15 @@ import argparse import os from datetime import datetime -import utils -from firewall import MikrotikFirewall -from copyparty import CopypartyAnalyzer, DEFAULT_LOG_PATH as CP_DEFAULT_LOG, DEFAULT_REPORT_DIR as CP_DEFAULT_REPORT -from npm import NpmAnalyzer, DEFAULT_LOG_PATH as NPM_DEFAULT_LOG, DEFAULT_REPORT_DIR as NPM_DEFAULT_REPORT -from ip_utils import is_whitelisted, split_versions -from whois import consolidate_by_subnet +from . import utils +from .firewall import MikrotikFirewall +from .copyparty import CopypartyAnalyzer, DEFAULT_LOG_PATH as CP_DEFAULT_LOG, DEFAULT_REPORT_DIR as CP_DEFAULT_REPORT +from .npm import NpmAnalyzer, DEFAULT_LOG_PATH as NPM_DEFAULT_LOG, DEFAULT_REPORT_DIR as NPM_DEFAULT_REPORT +from .ip_utils import is_whitelisted, split_versions +from .whois import consolidate_by_subnet DEFAULT_CONSOLIDATED_REPORT_DIR = os.path.join( - os.path.dirname(os.path.abspath(__file__)), "reports") + os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "reports") def main() -> None: diff --git a/utils.py b/app/utils.py similarity index 100% rename from utils.py rename to app/utils.py diff --git a/whitelists.py b/app/whitelists.py similarity index 99% rename from whitelists.py rename to app/whitelists.py index e5edea5..ff09873 100644 --- a/whitelists.py +++ b/app/whitelists.py @@ -22,7 +22,7 @@ from typing import Any # Paths # --------------------------------------------------------------------------- -_HERE = os.path.dirname(os.path.abspath(__file__)) +_HERE = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) _DATA_DIR = os.path.join(_HERE, "data") # --------------------------------------------------------------------------- diff --git a/whois.py b/app/whois.py similarity index 95% rename from whois.py rename to app/whois.py index 9805bb6..1624507 100644 --- a/whois.py +++ b/app/whois.py @@ -9,11 +9,12 @@ import os import re from typing import Iterable -from ip_utils import ip_version, parse_ip +from .ip_utils import ip_version, parse_ip # WHOIS Cache file path _WHOIS_CACHE_PATH = os.path.join( - os.path.dirname(os.path.abspath(__file__)), "data", "whois_cache.json" + os.path.dirname(os.path.dirname(os.path.abspath(__file__)) + ), "data", "whois_cache.json" ) _whois_cache: dict[str, str] = {}