Refactor web_scan.py for improved readability and maintainability; add cron job script for npm log backups; update start.ps1 for consistent formatting.
This commit is contained in:
1 parent
0d1cd21468
commit
c2eba88ac8
113 files changed
+772606
-772579
No files matched your search
+84
-84
@@ -1,85 +1,85 @@
|
||||
# ---------------------------------------------------------------------------
|
||||
# Intrusion Detection System — environment template
|
||||
# ---------------------------------------------------------------------------
|
||||
# Copy this file to `.env` for local development and fill in your values:
|
||||
#
|
||||
# copy .env.example .env
|
||||
#
|
||||
# Precedence: real system environment variables win over values in `.env`,
|
||||
# so production deployments can set these via the OS and skip `.env`.
|
||||
# `.env` is git-ignored — never commit real secrets to it.
|
||||
|
||||
# --- Web server (localhost only) -------------------------------------------------
|
||||
|
||||
# The Flask web UI binds to localhost so it is only reachable from this machine.
|
||||
# Do not expose WEB_HOST beyond 127.0.0.1!
|
||||
WEB_HOST=127.0.0.1
|
||||
# Please choose a very high port number (e.g. 54666) to avoid conflicts with other services.
|
||||
WEB_PORT=54666
|
||||
|
||||
# --- Log sources -----------------------------------------------------------
|
||||
|
||||
# Directory containing copyparty access logs (YYYY-MM-DD.txt files).
|
||||
COPYPARTY_LOG_PATH=P:\copyparty
|
||||
|
||||
# Directory containing Nginx Proxy Manager proxy logs (.log / .gz files).
|
||||
NPM_LOG_PATH=Y:\npm\logs
|
||||
|
||||
# --- MikroTik RouterOS connection -----------------------------------------
|
||||
|
||||
# IP/hostname of the router to sync the blocklist to.
|
||||
ROUTER_IP=192.168.88.1
|
||||
|
||||
# SSH user for the router.
|
||||
ROUTER_USER=admin
|
||||
|
||||
# SSH password for the router (required when --update-firewall is used).
|
||||
ROUTER_PASSWORD=change-me
|
||||
|
||||
# Address list on the router that holds blocked IPs/subnets.
|
||||
BLOCKLIST_NAME=Blocked
|
||||
|
||||
# Comma-separated address lists that are treated as whitelisted (never blocked).
|
||||
WHITELIST_NAMES=Cloudflare,Openfactory
|
||||
|
||||
# --- WHOIS subnet consolidation --------------------------------------------
|
||||
|
||||
WHOIS_SERVER=whois.radb.net
|
||||
WHOIS_PORT=43
|
||||
WHOIS_TIMEOUT=3.0
|
||||
|
||||
# Minimum number of same-subnet IPs before blocking the whole subnet.
|
||||
SUBNET_THRESHOLD=3
|
||||
|
||||
# --- Report retention ------------------------------------------------------
|
||||
|
||||
# Each subdirectory under /reports/ keeps at most REPORT_RETENTION_MAX_FILES
|
||||
# files, all newer than REPORT_RETENTION_DAYS days. Older timestamped reports
|
||||
# are pruned automatically after each consolidated scan. The blocklist files
|
||||
# in reports/app/data/ are always protected.
|
||||
REPORT_RETENTION_DAYS=30
|
||||
REPORT_RETENTION_MAX_FILES=10
|
||||
|
||||
# --- Scan / flagging defaults ----------------------------------------------
|
||||
|
||||
# Rows in the top-IP report tables.
|
||||
DEFAULT_TOP=30
|
||||
|
||||
# copyparty: minimum denied hits before flagging an IP.
|
||||
DEFAULT_MIN_DENIED=1
|
||||
|
||||
# npm: minimum error responses before flagging an IP.
|
||||
DEFAULT_MIN_ERRORS=5
|
||||
|
||||
# npm: minimum error ratio before flagging an IP.
|
||||
DEFAULT_ERROR_RATIO=0.5
|
||||
|
||||
# Rows in the "top error paths" report section.
|
||||
DEFAULT_TOP_PATHS=20
|
||||
|
||||
# --- Whitelist sources -----------------------------------------------------
|
||||
|
||||
OPENFACTORY_URL=https://openfactory.net/geofeed.csv
|
||||
CLOUDFLARE_URL_V4=https://www.cloudflare.com/ips-v4
|
||||
CLOUDFLARE_URL_V6=https://www.cloudflare.com/ips-v6
|
||||
# ---------------------------------------------------------------------------
|
||||
# Intrusion Detection System — environment template
|
||||
# ---------------------------------------------------------------------------
|
||||
# Copy this file to `.env` for local development and fill in your values:
|
||||
#
|
||||
# copy .env.example .env
|
||||
#
|
||||
# Precedence: real system environment variables win over values in `.env`,
|
||||
# so production deployments can set these via the OS and skip `.env`.
|
||||
# `.env` is git-ignored — never commit real secrets to it.
|
||||
|
||||
# --- Web server (localhost only) -------------------------------------------------
|
||||
|
||||
# The Flask web UI binds to localhost so it is only reachable from this machine.
|
||||
# Do not expose WEB_HOST beyond 127.0.0.1!
|
||||
WEB_HOST=127.0.0.1
|
||||
# Please choose a very high port number (e.g. 54666) to avoid conflicts with other services.
|
||||
WEB_PORT=54666
|
||||
|
||||
# --- Log sources -----------------------------------------------------------
|
||||
|
||||
# Directory containing copyparty access logs (YYYY-MM-DD.txt files).
|
||||
COPYPARTY_LOG_PATH=P:\copyparty
|
||||
|
||||
# Directory containing Nginx Proxy Manager proxy logs (.log / .gz files).
|
||||
NPM_LOG_PATH=Y:\npm\logs
|
||||
|
||||
# --- MikroTik RouterOS connection -----------------------------------------
|
||||
|
||||
# IP/hostname of the router to sync the blocklist to.
|
||||
ROUTER_IP=192.168.88.1
|
||||
|
||||
# SSH user for the router.
|
||||
ROUTER_USER=admin
|
||||
|
||||
# SSH password for the router (required when --update-firewall is used).
|
||||
ROUTER_PASSWORD=change-me
|
||||
|
||||
# Address list on the router that holds blocked IPs/subnets.
|
||||
BLOCKLIST_NAME=Blocked
|
||||
|
||||
# Comma-separated address lists that are treated as whitelisted (never blocked).
|
||||
WHITELIST_NAMES=Cloudflare,Openfactory
|
||||
|
||||
# --- WHOIS subnet consolidation --------------------------------------------
|
||||
|
||||
WHOIS_SERVER=whois.radb.net
|
||||
WHOIS_PORT=43
|
||||
WHOIS_TIMEOUT=3.0
|
||||
|
||||
# Minimum number of same-subnet IPs before blocking the whole subnet.
|
||||
SUBNET_THRESHOLD=3
|
||||
|
||||
# --- Report retention ------------------------------------------------------
|
||||
|
||||
# Each subdirectory under /reports/ keeps at most REPORT_RETENTION_MAX_FILES
|
||||
# files, all newer than REPORT_RETENTION_DAYS days. Older timestamped reports
|
||||
# are pruned automatically after each consolidated scan. The blocklist files
|
||||
# in reports/app/data/ are always protected.
|
||||
REPORT_RETENTION_DAYS=30
|
||||
REPORT_RETENTION_MAX_FILES=10
|
||||
|
||||
# --- Scan / flagging defaults ----------------------------------------------
|
||||
|
||||
# Rows in the top-IP report tables.
|
||||
DEFAULT_TOP=30
|
||||
|
||||
# copyparty: minimum denied hits before flagging an IP.
|
||||
DEFAULT_MIN_DENIED=1
|
||||
|
||||
# npm: minimum error responses before flagging an IP.
|
||||
DEFAULT_MIN_ERRORS=5
|
||||
|
||||
# npm: minimum error ratio before flagging an IP.
|
||||
DEFAULT_ERROR_RATIO=0.5
|
||||
|
||||
# Rows in the "top error paths" report section.
|
||||
DEFAULT_TOP_PATHS=20
|
||||
|
||||
# --- Whitelist sources -----------------------------------------------------
|
||||
|
||||
OPENFACTORY_URL=https://openfactory.net/geofeed.csv
|
||||
CLOUDFLARE_URL_V4=https://www.cloudflare.com/ips-v4
|
||||
CLOUDFLARE_URL_V6=https://www.cloudflare.com/ips-v6
|
||||
PALOALTO_URL=https://docs-cortex.paloaltonetworks.com/r/1/Cortex-Xpanse/Scanning-activity
|
||||
+19
-19
@@ -1,20 +1,20 @@
|
||||
# instructions for agents
|
||||
.github/instructions/
|
||||
.agents
|
||||
skills-lock.json
|
||||
|
||||
# environment variables
|
||||
.env
|
||||
|
||||
# python cache
|
||||
__pycache__/
|
||||
|
||||
# incremental-scan state (regenerated each run)
|
||||
data/scan_state.json
|
||||
|
||||
# reports data
|
||||
reports/copyparty/
|
||||
reports/mikrotik/
|
||||
reports/npm/
|
||||
# timestamped app blocklist change reports (reports/app/data/ stays tracked)
|
||||
# instructions for agents
|
||||
.github/instructions/
|
||||
.agents
|
||||
skills-lock.json
|
||||
|
||||
# environment variables
|
||||
.env
|
||||
|
||||
# python cache
|
||||
__pycache__/
|
||||
|
||||
# incremental-scan state (regenerated each run)
|
||||
data/scan_state.json
|
||||
|
||||
# reports data
|
||||
reports/copyparty/
|
||||
reports/mikrotik/
|
||||
reports/npm/
|
||||
# timestamped app blocklist change reports (reports/app/data/ stays tracked)
|
||||
reports/app/*.json
|
||||
@@ -142,6 +142,19 @@ production can set the same variables via the OS and skip `.env` entirely.
|
||||
See `.env.example` for the complete list of supported variables (WHOIS
|
||||
tuning, scan thresholds, whitelist source URLs, and more).
|
||||
|
||||
### Network context (2026-09-08)
|
||||
|
||||
Connectivity provider switched Openfactory → Init7 on 2026-09-08:
|
||||
|
||||
- WAN IPv4: `77.74.80.159/32` (init7 `77.74.80.0/24`, "Hybrid7-NET").
|
||||
- IPv6: delegated `/48` `2001:1620:549f::/48` (init7 allocation `2001:1620::/30`).
|
||||
- Upstream DNS: `77.109.128.2`, `213.144.129.20`.
|
||||
|
||||
The `Openfactory` whitelist (old AS58299 geofeed) is obsolete and must be
|
||||
replaced with an `Init7` whitelist — see
|
||||
[`.github/instructions/TODO.md`](.github/instructions/TODO.md) for the
|
||||
switchover plan and the verified init7 CIDR ranges.
|
||||
|
||||
## Usage
|
||||
|
||||
```powershell
|
||||
|
||||
@@ -1,55 +1,55 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Intrusion Detection System — unified entry point.
|
||||
|
||||
By default this starts the localhost-only Flask web UI. Pass ``scan`` to
|
||||
run the consolidated CLI scan instead.
|
||||
|
||||
Usage:
|
||||
python app.py # start the web UI (default)
|
||||
python app.py --web-port 54666 # web UI with a custom port
|
||||
python app.py scan [options] # run the consolidated CLI scan
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
from app.utils.constants import WEB_HOST, WEB_PORT
|
||||
|
||||
|
||||
def _web_parser() -> argparse.ArgumentParser:
|
||||
parser = argparse.ArgumentParser(
|
||||
prog="app.py",
|
||||
description="Intrusion Detection System: web UI (default) or 'scan' subcommand.",
|
||||
)
|
||||
parser.add_argument("--web-host", default=WEB_HOST,
|
||||
help=f"web UI bind host (default: {WEB_HOST})")
|
||||
parser.add_argument("--web-port", type=int, default=WEB_PORT,
|
||||
help=f"web UI port (default: {WEB_PORT})")
|
||||
return parser
|
||||
|
||||
|
||||
def _run_web(host: str, port: int) -> None:
|
||||
from app.web import serve
|
||||
serve(host=host, port=port)
|
||||
|
||||
|
||||
def _run_scan(argv: list[str]) -> None:
|
||||
from app.scan import main as scan_main
|
||||
scan_main(argv)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
# `python app.py scan ...` runs the consolidated CLI scan.
|
||||
if len(sys.argv) > 1 and sys.argv[1] == "scan":
|
||||
_run_scan(sys.argv[2:])
|
||||
return
|
||||
|
||||
# Default: start the web UI (parse_known_args tolerates stray flags).
|
||||
args, _ = _web_parser().parse_known_args()
|
||||
_run_web(args.web_host, args.web_port)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
#!/usr/bin/env python3
|
||||
"""Intrusion Detection System — unified entry point.
|
||||
|
||||
By default this starts the localhost-only Flask web UI. Pass ``scan`` to
|
||||
run the consolidated CLI scan instead.
|
||||
|
||||
Usage:
|
||||
python app.py # start the web UI (default)
|
||||
python app.py --web-port 54666 # web UI with a custom port
|
||||
python app.py scan [options] # run the consolidated CLI scan
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
from app.utils.constants import WEB_HOST, WEB_PORT
|
||||
|
||||
|
||||
def _web_parser() -> argparse.ArgumentParser:
|
||||
parser = argparse.ArgumentParser(
|
||||
prog="app.py",
|
||||
description="Intrusion Detection System: web UI (default) or 'scan' subcommand.",
|
||||
)
|
||||
parser.add_argument("--web-host", default=WEB_HOST,
|
||||
help=f"web UI bind host (default: {WEB_HOST})")
|
||||
parser.add_argument("--web-port", type=int, default=WEB_PORT,
|
||||
help=f"web UI port (default: {WEB_PORT})")
|
||||
return parser
|
||||
|
||||
|
||||
def _run_web(host: str, port: int) -> None:
|
||||
from app.web import serve
|
||||
serve(host=host, port=port)
|
||||
|
||||
|
||||
def _run_scan(argv: list[str]) -> None:
|
||||
from app.scan import main as scan_main
|
||||
scan_main(argv)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
# `python app.py scan ...` runs the consolidated CLI scan.
|
||||
if len(sys.argv) > 1 and sys.argv[1] == "scan":
|
||||
_run_scan(sys.argv[2:])
|
||||
return
|
||||
|
||||
# Default: start the web UI (parse_known_args tolerates stray flags).
|
||||
args, _ = _web_parser().parse_known_args()
|
||||
_run_web(args.web_host, args.web_port)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
+9
-9
@@ -1,9 +1,9 @@
|
||||
# Intrusion Detection System — app package
|
||||
#
|
||||
# Package structure:
|
||||
# app/ core domain (analyzers, firewall, detection rules)
|
||||
# app/web/ Flask web UI (app factory, routes, background scan runner)
|
||||
# app/scan/ consolidated scan pipeline + incremental scan state
|
||||
# app/utils/ shared utilities (constants, I/O, models, whitelists, etc.)
|
||||
# app/static/ static assets (CSS, JS)
|
||||
# app/templates/ Jinja2 templates
|
||||
# Intrusion Detection System — app package
|
||||
#
|
||||
# Package structure:
|
||||
# app/ core domain (analyzers, firewall, detection rules)
|
||||
# app/web/ Flask web UI (app factory, routes, background scan runner)
|
||||
# app/scan/ consolidated scan pipeline + incremental scan state
|
||||
# app/utils/ shared utilities (constants, I/O, models, whitelists, etc.)
|
||||
# app/static/ static assets (CSS, JS)
|
||||
# app/templates/ Jinja2 templates
|
||||
+290
-290
@@ -1,290 +1,290 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Analysis pipeline for the intrusion-detection system.
|
||||
|
||||
`Analyzer` is the log-source-agnostic base class. Subclasses implement
|
||||
`parse_line()` and `flag()`.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import re
|
||||
from collections import Counter
|
||||
from datetime import datetime
|
||||
from typing import Any, Sequence
|
||||
|
||||
from .utils.files import ensure_dirs, find_logs, read_lines, read_lines_from, validate_dir, write_csv, write_json, write_lines
|
||||
from .flags import by_total, flag_malicious_patterns
|
||||
from .utils.ip_utils import is_whitelisted, split_versions
|
||||
from .mikrotik import write_mikrotik
|
||||
from .utils.models import IPStats, Request, aggregate
|
||||
from .utils.reporting import Column, columns_header, columns_row, render_kv, render_table, timestamp_name
|
||||
from .utils.constants import DEFAULT_TOP, DEFAULT_TOP_PATHS
|
||||
from .scan import scan_state
|
||||
from .utils.whitelists import refresh_whitelists
|
||||
|
||||
|
||||
class Analyzer:
|
||||
"""Log-source-agnostic analysis pipeline.
|
||||
|
||||
Subclasses must set the class attributes below and implement
|
||||
`parse_line()` and `flag()`.
|
||||
"""
|
||||
|
||||
name = "ids" # short id, used in file names / tags
|
||||
title = "IDS log analysis report"
|
||||
log_pattern: re.Pattern | None = None
|
||||
log_suffixes: tuple[str, ...] = ()
|
||||
exclude_prefixes: tuple[str, ...] = ()
|
||||
ip_columns: Sequence[Column] = ()
|
||||
request_columns: Sequence[Column] = ()
|
||||
paths_file = "error_paths.csv"
|
||||
paths_label = "error paths"
|
||||
flag_files = ("flagged_ips.txt", "flagged_ipv6.txt")
|
||||
flag_label = "Flagged IPs"
|
||||
flag_note = ""
|
||||
|
||||
def __init__(self, log_path: str, report_dir: str, top: int = DEFAULT_TOP,
|
||||
quiet: bool = False, write_rsc: bool = True,
|
||||
full: bool = False):
|
||||
self.log_path = log_path
|
||||
self.report_dir = report_dir
|
||||
self.data_dir = os.path.join(report_dir, "data")
|
||||
self.top = top
|
||||
self.quiet = quiet
|
||||
self.write_rsc = write_rsc
|
||||
self.full = full
|
||||
self.files: list[str] = []
|
||||
self.requests: list[Request] = []
|
||||
self.stats: dict[str, IPStats] = {}
|
||||
self.flagged: dict[str, IPStats] = {}
|
||||
self.per_file: dict[str, int] = {}
|
||||
|
||||
# --- hooks -------------------------------------------------------------
|
||||
|
||||
def parse_line(self, line: str) -> Request | None:
|
||||
raise NotImplementedError
|
||||
|
||||
def flag(self, stats: dict[str, IPStats]) -> dict[str, IPStats]:
|
||||
raise NotImplementedError
|
||||
|
||||
def flag_comment(self, s: IPStats) -> str:
|
||||
return (f"errors={s.errors} total={s.total} ratio={s.error_ratio} "
|
||||
f"first={s.first} last={s.last}")
|
||||
|
||||
def block_candidates(self) -> set[str]:
|
||||
malicious = flag_malicious_patterns(self.stats)
|
||||
return set(self.flagged) | set(malicious)
|
||||
|
||||
def extra_summary_rows(self) -> list[tuple[str, Any]]:
|
||||
return []
|
||||
|
||||
def write_extra(self, data_dir: str) -> list[str]:
|
||||
return []
|
||||
|
||||
# --- pipeline ----------------------------------------------------------
|
||||
|
||||
def discover(self) -> list[str]:
|
||||
self.files = find_logs(self.log_path, self.log_pattern,
|
||||
self.log_suffixes, self.exclude_prefixes)
|
||||
if not self.files:
|
||||
raise FileNotFoundError(f"no log files found in: {self.log_path}")
|
||||
return self.files
|
||||
|
||||
def load(self) -> list[Request]:
|
||||
"""Read log entries, resuming from the last processed offset.
|
||||
|
||||
Non-gzip logs are read incrementally (only new bytes since the last
|
||||
scan) unless ``full`` is set; gzip archives are always fully read
|
||||
because they cannot be seeked.
|
||||
"""
|
||||
state: dict[str, int] = {}
|
||||
if not self.full:
|
||||
state = scan_state.load_state()
|
||||
# Prune entries whose log file no longer exists (safe across
|
||||
# analyzers: only removes dead keys, keeps live ones).
|
||||
state = {k: v for k, v in state.items() if os.path.exists(k)}
|
||||
for name in self.files:
|
||||
full_path = os.path.join(self.log_path, name)
|
||||
count = 0
|
||||
if self.full or full_path.endswith(".gz"):
|
||||
for line in read_lines(full_path):
|
||||
req = self.parse_line(line)
|
||||
if req is not None:
|
||||
self.requests.append(req)
|
||||
count += 1
|
||||
else:
|
||||
try:
|
||||
size = os.path.getsize(full_path)
|
||||
except OSError:
|
||||
size = 0
|
||||
recorded = state.get(full_path, 0)
|
||||
# Reset to the start if the file shrank or was truncated.
|
||||
start = recorded if 0 < recorded <= size else 0
|
||||
last_resume = start
|
||||
for line, resume in read_lines_from(full_path, start):
|
||||
req = self.parse_line(line)
|
||||
if req is not None:
|
||||
self.requests.append(req)
|
||||
count += 1
|
||||
last_resume = resume
|
||||
state[full_path] = last_resume
|
||||
self.per_file[name] = count
|
||||
if not self.full:
|
||||
scan_state.save_state(state)
|
||||
return self.requests
|
||||
|
||||
def analyze(self) -> dict[str, IPStats]:
|
||||
self.stats = aggregate(self.requests)
|
||||
self.flagged = self.flag(self.stats)
|
||||
return self.stats
|
||||
|
||||
# --- derived data ------------------------------------------------------
|
||||
|
||||
def error_paths(self) -> Counter:
|
||||
return Counter(r.path for r in self.requests if r.is_error and r.path)
|
||||
|
||||
def flagged_split(self) -> tuple[list[IPStats], list[IPStats]]:
|
||||
v4 = [s for s in self.flagged.values() if s.version == 4]
|
||||
v6 = [s for s in self.flagged.values() if s.version == 6]
|
||||
def key(s): return (-s.errors, s.ip)
|
||||
return sorted(v4, key=key), sorted(v6, key=key)
|
||||
|
||||
def summary_rows(self) -> list[tuple[str, Any]]:
|
||||
v4, v6 = split_versions(self.stats)
|
||||
rows = [
|
||||
("log path", self.log_path),
|
||||
("log files", len(self.files)),
|
||||
("total requests", len(self.requests)),
|
||||
("unique IPs",
|
||||
f"{len(self.stats)} (IPv4 {len(v4)} / IPv6 {len(v6)})"),
|
||||
("error requests", sum(1 for r in self.requests if r.is_error)),
|
||||
(f"unique {self.paths_label}", len(self.error_paths())),
|
||||
]
|
||||
rows += self.extra_summary_rows()
|
||||
rows += [
|
||||
(self.flag_label.lower(), len(self.flagged)),
|
||||
("whitelisted IPs seen",
|
||||
sum(1 for ip in self.stats if is_whitelisted(ip))),
|
||||
("block candidates", len(self.block_candidates())),
|
||||
]
|
||||
return rows
|
||||
|
||||
# --- reporting ---------------------------------------------------------
|
||||
|
||||
def text_report(self) -> str:
|
||||
out = [self.title,
|
||||
f"generated: {datetime.now().isoformat(timespec='seconds')}",
|
||||
"",
|
||||
render_kv(self.summary_rows()), ""]
|
||||
|
||||
out.append(f"== top {self.top} IPs ==")
|
||||
rows = [columns_row(self.ip_columns, s)
|
||||
for s in by_total(self.stats)[:self.top]]
|
||||
out.append(render_table(columns_header(self.ip_columns), rows))
|
||||
if len(self.stats) > self.top:
|
||||
out.append(f"... {len(self.stats) - self.top} more IPs omitted")
|
||||
out.append("")
|
||||
|
||||
out.append(f"== top {DEFAULT_TOP_PATHS} {self.paths_label} ==")
|
||||
for path, n in self.error_paths().most_common(DEFAULT_TOP_PATHS):
|
||||
out.append(f" {n:>5} {path}")
|
||||
out.append("")
|
||||
|
||||
v4, v6 = self.flagged_split()
|
||||
out.append(f"== {self.flag_label} ({len(self.flagged)}) ==")
|
||||
if self.flag_note:
|
||||
out.append(self.flag_note)
|
||||
for label, group in (("IPv4", v4), ("IPv6", v6)):
|
||||
if not group:
|
||||
continue
|
||||
out.append(f"-- {label} ({len(group)}) --")
|
||||
rows = [columns_row(self.ip_columns, s) for s in group]
|
||||
out.append(render_table(columns_header(self.ip_columns), rows))
|
||||
out.append("")
|
||||
return "\n".join(out)
|
||||
|
||||
# --- writing -----------------------------------------------------------
|
||||
|
||||
def write_data(self) -> list[str]:
|
||||
ensure_dirs(self.report_dir, self.data_dir)
|
||||
written: list[str] = []
|
||||
d = self.data_dir
|
||||
header = columns_header(self.ip_columns)
|
||||
ordered = by_total(self.stats)
|
||||
|
||||
for version, fname in ((4, "ips_ipv4.csv"), (6, "ips_ipv6.csv")):
|
||||
rows = [columns_row(self.ip_columns, s)
|
||||
for s in ordered if s.version == version]
|
||||
written.append(write_csv(os.path.join(d, fname), header, rows))
|
||||
|
||||
written.append(write_json(
|
||||
os.path.join(d, "ips.json"),
|
||||
{s.ip: s.to_dict() for s in ordered}))
|
||||
|
||||
written.append(write_csv(
|
||||
os.path.join(d, self.paths_file), ["path", "count"],
|
||||
self.error_paths().most_common()))
|
||||
|
||||
v4, v6 = self.flagged_split()
|
||||
for group, fname in zip((v4, v6), self.flag_files):
|
||||
written.append(write_lines(
|
||||
os.path.join(d, fname),
|
||||
[f"{s.ip} # {self.flag_comment(s)}" for s in group]))
|
||||
|
||||
blocked_v4, blocked_v6 = split_versions(
|
||||
ip for ip in self.block_candidates() if not is_whitelisted(ip))
|
||||
written.append(write_lines(
|
||||
os.path.join(d, "blocked_ipv4.txt"), blocked_v4))
|
||||
written.append(write_lines(
|
||||
os.path.join(d, "blocked_ipv6.txt"), blocked_v6))
|
||||
|
||||
written.append(write_csv(
|
||||
os.path.join(d, "requests.csv"),
|
||||
columns_header(self.request_columns),
|
||||
(columns_row(self.request_columns, r) for r in self.requests)))
|
||||
|
||||
written += self.write_extra(d)
|
||||
return written
|
||||
|
||||
def write_report(self) -> str:
|
||||
ensure_dirs(self.report_dir)
|
||||
path = os.path.join(self.report_dir, f"{timestamp_name()}.txt")
|
||||
with open(path, "w", encoding="utf-8") as f:
|
||||
f.write(self.text_report())
|
||||
return path
|
||||
|
||||
def write_rsc_file(self) -> tuple[str, int, int]:
|
||||
ensure_dirs(self.data_dir)
|
||||
return write_mikrotik(
|
||||
os.path.join(self.data_dir, "mikrotik-block.rsc"),
|
||||
f"{self.name}-ids", self.block_candidates())
|
||||
|
||||
# --- entrypoint --------------------------------------------------------
|
||||
|
||||
def run(self) -> dict[str, Any]:
|
||||
validate_dir(self.log_path)
|
||||
ensure_dirs(self.report_dir, self.data_dir)
|
||||
refresh_whitelists()
|
||||
self.discover()
|
||||
self.load()
|
||||
self.analyze()
|
||||
|
||||
if not self.quiet:
|
||||
print(self.text_report())
|
||||
|
||||
self.write_data()
|
||||
report_path = self.write_report()
|
||||
print(f"data files: {self.data_dir}")
|
||||
print(f"summary report: {report_path}")
|
||||
|
||||
result: dict[str, Any] = {"report": report_path,
|
||||
"data_dir": self.data_dir}
|
||||
if self.write_rsc:
|
||||
rsc, n_blocked, n_whitelisted = self.write_rsc_file()
|
||||
print(f"mikrotik script: {rsc}")
|
||||
print(f" {n_blocked} IPs blocked, "
|
||||
f"{n_whitelisted} CIDR ranges whitelisted")
|
||||
result.update(rsc=rsc, blocked=n_blocked,
|
||||
whitelisted=n_whitelisted)
|
||||
return result
|
||||
#!/usr/bin/env python3
|
||||
"""Analysis pipeline for the intrusion-detection system.
|
||||
|
||||
`Analyzer` is the log-source-agnostic base class. Subclasses implement
|
||||
`parse_line()` and `flag()`.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import re
|
||||
from collections import Counter
|
||||
from datetime import datetime
|
||||
from typing import Any, Sequence
|
||||
|
||||
from .utils.files import ensure_dirs, find_logs, read_lines, read_lines_from, validate_dir, write_csv, write_json, write_lines
|
||||
from .flags import by_total, flag_malicious_patterns
|
||||
from .utils.ip_utils import is_whitelisted, split_versions
|
||||
from .mikrotik import write_mikrotik
|
||||
from .utils.models import IPStats, Request, aggregate
|
||||
from .utils.reporting import Column, columns_header, columns_row, render_kv, render_table, timestamp_name
|
||||
from .utils.constants import DEFAULT_TOP, DEFAULT_TOP_PATHS
|
||||
from .scan import scan_state
|
||||
from .utils.whitelists import refresh_whitelists
|
||||
|
||||
|
||||
class Analyzer:
|
||||
"""Log-source-agnostic analysis pipeline.
|
||||
|
||||
Subclasses must set the class attributes below and implement
|
||||
`parse_line()` and `flag()`.
|
||||
"""
|
||||
|
||||
name = "ids" # short id, used in file names / tags
|
||||
title = "IDS log analysis report"
|
||||
log_pattern: re.Pattern | None = None
|
||||
log_suffixes: tuple[str, ...] = ()
|
||||
exclude_prefixes: tuple[str, ...] = ()
|
||||
ip_columns: Sequence[Column] = ()
|
||||
request_columns: Sequence[Column] = ()
|
||||
paths_file = "error_paths.csv"
|
||||
paths_label = "error paths"
|
||||
flag_files = ("flagged_ips.txt", "flagged_ipv6.txt")
|
||||
flag_label = "Flagged IPs"
|
||||
flag_note = ""
|
||||
|
||||
def __init__(self, log_path: str, report_dir: str, top: int = DEFAULT_TOP,
|
||||
quiet: bool = False, write_rsc: bool = True,
|
||||
full: bool = False):
|
||||
self.log_path = log_path
|
||||
self.report_dir = report_dir
|
||||
self.data_dir = os.path.join(report_dir, "data")
|
||||
self.top = top
|
||||
self.quiet = quiet
|
||||
self.write_rsc = write_rsc
|
||||
self.full = full
|
||||
self.files: list[str] = []
|
||||
self.requests: list[Request] = []
|
||||
self.stats: dict[str, IPStats] = {}
|
||||
self.flagged: dict[str, IPStats] = {}
|
||||
self.per_file: dict[str, int] = {}
|
||||
|
||||
# --- hooks -------------------------------------------------------------
|
||||
|
||||
def parse_line(self, line: str) -> Request | None:
|
||||
raise NotImplementedError
|
||||
|
||||
def flag(self, stats: dict[str, IPStats]) -> dict[str, IPStats]:
|
||||
raise NotImplementedError
|
||||
|
||||
def flag_comment(self, s: IPStats) -> str:
|
||||
return (f"errors={s.errors} total={s.total} ratio={s.error_ratio} "
|
||||
f"first={s.first} last={s.last}")
|
||||
|
||||
def block_candidates(self) -> set[str]:
|
||||
malicious = flag_malicious_patterns(self.stats)
|
||||
return set(self.flagged) | set(malicious)
|
||||
|
||||
def extra_summary_rows(self) -> list[tuple[str, Any]]:
|
||||
return []
|
||||
|
||||
def write_extra(self, data_dir: str) -> list[str]:
|
||||
return []
|
||||
|
||||
# --- pipeline ----------------------------------------------------------
|
||||
|
||||
def discover(self) -> list[str]:
|
||||
self.files = find_logs(self.log_path, self.log_pattern,
|
||||
self.log_suffixes, self.exclude_prefixes)
|
||||
if not self.files:
|
||||
raise FileNotFoundError(f"no log files found in: {self.log_path}")
|
||||
return self.files
|
||||
|
||||
def load(self) -> list[Request]:
|
||||
"""Read log entries, resuming from the last processed offset.
|
||||
|
||||
Non-gzip logs are read incrementally (only new bytes since the last
|
||||
scan) unless ``full`` is set; gzip archives are always fully read
|
||||
because they cannot be seeked.
|
||||
"""
|
||||
state: dict[str, int] = {}
|
||||
if not self.full:
|
||||
state = scan_state.load_state()
|
||||
# Prune entries whose log file no longer exists (safe across
|
||||
# analyzers: only removes dead keys, keeps live ones).
|
||||
state = {k: v for k, v in state.items() if os.path.exists(k)}
|
||||
for name in self.files:
|
||||
full_path = os.path.join(self.log_path, name)
|
||||
count = 0
|
||||
if self.full or full_path.endswith(".gz"):
|
||||
for line in read_lines(full_path):
|
||||
req = self.parse_line(line)
|
||||
if req is not None:
|
||||
self.requests.append(req)
|
||||
count += 1
|
||||
else:
|
||||
try:
|
||||
size = os.path.getsize(full_path)
|
||||
except OSError:
|
||||
size = 0
|
||||
recorded = state.get(full_path, 0)
|
||||
# Reset to the start if the file shrank or was truncated.
|
||||
start = recorded if 0 < recorded <= size else 0
|
||||
last_resume = start
|
||||
for line, resume in read_lines_from(full_path, start):
|
||||
req = self.parse_line(line)
|
||||
if req is not None:
|
||||
self.requests.append(req)
|
||||
count += 1
|
||||
last_resume = resume
|
||||
state[full_path] = last_resume
|
||||
self.per_file[name] = count
|
||||
if not self.full:
|
||||
scan_state.save_state(state)
|
||||
return self.requests
|
||||
|
||||
def analyze(self) -> dict[str, IPStats]:
|
||||
self.stats = aggregate(self.requests)
|
||||
self.flagged = self.flag(self.stats)
|
||||
return self.stats
|
||||
|
||||
# --- derived data ------------------------------------------------------
|
||||
|
||||
def error_paths(self) -> Counter:
|
||||
return Counter(r.path for r in self.requests if r.is_error and r.path)
|
||||
|
||||
def flagged_split(self) -> tuple[list[IPStats], list[IPStats]]:
|
||||
v4 = [s for s in self.flagged.values() if s.version == 4]
|
||||
v6 = [s for s in self.flagged.values() if s.version == 6]
|
||||
def key(s): return (-s.errors, s.ip)
|
||||
return sorted(v4, key=key), sorted(v6, key=key)
|
||||
|
||||
def summary_rows(self) -> list[tuple[str, Any]]:
|
||||
v4, v6 = split_versions(self.stats)
|
||||
rows = [
|
||||
("log path", self.log_path),
|
||||
("log files", len(self.files)),
|
||||
("total requests", len(self.requests)),
|
||||
("unique IPs",
|
||||
f"{len(self.stats)} (IPv4 {len(v4)} / IPv6 {len(v6)})"),
|
||||
("error requests", sum(1 for r in self.requests if r.is_error)),
|
||||
(f"unique {self.paths_label}", len(self.error_paths())),
|
||||
]
|
||||
rows += self.extra_summary_rows()
|
||||
rows += [
|
||||
(self.flag_label.lower(), len(self.flagged)),
|
||||
("whitelisted IPs seen",
|
||||
sum(1 for ip in self.stats if is_whitelisted(ip))),
|
||||
("block candidates", len(self.block_candidates())),
|
||||
]
|
||||
return rows
|
||||
|
||||
# --- reporting ---------------------------------------------------------
|
||||
|
||||
def text_report(self) -> str:
|
||||
out = [self.title,
|
||||
f"generated: {datetime.now().isoformat(timespec='seconds')}",
|
||||
"",
|
||||
render_kv(self.summary_rows()), ""]
|
||||
|
||||
out.append(f"== top {self.top} IPs ==")
|
||||
rows = [columns_row(self.ip_columns, s)
|
||||
for s in by_total(self.stats)[:self.top]]
|
||||
out.append(render_table(columns_header(self.ip_columns), rows))
|
||||
if len(self.stats) > self.top:
|
||||
out.append(f"... {len(self.stats) - self.top} more IPs omitted")
|
||||
out.append("")
|
||||
|
||||
out.append(f"== top {DEFAULT_TOP_PATHS} {self.paths_label} ==")
|
||||
for path, n in self.error_paths().most_common(DEFAULT_TOP_PATHS):
|
||||
out.append(f" {n:>5} {path}")
|
||||
out.append("")
|
||||
|
||||
v4, v6 = self.flagged_split()
|
||||
out.append(f"== {self.flag_label} ({len(self.flagged)}) ==")
|
||||
if self.flag_note:
|
||||
out.append(self.flag_note)
|
||||
for label, group in (("IPv4", v4), ("IPv6", v6)):
|
||||
if not group:
|
||||
continue
|
||||
out.append(f"-- {label} ({len(group)}) --")
|
||||
rows = [columns_row(self.ip_columns, s) for s in group]
|
||||
out.append(render_table(columns_header(self.ip_columns), rows))
|
||||
out.append("")
|
||||
return "\n".join(out)
|
||||
|
||||
# --- writing -----------------------------------------------------------
|
||||
|
||||
def write_data(self) -> list[str]:
|
||||
ensure_dirs(self.report_dir, self.data_dir)
|
||||
written: list[str] = []
|
||||
d = self.data_dir
|
||||
header = columns_header(self.ip_columns)
|
||||
ordered = by_total(self.stats)
|
||||
|
||||
for version, fname in ((4, "ips_ipv4.csv"), (6, "ips_ipv6.csv")):
|
||||
rows = [columns_row(self.ip_columns, s)
|
||||
for s in ordered if s.version == version]
|
||||
written.append(write_csv(os.path.join(d, fname), header, rows))
|
||||
|
||||
written.append(write_json(
|
||||
os.path.join(d, "ips.json"),
|
||||
{s.ip: s.to_dict() for s in ordered}))
|
||||
|
||||
written.append(write_csv(
|
||||
os.path.join(d, self.paths_file), ["path", "count"],
|
||||
self.error_paths().most_common()))
|
||||
|
||||
v4, v6 = self.flagged_split()
|
||||
for group, fname in zip((v4, v6), self.flag_files):
|
||||
written.append(write_lines(
|
||||
os.path.join(d, fname),
|
||||
[f"{s.ip} # {self.flag_comment(s)}" for s in group]))
|
||||
|
||||
blocked_v4, blocked_v6 = split_versions(
|
||||
ip for ip in self.block_candidates() if not is_whitelisted(ip))
|
||||
written.append(write_lines(
|
||||
os.path.join(d, "blocked_ipv4.txt"), blocked_v4))
|
||||
written.append(write_lines(
|
||||
os.path.join(d, "blocked_ipv6.txt"), blocked_v6))
|
||||
|
||||
written.append(write_csv(
|
||||
os.path.join(d, "requests.csv"),
|
||||
columns_header(self.request_columns),
|
||||
(columns_row(self.request_columns, r) for r in self.requests)))
|
||||
|
||||
written += self.write_extra(d)
|
||||
return written
|
||||
|
||||
def write_report(self) -> str:
|
||||
ensure_dirs(self.report_dir)
|
||||
path = os.path.join(self.report_dir, f"{timestamp_name()}.txt")
|
||||
with open(path, "w", encoding="utf-8") as f:
|
||||
f.write(self.text_report())
|
||||
return path
|
||||
|
||||
def write_rsc_file(self) -> tuple[str, int, int]:
|
||||
ensure_dirs(self.data_dir)
|
||||
return write_mikrotik(
|
||||
os.path.join(self.data_dir, "mikrotik-block.rsc"),
|
||||
f"{self.name}-ids", self.block_candidates())
|
||||
|
||||
# --- entrypoint --------------------------------------------------------
|
||||
|
||||
def run(self) -> dict[str, Any]:
|
||||
validate_dir(self.log_path)
|
||||
ensure_dirs(self.report_dir, self.data_dir)
|
||||
refresh_whitelists()
|
||||
self.discover()
|
||||
self.load()
|
||||
self.analyze()
|
||||
|
||||
if not self.quiet:
|
||||
print(self.text_report())
|
||||
|
||||
self.write_data()
|
||||
report_path = self.write_report()
|
||||
print(f"data files: {self.data_dir}")
|
||||
print(f"summary report: {report_path}")
|
||||
|
||||
result: dict[str, Any] = {"report": report_path,
|
||||
"data_dir": self.data_dir}
|
||||
if self.write_rsc:
|
||||
rsc, n_blocked, n_whitelisted = self.write_rsc_file()
|
||||
print(f"mikrotik script: {rsc}")
|
||||
print(f" {n_blocked} IPs blocked, "
|
||||
f"{n_whitelisted} CIDR ranges whitelisted")
|
||||
result.update(rsc=rsc, blocked=n_blocked,
|
||||
whitelisted=n_whitelisted)
|
||||
return result
|
||||
+190
-190
@@ -1,190 +1,190 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Malicious-pattern detection rules for the intrusion-detection system.
|
||||
|
||||
Defines compiled regex patterns and classifiers that identify
|
||||
probing/scanning URLs (e.g. env files, wp-admin, webshells) and
|
||||
suspicious file names. Imported by analyzers to flag IPs hitting
|
||||
these patterns as blocklist candidates.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from dataclasses import dataclass, field
|
||||
from typing import ClassVar, Pattern
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Pattern categories
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class BadPattern:
|
||||
"""A single detection rule.
|
||||
|
||||
Attributes:
|
||||
name: Short identifier (e.g. "env_file", "wp_admin").
|
||||
label: Human-readable description for reports.
|
||||
regex: Compiled regex matched against the request path.
|
||||
severity: 1 = moderate, 2 = high, 3 = critical (auto-block).
|
||||
"""
|
||||
|
||||
name: str
|
||||
label: str
|
||||
regex: Pattern[str]
|
||||
severity: int = 2
|
||||
|
||||
def matches(self, path: str) -> bool:
|
||||
return bool(self.regex.search(path))
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Compiled pattern bank
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# -- env / config file probes -------------------------------------------------
|
||||
|
||||
ENV_FILE = BadPattern(
|
||||
"env_file",
|
||||
"env/config file probe (.env, .aws/credentials, config.json)",
|
||||
re.compile(
|
||||
r"/\.(?:env|config)(?:\.\w+)*|"
|
||||
r"/\.aws/credentials|"
|
||||
r"/config\.json",
|
||||
re.IGNORECASE,
|
||||
),
|
||||
severity=3,
|
||||
)
|
||||
|
||||
# -- version control probes ---------------------------------------------------
|
||||
|
||||
VCS_PROBE = BadPattern(
|
||||
"vcs_probe",
|
||||
"version-control probe (.git, .svn)",
|
||||
re.compile(
|
||||
r"/\.(?:git|svn)(?:/|$)",
|
||||
re.IGNORECASE,
|
||||
),
|
||||
severity=3,
|
||||
)
|
||||
|
||||
# -- WordPress / CMS probes ---------------------------------------------------
|
||||
|
||||
WP_PROBE = BadPattern(
|
||||
"wp_probe",
|
||||
"WordPress/CMS probe (wp-admin, wp-login, wp-content, wp-includes)",
|
||||
re.compile(
|
||||
r"/wp-(?:admin|login|content|includes|load|cron|xmlrpc)(?:/|\.php)",
|
||||
re.IGNORECASE,
|
||||
),
|
||||
severity=2,
|
||||
)
|
||||
|
||||
# -- well-known / common probe paths ------------------------------------------
|
||||
|
||||
WELL_KNOWN_PROBE = BadPattern(
|
||||
"well_known_probe",
|
||||
".well-known probe",
|
||||
re.compile(
|
||||
r"/\.well-known/",
|
||||
re.IGNORECASE,
|
||||
),
|
||||
severity=1,
|
||||
)
|
||||
|
||||
# -- webshell / backdoor probes -----------------------------------------------
|
||||
|
||||
WEBSHELL_PROBE = BadPattern(
|
||||
"webshell_probe",
|
||||
"webshell/backdoor probe (known shell filenames, phpinfo, file managers)",
|
||||
re.compile(
|
||||
r"/(?:"
|
||||
r"phpinfo|info|shell|cmd|upload|"
|
||||
r"wp_filemanager|filemanager|"
|
||||
r"xstelth|adminfuns|hellopress|"
|
||||
r"fpwch|crgio|coffexium|"
|
||||
r"ccou|biufile|"
|
||||
r"ms-edit|classwithtostring|"
|
||||
r"this_is_a_new_hello_world|"
|
||||
r"chosen|ops|simple|inputs"
|
||||
r")\.php",
|
||||
re.IGNORECASE,
|
||||
),
|
||||
severity=3,
|
||||
)
|
||||
|
||||
# -- suspicious generic PHP file requests -------------------------------------
|
||||
|
||||
GENERIC_PHP_PROBE = BadPattern(
|
||||
"generic_php_probe",
|
||||
"generic/random PHP file probe (single-char, numeric names)",
|
||||
re.compile(
|
||||
r"/(?:"
|
||||
r"[a-z]\.php|" # single letter: a.php, k.php, x.php
|
||||
r"\d{1,3}\.php|" # numeric: 1.php, 222.php, 155.php
|
||||
r"[a-z]{2}\.php|" # two-letter: aa.php, dx.php
|
||||
r"a\d\.php|" # a1.php
|
||||
r"\w+\.php" # generic: anything.php
|
||||
r")",
|
||||
re.IGNORECASE,
|
||||
),
|
||||
severity=1,
|
||||
)
|
||||
|
||||
# -- sensitive file probes ----------------------------------------------------
|
||||
|
||||
SENSITIVE_FILE = BadPattern(
|
||||
"sensitive_file",
|
||||
"sensitive file probe (id_rsa, id_dsa, .pem, .key)",
|
||||
re.compile(
|
||||
r"/(?:id_rsa|id_dsa|id_ecdsa|id_ed25519|.*\.(?:pem|key|ppk|pfx|p12))",
|
||||
re.IGNORECASE,
|
||||
),
|
||||
severity=3,
|
||||
)
|
||||
|
||||
# -- suspicious user-agent (optional, path-based only for now) -----------------
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# All active patterns (ordered by severity, highest first)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
ALL_PATTERNS: list[BadPattern] = [
|
||||
ENV_FILE,
|
||||
VCS_PROBE,
|
||||
SENSITIVE_FILE,
|
||||
WEBSHELL_PROBE,
|
||||
WP_PROBE,
|
||||
GENERIC_PHP_PROBE,
|
||||
WELL_KNOWN_PROBE,
|
||||
]
|
||||
|
||||
# Quick lookup by name
|
||||
PATTERNS_BY_NAME: dict[str, BadPattern] = {p.name: p for p in ALL_PATTERNS}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Classification API
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def classify_path(path: str) -> list[BadPattern]:
|
||||
"""Return all patterns that match a given request path."""
|
||||
return [p for p in ALL_PATTERNS if p.matches(path)]
|
||||
|
||||
|
||||
def is_malicious(path: str) -> bool:
|
||||
"""Return True if any pattern matches the path."""
|
||||
return any(p.matches(path) for p in ALL_PATTERNS)
|
||||
|
||||
|
||||
def malicious_severity(path: str) -> int:
|
||||
"""Return the highest severity among matching patterns, or 0 if none."""
|
||||
matched = classify_path(path)
|
||||
return max((p.severity for p in matched), default=0)
|
||||
|
||||
|
||||
def pattern_names(path: str) -> list[str]:
|
||||
"""Return names of all patterns matching the path."""
|
||||
return [p.name for p in classify_path(path)]
|
||||
#!/usr/bin/env python3
|
||||
"""Malicious-pattern detection rules for the intrusion-detection system.
|
||||
|
||||
Defines compiled regex patterns and classifiers that identify
|
||||
probing/scanning URLs (e.g. env files, wp-admin, webshells) and
|
||||
suspicious file names. Imported by analyzers to flag IPs hitting
|
||||
these patterns as blocklist candidates.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from dataclasses import dataclass, field
|
||||
from typing import ClassVar, Pattern
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Pattern categories
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class BadPattern:
|
||||
"""A single detection rule.
|
||||
|
||||
Attributes:
|
||||
name: Short identifier (e.g. "env_file", "wp_admin").
|
||||
label: Human-readable description for reports.
|
||||
regex: Compiled regex matched against the request path.
|
||||
severity: 1 = moderate, 2 = high, 3 = critical (auto-block).
|
||||
"""
|
||||
|
||||
name: str
|
||||
label: str
|
||||
regex: Pattern[str]
|
||||
severity: int = 2
|
||||
|
||||
def matches(self, path: str) -> bool:
|
||||
return bool(self.regex.search(path))
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Compiled pattern bank
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# -- env / config file probes -------------------------------------------------
|
||||
|
||||
ENV_FILE = BadPattern(
|
||||
"env_file",
|
||||
"env/config file probe (.env, .aws/credentials, config.json)",
|
||||
re.compile(
|
||||
r"/\.(?:env|config)(?:\.\w+)*|"
|
||||
r"/\.aws/credentials|"
|
||||
r"/config\.json",
|
||||
re.IGNORECASE,
|
||||
),
|
||||
severity=3,
|
||||
)
|
||||
|
||||
# -- version control probes ---------------------------------------------------
|
||||
|
||||
VCS_PROBE = BadPattern(
|
||||
"vcs_probe",
|
||||
"version-control probe (.git, .svn)",
|
||||
re.compile(
|
||||
r"/\.(?:git|svn)(?:/|$)",
|
||||
re.IGNORECASE,
|
||||
),
|
||||
severity=3,
|
||||
)
|
||||
|
||||
# -- WordPress / CMS probes ---------------------------------------------------
|
||||
|
||||
WP_PROBE = BadPattern(
|
||||
"wp_probe",
|
||||
"WordPress/CMS probe (wp-admin, wp-login, wp-content, wp-includes)",
|
||||
re.compile(
|
||||
r"/wp-(?:admin|login|content|includes|load|cron|xmlrpc)(?:/|\.php)",
|
||||
re.IGNORECASE,
|
||||
),
|
||||
severity=2,
|
||||
)
|
||||
|
||||
# -- well-known / common probe paths ------------------------------------------
|
||||
|
||||
WELL_KNOWN_PROBE = BadPattern(
|
||||
"well_known_probe",
|
||||
".well-known probe",
|
||||
re.compile(
|
||||
r"/\.well-known/",
|
||||
re.IGNORECASE,
|
||||
),
|
||||
severity=1,
|
||||
)
|
||||
|
||||
# -- webshell / backdoor probes -----------------------------------------------
|
||||
|
||||
WEBSHELL_PROBE = BadPattern(
|
||||
"webshell_probe",
|
||||
"webshell/backdoor probe (known shell filenames, phpinfo, file managers)",
|
||||
re.compile(
|
||||
r"/(?:"
|
||||
r"phpinfo|info|shell|cmd|upload|"
|
||||
r"wp_filemanager|filemanager|"
|
||||
r"xstelth|adminfuns|hellopress|"
|
||||
r"fpwch|crgio|coffexium|"
|
||||
r"ccou|biufile|"
|
||||
r"ms-edit|classwithtostring|"
|
||||
r"this_is_a_new_hello_world|"
|
||||
r"chosen|ops|simple|inputs"
|
||||
r")\.php",
|
||||
re.IGNORECASE,
|
||||
),
|
||||
severity=3,
|
||||
)
|
||||
|
||||
# -- suspicious generic PHP file requests -------------------------------------
|
||||
|
||||
GENERIC_PHP_PROBE = BadPattern(
|
||||
"generic_php_probe",
|
||||
"generic/random PHP file probe (single-char, numeric names)",
|
||||
re.compile(
|
||||
r"/(?:"
|
||||
r"[a-z]\.php|" # single letter: a.php, k.php, x.php
|
||||
r"\d{1,3}\.php|" # numeric: 1.php, 222.php, 155.php
|
||||
r"[a-z]{2}\.php|" # two-letter: aa.php, dx.php
|
||||
r"a\d\.php|" # a1.php
|
||||
r"\w+\.php" # generic: anything.php
|
||||
r")",
|
||||
re.IGNORECASE,
|
||||
),
|
||||
severity=1,
|
||||
)
|
||||
|
||||
# -- sensitive file probes ----------------------------------------------------
|
||||
|
||||
SENSITIVE_FILE = BadPattern(
|
||||
"sensitive_file",
|
||||
"sensitive file probe (id_rsa, id_dsa, .pem, .key)",
|
||||
re.compile(
|
||||
r"/(?:id_rsa|id_dsa|id_ecdsa|id_ed25519|.*\.(?:pem|key|ppk|pfx|p12))",
|
||||
re.IGNORECASE,
|
||||
),
|
||||
severity=3,
|
||||
)
|
||||
|
||||
# -- suspicious user-agent (optional, path-based only for now) -----------------
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# All active patterns (ordered by severity, highest first)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
ALL_PATTERNS: list[BadPattern] = [
|
||||
ENV_FILE,
|
||||
VCS_PROBE,
|
||||
SENSITIVE_FILE,
|
||||
WEBSHELL_PROBE,
|
||||
WP_PROBE,
|
||||
GENERIC_PHP_PROBE,
|
||||
WELL_KNOWN_PROBE,
|
||||
]
|
||||
|
||||
# Quick lookup by name
|
||||
PATTERNS_BY_NAME: dict[str, BadPattern] = {p.name: p for p in ALL_PATTERNS}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Classification API
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def classify_path(path: str) -> list[BadPattern]:
|
||||
"""Return all patterns that match a given request path."""
|
||||
return [p for p in ALL_PATTERNS if p.matches(path)]
|
||||
|
||||
|
||||
def is_malicious(path: str) -> bool:
|
||||
"""Return True if any pattern matches the path."""
|
||||
return any(p.matches(path) for p in ALL_PATTERNS)
|
||||
|
||||
|
||||
def malicious_severity(path: str) -> int:
|
||||
"""Return the highest severity among matching patterns, or 0 if none."""
|
||||
matched = classify_path(path)
|
||||
return max((p.severity for p in matched), default=0)
|
||||
|
||||
|
||||
def pattern_names(path: str) -> list[str]:
|
||||
"""Return names of all patterns matching the path."""
|
||||
return [p.name for p in classify_path(path)]
|
||||
+182
-182
@@ -1,182 +1,182 @@
|
||||
#!/usr/bin/env python3
|
||||
"""copyparty access-log analyzer.
|
||||
|
||||
Parses copyparty server logs, aggregates per-IP behaviour and flags
|
||||
"denied-only" clients: IPs that never authenticated and only ever hit
|
||||
`@* has no access to '...'`. Those plus copyparty's own auto-bans become
|
||||
the MikroTik block list.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
from .analyzer import Analyzer
|
||||
from .utils.constants import (
|
||||
COPYPARTY_LOG_PATH,
|
||||
COPYPARTY_REPORT_DIR,
|
||||
DEFAULT_MIN_DENIED,
|
||||
)
|
||||
from .utils.ip_utils import split_versions
|
||||
from .utils.files import write_json, write_lines
|
||||
from .flags import flag_denied_only
|
||||
from .utils.models import IPStats, Request
|
||||
from .utils.utils import arg_parser
|
||||
|
||||
# "HH:MM:SS.mmm <ip> <port> LEVEL: message"
|
||||
# System lines ("hsrv", "root", ...) have no port and are skipped.
|
||||
LINE_RE = re.compile(
|
||||
r"^(\d{2}:\d{2}:\d{2}\.\d{3})\s+" # timestamp
|
||||
r"(\S+)\s+" # ip
|
||||
r"(\d+)\s+" # port
|
||||
r"(LOG|WARN|CRIT|BTW|INFO|ERR|DEBUG):\s" # level
|
||||
r"(.*)$" # message
|
||||
)
|
||||
|
||||
METHOD_RE = re.compile(
|
||||
r"^(GET|HEAD|POST|PUT|PATCH|DELETE|OPTIONS|PROPFIND|PROPPATCH|MKCOL|"
|
||||
r"MOVE|COPY|LOCK|UNLOCK)\s+(\S+)(?:\s+@(\S+))?")
|
||||
DENY_RE = re.compile(r"^@(\S+) has no access to '([^']+)'")
|
||||
CLIENT_BAN_RE = re.compile(r"client banned")
|
||||
BAN_SECS_RE = re.compile(r"banned for (\d+) sec")
|
||||
|
||||
|
||||
class CopypartyAnalyzer(Analyzer):
|
||||
name = "copyparty"
|
||||
title = "copyparty log analysis report"
|
||||
log_pattern = re.compile(r"\d{4}-\d{2}-\d{2}\.txt(\.\d+)?$")
|
||||
paths_file = "denied_paths.csv"
|
||||
paths_label = "denied paths"
|
||||
flag_files = ("denied_ips.txt", "denied_ipv6.txt")
|
||||
flag_label = "Denied-only IPs"
|
||||
flag_note = "never authenticated -- ban candidates"
|
||||
|
||||
ip_columns = (
|
||||
("ip", lambda s: s.ip),
|
||||
("total", lambda s: s.total),
|
||||
("denied", lambda s: s.denied),
|
||||
("banned", lambda s: s.banned),
|
||||
("first", lambda s: s.first),
|
||||
("last", lambda s: s.last),
|
||||
("users", lambda s: s.users_str),
|
||||
("whitelist", lambda s: s.whitelist),
|
||||
)
|
||||
|
||||
request_columns = (
|
||||
("time", lambda r: r.ts),
|
||||
("ip", lambda r: r.ip),
|
||||
("port", lambda r: r.extra.get("port")),
|
||||
("level", lambda r: r.extra.get("level")),
|
||||
("method", lambda r: r.method),
|
||||
("path", lambda r: r.path),
|
||||
("user", lambda r: r.user),
|
||||
("denied", lambda r: r.denied),
|
||||
("banned", lambda r: r.banned),
|
||||
("ban_secs", lambda r: r.extra.get("ban_secs")),
|
||||
)
|
||||
|
||||
def __init__(self, *args, min_denied: int = DEFAULT_MIN_DENIED, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.min_denied = min_denied
|
||||
|
||||
# --- parsing -----------------------------------------------------------
|
||||
|
||||
def parse_line(self, line: str) -> Request | None:
|
||||
if not line:
|
||||
return None
|
||||
m = LINE_RE.match(line)
|
||||
if not m:
|
||||
return None
|
||||
ts, ip, port, level, msg = m.groups()
|
||||
req = Request(ts=ts, ip=ip, user=None,
|
||||
extra={"port": int(port), "level": level})
|
||||
|
||||
mm = METHOD_RE.match(msg)
|
||||
if mm:
|
||||
req.method, req.path, user = mm.groups()
|
||||
req.user = user or "*"
|
||||
return req
|
||||
|
||||
dm = DENY_RE.match(msg)
|
||||
if dm:
|
||||
req.user, req.path = dm.groups()
|
||||
req.denied = True
|
||||
return req
|
||||
|
||||
if CLIENT_BAN_RE.search(msg):
|
||||
req.banned = True
|
||||
bs = BAN_SECS_RE.search(msg)
|
||||
if bs:
|
||||
req.extra["ban_secs"] = int(bs.group(1))
|
||||
return req
|
||||
|
||||
bs = BAN_SECS_RE.search(msg)
|
||||
if bs:
|
||||
req.banned = True
|
||||
req.extra["ban_secs"] = int(bs.group(1))
|
||||
return req
|
||||
|
||||
# --- flagging ----------------------------------------------------------
|
||||
|
||||
def flag(self, stats):
|
||||
return flag_denied_only(stats, min_denied=self.min_denied)
|
||||
|
||||
def flag_comment(self, s):
|
||||
return (f"denied={s.denied} total={s.total} "
|
||||
f"first={s.first} last={s.last}")
|
||||
|
||||
def block_candidates(self) -> set[str]:
|
||||
banned = {ip for ip, s in self.stats.items() if s.banned}
|
||||
return set(self.flagged) | banned
|
||||
|
||||
# --- extras ------------------------------------------------------------
|
||||
|
||||
def banned_ips(self) -> dict[str, IPStats]:
|
||||
return {ip: s for ip, s in self.stats.items() if s.banned}
|
||||
|
||||
def authed_users(self) -> dict[str, int]:
|
||||
counts: dict[str, int] = {}
|
||||
for r in self.requests:
|
||||
if r.user and r.user != "*":
|
||||
counts[r.user] = counts.get(r.user, 0) + 1
|
||||
return dict(sorted(counts.items(), key=lambda kv: -kv[1]))
|
||||
|
||||
def extra_summary_rows(self):
|
||||
return [("denied requests",
|
||||
sum(1 for r in self.requests if r.denied)),
|
||||
("banned IPs", len(self.banned_ips())),
|
||||
("authenticated users", self.authed_users() or "{}")]
|
||||
|
||||
def write_extra(self, data_dir: str) -> list[str]:
|
||||
v4, v6 = split_versions(self.banned_ips())
|
||||
return [
|
||||
write_lines(os.path.join(data_dir, "banned_ips.txt"), v4),
|
||||
write_lines(os.path.join(data_dir, "banned_ipv6.txt"), v6),
|
||||
write_json(os.path.join(data_dir, "authed_users.json"),
|
||||
self.authed_users()),
|
||||
]
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = arg_parser(
|
||||
"analyze copyparty logs, flag denied-only IPs, export MikroTik rules",
|
||||
COPYPARTY_LOG_PATH, COPYPARTY_REPORT_DIR)
|
||||
parser.add_argument("--min-denied", type=int, default=DEFAULT_MIN_DENIED,
|
||||
help=f"minimum denied hits before flagging (default: {DEFAULT_MIN_DENIED})")
|
||||
parser.add_argument("--full", action="store_true",
|
||||
help="rescan all logs from the start (ignore incremental state)")
|
||||
args = parser.parse_args()
|
||||
|
||||
CopypartyAnalyzer(
|
||||
log_path=args.log_path,
|
||||
report_dir=args.report_dir,
|
||||
top=args.top,
|
||||
quiet=args.quiet,
|
||||
full=args.full,
|
||||
min_denied=args.min_denied,
|
||||
).run()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
#!/usr/bin/env python3
|
||||
"""copyparty access-log analyzer.
|
||||
|
||||
Parses copyparty server logs, aggregates per-IP behaviour and flags
|
||||
"denied-only" clients: IPs that never authenticated and only ever hit
|
||||
`@* has no access to '...'`. Those plus copyparty's own auto-bans become
|
||||
the MikroTik block list.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
from .analyzer import Analyzer
|
||||
from .utils.constants import (
|
||||
COPYPARTY_LOG_PATH,
|
||||
COPYPARTY_REPORT_DIR,
|
||||
DEFAULT_MIN_DENIED,
|
||||
)
|
||||
from .utils.ip_utils import split_versions
|
||||
from .utils.files import write_json, write_lines
|
||||
from .flags import flag_denied_only
|
||||
from .utils.models import IPStats, Request
|
||||
from .utils.utils import arg_parser
|
||||
|
||||
# "HH:MM:SS.mmm <ip> <port> LEVEL: message"
|
||||
# System lines ("hsrv", "root", ...) have no port and are skipped.
|
||||
LINE_RE = re.compile(
|
||||
r"^(\d{2}:\d{2}:\d{2}\.\d{3})\s+" # timestamp
|
||||
r"(\S+)\s+" # ip
|
||||
r"(\d+)\s+" # port
|
||||
r"(LOG|WARN|CRIT|BTW|INFO|ERR|DEBUG):\s" # level
|
||||
r"(.*)$" # message
|
||||
)
|
||||
|
||||
METHOD_RE = re.compile(
|
||||
r"^(GET|HEAD|POST|PUT|PATCH|DELETE|OPTIONS|PROPFIND|PROPPATCH|MKCOL|"
|
||||
r"MOVE|COPY|LOCK|UNLOCK)\s+(\S+)(?:\s+@(\S+))?")
|
||||
DENY_RE = re.compile(r"^@(\S+) has no access to '([^']+)'")
|
||||
CLIENT_BAN_RE = re.compile(r"client banned")
|
||||
BAN_SECS_RE = re.compile(r"banned for (\d+) sec")
|
||||
|
||||
|
||||
class CopypartyAnalyzer(Analyzer):
|
||||
name = "copyparty"
|
||||
title = "copyparty log analysis report"
|
||||
log_pattern = re.compile(r"\d{4}-\d{2}-\d{2}\.txt(\.\d+)?$")
|
||||
paths_file = "denied_paths.csv"
|
||||
paths_label = "denied paths"
|
||||
flag_files = ("denied_ips.txt", "denied_ipv6.txt")
|
||||
flag_label = "Denied-only IPs"
|
||||
flag_note = "never authenticated -- ban candidates"
|
||||
|
||||
ip_columns = (
|
||||
("ip", lambda s: s.ip),
|
||||
("total", lambda s: s.total),
|
||||
("denied", lambda s: s.denied),
|
||||
("banned", lambda s: s.banned),
|
||||
("first", lambda s: s.first),
|
||||
("last", lambda s: s.last),
|
||||
("users", lambda s: s.users_str),
|
||||
("whitelist", lambda s: s.whitelist),
|
||||
)
|
||||
|
||||
request_columns = (
|
||||
("time", lambda r: r.ts),
|
||||
("ip", lambda r: r.ip),
|
||||
("port", lambda r: r.extra.get("port")),
|
||||
("level", lambda r: r.extra.get("level")),
|
||||
("method", lambda r: r.method),
|
||||
("path", lambda r: r.path),
|
||||
("user", lambda r: r.user),
|
||||
("denied", lambda r: r.denied),
|
||||
("banned", lambda r: r.banned),
|
||||
("ban_secs", lambda r: r.extra.get("ban_secs")),
|
||||
)
|
||||
|
||||
def __init__(self, *args, min_denied: int = DEFAULT_MIN_DENIED, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.min_denied = min_denied
|
||||
|
||||
# --- parsing -----------------------------------------------------------
|
||||
|
||||
def parse_line(self, line: str) -> Request | None:
|
||||
if not line:
|
||||
return None
|
||||
m = LINE_RE.match(line)
|
||||
if not m:
|
||||
return None
|
||||
ts, ip, port, level, msg = m.groups()
|
||||
req = Request(ts=ts, ip=ip, user=None,
|
||||
extra={"port": int(port), "level": level})
|
||||
|
||||
mm = METHOD_RE.match(msg)
|
||||
if mm:
|
||||
req.method, req.path, user = mm.groups()
|
||||
req.user = user or "*"
|
||||
return req
|
||||
|
||||
dm = DENY_RE.match(msg)
|
||||
if dm:
|
||||
req.user, req.path = dm.groups()
|
||||
req.denied = True
|
||||
return req
|
||||
|
||||
if CLIENT_BAN_RE.search(msg):
|
||||
req.banned = True
|
||||
bs = BAN_SECS_RE.search(msg)
|
||||
if bs:
|
||||
req.extra["ban_secs"] = int(bs.group(1))
|
||||
return req
|
||||
|
||||
bs = BAN_SECS_RE.search(msg)
|
||||
if bs:
|
||||
req.banned = True
|
||||
req.extra["ban_secs"] = int(bs.group(1))
|
||||
return req
|
||||
|
||||
# --- flagging ----------------------------------------------------------
|
||||
|
||||
def flag(self, stats):
|
||||
return flag_denied_only(stats, min_denied=self.min_denied)
|
||||
|
||||
def flag_comment(self, s):
|
||||
return (f"denied={s.denied} total={s.total} "
|
||||
f"first={s.first} last={s.last}")
|
||||
|
||||
def block_candidates(self) -> set[str]:
|
||||
banned = {ip for ip, s in self.stats.items() if s.banned}
|
||||
return set(self.flagged) | banned
|
||||
|
||||
# --- extras ------------------------------------------------------------
|
||||
|
||||
def banned_ips(self) -> dict[str, IPStats]:
|
||||
return {ip: s for ip, s in self.stats.items() if s.banned}
|
||||
|
||||
def authed_users(self) -> dict[str, int]:
|
||||
counts: dict[str, int] = {}
|
||||
for r in self.requests:
|
||||
if r.user and r.user != "*":
|
||||
counts[r.user] = counts.get(r.user, 0) + 1
|
||||
return dict(sorted(counts.items(), key=lambda kv: -kv[1]))
|
||||
|
||||
def extra_summary_rows(self):
|
||||
return [("denied requests",
|
||||
sum(1 for r in self.requests if r.denied)),
|
||||
("banned IPs", len(self.banned_ips())),
|
||||
("authenticated users", self.authed_users() or "{}")]
|
||||
|
||||
def write_extra(self, data_dir: str) -> list[str]:
|
||||
v4, v6 = split_versions(self.banned_ips())
|
||||
return [
|
||||
write_lines(os.path.join(data_dir, "banned_ips.txt"), v4),
|
||||
write_lines(os.path.join(data_dir, "banned_ipv6.txt"), v6),
|
||||
write_json(os.path.join(data_dir, "authed_users.json"),
|
||||
self.authed_users()),
|
||||
]
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = arg_parser(
|
||||
"analyze copyparty logs, flag denied-only IPs, export MikroTik rules",
|
||||
COPYPARTY_LOG_PATH, COPYPARTY_REPORT_DIR)
|
||||
parser.add_argument("--min-denied", type=int, default=DEFAULT_MIN_DENIED,
|
||||
help=f"minimum denied hits before flagging (default: {DEFAULT_MIN_DENIED})")
|
||||
parser.add_argument("--full", action="store_true",
|
||||
help="rescan all logs from the start (ignore incremental state)")
|
||||
args = parser.parse_args()
|
||||
|
||||
CopypartyAnalyzer(
|
||||
log_path=args.log_path,
|
||||
report_dir=args.report_dir,
|
||||
top=args.top,
|
||||
quiet=args.quiet,
|
||||
full=args.full,
|
||||
min_denied=args.min_denied,
|
||||
).run()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
+15
-15
@@ -1,15 +1,15 @@
|
||||
# Data directory for allucanget-ids
|
||||
|
||||
This directory contains data files used by the `allucanget-ids` Intrusion Detection System application, including whitelists, blocklists, and other configuration files. The data files are organized into subdirectories for easier management and maintenance.
|
||||
|
||||
## Data files
|
||||
|
||||
- [whois cache](./whois_cache.json): Local cache of WHOIS queries to reduce network requests and improve performance. The cache is automatically updated when new IP addresses are queried.
|
||||
- [Cloudflare IPv4 list](./cloudflare/ips-v4.txt): Contains a list of Cloudflare IPv4 addresses from `https://www.cloudflare.com/ips-v4`, used for whitelisting traffic from Cloudflare services.
|
||||
- [Cloudflare IPv6 list](./cloudflare/ips-v6.txt): Contains a list of Cloudflare IPv6 addresses from `https://www.cloudflare.com/ips-v6`, used for whitelisting traffic from Cloudflare services.
|
||||
- [MikroTik RouterOS IPv4 Firewall rules](./mikrotik/firewall_ipv4.json): Current MikroTik RouterOS IPv4 firewall rules.
|
||||
- [MikroTik RouterOS IPv6 Firewall rules](./mikrotik/firewall_ipv6.json): Current MikroTik RouterOS IPv6 firewall rules.
|
||||
- [MikroTik RouterOS IPv4 address list](./mikrotik/address_list_ipv4.json): Current MikroTik RouterOS IPv4 address list.
|
||||
- [MikroTik RouterOS IPv6 address list](./mikrotik/address_list_ipv6.json): Current MikroTik RouterOS IPv6 address list.
|
||||
- [Openfactory Geofeed](./openfactory/geofeed.csv): Contains Openfactory IP addresses and associated geolocation data from `https://openfactory.net/geofeed.csv`. Used for identifying and whitelisting traffic from known Openfactory sources.
|
||||
- [PaloAlto Scanner IP list](./paloalto/scanner-ips.txt): List of known PaloAlto scanner IP addresses from `https://docs-cortex.paloaltonetworks.com/r/1/Cortex-Xpanse/Scanning-activity`, used for whitelisting traffic from PaloAlto scanners. !NOTE: This list can not be scraped easily (Javascript-based), so it is maintained manually and may be outdated. Please verify the list against the official source if needed.
|
||||
# Data directory for allucanget-ids
|
||||
|
||||
This directory contains data files used by the `allucanget-ids` Intrusion Detection System application, including whitelists, blocklists, and other configuration files. The data files are organized into subdirectories for easier management and maintenance.
|
||||
|
||||
## Data files
|
||||
|
||||
- [whois cache](./whois_cache.json): Local cache of WHOIS queries to reduce network requests and improve performance. The cache is automatically updated when new IP addresses are queried.
|
||||
- [Cloudflare IPv4 list](./cloudflare/ips-v4.txt): Contains a list of Cloudflare IPv4 addresses from `https://www.cloudflare.com/ips-v4`, used for whitelisting traffic from Cloudflare services.
|
||||
- [Cloudflare IPv6 list](./cloudflare/ips-v6.txt): Contains a list of Cloudflare IPv6 addresses from `https://www.cloudflare.com/ips-v6`, used for whitelisting traffic from Cloudflare services.
|
||||
- [MikroTik RouterOS IPv4 Firewall rules](./mikrotik/firewall_ipv4.json): Current MikroTik RouterOS IPv4 firewall rules.
|
||||
- [MikroTik RouterOS IPv6 Firewall rules](./mikrotik/firewall_ipv6.json): Current MikroTik RouterOS IPv6 firewall rules.
|
||||
- [MikroTik RouterOS IPv4 address list](./mikrotik/address_list_ipv4.json): Current MikroTik RouterOS IPv4 address list.
|
||||
- [MikroTik RouterOS IPv6 address list](./mikrotik/address_list_ipv6.json): Current MikroTik RouterOS IPv6 address list.
|
||||
- [Openfactory Geofeed](./openfactory/geofeed.csv): **Obsolete since 2026-09-08** (provider switched to Init7). Kept for historical reference; the replacement `Init7` ranges are documented in the switchover plan (`.github/instructions/TODO.md`).
|
||||
- [PaloAlto Scanner IP list](./paloalto/scanner-ips.txt): List of known PaloAlto scanner IP addresses from `https://docs-cortex.paloaltonetworks.com/r/1/Cortex-Xpanse/Scanning-activity`, used for whitelisting traffic from PaloAlto scanners. !NOTE: This list can not be scraped easily (Javascript-based), so it is maintained manually and may be outdated. Please verify the list against the official source if needed.
|
||||
@@ -1 +1 @@
|
||||
$ = cloudflare
|
||||
$ = cloudflare
|
||||
@@ -1,15 +1,15 @@
|
||||
173.245.48.0/20
|
||||
103.21.244.0/22
|
||||
103.22.200.0/22
|
||||
103.31.4.0/22
|
||||
141.101.64.0/18
|
||||
108.162.192.0/18
|
||||
190.93.240.0/20
|
||||
188.114.96.0/20
|
||||
197.234.240.0/22
|
||||
198.41.128.0/17
|
||||
162.158.0.0/15
|
||||
104.16.0.0/13
|
||||
104.24.0.0/14
|
||||
172.64.0.0/13
|
||||
173.245.48.0/20
|
||||
103.21.244.0/22
|
||||
103.22.200.0/22
|
||||
103.31.4.0/22
|
||||
141.101.64.0/18
|
||||
108.162.192.0/18
|
||||
190.93.240.0/20
|
||||
188.114.96.0/20
|
||||
197.234.240.0/22
|
||||
198.41.128.0/17
|
||||
162.158.0.0/15
|
||||
104.16.0.0/13
|
||||
104.24.0.0/14
|
||||
172.64.0.0/13
|
||||
131.0.72.0/22
|
||||
@@ -1,7 +1,7 @@
|
||||
2400:cb00::/32
|
||||
2606:4700::/32
|
||||
2803:f800::/32
|
||||
2405:b500::/32
|
||||
2405:8100::/32
|
||||
2a06:98c0::/29
|
||||
2400:cb00::/32
|
||||
2606:4700::/32
|
||||
2803:f800::/32
|
||||
2405:b500::/32
|
||||
2405:8100::/32
|
||||
2a06:98c0::/29
|
||||
2c0f:f248::/32
|
||||
+4423
-4423
File diff suppressed because it is too large.
Load diff
@@ -1,384 +1,384 @@
|
||||
[
|
||||
{
|
||||
"address": "::/128",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "::1/128",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "fec0::/10",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "::ffff:0.0.0.0/96",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "::/96",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "100::/64",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "2001:db8::/32",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "2001:10::/28",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "3ffe::/16",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "2a0e:8f04::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2a0e:8f05::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2a0e:8f06::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2a0e:8f07::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340:2080::/48",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2001:67c:2648::/48",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340:2044:200::/56",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340:2044:600::/56",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340:2044:800::/56",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2400:cb00::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"address": "2606:4700::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"address": "2803:f800::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"address": "2405:b500::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"address": "2405:8100::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"address": "2a06:98c0::/29",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"address": "2c0f:f248::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"address": "2604:a940:300:5b6::/64",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "PaloAlto"
|
||||
},
|
||||
{
|
||||
"address": "2604:a940:301:225::/64",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "PaloAlto"
|
||||
},
|
||||
{
|
||||
"address": "2604:a940:302:118::/64",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "PaloAlto"
|
||||
},
|
||||
{
|
||||
"address": "2001:4ca0:108:42::24/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2400:8901::2000:62ff:fe9a:e1c2/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2600:3000::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2600:3c09::2000:5cff:fe99:c802/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2600:3c15::2000:53ff:fe31:8c0b/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2602:fa59:10:a3a::1/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a01:2a8:a0dd:1::1012/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a04:4e40:e000:0:d09:97ab:43b1:a59a/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a04:c300::/29",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a09:bac5:9443:3af::5e:4d/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a09:bac5:9443:3af::5e:88/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a0a:4cc0:2000:8528:c4e8:3ff:febb:3ee9/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2001:ba0:24c:a500::1/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2406:da18:525:0:a23e:e8f6:3ea1:4c2c/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2600:3c15::2000:9cff:fef0:8ad6/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2602:fa59::/40",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340:2008:ec80:64cc:9116:beb2:1931/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340:2008:ec80:be24:11ff:fe3b:4058/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340:2008:ec80:be24:11ff:fe82:2775/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a01:4f8:c014:7f9e::1/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a04:4e40:4400:0:537:cdd2:7250:95db/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a04:4e40:e000::/48",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a05:4140:3::37cd/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a06:a880:5:7fb3::1/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a09:bac1:76c0:460::5e:6a/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a09:bac5::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a13:adc0::2ed:89ff:fe58:19c5/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2400:8901::2000:beff:fea3:5a44/128",
|
||||
"creation-time": "2026-08-05",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340::/32",
|
||||
"creation-time": "2026-08-06",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340:2017:3810::/64",
|
||||
"comment": "hosting",
|
||||
"creation-time": "2026-08-07",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2001:8d8:5ff:5f:82:165:82:154/128",
|
||||
"creation-time": "2026-08-07",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2600:3c15::/32",
|
||||
"creation-time": "2026-08-07",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2001:448a:a071:520:e18f:3d1f:944e:174d/128",
|
||||
"creation-time": "2026-08-08",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
}
|
||||
[
|
||||
{
|
||||
"address": "::/128",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "::1/128",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "fec0::/10",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "::ffff:0.0.0.0/96",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "::/96",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "100::/64",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "2001:db8::/32",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "2001:10::/28",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "3ffe::/16",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "2a0e:8f04::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2a0e:8f05::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2a0e:8f06::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2a0e:8f07::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340:2080::/48",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2001:67c:2648::/48",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340:2044:200::/56",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340:2044:600::/56",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340:2044:800::/56",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2400:cb00::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"address": "2606:4700::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"address": "2803:f800::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"address": "2405:b500::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"address": "2405:8100::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"address": "2a06:98c0::/29",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"address": "2c0f:f248::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"address": "2604:a940:300:5b6::/64",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "PaloAlto"
|
||||
},
|
||||
{
|
||||
"address": "2604:a940:301:225::/64",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "PaloAlto"
|
||||
},
|
||||
{
|
||||
"address": "2604:a940:302:118::/64",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "PaloAlto"
|
||||
},
|
||||
{
|
||||
"address": "2001:4ca0:108:42::24/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2400:8901::2000:62ff:fe9a:e1c2/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2600:3000::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2600:3c09::2000:5cff:fe99:c802/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2600:3c15::2000:53ff:fe31:8c0b/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2602:fa59:10:a3a::1/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a01:2a8:a0dd:1::1012/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a04:4e40:e000:0:d09:97ab:43b1:a59a/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a04:c300::/29",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a09:bac5:9443:3af::5e:4d/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a09:bac5:9443:3af::5e:88/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a0a:4cc0:2000:8528:c4e8:3ff:febb:3ee9/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2001:ba0:24c:a500::1/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2406:da18:525:0:a23e:e8f6:3ea1:4c2c/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2600:3c15::2000:9cff:fef0:8ad6/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2602:fa59::/40",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340:2008:ec80:64cc:9116:beb2:1931/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340:2008:ec80:be24:11ff:fe3b:4058/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340:2008:ec80:be24:11ff:fe82:2775/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a01:4f8:c014:7f9e::1/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a04:4e40:4400:0:537:cdd2:7250:95db/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a04:4e40:e000::/48",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a05:4140:3::37cd/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a06:a880:5:7fb3::1/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a09:bac1:76c0:460::5e:6a/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a09:bac5::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a13:adc0::2ed:89ff:fe58:19c5/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2400:8901::2000:beff:fea3:5a44/128",
|
||||
"creation-time": "2026-08-05",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340::/32",
|
||||
"creation-time": "2026-08-06",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340:2017:3810::/64",
|
||||
"comment": "hosting",
|
||||
"creation-time": "2026-08-07",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2001:8d8:5ff:5f:82:165:82:154/128",
|
||||
"creation-time": "2026-08-07",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2600:3c15::/32",
|
||||
"creation-time": "2026-08-07",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2001:448a:a071:520:e18f:3d1f:944e:174d/128",
|
||||
"creation-time": "2026-08-08",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
}
|
||||
]
|
||||
@@ -1,137 +1,137 @@
|
||||
[
|
||||
{
|
||||
"action": "passthrough",
|
||||
"chain": "forward",
|
||||
"comment": "special"
|
||||
},
|
||||
{
|
||||
"action": "fasttrack-connection",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"connection-state": "established,related",
|
||||
"hw-offload": "yes",
|
||||
"log": "no",
|
||||
"log-prefix": ""
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"connection-state": "established,related",
|
||||
"log": "no",
|
||||
"log-prefix": ""
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"connection-state": "invalid",
|
||||
"log": "no",
|
||||
"log-prefix": ""
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "Allow",
|
||||
"connection-nat-state": "dstnat"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "allow",
|
||||
"connection-state": "new",
|
||||
"dst-address": "192.168.88.25",
|
||||
"dst-port": "6667",
|
||||
"log": "no",
|
||||
"log-prefix": "",
|
||||
"protocol": "tcp"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"connection-nat-state": "!dstnat",
|
||||
"connection-state": "new",
|
||||
"in-interface-list": "WAN",
|
||||
"log": "no",
|
||||
"log-prefix": ""
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "allow",
|
||||
"log": "no",
|
||||
"log-prefix": "",
|
||||
"protocol": "icmp"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "accept",
|
||||
"connection-state": "established",
|
||||
"log": "no",
|
||||
"log-prefix": ""
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "allow",
|
||||
"dst-port": "500",
|
||||
"protocol": "udp"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "input",
|
||||
"comment": "Block",
|
||||
"dst-port": "80,443",
|
||||
"in-interface-list": "WAN",
|
||||
"protocol": "tcp"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "Allow",
|
||||
"dst-port": "80,443",
|
||||
"in-interface-list": "LAN",
|
||||
"protocol": "tcp",
|
||||
"src-address": "192.168.88.0/24"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "ids",
|
||||
"src-address-list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "ids",
|
||||
"src-address-list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "ids",
|
||||
"src-address-list": "PaloAlto"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "input",
|
||||
"comment": "ids",
|
||||
"src-address-list": "Blocked"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "ids",
|
||||
"src-address-list": "Blocked"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "input",
|
||||
"comment": "drop",
|
||||
"in-interface": "pppoe-out1",
|
||||
"log": "no",
|
||||
"log-prefix": ""
|
||||
}
|
||||
[
|
||||
{
|
||||
"action": "passthrough",
|
||||
"chain": "forward",
|
||||
"comment": "special"
|
||||
},
|
||||
{
|
||||
"action": "fasttrack-connection",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"connection-state": "established,related",
|
||||
"hw-offload": "yes",
|
||||
"log": "no",
|
||||
"log-prefix": ""
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"connection-state": "established,related",
|
||||
"log": "no",
|
||||
"log-prefix": ""
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"connection-state": "invalid",
|
||||
"log": "no",
|
||||
"log-prefix": ""
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "Allow",
|
||||
"connection-nat-state": "dstnat"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "allow",
|
||||
"connection-state": "new",
|
||||
"dst-address": "192.168.88.25",
|
||||
"dst-port": "6667",
|
||||
"log": "no",
|
||||
"log-prefix": "",
|
||||
"protocol": "tcp"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"connection-nat-state": "!dstnat",
|
||||
"connection-state": "new",
|
||||
"in-interface-list": "WAN",
|
||||
"log": "no",
|
||||
"log-prefix": ""
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "allow",
|
||||
"log": "no",
|
||||
"log-prefix": "",
|
||||
"protocol": "icmp"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "accept",
|
||||
"connection-state": "established",
|
||||
"log": "no",
|
||||
"log-prefix": ""
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "allow",
|
||||
"dst-port": "500",
|
||||
"protocol": "udp"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "input",
|
||||
"comment": "Block",
|
||||
"dst-port": "80,443",
|
||||
"in-interface-list": "WAN",
|
||||
"protocol": "tcp"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "Allow",
|
||||
"dst-port": "80,443",
|
||||
"in-interface-list": "LAN",
|
||||
"protocol": "tcp",
|
||||
"src-address": "192.168.88.0/24"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "ids",
|
||||
"src-address-list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "ids",
|
||||
"src-address-list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "ids",
|
||||
"src-address-list": "PaloAlto"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "input",
|
||||
"comment": "ids",
|
||||
"src-address-list": "Blocked"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "ids",
|
||||
"src-address-list": "Blocked"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "input",
|
||||
"comment": "drop",
|
||||
"in-interface": "pppoe-out1",
|
||||
"log": "no",
|
||||
"log-prefix": ""
|
||||
}
|
||||
]
|
||||
@@ -1,186 +1,186 @@
|
||||
[
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"connection-state": "established,related,untracked"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"connection-state": "invalid"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"protocol": "icmpv6"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"port": "33434-33534",
|
||||
"protocol": "udp"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"dst-port": "546",
|
||||
"protocol": "udp",
|
||||
"src-address": "fe80::/10"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"dst-port": "500,4500",
|
||||
"protocol": "udp"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"protocol": "ipsec-ah"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"protocol": "ipsec-esp"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"ipsec-policy": "in,ipsec"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"in-interface-list": "!LAN"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"connection-state": "established,related,untracked"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"connection-state": "invalid"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"src-address-list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"dst-address-list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"hop-limit": "equal:1",
|
||||
"protocol": "icmpv6"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "ids",
|
||||
"log": "no",
|
||||
"log-prefix": "",
|
||||
"src-address-list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "ids",
|
||||
"src-address-list": "Blocked"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"protocol": "icmpv6"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"log": "no",
|
||||
"log-prefix": "",
|
||||
"protocol": "icmpv6"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"protocol": "139"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"dst-port": "500,4500",
|
||||
"protocol": "udp"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"protocol": "ipsec-ah"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"protocol": "ipsec-esp"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"ipsec-policy": "in,ipsec"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"in-interface-list": "!LAN"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "ids",
|
||||
"src-address-list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "ids",
|
||||
"src-address-list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "ids",
|
||||
"src-address-list": "PaloAlto"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "input",
|
||||
"comment": "ids",
|
||||
"src-address-list": "Blocked"
|
||||
}
|
||||
[
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"connection-state": "established,related,untracked"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"connection-state": "invalid"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"protocol": "icmpv6"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"port": "33434-33534",
|
||||
"protocol": "udp"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"dst-port": "546",
|
||||
"protocol": "udp",
|
||||
"src-address": "fe80::/10"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"dst-port": "500,4500",
|
||||
"protocol": "udp"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"protocol": "ipsec-ah"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"protocol": "ipsec-esp"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"ipsec-policy": "in,ipsec"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"in-interface-list": "!LAN"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"connection-state": "established,related,untracked"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"connection-state": "invalid"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"src-address-list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"dst-address-list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"hop-limit": "equal:1",
|
||||
"protocol": "icmpv6"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "ids",
|
||||
"log": "no",
|
||||
"log-prefix": "",
|
||||
"src-address-list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "ids",
|
||||
"src-address-list": "Blocked"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"protocol": "icmpv6"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"log": "no",
|
||||
"log-prefix": "",
|
||||
"protocol": "icmpv6"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"protocol": "139"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"dst-port": "500,4500",
|
||||
"protocol": "udp"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"protocol": "ipsec-ah"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"protocol": "ipsec-esp"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"ipsec-policy": "in,ipsec"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"in-interface-list": "!LAN"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "ids",
|
||||
"src-address-list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "ids",
|
||||
"src-address-list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "ids",
|
||||
"src-address-list": "PaloAlto"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "input",
|
||||
"comment": "ids",
|
||||
"src-address-list": "Blocked"
|
||||
}
|
||||
]
|
||||
@@ -1 +1 @@
|
||||
$ = openfactory
|
||||
$ = openfactory
|
||||
@@ -1,46 +1,46 @@
|
||||
45.11.248.0/23,DE,DE-HE,Frankfurt Am Main,
|
||||
45.11.250.0/24,NL,NL-NH,Amsterdam,
|
||||
45.11.251.0/24,AT,AT-9,Vienna,
|
||||
2a0e:8f04::/32,DE,DE-HE,Frankfurt Am Main,
|
||||
2a0e:8f05::/32,GB,GB-LND,London,
|
||||
2a0e:8f06::/32,NL,NL-NH,Amsterdam,
|
||||
2a0e:8f07::/32,AT,AT-9,Vienna,
|
||||
5.226.144.0/21,CH,CH-TG,Frauenfeld,
|
||||
5.226.144.192/26,CH,CH-ZH,Winterthur,
|
||||
5.226.145.0/26,CH,CH-ZH,Wangen-Bruettisellen,
|
||||
5.226.145.64/26,LI,LI-07,Schaan,
|
||||
5.226.145.128/25,CH,CH-ZH,Kloten,
|
||||
5.226.148.0/29,CH,CH-ZH,Zurich,
|
||||
5.226.148.8/29,CH,CH-ZH,Kloten,
|
||||
5.226.148.16/28,CH,CH-ZH,Zurich,
|
||||
5.226.148.32/27,CH,CH-ZH,Kloten,
|
||||
5.226.148.64/26,CH,CH-ZH,Zurich,
|
||||
5.226.148.96/27,CH,CH-ZH,Zurich,
|
||||
5.226.148.128/25,CH,CH-ZH,Zurich,
|
||||
5.226.149.0/26,CH,CH-ZH,Zurich,
|
||||
5.226.149.64/28,CH,CH-LU,Lutzern,
|
||||
5.226.149.128/26,CH,CH-ZH,Glattfelden,
|
||||
5.226.149.240/30,CH,CH-SZ,Wollerau,
|
||||
5.226.150.0/27,CH,CH-ZH,Glattfelden,
|
||||
5.226.150.32/27,CH,CH-BE,Biel,
|
||||
5.226.150.152/29,LI,LI-07,Schaan,
|
||||
5.226.150.160/28,CH,CH-ZH,Winterthur,
|
||||
5.226.150.224/27,CH,CH-BE,Bern,
|
||||
5.226.151.0/26,NL,NL-NH,Amsterdam,
|
||||
5.226.151.64/27,CH,CH-ZH,Ruemlang,
|
||||
185.86.228.0/23,CH,CH-ZH,Zurich,
|
||||
195.138.203.0/24,CH,CH-ZH,Zurich,
|
||||
2a00:6340::/32,CH,CH-TG,Frauenfeld,
|
||||
2a00:6340:2080::/48,NL,NL-NH,Amsterdam,
|
||||
2001:67c:2648::/48,CH,CH-ZH,Winterthur,
|
||||
|
||||
# Customer geofeed details on request
|
||||
# Having issues with your geolocation? send us a ticket!
|
||||
|
||||
45.11.248.94/32,DE,DE-NW,Dortmund,
|
||||
2a00:6340:2044:200::/56,DE,DE-NW,Dortmund,
|
||||
2a00:6340:2044:600::/56,DE,DE-BW,Stuttgart,
|
||||
45.11.248.96/32,DE,DE-BW,Stuttgart,
|
||||
45.11.248.37/32,DE,DE-BE,Berlin,
|
||||
2a00:6340:2044:800::/56,DE,DE-BE,Berlin,
|
||||
5.226.146.49/32,CH,CH-ZH,Winterthur,8405,47.472502,8.779930
|
||||
45.11.248.0/23,DE,DE-HE,Frankfurt Am Main,
|
||||
45.11.250.0/24,NL,NL-NH,Amsterdam,
|
||||
45.11.251.0/24,AT,AT-9,Vienna,
|
||||
2a0e:8f04::/32,DE,DE-HE,Frankfurt Am Main,
|
||||
2a0e:8f05::/32,GB,GB-LND,London,
|
||||
2a0e:8f06::/32,NL,NL-NH,Amsterdam,
|
||||
2a0e:8f07::/32,AT,AT-9,Vienna,
|
||||
5.226.144.0/21,CH,CH-TG,Frauenfeld,
|
||||
5.226.144.192/26,CH,CH-ZH,Winterthur,
|
||||
5.226.145.0/26,CH,CH-ZH,Wangen-Bruettisellen,
|
||||
5.226.145.64/26,LI,LI-07,Schaan,
|
||||
5.226.145.128/25,CH,CH-ZH,Kloten,
|
||||
5.226.148.0/29,CH,CH-ZH,Zurich,
|
||||
5.226.148.8/29,CH,CH-ZH,Kloten,
|
||||
5.226.148.16/28,CH,CH-ZH,Zurich,
|
||||
5.226.148.32/27,CH,CH-ZH,Kloten,
|
||||
5.226.148.64/26,CH,CH-ZH,Zurich,
|
||||
5.226.148.96/27,CH,CH-ZH,Zurich,
|
||||
5.226.148.128/25,CH,CH-ZH,Zurich,
|
||||
5.226.149.0/26,CH,CH-ZH,Zurich,
|
||||
5.226.149.64/28,CH,CH-LU,Lutzern,
|
||||
5.226.149.128/26,CH,CH-ZH,Glattfelden,
|
||||
5.226.149.240/30,CH,CH-SZ,Wollerau,
|
||||
5.226.150.0/27,CH,CH-ZH,Glattfelden,
|
||||
5.226.150.32/27,CH,CH-BE,Biel,
|
||||
5.226.150.152/29,LI,LI-07,Schaan,
|
||||
5.226.150.160/28,CH,CH-ZH,Winterthur,
|
||||
5.226.150.224/27,CH,CH-BE,Bern,
|
||||
5.226.151.0/26,NL,NL-NH,Amsterdam,
|
||||
5.226.151.64/27,CH,CH-ZH,Ruemlang,
|
||||
185.86.228.0/23,CH,CH-ZH,Zurich,
|
||||
195.138.203.0/24,CH,CH-ZH,Zurich,
|
||||
2a00:6340::/32,CH,CH-TG,Frauenfeld,
|
||||
2a00:6340:2080::/48,NL,NL-NH,Amsterdam,
|
||||
2001:67c:2648::/48,CH,CH-ZH,Winterthur,
|
||||
|
||||
# Customer geofeed details on request
|
||||
# Having issues with your geolocation? send us a ticket!
|
||||
|
||||
45.11.248.94/32,DE,DE-NW,Dortmund,
|
||||
2a00:6340:2044:200::/56,DE,DE-NW,Dortmund,
|
||||
2a00:6340:2044:600::/56,DE,DE-BW,Stuttgart,
|
||||
45.11.248.96/32,DE,DE-BW,Stuttgart,
|
||||
45.11.248.37/32,DE,DE-BE,Berlin,
|
||||
2a00:6340:2044:800::/56,DE,DE-BE,Berlin,
|
||||
5.226.146.49/32,CH,CH-ZH,Winterthur,8405,47.472502,8.779930
|
||||
|
@@ -1 +1 @@
|
||||
$ = paloalto
|
||||
$ = paloalto
|
||||
@@ -1,12 +1,12 @@
|
||||
35.203.210.0/23
|
||||
144.86.173.0/24
|
||||
147.185.132.0/23
|
||||
162.216.149.0/24
|
||||
162.216.150.0/24
|
||||
172.105.147.0/24
|
||||
198.235.24.0/24
|
||||
205.210.31.0/24
|
||||
216.25.88.0/21
|
||||
2604:a940:300:5b6:0:0:0:0/64
|
||||
2604:a940:301:225:0:0:0:0/64
|
||||
35.203.210.0/23
|
||||
144.86.173.0/24
|
||||
147.185.132.0/23
|
||||
162.216.149.0/24
|
||||
162.216.150.0/24
|
||||
172.105.147.0/24
|
||||
198.235.24.0/24
|
||||
205.210.31.0/24
|
||||
216.25.88.0/21
|
||||
2604:a940:300:5b6:0:0:0:0/64
|
||||
2604:a940:301:225:0:0:0:0/64
|
||||
2604:a940:302:118:0:0:0:0/64
|
||||
+10819
-10819
File diff suppressed because it is too large.
Load diff
+232
-232
@@ -1,233 +1,233 @@
|
||||
{
|
||||
"P:\\copyparty\\2026-07-11.txt": 7403,
|
||||
"P:\\copyparty\\2026-07-11.txt.1": 84622,
|
||||
"P:\\copyparty\\2026-07-12.txt": 99031,
|
||||
"P:\\copyparty\\2026-07-13.txt": 92896,
|
||||
"P:\\copyparty\\2026-07-14.txt": 191781,
|
||||
"P:\\copyparty\\2026-07-15.txt": 55394,
|
||||
"P:\\copyparty\\2026-07-15.txt.1": 8770,
|
||||
"P:\\copyparty\\2026-07-15.txt.2": 9606,
|
||||
"P:\\copyparty\\2026-07-16.txt": 35715,
|
||||
"P:\\copyparty\\2026-07-17.txt": 102469,
|
||||
"P:\\copyparty\\2026-07-17.txt.1": 35820,
|
||||
"P:\\copyparty\\2026-07-18.txt": 1784,
|
||||
"P:\\copyparty\\2026-07-19.txt": 273815,
|
||||
"P:\\copyparty\\2026-07-20.txt": 572443,
|
||||
"P:\\copyparty\\2026-07-21.txt": 56055,
|
||||
"P:\\copyparty\\2026-07-22.txt": 135922,
|
||||
"P:\\copyparty\\2026-07-23.txt": 2468,
|
||||
"P:\\copyparty\\2026-07-23.txt.1": 349125,
|
||||
"P:\\copyparty\\2026-07-23.txt.2": 199809,
|
||||
"P:\\copyparty\\2026-07-23.txt.3": 1023,
|
||||
"P:\\copyparty\\2026-07-23.txt.4": 1023,
|
||||
"P:\\copyparty\\2026-07-23.txt.5": 1041,
|
||||
"P:\\copyparty\\2026-07-23.txt.6": 114042,
|
||||
"P:\\copyparty\\2026-07-23.txt.7": 19621,
|
||||
"P:\\copyparty\\2026-07-23.txt.8": 29806,
|
||||
"P:\\copyparty\\2026-07-23.txt.9": 15526221,
|
||||
"P:\\copyparty\\2026-07-24.txt": 99348,
|
||||
"P:\\copyparty\\2026-07-25.txt": 63410,
|
||||
"P:\\copyparty\\2026-07-26.txt": 217801,
|
||||
"P:\\copyparty\\2026-07-27.txt": 66457,
|
||||
"P:\\copyparty\\2026-07-28.txt": 59236,
|
||||
"P:\\copyparty\\2026-07-29.txt": 153562,
|
||||
"P:\\copyparty\\2026-07-29.txt.1": 24147,
|
||||
"P:\\copyparty\\2026-07-30.txt": 1212354,
|
||||
"P:\\copyparty\\2026-07-31.txt": 49026,
|
||||
"P:\\copyparty\\2026-08-01.txt": 298970,
|
||||
"P:\\copyparty\\2026-08-01.txt.1": 274541,
|
||||
"P:\\copyparty\\2026-08-02.txt": 45372,
|
||||
"P:\\copyparty\\2026-08-03.txt": 34302,
|
||||
"P:\\copyparty\\2026-08-04.txt": 33282,
|
||||
"P:\\copyparty\\2026-08-05.txt": 75013,
|
||||
"P:\\copyparty\\2026-08-06.txt": 64948,
|
||||
"P:\\copyparty\\2026-08-07.txt": 38873,
|
||||
"Y:\\npm\\logs\\fallback_error.log": 20586,
|
||||
"Y:\\npm\\logs\\fallback_http_access.log": 1966362,
|
||||
"Y:\\npm\\logs\\fallback_http_error.log": 2930280,
|
||||
"Y:\\npm\\logs\\fallback_stream_access.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-10_access.log": 495244,
|
||||
"Y:\\npm\\logs\\proxy-host-10_error.log": 316,
|
||||
"Y:\\npm\\logs\\proxy-host-11_access.log": 2618795,
|
||||
"Y:\\npm\\logs\\proxy-host-11_error.log": 53360,
|
||||
"Y:\\npm\\logs\\proxy-host-12_access.log": 3171885,
|
||||
"Y:\\npm\\logs\\proxy-host-12_error.log": 40987,
|
||||
"Y:\\npm\\logs\\proxy-host-13_access.log": 1032922,
|
||||
"Y:\\npm\\logs\\proxy-host-13_error.log": 160173,
|
||||
"Y:\\npm\\logs\\proxy-host-14_access.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-14_error.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-15_access.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-15_error.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-16_access.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-16_error.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-17_access.log": 249525,
|
||||
"Y:\\npm\\logs\\proxy-host-17_error.log": 45568,
|
||||
"Y:\\npm\\logs\\proxy-host-18_access.log": 210292,
|
||||
"Y:\\npm\\logs\\proxy-host-18_error.log": 45944,
|
||||
"Y:\\npm\\logs\\proxy-host-19_access.log": 56437,
|
||||
"Y:\\npm\\logs\\proxy-host-19_error.log": 41305,
|
||||
"Y:\\npm\\logs\\proxy-host-1_access.log": 421346,
|
||||
"Y:\\npm\\logs\\proxy-host-1_error.log": 46031,
|
||||
"Y:\\npm\\logs\\proxy-host-20_access.log": 2074017,
|
||||
"Y:\\npm\\logs\\proxy-host-20_error.log": 50956,
|
||||
"Y:\\npm\\logs\\proxy-host-21_access.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-21_error.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-22_access.log": 263312,
|
||||
"Y:\\npm\\logs\\proxy-host-22_error.log": 3733,
|
||||
"Y:\\npm\\logs\\proxy-host-23_access.log": 4268,
|
||||
"Y:\\npm\\logs\\proxy-host-23_error.log": 4454,
|
||||
"Y:\\npm\\logs\\proxy-host-24_access.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-24_error.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-25_access.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-25_error.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-26_access.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-26_error.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-27_access.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-27_error.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-28_access.log": 107302,
|
||||
"Y:\\npm\\logs\\proxy-host-28_error.log": 116208,
|
||||
"Y:\\npm\\logs\\proxy-host-29_access.log": 158185,
|
||||
"Y:\\npm\\logs\\proxy-host-29_error.log": 90709,
|
||||
"Y:\\npm\\logs\\proxy-host-2_access.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-2_error.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-30_access.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-30_error.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-31_access.log": 3846085,
|
||||
"Y:\\npm\\logs\\proxy-host-31_error.log": 282448,
|
||||
"Y:\\npm\\logs\\proxy-host-3_access.log": 658178,
|
||||
"Y:\\npm\\logs\\proxy-host-3_error.log": 46739,
|
||||
"Y:\\npm\\logs\\proxy-host-4_access.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-4_error.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-5_access.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-5_error.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-6_access.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-6_error.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-7_access.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-7_error.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-8_access.log": 558598,
|
||||
"Y:\\npm\\logs\\proxy-host-8_error.log": 45468,
|
||||
"Y:\\npm\\logs\\proxy-host-9_access.log": 34788693,
|
||||
"Y:\\npm\\logs\\proxy-host-9_error.log": 292624,
|
||||
"Y:\\npm\\logs\\stream-1_access.log": 0,
|
||||
"Y:\\npm\\logs\\stream-1_error.log": 0,
|
||||
"Y:\\npm\\logs\\stream-2_access.log": 0,
|
||||
"Y:\\npm\\logs\\stream-2_error.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\fallback_error.log": 2342,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\fallback_http_access.log": 444743,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\fallback_http_error.log": 507761,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\fallback_stream_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-10_access.log": 131738,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-10_error.log": 314,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-11_access.log": 1345373,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-11_error.log": 11526,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-12_access.log": 692484,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-12_error.log": 13649,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-13_access.log": 907343,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-13_error.log": 31479,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-14_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-14_error.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-15_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-15_error.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-16_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-16_error.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-17_access.log": 18521,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-17_error.log": 11333,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-18_access.log": 610146,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-18_error.log": 12622,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-19_access.log": 2708,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-19_error.log": 1937,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-1_access.log": 87903,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-1_error.log": 11003,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-20_access.log": 827861,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-20_error.log": 11032,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-21_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-21_error.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-22_access.log": 200379,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-22_error.log": 1052,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-23_access.log": 453,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-23_error.log": 525,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-24_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-24_error.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-25_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-25_error.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-26_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-26_error.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-27_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-27_error.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-28_access.log": 2104,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-28_error.log": 2174,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-29_access.log": 9608,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-29_error.log": 2462,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-2_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-2_error.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-30_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-30_error.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-31_access.log": 41817,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-31_error.log": 1547,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-3_access.log": 277282,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-3_error.log": 10645,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-4_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-4_error.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-5_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-5_error.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-6_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-6_error.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-7_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-7_error.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-8_access.log": 163769,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-8_error.log": 10207,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-9_access.log": 2603446,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-9_error.log": 55751,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\stream-1_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\stream-1_error.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\stream-2_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\stream-2_error.log": 0,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-11.txt": 7403,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-11.txt.1": 84622,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-12.txt": 99031,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-13.txt": 92896,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-14.txt": 191781,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-15.txt": 55394,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-15.txt.1": 8770,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-15.txt.2": 9606,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-16.txt": 35715,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-17.txt": 102469,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-17.txt.1": 35820,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-18.txt": 1784,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-19.txt": 273815,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-20.txt": 572443,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-21.txt": 56055,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-22.txt": 135922,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-23.txt": 2468,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-23.txt.1": 349125,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-23.txt.2": 199809,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-23.txt.3": 1023,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-23.txt.4": 1023,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-23.txt.5": 1041,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-23.txt.6": 114042,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-23.txt.7": 19621,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-23.txt.8": 29806,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-23.txt.9": 15526221,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-24.txt": 99348,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-25.txt": 63410,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-26.txt": 217801,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-27.txt": 66457,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-28.txt": 59236,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-29.txt": 153562,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-29.txt.1": 24147,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-30.txt": 1212354,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-31.txt": 49026,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-08-01.txt": 298970,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-08-01.txt.1": 274541,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-08-02.txt": 45372,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-08-03.txt": 34302,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-08-04.txt": 33282,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-08-05.txt": 75013,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-08-06.txt": 64948,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-08-07.txt": 48371,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-08-08.txt": 39365,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-08-09.txt": 154216,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-08-09.txt.1": 12568,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-08-10.txt": 85753,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-08-11.txt": 6042
|
||||
{
|
||||
"P:\\copyparty\\2026-07-11.txt": 7403,
|
||||
"P:\\copyparty\\2026-07-11.txt.1": 84622,
|
||||
"P:\\copyparty\\2026-07-12.txt": 99031,
|
||||
"P:\\copyparty\\2026-07-13.txt": 92896,
|
||||
"P:\\copyparty\\2026-07-14.txt": 191781,
|
||||
"P:\\copyparty\\2026-07-15.txt": 55394,
|
||||
"P:\\copyparty\\2026-07-15.txt.1": 8770,
|
||||
"P:\\copyparty\\2026-07-15.txt.2": 9606,
|
||||
"P:\\copyparty\\2026-07-16.txt": 35715,
|
||||
"P:\\copyparty\\2026-07-17.txt": 102469,
|
||||
"P:\\copyparty\\2026-07-17.txt.1": 35820,
|
||||
"P:\\copyparty\\2026-07-18.txt": 1784,
|
||||
"P:\\copyparty\\2026-07-19.txt": 273815,
|
||||
"P:\\copyparty\\2026-07-20.txt": 572443,
|
||||
"P:\\copyparty\\2026-07-21.txt": 56055,
|
||||
"P:\\copyparty\\2026-07-22.txt": 135922,
|
||||
"P:\\copyparty\\2026-07-23.txt": 2468,
|
||||
"P:\\copyparty\\2026-07-23.txt.1": 349125,
|
||||
"P:\\copyparty\\2026-07-23.txt.2": 199809,
|
||||
"P:\\copyparty\\2026-07-23.txt.3": 1023,
|
||||
"P:\\copyparty\\2026-07-23.txt.4": 1023,
|
||||
"P:\\copyparty\\2026-07-23.txt.5": 1041,
|
||||
"P:\\copyparty\\2026-07-23.txt.6": 114042,
|
||||
"P:\\copyparty\\2026-07-23.txt.7": 19621,
|
||||
"P:\\copyparty\\2026-07-23.txt.8": 29806,
|
||||
"P:\\copyparty\\2026-07-23.txt.9": 15526221,
|
||||
"P:\\copyparty\\2026-07-24.txt": 99348,
|
||||
"P:\\copyparty\\2026-07-25.txt": 63410,
|
||||
"P:\\copyparty\\2026-07-26.txt": 217801,
|
||||
"P:\\copyparty\\2026-07-27.txt": 66457,
|
||||
"P:\\copyparty\\2026-07-28.txt": 59236,
|
||||
"P:\\copyparty\\2026-07-29.txt": 153562,
|
||||
"P:\\copyparty\\2026-07-29.txt.1": 24147,
|
||||
"P:\\copyparty\\2026-07-30.txt": 1212354,
|
||||
"P:\\copyparty\\2026-07-31.txt": 49026,
|
||||
"P:\\copyparty\\2026-08-01.txt": 298970,
|
||||
"P:\\copyparty\\2026-08-01.txt.1": 274541,
|
||||
"P:\\copyparty\\2026-08-02.txt": 45372,
|
||||
"P:\\copyparty\\2026-08-03.txt": 34302,
|
||||
"P:\\copyparty\\2026-08-04.txt": 33282,
|
||||
"P:\\copyparty\\2026-08-05.txt": 75013,
|
||||
"P:\\copyparty\\2026-08-06.txt": 64948,
|
||||
"P:\\copyparty\\2026-08-07.txt": 38873,
|
||||
"Y:\\npm\\logs\\fallback_error.log": 20586,
|
||||
"Y:\\npm\\logs\\fallback_http_access.log": 1966362,
|
||||
"Y:\\npm\\logs\\fallback_http_error.log": 2930280,
|
||||
"Y:\\npm\\logs\\fallback_stream_access.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-10_access.log": 495244,
|
||||
"Y:\\npm\\logs\\proxy-host-10_error.log": 316,
|
||||
"Y:\\npm\\logs\\proxy-host-11_access.log": 2618795,
|
||||
"Y:\\npm\\logs\\proxy-host-11_error.log": 53360,
|
||||
"Y:\\npm\\logs\\proxy-host-12_access.log": 3171885,
|
||||
"Y:\\npm\\logs\\proxy-host-12_error.log": 40987,
|
||||
"Y:\\npm\\logs\\proxy-host-13_access.log": 1032922,
|
||||
"Y:\\npm\\logs\\proxy-host-13_error.log": 160173,
|
||||
"Y:\\npm\\logs\\proxy-host-14_access.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-14_error.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-15_access.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-15_error.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-16_access.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-16_error.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-17_access.log": 249525,
|
||||
"Y:\\npm\\logs\\proxy-host-17_error.log": 45568,
|
||||
"Y:\\npm\\logs\\proxy-host-18_access.log": 210292,
|
||||
"Y:\\npm\\logs\\proxy-host-18_error.log": 45944,
|
||||
"Y:\\npm\\logs\\proxy-host-19_access.log": 56437,
|
||||
"Y:\\npm\\logs\\proxy-host-19_error.log": 41305,
|
||||
"Y:\\npm\\logs\\proxy-host-1_access.log": 421346,
|
||||
"Y:\\npm\\logs\\proxy-host-1_error.log": 46031,
|
||||
"Y:\\npm\\logs\\proxy-host-20_access.log": 2074017,
|
||||
"Y:\\npm\\logs\\proxy-host-20_error.log": 50956,
|
||||
"Y:\\npm\\logs\\proxy-host-21_access.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-21_error.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-22_access.log": 263312,
|
||||
"Y:\\npm\\logs\\proxy-host-22_error.log": 3733,
|
||||
"Y:\\npm\\logs\\proxy-host-23_access.log": 4268,
|
||||
"Y:\\npm\\logs\\proxy-host-23_error.log": 4454,
|
||||
"Y:\\npm\\logs\\proxy-host-24_access.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-24_error.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-25_access.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-25_error.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-26_access.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-26_error.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-27_access.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-27_error.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-28_access.log": 107302,
|
||||
"Y:\\npm\\logs\\proxy-host-28_error.log": 116208,
|
||||
"Y:\\npm\\logs\\proxy-host-29_access.log": 158185,
|
||||
"Y:\\npm\\logs\\proxy-host-29_error.log": 90709,
|
||||
"Y:\\npm\\logs\\proxy-host-2_access.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-2_error.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-30_access.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-30_error.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-31_access.log": 3846085,
|
||||
"Y:\\npm\\logs\\proxy-host-31_error.log": 282448,
|
||||
"Y:\\npm\\logs\\proxy-host-3_access.log": 658178,
|
||||
"Y:\\npm\\logs\\proxy-host-3_error.log": 46739,
|
||||
"Y:\\npm\\logs\\proxy-host-4_access.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-4_error.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-5_access.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-5_error.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-6_access.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-6_error.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-7_access.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-7_error.log": 0,
|
||||
"Y:\\npm\\logs\\proxy-host-8_access.log": 558598,
|
||||
"Y:\\npm\\logs\\proxy-host-8_error.log": 45468,
|
||||
"Y:\\npm\\logs\\proxy-host-9_access.log": 34788693,
|
||||
"Y:\\npm\\logs\\proxy-host-9_error.log": 292624,
|
||||
"Y:\\npm\\logs\\stream-1_access.log": 0,
|
||||
"Y:\\npm\\logs\\stream-1_error.log": 0,
|
||||
"Y:\\npm\\logs\\stream-2_access.log": 0,
|
||||
"Y:\\npm\\logs\\stream-2_error.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\fallback_error.log": 2342,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\fallback_http_access.log": 444743,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\fallback_http_error.log": 507761,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\fallback_stream_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-10_access.log": 131738,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-10_error.log": 314,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-11_access.log": 1345373,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-11_error.log": 11526,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-12_access.log": 692484,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-12_error.log": 13649,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-13_access.log": 907343,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-13_error.log": 31479,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-14_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-14_error.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-15_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-15_error.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-16_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-16_error.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-17_access.log": 18521,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-17_error.log": 11333,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-18_access.log": 610146,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-18_error.log": 12622,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-19_access.log": 2708,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-19_error.log": 1937,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-1_access.log": 87903,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-1_error.log": 11003,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-20_access.log": 827861,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-20_error.log": 11032,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-21_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-21_error.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-22_access.log": 200379,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-22_error.log": 1052,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-23_access.log": 453,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-23_error.log": 525,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-24_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-24_error.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-25_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-25_error.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-26_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-26_error.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-27_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-27_error.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-28_access.log": 2104,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-28_error.log": 2174,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-29_access.log": 9608,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-29_error.log": 2462,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-2_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-2_error.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-30_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-30_error.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-31_access.log": 41817,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-31_error.log": 1547,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-3_access.log": 277282,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-3_error.log": 10645,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-4_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-4_error.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-5_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-5_error.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-6_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-6_error.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-7_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-7_error.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-8_access.log": 163769,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-8_error.log": 10207,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-9_access.log": 2603446,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\proxy-host-9_error.log": 55751,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\stream-1_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\stream-1_error.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\stream-2_access.log": 0,
|
||||
"\\\\naspve\\nas\\backups\\npm\\logs\\stream-2_error.log": 0,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-11.txt": 7403,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-11.txt.1": 84622,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-12.txt": 99031,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-13.txt": 92896,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-14.txt": 191781,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-15.txt": 55394,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-15.txt.1": 8770,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-15.txt.2": 9606,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-16.txt": 35715,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-17.txt": 102469,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-17.txt.1": 35820,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-18.txt": 1784,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-19.txt": 273815,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-20.txt": 572443,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-21.txt": 56055,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-22.txt": 135922,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-23.txt": 2468,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-23.txt.1": 349125,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-23.txt.2": 199809,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-23.txt.3": 1023,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-23.txt.4": 1023,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-23.txt.5": 1041,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-23.txt.6": 114042,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-23.txt.7": 19621,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-23.txt.8": 29806,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-23.txt.9": 15526221,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-24.txt": 99348,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-25.txt": 63410,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-26.txt": 217801,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-27.txt": 66457,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-28.txt": 59236,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-29.txt": 153562,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-29.txt.1": 24147,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-30.txt": 1212354,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-07-31.txt": 49026,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-08-01.txt": 298970,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-08-01.txt.1": 274541,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-08-02.txt": 45372,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-08-03.txt": 34302,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-08-04.txt": 33282,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-08-05.txt": 75013,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-08-06.txt": 64948,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-08-07.txt": 48371,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-08-08.txt": 39365,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-08-09.txt": 154216,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-08-09.txt.1": 12568,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-08-10.txt": 85753,
|
||||
"\\\\naspve\\nas\\projects\\copyparty\\2026-08-11.txt": 6042
|
||||
}
|
||||
+1130
-1130
File diff suppressed because it is too large.
Load diff
+364
-364
@@ -1,364 +1,364 @@
|
||||
"""
|
||||
firewall.py -
|
||||
Module for interacting with the Mikrotik routeros shell to manage firewall rules and IP address lists.
|
||||
Provides functions to read the current firewall configuration, add and remove IPs from the blocklist.
|
||||
Reads the latest report from the IDS scan, reads the current firewall configuration, and updates the router's blocklist accordingly.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import json
|
||||
import paramiko
|
||||
from datetime import datetime
|
||||
import shlex
|
||||
from typing import Iterable
|
||||
from .utils.constants import (
|
||||
BLOCKLIST_NAME,
|
||||
MIKROTIK_DATA_DIR,
|
||||
REPORT_DIR,
|
||||
ROUTER_IP,
|
||||
ROUTER_PASSWORD,
|
||||
ROUTER_USER,
|
||||
SSH_PORT,
|
||||
SSH_TIMEOUT,
|
||||
WHITELIST_NAMES,
|
||||
)
|
||||
from .utils.files import write_lines
|
||||
from .utils.ip_utils import is_whitelisted
|
||||
from .utils.blocklist_history import compute_changes, cumulative_blocklist
|
||||
|
||||
|
||||
class MikrotikFirewall:
|
||||
"""
|
||||
Class to manage Mikrotik firewall rules and IP address lists.
|
||||
Provides methods to read the current blocklist, add/remove IPs, and update the blocklist based on IDS scan reports.
|
||||
"""
|
||||
|
||||
def __init__(self, router_ip: str = ROUTER_IP, username: str = ROUTER_USER,
|
||||
password: str = ROUTER_PASSWORD):
|
||||
self.router_ip = router_ip
|
||||
self.username = username
|
||||
self.password = password
|
||||
self.client: paramiko.SSHClient | None = None
|
||||
|
||||
def connect(self) -> None:
|
||||
"""Establish an SSH connection to the Mikrotik router."""
|
||||
client = paramiko.SSHClient()
|
||||
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
try:
|
||||
# RouterOS 7.20.x exposes an RSA host key and classic SSH ciphers.
|
||||
client.connect(
|
||||
self.router_ip,
|
||||
port=SSH_PORT,
|
||||
username=self.username,
|
||||
password=self.password,
|
||||
timeout=SSH_TIMEOUT,
|
||||
banner_timeout=SSH_TIMEOUT,
|
||||
auth_timeout=SSH_TIMEOUT,
|
||||
allow_agent=False,
|
||||
look_for_keys=False,
|
||||
compress=False,
|
||||
disabled_algorithms={"pubkeys": ["rsa-sha2-512"]},
|
||||
)
|
||||
except Exception:
|
||||
client.close()
|
||||
raise
|
||||
self.client = client
|
||||
|
||||
def disconnect(self) -> None:
|
||||
"""Close the SSH connection."""
|
||||
if self.client:
|
||||
self.client.close()
|
||||
self.client = None
|
||||
|
||||
def execute_command(self, command: str) -> str:
|
||||
"""Execute a command on the Mikrotik router via SSH and return the output."""
|
||||
if not self.client:
|
||||
raise RuntimeError("SSH client is not connected.")
|
||||
stdin, stdout, stderr = self.client.exec_command(command)
|
||||
output = stdout.read().decode("utf-8")
|
||||
error = stderr.read().decode("utf-8")
|
||||
if error:
|
||||
raise RuntimeError(f"Error executing command '{command}': {error}")
|
||||
return output
|
||||
|
||||
def get_address_list_ipv4(self, name: str) -> set[str]:
|
||||
"""Retrieve the current IPv4 address list from the Mikrotik router."""
|
||||
output = self.execute_command("/ip firewall address-list print")
|
||||
ips = set()
|
||||
for line in output.splitlines():
|
||||
parts = line.split()
|
||||
if len(parts) >= 3 and parts[1] == "list" and parts[2] == name:
|
||||
ip = parts[0]
|
||||
ips.add(ip)
|
||||
return ips
|
||||
|
||||
def get_address_list_ipv6(self, name: str) -> set[str]:
|
||||
"""Retrieve the current IPv6 address list from the Mikrotik router."""
|
||||
output = self.execute_command("/ipv6 firewall address-list print")
|
||||
ips = set()
|
||||
for line in output.splitlines():
|
||||
parts = line.split()
|
||||
if len(parts) >= 3 and parts[1] == "list" and parts[2] == name:
|
||||
ip = parts[0]
|
||||
ips.add(ip)
|
||||
return ips
|
||||
|
||||
@staticmethod
|
||||
def _parse_terse_output(output: str) -> list[dict[str, str]]:
|
||||
"""Parse RouterOS `print terse` records into key/value dictionaries."""
|
||||
records = []
|
||||
for line in output.splitlines():
|
||||
fields = {}
|
||||
for field in shlex.split(line):
|
||||
key, separator, value = field.partition("=")
|
||||
if separator:
|
||||
fields[key] = value
|
||||
if fields:
|
||||
records.append(fields)
|
||||
return records
|
||||
|
||||
def get_address_lists(self, ipv6: bool = False) -> list[dict[str, str]]:
|
||||
"""Retrieve all address-list entries in structured form."""
|
||||
path = "/ipv6" if ipv6 else "/ip"
|
||||
output = self.execute_command(
|
||||
f"{path} firewall address-list print terse")
|
||||
return self._parse_terse_output(output)
|
||||
|
||||
def get_firewall_rules(self, ipv6: bool = False) -> list[dict[str, str]]:
|
||||
"""Retrieve all firewall filter rules in structured form."""
|
||||
path = "/ipv6" if ipv6 else "/ip"
|
||||
output = self.execute_command(
|
||||
f"{path} firewall filter print terse")
|
||||
return self._parse_terse_output(output)
|
||||
|
||||
@staticmethod
|
||||
def _write_json(path: str, obj) -> None:
|
||||
with open(path, "w", encoding="utf-8") as file:
|
||||
json.dump(obj, file, indent=2, sort_keys=True)
|
||||
|
||||
def save_state_report(self, report_dir: str = REPORT_DIR,
|
||||
changes: dict | None = None) -> str:
|
||||
"""Save current address lists and firewall rules for auditing.
|
||||
|
||||
Writes structured snapshots to ``<report_dir>/mikrotik/data/`` and to
|
||||
the common ``data/mikrotik/`` directory (overwritten every run so git
|
||||
can diff changes to the firewall state over time), plus a timestamped
|
||||
JSON report under ``<report_dir>/mikrotik/``.
|
||||
"""
|
||||
state = {
|
||||
"router": self.router_ip,
|
||||
"collected_at": datetime.now().astimezone().isoformat(),
|
||||
"address_lists": {
|
||||
"ipv4": self.get_address_lists(),
|
||||
"ipv6": self.get_address_lists(ipv6=True),
|
||||
},
|
||||
"firewall_rules": {
|
||||
"ipv4": self.get_firewall_rules(),
|
||||
"ipv6": self.get_firewall_rules(ipv6=True),
|
||||
},
|
||||
}
|
||||
if changes is not None:
|
||||
state["changes"] = changes
|
||||
|
||||
report_data_dir = os.path.join(report_dir, "mikrotik", "data")
|
||||
os.makedirs(report_data_dir, exist_ok=True)
|
||||
os.makedirs(MIKROTIK_DATA_DIR, exist_ok=True)
|
||||
for version in ("ipv4", "ipv6"):
|
||||
for data_dir in (report_data_dir, MIKROTIK_DATA_DIR):
|
||||
self._write_json(
|
||||
os.path.join(data_dir, f"address_list_{version}.json"),
|
||||
state["address_lists"][version])
|
||||
self._write_json(
|
||||
os.path.join(data_dir, f"firewall_{version}.json"),
|
||||
state["firewall_rules"][version])
|
||||
|
||||
timestamp = datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
|
||||
report_path = os.path.join(report_dir, "mikrotik", f"{timestamp}.json")
|
||||
self._write_json(report_path, state)
|
||||
return report_path
|
||||
|
||||
def sync_blocklist(self, blocked_ipv4: Iterable[str],
|
||||
blocked_ipv6: Iterable[str],
|
||||
dry_run: bool = False,
|
||||
report_dir: str = REPORT_DIR) -> dict[str, list[str]]:
|
||||
"""Synchronize the Blocked list cumulatively and audit the result.
|
||||
|
||||
The blocklist is grow-only: targets are added when present in the
|
||||
complete set (all git history of the blocklist files + the current
|
||||
working files + this scan's targets) and never removed automatically.
|
||||
Only router entries absent from the complete set — i.e. never blocked
|
||||
by the system — are pruned. See ``app.blocklist_history``.
|
||||
"""
|
||||
|
||||
desired_ipv4 = set(blocked_ipv4)
|
||||
desired_ipv6 = set(blocked_ipv6)
|
||||
current_ipv4 = self.get_address_list_ipv4(BLOCKLIST_NAME)
|
||||
current_ipv6 = self.get_address_list_ipv6(BLOCKLIST_NAME)
|
||||
whitelisted_ipv4 = set()
|
||||
whitelisted_ipv6 = set()
|
||||
for name in WHITELIST_NAMES:
|
||||
whitelisted_ipv4.update(self.get_address_list_ipv4(name))
|
||||
whitelisted_ipv6.update(self.get_address_list_ipv6(name))
|
||||
|
||||
v4_path = os.path.join(
|
||||
report_dir, "app", "data", "blocklist_ipv4.txt")
|
||||
v6_path = os.path.join(
|
||||
report_dir, "app", "data", "blocklist_ipv6.txt")
|
||||
complete_v4, complete_v6 = cumulative_blocklist(
|
||||
v4_path, v6_path, desired_ipv4, desired_ipv6)
|
||||
|
||||
changes = compute_changes(
|
||||
current_ipv4, current_ipv6,
|
||||
complete_v4, complete_v6,
|
||||
whitelisted_ipv4, whitelisted_ipv6)
|
||||
changes["dry_run"] = dry_run
|
||||
|
||||
if not dry_run:
|
||||
for ip in changes["removed_ipv4"]:
|
||||
self.execute_command(
|
||||
f"/ip firewall address-list remove [find list={BLOCKLIST_NAME} address={ip}]")
|
||||
for ip in changes["removed_ipv6"]:
|
||||
self.execute_command(
|
||||
f"/ipv6 firewall address-list remove [find list={BLOCKLIST_NAME} address={ip}]")
|
||||
self.write_address_list_ipv4(BLOCKLIST_NAME, changes["added_ipv4"])
|
||||
self.write_address_list_ipv6(BLOCKLIST_NAME, changes["added_ipv6"])
|
||||
self.save_state_report(report_dir, changes)
|
||||
return changes
|
||||
|
||||
def write_address_list_ipv4(self, name: str, ips: Iterable[str]) -> None:
|
||||
"""Write a list of IPv4 addresses to the Mikrotik router's address list."""
|
||||
for ip in ips:
|
||||
if is_whitelisted(ip):
|
||||
continue # Skip whitelisted IPs
|
||||
self.execute_command(
|
||||
f"/ip firewall address-list add list={name} address={ip}")
|
||||
|
||||
def write_address_list_ipv6(self, name: str, ips: Iterable[str]) -> None:
|
||||
"""Write a list of IPv6 addresses to the Mikrotik router's address list."""
|
||||
for ip in ips:
|
||||
if is_whitelisted(ip):
|
||||
continue # Skip whitelisted IPs
|
||||
self.execute_command(
|
||||
f"/ipv6 firewall address-list add list={name} address={ip}")
|
||||
|
||||
|
||||
def write_blocklist_files(blocked_ipv4: Iterable[str],
|
||||
blocked_ipv6: Iterable[str],
|
||||
report_dir: str = REPORT_DIR) -> tuple[str, str]:
|
||||
"""Write the final consolidated blocklist to ``<report_dir>/app/data/``.
|
||||
|
||||
Returns the paths of the IPv4 and IPv6 blocklist files
|
||||
(``blocklist_ipv4.txt`` / ``blocklist_ipv6.txt``).
|
||||
"""
|
||||
data_dir = os.path.join(report_dir, "app", "data")
|
||||
os.makedirs(data_dir, exist_ok=True)
|
||||
v4_path = os.path.join(data_dir, "blocklist_ipv4.txt")
|
||||
v6_path = os.path.join(data_dir, "blocklist_ipv6.txt")
|
||||
write_lines(v4_path, sorted(blocked_ipv4))
|
||||
write_lines(v6_path, sorted(blocked_ipv6))
|
||||
return v4_path, v6_path
|
||||
|
||||
|
||||
def get_scan_report(report_dir: str = REPORT_DIR) -> dict[str, list[str]]:
|
||||
"""Read the latest scan report `mikrotik-block.rsc` from the report directory and return the list of blocked IPs."""
|
||||
report_path = os.path.join(report_dir, "mikrotik-block.rsc")
|
||||
if not os.path.exists(report_path):
|
||||
raise FileNotFoundError(f"Scan report not found: {report_path}")
|
||||
|
||||
# add sections, they start with `/ip firewall address-list` or `/ipv6 firewall address-list` and end with a blank line or EOF
|
||||
sections = {
|
||||
"/ip firewall address-list": [],
|
||||
"/ipv6 firewall address-list": [],
|
||||
}
|
||||
# add list=Cloudflare or list=Openfactory to whitelist sections, list=Blocked to blocked section
|
||||
with open(report_path, "r", encoding="utf-8") as f:
|
||||
current_section = None
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if not line:
|
||||
current_section = None
|
||||
continue
|
||||
if line.startswith("/ip firewall address-list"):
|
||||
current_section = "/ip firewall address-list"
|
||||
continue
|
||||
if line.startswith("/ipv6 firewall address-list"):
|
||||
current_section = "/ipv6 firewall address-list"
|
||||
continue
|
||||
if current_section:
|
||||
sections[current_section].append(line)
|
||||
|
||||
return sections
|
||||
|
||||
|
||||
def main():
|
||||
"""Legacy entry point for applying the latest generated RouterOS report."""
|
||||
# Read the latest scan report
|
||||
scan_report = get_scan_report(REPORT_DIR)
|
||||
|
||||
# Connect to the Mikrotik router
|
||||
firewall = MikrotikFirewall()
|
||||
firewall.connect()
|
||||
|
||||
# read current blocked IPs from the router
|
||||
current_blocked_ipv4 = firewall.get_address_list_ipv4(BLOCKLIST_NAME)
|
||||
current_blocked_ipv6 = firewall.get_address_list_ipv6(BLOCKLIST_NAME)
|
||||
|
||||
# read whitelisted IPs from the router
|
||||
whitelisted_ipv4 = set()
|
||||
whitelisted_ipv6 = set()
|
||||
for wl_name in WHITELIST_NAMES:
|
||||
whitelisted_ipv4.update(firewall.get_address_list_ipv4(wl_name))
|
||||
whitelisted_ipv6.update(firewall.get_address_list_ipv6(wl_name))
|
||||
|
||||
# read blocked IPs from the scan report
|
||||
blocked_ipv4 = set()
|
||||
blocked_ipv6 = set()
|
||||
for line in scan_report["/ip firewall address-list"]:
|
||||
if "list=Blocked" in line:
|
||||
parts = line.split()
|
||||
for part in parts:
|
||||
if part.startswith("address="):
|
||||
ip = part.split("=")[1]
|
||||
blocked_ipv4.add(ip)
|
||||
for line in scan_report["/ipv6 firewall address-list"]:
|
||||
if "list=Blocked" in line:
|
||||
parts = line.split()
|
||||
for part in parts:
|
||||
if part.startswith("address="):
|
||||
ip = part.split("=")[1]
|
||||
blocked_ipv6.add(ip)
|
||||
|
||||
# Determine which IPs to add and remove
|
||||
to_add_ipv4 = blocked_ipv4 - current_blocked_ipv4 - whitelisted_ipv4
|
||||
to_add_ipv6 = blocked_ipv6 - current_blocked_ipv6 - whitelisted_ipv6
|
||||
to_remove_ipv4 = current_blocked_ipv4 - blocked_ipv4
|
||||
to_remove_ipv6 = current_blocked_ipv6 - blocked_ipv6
|
||||
|
||||
# Remove old blocked IPs
|
||||
for ip in to_remove_ipv4:
|
||||
firewall.execute_command(
|
||||
f"/ip firewall address-list remove [find list={BLOCKLIST_NAME} address={ip}]")
|
||||
for ip in to_remove_ipv6:
|
||||
firewall.execute_command(
|
||||
f"/ipv6 firewall address-list remove [find list={BLOCKLIST_NAME} address={ip}]")
|
||||
|
||||
# Add new blocked IPs
|
||||
firewall.write_address_list_ipv4(BLOCKLIST_NAME, to_add_ipv4)
|
||||
firewall.write_address_list_ipv6(BLOCKLIST_NAME, to_add_ipv6)
|
||||
|
||||
firewall.save_state_report(REPORT_DIR)
|
||||
|
||||
# Disconnect from the router
|
||||
firewall.disconnect()
|
||||
|
||||
# Print summary
|
||||
print(
|
||||
f"Removed {len(to_remove_ipv4)} IPv4 and {len(to_remove_ipv6)} IPv6 addresses from the blocklist.")
|
||||
print(
|
||||
f"Added {len(to_add_ipv4)} IPv4 and {len(to_add_ipv6)} IPv6 addresses to the blocklist.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
"""
|
||||
firewall.py -
|
||||
Module for interacting with the Mikrotik routeros shell to manage firewall rules and IP address lists.
|
||||
Provides functions to read the current firewall configuration, add and remove IPs from the blocklist.
|
||||
Reads the latest report from the IDS scan, reads the current firewall configuration, and updates the router's blocklist accordingly.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import json
|
||||
import paramiko
|
||||
from datetime import datetime
|
||||
import shlex
|
||||
from typing import Iterable
|
||||
from .utils.constants import (
|
||||
BLOCKLIST_NAME,
|
||||
MIKROTIK_DATA_DIR,
|
||||
REPORT_DIR,
|
||||
ROUTER_IP,
|
||||
ROUTER_PASSWORD,
|
||||
ROUTER_USER,
|
||||
SSH_PORT,
|
||||
SSH_TIMEOUT,
|
||||
WHITELIST_NAMES,
|
||||
)
|
||||
from .utils.files import write_lines
|
||||
from .utils.ip_utils import is_whitelisted
|
||||
from .utils.blocklist_history import compute_changes, cumulative_blocklist
|
||||
|
||||
|
||||
class MikrotikFirewall:
|
||||
"""
|
||||
Class to manage Mikrotik firewall rules and IP address lists.
|
||||
Provides methods to read the current blocklist, add/remove IPs, and update the blocklist based on IDS scan reports.
|
||||
"""
|
||||
|
||||
def __init__(self, router_ip: str = ROUTER_IP, username: str = ROUTER_USER,
|
||||
password: str = ROUTER_PASSWORD):
|
||||
self.router_ip = router_ip
|
||||
self.username = username
|
||||
self.password = password
|
||||
self.client: paramiko.SSHClient | None = None
|
||||
|
||||
def connect(self) -> None:
|
||||
"""Establish an SSH connection to the Mikrotik router."""
|
||||
client = paramiko.SSHClient()
|
||||
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
try:
|
||||
# RouterOS 7.20.x exposes an RSA host key and classic SSH ciphers.
|
||||
client.connect(
|
||||
self.router_ip,
|
||||
port=SSH_PORT,
|
||||
username=self.username,
|
||||
password=self.password,
|
||||
timeout=SSH_TIMEOUT,
|
||||
banner_timeout=SSH_TIMEOUT,
|
||||
auth_timeout=SSH_TIMEOUT,
|
||||
allow_agent=False,
|
||||
look_for_keys=False,
|
||||
compress=False,
|
||||
disabled_algorithms={"pubkeys": ["rsa-sha2-512"]},
|
||||
)
|
||||
except Exception:
|
||||
client.close()
|
||||
raise
|
||||
self.client = client
|
||||
|
||||
def disconnect(self) -> None:
|
||||
"""Close the SSH connection."""
|
||||
if self.client:
|
||||
self.client.close()
|
||||
self.client = None
|
||||
|
||||
def execute_command(self, command: str) -> str:
|
||||
"""Execute a command on the Mikrotik router via SSH and return the output."""
|
||||
if not self.client:
|
||||
raise RuntimeError("SSH client is not connected.")
|
||||
stdin, stdout, stderr = self.client.exec_command(command)
|
||||
output = stdout.read().decode("utf-8")
|
||||
error = stderr.read().decode("utf-8")
|
||||
if error:
|
||||
raise RuntimeError(f"Error executing command '{command}': {error}")
|
||||
return output
|
||||
|
||||
def get_address_list_ipv4(self, name: str) -> set[str]:
|
||||
"""Retrieve the current IPv4 address list from the Mikrotik router."""
|
||||
output = self.execute_command("/ip firewall address-list print")
|
||||
ips = set()
|
||||
for line in output.splitlines():
|
||||
parts = line.split()
|
||||
if len(parts) >= 3 and parts[1] == "list" and parts[2] == name:
|
||||
ip = parts[0]
|
||||
ips.add(ip)
|
||||
return ips
|
||||
|
||||
def get_address_list_ipv6(self, name: str) -> set[str]:
|
||||
"""Retrieve the current IPv6 address list from the Mikrotik router."""
|
||||
output = self.execute_command("/ipv6 firewall address-list print")
|
||||
ips = set()
|
||||
for line in output.splitlines():
|
||||
parts = line.split()
|
||||
if len(parts) >= 3 and parts[1] == "list" and parts[2] == name:
|
||||
ip = parts[0]
|
||||
ips.add(ip)
|
||||
return ips
|
||||
|
||||
@staticmethod
|
||||
def _parse_terse_output(output: str) -> list[dict[str, str]]:
|
||||
"""Parse RouterOS `print terse` records into key/value dictionaries."""
|
||||
records = []
|
||||
for line in output.splitlines():
|
||||
fields = {}
|
||||
for field in shlex.split(line):
|
||||
key, separator, value = field.partition("=")
|
||||
if separator:
|
||||
fields[key] = value
|
||||
if fields:
|
||||
records.append(fields)
|
||||
return records
|
||||
|
||||
def get_address_lists(self, ipv6: bool = False) -> list[dict[str, str]]:
|
||||
"""Retrieve all address-list entries in structured form."""
|
||||
path = "/ipv6" if ipv6 else "/ip"
|
||||
output = self.execute_command(
|
||||
f"{path} firewall address-list print terse")
|
||||
return self._parse_terse_output(output)
|
||||
|
||||
def get_firewall_rules(self, ipv6: bool = False) -> list[dict[str, str]]:
|
||||
"""Retrieve all firewall filter rules in structured form."""
|
||||
path = "/ipv6" if ipv6 else "/ip"
|
||||
output = self.execute_command(
|
||||
f"{path} firewall filter print terse")
|
||||
return self._parse_terse_output(output)
|
||||
|
||||
@staticmethod
|
||||
def _write_json(path: str, obj) -> None:
|
||||
with open(path, "w", encoding="utf-8") as file:
|
||||
json.dump(obj, file, indent=2, sort_keys=True)
|
||||
|
||||
def save_state_report(self, report_dir: str = REPORT_DIR,
|
||||
changes: dict | None = None) -> str:
|
||||
"""Save current address lists and firewall rules for auditing.
|
||||
|
||||
Writes structured snapshots to ``<report_dir>/mikrotik/data/`` and to
|
||||
the common ``data/mikrotik/`` directory (overwritten every run so git
|
||||
can diff changes to the firewall state over time), plus a timestamped
|
||||
JSON report under ``<report_dir>/mikrotik/``.
|
||||
"""
|
||||
state = {
|
||||
"router": self.router_ip,
|
||||
"collected_at": datetime.now().astimezone().isoformat(),
|
||||
"address_lists": {
|
||||
"ipv4": self.get_address_lists(),
|
||||
"ipv6": self.get_address_lists(ipv6=True),
|
||||
},
|
||||
"firewall_rules": {
|
||||
"ipv4": self.get_firewall_rules(),
|
||||
"ipv6": self.get_firewall_rules(ipv6=True),
|
||||
},
|
||||
}
|
||||
if changes is not None:
|
||||
state["changes"] = changes
|
||||
|
||||
report_data_dir = os.path.join(report_dir, "mikrotik", "data")
|
||||
os.makedirs(report_data_dir, exist_ok=True)
|
||||
os.makedirs(MIKROTIK_DATA_DIR, exist_ok=True)
|
||||
for version in ("ipv4", "ipv6"):
|
||||
for data_dir in (report_data_dir, MIKROTIK_DATA_DIR):
|
||||
self._write_json(
|
||||
os.path.join(data_dir, f"address_list_{version}.json"),
|
||||
state["address_lists"][version])
|
||||
self._write_json(
|
||||
os.path.join(data_dir, f"firewall_{version}.json"),
|
||||
state["firewall_rules"][version])
|
||||
|
||||
timestamp = datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
|
||||
report_path = os.path.join(report_dir, "mikrotik", f"{timestamp}.json")
|
||||
self._write_json(report_path, state)
|
||||
return report_path
|
||||
|
||||
def sync_blocklist(self, blocked_ipv4: Iterable[str],
|
||||
blocked_ipv6: Iterable[str],
|
||||
dry_run: bool = False,
|
||||
report_dir: str = REPORT_DIR) -> dict[str, list[str]]:
|
||||
"""Synchronize the Blocked list cumulatively and audit the result.
|
||||
|
||||
The blocklist is grow-only: targets are added when present in the
|
||||
complete set (all git history of the blocklist files + the current
|
||||
working files + this scan's targets) and never removed automatically.
|
||||
Only router entries absent from the complete set — i.e. never blocked
|
||||
by the system — are pruned. See ``app.blocklist_history``.
|
||||
"""
|
||||
|
||||
desired_ipv4 = set(blocked_ipv4)
|
||||
desired_ipv6 = set(blocked_ipv6)
|
||||
current_ipv4 = self.get_address_list_ipv4(BLOCKLIST_NAME)
|
||||
current_ipv6 = self.get_address_list_ipv6(BLOCKLIST_NAME)
|
||||
whitelisted_ipv4 = set()
|
||||
whitelisted_ipv6 = set()
|
||||
for name in WHITELIST_NAMES:
|
||||
whitelisted_ipv4.update(self.get_address_list_ipv4(name))
|
||||
whitelisted_ipv6.update(self.get_address_list_ipv6(name))
|
||||
|
||||
v4_path = os.path.join(
|
||||
report_dir, "app", "data", "blocklist_ipv4.txt")
|
||||
v6_path = os.path.join(
|
||||
report_dir, "app", "data", "blocklist_ipv6.txt")
|
||||
complete_v4, complete_v6 = cumulative_blocklist(
|
||||
v4_path, v6_path, desired_ipv4, desired_ipv6)
|
||||
|
||||
changes = compute_changes(
|
||||
current_ipv4, current_ipv6,
|
||||
complete_v4, complete_v6,
|
||||
whitelisted_ipv4, whitelisted_ipv6)
|
||||
changes["dry_run"] = dry_run
|
||||
|
||||
if not dry_run:
|
||||
for ip in changes["removed_ipv4"]:
|
||||
self.execute_command(
|
||||
f"/ip firewall address-list remove [find list={BLOCKLIST_NAME} address={ip}]")
|
||||
for ip in changes["removed_ipv6"]:
|
||||
self.execute_command(
|
||||
f"/ipv6 firewall address-list remove [find list={BLOCKLIST_NAME} address={ip}]")
|
||||
self.write_address_list_ipv4(BLOCKLIST_NAME, changes["added_ipv4"])
|
||||
self.write_address_list_ipv6(BLOCKLIST_NAME, changes["added_ipv6"])
|
||||
self.save_state_report(report_dir, changes)
|
||||
return changes
|
||||
|
||||
def write_address_list_ipv4(self, name: str, ips: Iterable[str]) -> None:
|
||||
"""Write a list of IPv4 addresses to the Mikrotik router's address list."""
|
||||
for ip in ips:
|
||||
if is_whitelisted(ip):
|
||||
continue # Skip whitelisted IPs
|
||||
self.execute_command(
|
||||
f"/ip firewall address-list add list={name} address={ip}")
|
||||
|
||||
def write_address_list_ipv6(self, name: str, ips: Iterable[str]) -> None:
|
||||
"""Write a list of IPv6 addresses to the Mikrotik router's address list."""
|
||||
for ip in ips:
|
||||
if is_whitelisted(ip):
|
||||
continue # Skip whitelisted IPs
|
||||
self.execute_command(
|
||||
f"/ipv6 firewall address-list add list={name} address={ip}")
|
||||
|
||||
|
||||
def write_blocklist_files(blocked_ipv4: Iterable[str],
|
||||
blocked_ipv6: Iterable[str],
|
||||
report_dir: str = REPORT_DIR) -> tuple[str, str]:
|
||||
"""Write the final consolidated blocklist to ``<report_dir>/app/data/``.
|
||||
|
||||
Returns the paths of the IPv4 and IPv6 blocklist files
|
||||
(``blocklist_ipv4.txt`` / ``blocklist_ipv6.txt``).
|
||||
"""
|
||||
data_dir = os.path.join(report_dir, "app", "data")
|
||||
os.makedirs(data_dir, exist_ok=True)
|
||||
v4_path = os.path.join(data_dir, "blocklist_ipv4.txt")
|
||||
v6_path = os.path.join(data_dir, "blocklist_ipv6.txt")
|
||||
write_lines(v4_path, sorted(blocked_ipv4))
|
||||
write_lines(v6_path, sorted(blocked_ipv6))
|
||||
return v4_path, v6_path
|
||||
|
||||
|
||||
def get_scan_report(report_dir: str = REPORT_DIR) -> dict[str, list[str]]:
|
||||
"""Read the latest scan report `mikrotik-block.rsc` from the report directory and return the list of blocked IPs."""
|
||||
report_path = os.path.join(report_dir, "mikrotik-block.rsc")
|
||||
if not os.path.exists(report_path):
|
||||
raise FileNotFoundError(f"Scan report not found: {report_path}")
|
||||
|
||||
# add sections, they start with `/ip firewall address-list` or `/ipv6 firewall address-list` and end with a blank line or EOF
|
||||
sections = {
|
||||
"/ip firewall address-list": [],
|
||||
"/ipv6 firewall address-list": [],
|
||||
}
|
||||
# add list=Cloudflare or list=Openfactory to whitelist sections, list=Blocked to blocked section
|
||||
with open(report_path, "r", encoding="utf-8") as f:
|
||||
current_section = None
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if not line:
|
||||
current_section = None
|
||||
continue
|
||||
if line.startswith("/ip firewall address-list"):
|
||||
current_section = "/ip firewall address-list"
|
||||
continue
|
||||
if line.startswith("/ipv6 firewall address-list"):
|
||||
current_section = "/ipv6 firewall address-list"
|
||||
continue
|
||||
if current_section:
|
||||
sections[current_section].append(line)
|
||||
|
||||
return sections
|
||||
|
||||
|
||||
def main():
|
||||
"""Legacy entry point for applying the latest generated RouterOS report."""
|
||||
# Read the latest scan report
|
||||
scan_report = get_scan_report(REPORT_DIR)
|
||||
|
||||
# Connect to the Mikrotik router
|
||||
firewall = MikrotikFirewall()
|
||||
firewall.connect()
|
||||
|
||||
# read current blocked IPs from the router
|
||||
current_blocked_ipv4 = firewall.get_address_list_ipv4(BLOCKLIST_NAME)
|
||||
current_blocked_ipv6 = firewall.get_address_list_ipv6(BLOCKLIST_NAME)
|
||||
|
||||
# read whitelisted IPs from the router
|
||||
whitelisted_ipv4 = set()
|
||||
whitelisted_ipv6 = set()
|
||||
for wl_name in WHITELIST_NAMES:
|
||||
whitelisted_ipv4.update(firewall.get_address_list_ipv4(wl_name))
|
||||
whitelisted_ipv6.update(firewall.get_address_list_ipv6(wl_name))
|
||||
|
||||
# read blocked IPs from the scan report
|
||||
blocked_ipv4 = set()
|
||||
blocked_ipv6 = set()
|
||||
for line in scan_report["/ip firewall address-list"]:
|
||||
if "list=Blocked" in line:
|
||||
parts = line.split()
|
||||
for part in parts:
|
||||
if part.startswith("address="):
|
||||
ip = part.split("=")[1]
|
||||
blocked_ipv4.add(ip)
|
||||
for line in scan_report["/ipv6 firewall address-list"]:
|
||||
if "list=Blocked" in line:
|
||||
parts = line.split()
|
||||
for part in parts:
|
||||
if part.startswith("address="):
|
||||
ip = part.split("=")[1]
|
||||
blocked_ipv6.add(ip)
|
||||
|
||||
# Determine which IPs to add and remove
|
||||
to_add_ipv4 = blocked_ipv4 - current_blocked_ipv4 - whitelisted_ipv4
|
||||
to_add_ipv6 = blocked_ipv6 - current_blocked_ipv6 - whitelisted_ipv6
|
||||
to_remove_ipv4 = current_blocked_ipv4 - blocked_ipv4
|
||||
to_remove_ipv6 = current_blocked_ipv6 - blocked_ipv6
|
||||
|
||||
# Remove old blocked IPs
|
||||
for ip in to_remove_ipv4:
|
||||
firewall.execute_command(
|
||||
f"/ip firewall address-list remove [find list={BLOCKLIST_NAME} address={ip}]")
|
||||
for ip in to_remove_ipv6:
|
||||
firewall.execute_command(
|
||||
f"/ipv6 firewall address-list remove [find list={BLOCKLIST_NAME} address={ip}]")
|
||||
|
||||
# Add new blocked IPs
|
||||
firewall.write_address_list_ipv4(BLOCKLIST_NAME, to_add_ipv4)
|
||||
firewall.write_address_list_ipv6(BLOCKLIST_NAME, to_add_ipv6)
|
||||
|
||||
firewall.save_state_report(REPORT_DIR)
|
||||
|
||||
# Disconnect from the router
|
||||
firewall.disconnect()
|
||||
|
||||
# Print summary
|
||||
print(
|
||||
f"Removed {len(to_remove_ipv4)} IPv4 and {len(to_remove_ipv6)} IPv6 addresses from the blocklist.")
|
||||
print(
|
||||
f"Added {len(to_add_ipv4)} IPv4 and {len(to_add_ipv6)} IPv6 addresses to the blocklist.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
+47
-47
@@ -1,47 +1,47 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Flagging rules for the intrusion-detection system.
|
||||
|
||||
Detection functions that identify hostile IPs based on aggregated stats.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from . import bad_patterns
|
||||
from .utils.constants import DEFAULT_ERROR_RATIO, DEFAULT_MIN_DENIED, DEFAULT_MIN_ERRORS
|
||||
from .utils.models import IPStats
|
||||
|
||||
|
||||
def flag_scanners(stats: dict[str, IPStats], min_errors: int = DEFAULT_MIN_ERRORS,
|
||||
min_ratio: float = DEFAULT_ERROR_RATIO) -> dict[str, IPStats]:
|
||||
"""IPs with many errors AND a high error ratio."""
|
||||
return {
|
||||
ip: s for ip, s in stats.items()
|
||||
if s.errors >= min_errors and s.error_ratio >= min_ratio
|
||||
}
|
||||
|
||||
|
||||
def flag_denied_only(stats: dict[str, IPStats],
|
||||
min_denied: int = DEFAULT_MIN_DENIED) -> dict[str, IPStats]:
|
||||
"""IPs that only ever hit denied paths and never authenticated."""
|
||||
return {
|
||||
ip: s for ip, s in stats.items()
|
||||
if s.denied >= min_denied and not s.authenticated
|
||||
}
|
||||
|
||||
|
||||
def flag_malicious_patterns(stats: dict[str, IPStats],
|
||||
min_severity: int = 2,
|
||||
min_hits: int = 1) -> dict[str, IPStats]:
|
||||
"""IPs with hits against malicious path patterns at or above severity threshold."""
|
||||
return {
|
||||
ip: s for ip, s in stats.items()
|
||||
if s.malicious_hits >= min_hits and any(
|
||||
bad_patterns.PATTERNS_BY_NAME[name].severity >= min_severity
|
||||
for name in s.malicious_patterns
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
def by_total(stats: dict[str, IPStats]) -> list[IPStats]:
|
||||
"""Stats sorted by request count, descending."""
|
||||
return sorted(stats.values(), key=lambda s: (-s.total, s.ip))
|
||||
#!/usr/bin/env python3
|
||||
"""Flagging rules for the intrusion-detection system.
|
||||
|
||||
Detection functions that identify hostile IPs based on aggregated stats.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from . import bad_patterns
|
||||
from .utils.constants import DEFAULT_ERROR_RATIO, DEFAULT_MIN_DENIED, DEFAULT_MIN_ERRORS
|
||||
from .utils.models import IPStats
|
||||
|
||||
|
||||
def flag_scanners(stats: dict[str, IPStats], min_errors: int = DEFAULT_MIN_ERRORS,
|
||||
min_ratio: float = DEFAULT_ERROR_RATIO) -> dict[str, IPStats]:
|
||||
"""IPs with many errors AND a high error ratio."""
|
||||
return {
|
||||
ip: s for ip, s in stats.items()
|
||||
if s.errors >= min_errors and s.error_ratio >= min_ratio
|
||||
}
|
||||
|
||||
|
||||
def flag_denied_only(stats: dict[str, IPStats],
|
||||
min_denied: int = DEFAULT_MIN_DENIED) -> dict[str, IPStats]:
|
||||
"""IPs that only ever hit denied paths and never authenticated."""
|
||||
return {
|
||||
ip: s for ip, s in stats.items()
|
||||
if s.denied >= min_denied and not s.authenticated
|
||||
}
|
||||
|
||||
|
||||
def flag_malicious_patterns(stats: dict[str, IPStats],
|
||||
min_severity: int = 2,
|
||||
min_hits: int = 1) -> dict[str, IPStats]:
|
||||
"""IPs with hits against malicious path patterns at or above severity threshold."""
|
||||
return {
|
||||
ip: s for ip, s in stats.items()
|
||||
if s.malicious_hits >= min_hits and any(
|
||||
bad_patterns.PATTERNS_BY_NAME[name].severity >= min_severity
|
||||
for name in s.malicious_patterns
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
def by_total(stats: dict[str, IPStats]) -> list[IPStats]:
|
||||
"""Stats sorted by request count, descending."""
|
||||
return sorted(stats.values(), key=lambda s: (-s.total, s.ip))
|
||||
+111
-111
@@ -1,111 +1,111 @@
|
||||
#!/usr/bin/env python3
|
||||
"""MikroTik RouterOS script generation."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import ipaddress
|
||||
from datetime import datetime
|
||||
from typing import Iterable
|
||||
|
||||
from .utils.ip_utils import is_ipv4, is_ipv6, is_whitelisted, parse_ip
|
||||
from .utils.whitelists import WHITELISTS
|
||||
from .utils.constants import BLOCKLIST_NAME
|
||||
|
||||
|
||||
def split_cidr_versions(targets: Iterable[str]) -> tuple[list[str], list[str]]:
|
||||
"""Split target CIDRs/IPs into (sorted IPv4 list, sorted IPv6 list)."""
|
||||
v4 = []
|
||||
v6 = []
|
||||
for t in targets:
|
||||
ip = t.split("/")[0]
|
||||
if is_ipv4(ip):
|
||||
v4.append(t)
|
||||
elif is_ipv6(ip):
|
||||
v6.append(t)
|
||||
|
||||
def key_cidr(cidr: str):
|
||||
ip = cidr.split("/")[0]
|
||||
addr = parse_ip(ip)
|
||||
if addr is None:
|
||||
return (9, b"", cidr)
|
||||
return (addr.version, addr.packed, cidr)
|
||||
|
||||
return sorted(v4, key=key_cidr), sorted(v6, key=key_cidr)
|
||||
|
||||
|
||||
def mikrotik_script(tag: str, blocked_ips_or_subnets: Iterable[str],
|
||||
whitelists: dict[str, list[str]] | None = None,
|
||||
generated: str | None = None) -> tuple[str, int, int]:
|
||||
"""Build a RouterOS .rsc script.
|
||||
|
||||
Whitelisted ranges become `accept` rules placed above the `drop` rules.
|
||||
Blocked targets can be individual IPs (e.g. 1.2.3.4/32) or CIDR blocks
|
||||
(e.g. 1.2.3.0/24).
|
||||
|
||||
Returns (script_text, blocked_count, whitelisted_cidr_count).
|
||||
"""
|
||||
whitelists = WHITELISTS if whitelists is None else whitelists
|
||||
generated = generated or datetime.now().isoformat(timespec="seconds")
|
||||
|
||||
def clean_blocked(targets: Iterable[str]) -> list[str]:
|
||||
cleaned = []
|
||||
for t in targets:
|
||||
ip = t.split("/")[0]
|
||||
if not is_whitelisted(ip):
|
||||
cleaned.append(t)
|
||||
return cleaned
|
||||
|
||||
blocked = clean_blocked(set(blocked_ips_or_subnets))
|
||||
block_v4, block_v6 = split_cidr_versions(blocked)
|
||||
|
||||
lines: list[str] = [f"# {tag} firewall export - generated {generated}", ""]
|
||||
wl_count = 0
|
||||
|
||||
for name, cidrs in whitelists.items():
|
||||
nets = [ipaddress.ip_network(c) for c in cidrs]
|
||||
wl_count += len(nets)
|
||||
for version, cmd in ((4, "/ip firewall address-list"),
|
||||
(6, "/ipv6 firewall address-list")):
|
||||
chunk = [n for n in nets if n.version == version]
|
||||
if not chunk:
|
||||
continue
|
||||
lines.append(f"# {name} IPv{version} ranges (whitelisted)")
|
||||
lines.append(cmd)
|
||||
lines += [f"add list={name} address={n}" for n in chunk]
|
||||
lines.append("")
|
||||
|
||||
if block_v4:
|
||||
lines.append(f"# Blocked IPv4 ({len(block_v4)}, non-whitelisted)")
|
||||
lines.append("/ip firewall address-list")
|
||||
lines += [f"add list={BLOCKLIST_NAME} address={t}" for t in block_v4]
|
||||
lines.append("")
|
||||
if block_v6:
|
||||
lines.append(f"# Blocked IPv6 ({len(block_v6)}, non-whitelisted)")
|
||||
lines.append("/ipv6 firewall address-list")
|
||||
lines += [f"add list={BLOCKLIST_NAME} address={t}" for t in block_v6]
|
||||
lines.append("")
|
||||
|
||||
for version, cmd, blocks in ((4, "/ip firewall filter", block_v4),
|
||||
(6, "/ipv6 firewall filter", block_v6)):
|
||||
lines.append(cmd)
|
||||
for name in whitelists:
|
||||
lines.append(
|
||||
f"add chain=input action=accept src-address-list={name} "
|
||||
f'comment="{tag} {name.lower()} whitelist (v{version})"')
|
||||
if blocks:
|
||||
for chain in ("input", "forward"):
|
||||
lines.append(
|
||||
f"add chain={chain} action=drop src-address-list={BLOCKLIST_NAME} "
|
||||
f'comment="{tag} blocked (v{version})"')
|
||||
lines.append("")
|
||||
|
||||
return "\n".join(lines), len(blocked), wl_count
|
||||
|
||||
|
||||
def write_mikrotik(path: str, tag: str,
|
||||
blocked_ips_or_subnets: Iterable[str]) -> tuple[str, int, int]:
|
||||
text, n_blocked, n_whitelisted = mikrotik_script(
|
||||
tag, blocked_ips_or_subnets)
|
||||
with open(path, "w", encoding="utf-8") as f:
|
||||
f.write(text)
|
||||
return path, n_blocked, n_whitelisted
|
||||
#!/usr/bin/env python3
|
||||
"""MikroTik RouterOS script generation."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import ipaddress
|
||||
from datetime import datetime
|
||||
from typing import Iterable
|
||||
|
||||
from .utils.ip_utils import is_ipv4, is_ipv6, is_whitelisted, parse_ip
|
||||
from .utils.whitelists import WHITELISTS
|
||||
from .utils.constants import BLOCKLIST_NAME
|
||||
|
||||
|
||||
def split_cidr_versions(targets: Iterable[str]) -> tuple[list[str], list[str]]:
|
||||
"""Split target CIDRs/IPs into (sorted IPv4 list, sorted IPv6 list)."""
|
||||
v4 = []
|
||||
v6 = []
|
||||
for t in targets:
|
||||
ip = t.split("/")[0]
|
||||
if is_ipv4(ip):
|
||||
v4.append(t)
|
||||
elif is_ipv6(ip):
|
||||
v6.append(t)
|
||||
|
||||
def key_cidr(cidr: str):
|
||||
ip = cidr.split("/")[0]
|
||||
addr = parse_ip(ip)
|
||||
if addr is None:
|
||||
return (9, b"", cidr)
|
||||
return (addr.version, addr.packed, cidr)
|
||||
|
||||
return sorted(v4, key=key_cidr), sorted(v6, key=key_cidr)
|
||||
|
||||
|
||||
def mikrotik_script(tag: str, blocked_ips_or_subnets: Iterable[str],
|
||||
whitelists: dict[str, list[str]] | None = None,
|
||||
generated: str | None = None) -> tuple[str, int, int]:
|
||||
"""Build a RouterOS .rsc script.
|
||||
|
||||
Whitelisted ranges become `accept` rules placed above the `drop` rules.
|
||||
Blocked targets can be individual IPs (e.g. 1.2.3.4/32) or CIDR blocks
|
||||
(e.g. 1.2.3.0/24).
|
||||
|
||||
Returns (script_text, blocked_count, whitelisted_cidr_count).
|
||||
"""
|
||||
whitelists = WHITELISTS if whitelists is None else whitelists
|
||||
generated = generated or datetime.now().isoformat(timespec="seconds")
|
||||
|
||||
def clean_blocked(targets: Iterable[str]) -> list[str]:
|
||||
cleaned = []
|
||||
for t in targets:
|
||||
ip = t.split("/")[0]
|
||||
if not is_whitelisted(ip):
|
||||
cleaned.append(t)
|
||||
return cleaned
|
||||
|
||||
blocked = clean_blocked(set(blocked_ips_or_subnets))
|
||||
block_v4, block_v6 = split_cidr_versions(blocked)
|
||||
|
||||
lines: list[str] = [f"# {tag} firewall export - generated {generated}", ""]
|
||||
wl_count = 0
|
||||
|
||||
for name, cidrs in whitelists.items():
|
||||
nets = [ipaddress.ip_network(c) for c in cidrs]
|
||||
wl_count += len(nets)
|
||||
for version, cmd in ((4, "/ip firewall address-list"),
|
||||
(6, "/ipv6 firewall address-list")):
|
||||
chunk = [n for n in nets if n.version == version]
|
||||
if not chunk:
|
||||
continue
|
||||
lines.append(f"# {name} IPv{version} ranges (whitelisted)")
|
||||
lines.append(cmd)
|
||||
lines += [f"add list={name} address={n}" for n in chunk]
|
||||
lines.append("")
|
||||
|
||||
if block_v4:
|
||||
lines.append(f"# Blocked IPv4 ({len(block_v4)}, non-whitelisted)")
|
||||
lines.append("/ip firewall address-list")
|
||||
lines += [f"add list={BLOCKLIST_NAME} address={t}" for t in block_v4]
|
||||
lines.append("")
|
||||
if block_v6:
|
||||
lines.append(f"# Blocked IPv6 ({len(block_v6)}, non-whitelisted)")
|
||||
lines.append("/ipv6 firewall address-list")
|
||||
lines += [f"add list={BLOCKLIST_NAME} address={t}" for t in block_v6]
|
||||
lines.append("")
|
||||
|
||||
for version, cmd, blocks in ((4, "/ip firewall filter", block_v4),
|
||||
(6, "/ipv6 firewall filter", block_v6)):
|
||||
lines.append(cmd)
|
||||
for name in whitelists:
|
||||
lines.append(
|
||||
f"add chain=input action=accept src-address-list={name} "
|
||||
f'comment="{tag} {name.lower()} whitelist (v{version})"')
|
||||
if blocks:
|
||||
for chain in ("input", "forward"):
|
||||
lines.append(
|
||||
f"add chain={chain} action=drop src-address-list={BLOCKLIST_NAME} "
|
||||
f'comment="{tag} blocked (v{version})"')
|
||||
lines.append("")
|
||||
|
||||
return "\n".join(lines), len(blocked), wl_count
|
||||
|
||||
|
||||
def write_mikrotik(path: str, tag: str,
|
||||
blocked_ips_or_subnets: Iterable[str]) -> tuple[str, int, int]:
|
||||
text, n_blocked, n_whitelisted = mikrotik_script(
|
||||
tag, blocked_ips_or_subnets)
|
||||
with open(path, "w", encoding="utf-8") as f:
|
||||
f.write(text)
|
||||
return path, n_blocked, n_whitelisted
|
||||
+170
-170
@@ -1,170 +1,170 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Nginx Proxy Manager access-log analyzer.
|
||||
|
||||
Parses NPM proxy access logs (plain + gzipped), aggregates per-IP
|
||||
behaviour and flags scanner IPs: clients with many error responses and a
|
||||
high error ratio. Flagged IPs become the MikroTik block list.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import re
|
||||
from collections import Counter
|
||||
|
||||
from .analyzer import Analyzer
|
||||
from .utils.constants import (
|
||||
DEFAULT_ERROR_RATIO,
|
||||
DEFAULT_MIN_ERRORS,
|
||||
NPM_LOG_PATH,
|
||||
NPM_REPORT_DIR,
|
||||
)
|
||||
from .utils.files import write_csv
|
||||
from .flags import flag_scanners
|
||||
from .utils.models import Request
|
||||
from .utils.utils import arg_parser
|
||||
|
||||
# [02/Aug/2026:05:01:31 +0200] - 401 401 - GET https host "/path"
|
||||
# [Client IP] [Length N] [Gzip X] [Sent-to IP] "UA" "Referer"
|
||||
LINE_RE = re.compile(
|
||||
r"^\[(\d{2}/\w{3}/\d{4}:\d{2}:\d{2}:\d{2}\s+[+-]\d{4})\]\s+" # [datetime]
|
||||
r"-\s+"
|
||||
r"(\d+|-)\s+" # upstream
|
||||
r"(\d+)\s+" # status
|
||||
r"-\s+"
|
||||
r"(\S+)\s+" # method
|
||||
r"(\S+)\s+" # scheme
|
||||
r"(\S+)\s+" # host
|
||||
r'"([^"]*)"\s+' # "path"
|
||||
r"\[Client\s+(\S+)\]\s+"
|
||||
r"\[Length\s+(\d+|-)\]\s+"
|
||||
r"\[Gzip\s+(\S+)\]\s+"
|
||||
r"\[Sent-to\s+(\S+)\]\s+"
|
||||
r'"([^"]*)"\s+' # "UA"
|
||||
r'"([^"]*)"' # "Referer"
|
||||
)
|
||||
|
||||
|
||||
class NpmAnalyzer(Analyzer):
|
||||
name = "npm"
|
||||
title = "Nginx Proxy Manager log analysis report"
|
||||
log_suffixes = (".log", ".gz")
|
||||
exclude_prefixes = ("letsencrypt",)
|
||||
paths_file = "error_paths.csv"
|
||||
paths_label = "error paths"
|
||||
flag_files = ("scanner_ips.txt", "scanner_ipv6.txt")
|
||||
flag_label = "Scanner IPs"
|
||||
flag_note = "high error rate -- probable scanners/attackers"
|
||||
|
||||
ip_columns = (
|
||||
("ip", lambda s: s.ip),
|
||||
("total", lambda s: s.total),
|
||||
("4xx", lambda s: s.c4xx),
|
||||
("5xx", lambda s: s.c5xx),
|
||||
("ratio", lambda s: s.error_ratio),
|
||||
("first", lambda s: s.first),
|
||||
("last", lambda s: s.last),
|
||||
("methods", lambda s: s.methods_str),
|
||||
("whitelist", lambda s: s.whitelist),
|
||||
)
|
||||
|
||||
request_columns = (
|
||||
("datetime", lambda r: r.ts),
|
||||
("ip", lambda r: r.ip),
|
||||
("method", lambda r: r.method),
|
||||
("scheme", lambda r: r.extra.get("scheme")),
|
||||
("host", lambda r: r.host),
|
||||
("path", lambda r: r.path),
|
||||
("status", lambda r: r.status),
|
||||
("upstream_status", lambda r: r.upstream_status),
|
||||
("length", lambda r: r.extra.get("length")),
|
||||
("gzip", lambda r: r.extra.get("gzip")),
|
||||
("sent_to", lambda r: r.extra.get("sent_to")),
|
||||
("referer", lambda r: r.referer),
|
||||
("ua", lambda r: r.ua),
|
||||
)
|
||||
|
||||
def __init__(self, *args, min_errors: int = DEFAULT_MIN_ERRORS,
|
||||
error_ratio: float = DEFAULT_ERROR_RATIO, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.min_errors = min_errors
|
||||
self.min_ratio = error_ratio
|
||||
|
||||
# --- parsing -----------------------------------------------------------
|
||||
|
||||
def parse_line(self, line: str) -> Request | None:
|
||||
if not line:
|
||||
return None
|
||||
m = LINE_RE.match(line)
|
||||
if not m:
|
||||
return None
|
||||
(ts, upstream, status, method, scheme, host, path, ip,
|
||||
length, gz, sent_to, ua, referer) = m.groups()
|
||||
return Request(
|
||||
ts=ts,
|
||||
ip=ip,
|
||||
method=method,
|
||||
path=path,
|
||||
status=int(status),
|
||||
upstream_status=int(upstream) if upstream.isdigit() else None,
|
||||
host=host,
|
||||
ua=ua,
|
||||
referer=referer,
|
||||
extra={"scheme": scheme, "length": length,
|
||||
"gzip": gz, "sent_to": sent_to},
|
||||
)
|
||||
|
||||
# --- flagging ----------------------------------------------------------
|
||||
|
||||
def flag(self, stats):
|
||||
return flag_scanners(stats, min_errors=self.min_errors,
|
||||
min_ratio=self.min_ratio)
|
||||
|
||||
# --- extras ------------------------------------------------------------
|
||||
|
||||
def extra_summary_rows(self):
|
||||
c4 = sum(1 for r in self.requests if r.is_client_error)
|
||||
c5 = sum(1 for r in self.requests if r.is_server_error)
|
||||
return [
|
||||
("4xx / 5xx", f"{c4} / {c5}"),
|
||||
("hosts seen", len({r.host for r in self.requests if r.host})),
|
||||
("scanner threshold",
|
||||
f">= {self.min_errors} errors and ratio >= {self.min_ratio}"),
|
||||
]
|
||||
|
||||
def write_extra(self, data_dir: str) -> list[str]:
|
||||
uas = Counter(r.ua for r in self.requests if r.ua and r.ua != "-")
|
||||
hosts = Counter(r.host for r in self.requests if r.host)
|
||||
return [
|
||||
write_csv(os.path.join(data_dir, "ua_summary.csv"),
|
||||
["user_agent", "count"], uas.most_common()),
|
||||
write_csv(os.path.join(data_dir, "host_summary.csv"),
|
||||
["host", "count"], hosts.most_common()),
|
||||
]
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = arg_parser(
|
||||
"analyze NPM proxy logs, flag scanner IPs, export MikroTik rules",
|
||||
NPM_LOG_PATH, NPM_REPORT_DIR)
|
||||
parser.add_argument("--min-errors", type=int, default=DEFAULT_MIN_ERRORS,
|
||||
help=f"minimum error responses to flag (default: {DEFAULT_MIN_ERRORS})")
|
||||
parser.add_argument("--error-ratio", type=float, default=DEFAULT_ERROR_RATIO,
|
||||
help=f"minimum error ratio to flag (default: {DEFAULT_ERROR_RATIO})")
|
||||
parser.add_argument("--full", action="store_true",
|
||||
help="rescan all logs from the start (ignore incremental state)")
|
||||
args = parser.parse_args()
|
||||
|
||||
NpmAnalyzer(
|
||||
log_path=args.log_path,
|
||||
report_dir=args.report_dir,
|
||||
top=args.top,
|
||||
quiet=args.quiet,
|
||||
full=args.full,
|
||||
min_errors=args.min_errors,
|
||||
error_ratio=args.error_ratio,
|
||||
).run()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
#!/usr/bin/env python3
|
||||
"""Nginx Proxy Manager access-log analyzer.
|
||||
|
||||
Parses NPM proxy access logs (plain + gzipped), aggregates per-IP
|
||||
behaviour and flags scanner IPs: clients with many error responses and a
|
||||
high error ratio. Flagged IPs become the MikroTik block list.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import re
|
||||
from collections import Counter
|
||||
|
||||
from .analyzer import Analyzer
|
||||
from .utils.constants import (
|
||||
DEFAULT_ERROR_RATIO,
|
||||
DEFAULT_MIN_ERRORS,
|
||||
NPM_LOG_PATH,
|
||||
NPM_REPORT_DIR,
|
||||
)
|
||||
from .utils.files import write_csv
|
||||
from .flags import flag_scanners
|
||||
from .utils.models import Request
|
||||
from .utils.utils import arg_parser
|
||||
|
||||
# [02/Aug/2026:05:01:31 +0200] - 401 401 - GET https host "/path"
|
||||
# [Client IP] [Length N] [Gzip X] [Sent-to IP] "UA" "Referer"
|
||||
LINE_RE = re.compile(
|
||||
r"^\[(\d{2}/\w{3}/\d{4}:\d{2}:\d{2}:\d{2}\s+[+-]\d{4})\]\s+" # [datetime]
|
||||
r"-\s+"
|
||||
r"(\d+|-)\s+" # upstream
|
||||
r"(\d+)\s+" # status
|
||||
r"-\s+"
|
||||
r"(\S+)\s+" # method
|
||||
r"(\S+)\s+" # scheme
|
||||
r"(\S+)\s+" # host
|
||||
r'"([^"]*)"\s+' # "path"
|
||||
r"\[Client\s+(\S+)\]\s+"
|
||||
r"\[Length\s+(\d+|-)\]\s+"
|
||||
r"\[Gzip\s+(\S+)\]\s+"
|
||||
r"\[Sent-to\s+(\S+)\]\s+"
|
||||
r'"([^"]*)"\s+' # "UA"
|
||||
r'"([^"]*)"' # "Referer"
|
||||
)
|
||||
|
||||
|
||||
class NpmAnalyzer(Analyzer):
|
||||
name = "npm"
|
||||
title = "Nginx Proxy Manager log analysis report"
|
||||
log_suffixes = (".log", ".gz")
|
||||
exclude_prefixes = ("letsencrypt",)
|
||||
paths_file = "error_paths.csv"
|
||||
paths_label = "error paths"
|
||||
flag_files = ("scanner_ips.txt", "scanner_ipv6.txt")
|
||||
flag_label = "Scanner IPs"
|
||||
flag_note = "high error rate -- probable scanners/attackers"
|
||||
|
||||
ip_columns = (
|
||||
("ip", lambda s: s.ip),
|
||||
("total", lambda s: s.total),
|
||||
("4xx", lambda s: s.c4xx),
|
||||
("5xx", lambda s: s.c5xx),
|
||||
("ratio", lambda s: s.error_ratio),
|
||||
("first", lambda s: s.first),
|
||||
("last", lambda s: s.last),
|
||||
("methods", lambda s: s.methods_str),
|
||||
("whitelist", lambda s: s.whitelist),
|
||||
)
|
||||
|
||||
request_columns = (
|
||||
("datetime", lambda r: r.ts),
|
||||
("ip", lambda r: r.ip),
|
||||
("method", lambda r: r.method),
|
||||
("scheme", lambda r: r.extra.get("scheme")),
|
||||
("host", lambda r: r.host),
|
||||
("path", lambda r: r.path),
|
||||
("status", lambda r: r.status),
|
||||
("upstream_status", lambda r: r.upstream_status),
|
||||
("length", lambda r: r.extra.get("length")),
|
||||
("gzip", lambda r: r.extra.get("gzip")),
|
||||
("sent_to", lambda r: r.extra.get("sent_to")),
|
||||
("referer", lambda r: r.referer),
|
||||
("ua", lambda r: r.ua),
|
||||
)
|
||||
|
||||
def __init__(self, *args, min_errors: int = DEFAULT_MIN_ERRORS,
|
||||
error_ratio: float = DEFAULT_ERROR_RATIO, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.min_errors = min_errors
|
||||
self.min_ratio = error_ratio
|
||||
|
||||
# --- parsing -----------------------------------------------------------
|
||||
|
||||
def parse_line(self, line: str) -> Request | None:
|
||||
if not line:
|
||||
return None
|
||||
m = LINE_RE.match(line)
|
||||
if not m:
|
||||
return None
|
||||
(ts, upstream, status, method, scheme, host, path, ip,
|
||||
length, gz, sent_to, ua, referer) = m.groups()
|
||||
return Request(
|
||||
ts=ts,
|
||||
ip=ip,
|
||||
method=method,
|
||||
path=path,
|
||||
status=int(status),
|
||||
upstream_status=int(upstream) if upstream.isdigit() else None,
|
||||
host=host,
|
||||
ua=ua,
|
||||
referer=referer,
|
||||
extra={"scheme": scheme, "length": length,
|
||||
"gzip": gz, "sent_to": sent_to},
|
||||
)
|
||||
|
||||
# --- flagging ----------------------------------------------------------
|
||||
|
||||
def flag(self, stats):
|
||||
return flag_scanners(stats, min_errors=self.min_errors,
|
||||
min_ratio=self.min_ratio)
|
||||
|
||||
# --- extras ------------------------------------------------------------
|
||||
|
||||
def extra_summary_rows(self):
|
||||
c4 = sum(1 for r in self.requests if r.is_client_error)
|
||||
c5 = sum(1 for r in self.requests if r.is_server_error)
|
||||
return [
|
||||
("4xx / 5xx", f"{c4} / {c5}"),
|
||||
("hosts seen", len({r.host for r in self.requests if r.host})),
|
||||
("scanner threshold",
|
||||
f">= {self.min_errors} errors and ratio >= {self.min_ratio}"),
|
||||
]
|
||||
|
||||
def write_extra(self, data_dir: str) -> list[str]:
|
||||
uas = Counter(r.ua for r in self.requests if r.ua and r.ua != "-")
|
||||
hosts = Counter(r.host for r in self.requests if r.host)
|
||||
return [
|
||||
write_csv(os.path.join(data_dir, "ua_summary.csv"),
|
||||
["user_agent", "count"], uas.most_common()),
|
||||
write_csv(os.path.join(data_dir, "host_summary.csv"),
|
||||
["host", "count"], hosts.most_common()),
|
||||
]
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = arg_parser(
|
||||
"analyze NPM proxy logs, flag scanner IPs, export MikroTik rules",
|
||||
NPM_LOG_PATH, NPM_REPORT_DIR)
|
||||
parser.add_argument("--min-errors", type=int, default=DEFAULT_MIN_ERRORS,
|
||||
help=f"minimum error responses to flag (default: {DEFAULT_MIN_ERRORS})")
|
||||
parser.add_argument("--error-ratio", type=float, default=DEFAULT_ERROR_RATIO,
|
||||
help=f"minimum error ratio to flag (default: {DEFAULT_ERROR_RATIO})")
|
||||
parser.add_argument("--full", action="store_true",
|
||||
help="rescan all logs from the start (ignore incremental state)")
|
||||
args = parser.parse_args()
|
||||
|
||||
NpmAnalyzer(
|
||||
log_path=args.log_path,
|
||||
report_dir=args.report_dir,
|
||||
top=args.top,
|
||||
quiet=args.quiet,
|
||||
full=args.full,
|
||||
min_errors=args.min_errors,
|
||||
error_ratio=args.error_ratio,
|
||||
).run()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
+1264
-1264
File diff suppressed because it is too large.
Load diff
+1408
-1408
File diff suppressed because it is too large.
Load diff
+1317
-1317
File diff suppressed because it is too large.
Load diff
+1435
-1435
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -1,21 +1,21 @@
|
||||
2001:4ca0:108:42::24/128
|
||||
2001:ba0:24c:a500::1/128
|
||||
2400:8901::2000:62ff:fe9a:e1c2/128
|
||||
2406:da18:525:0:a23e:e8f6:3ea1:4c2c/128
|
||||
2600:3000::/32
|
||||
2600:3c09::2000:5cff:fe99:c802/128
|
||||
2600:3c15::2000:53ff:fe31:8c0b/128
|
||||
2600:3c15::2000:9cff:fef0:8ad6/128
|
||||
2602:fa59::/40
|
||||
2a00:6340:2008:ec80:64cc:9116:beb2:1931/128
|
||||
2a00:6340:2008:ec80:be24:11ff:fe3b:4058/128
|
||||
2a00:6340:2008:ec80:be24:11ff:fe82:2775/128
|
||||
2a01:2a8:a0dd:1::1012/128
|
||||
2a01:4f8:c014:7f9e::1/128
|
||||
2a04:4e40:e000::/48
|
||||
2a04:c300::/29
|
||||
2a05:4140:3::37cd/128
|
||||
2a09:bac1:76c0:460::5e:6a/128
|
||||
2a09:bac5::/32
|
||||
2a0a:4cc0:2000:8528:c4e8:3ff:febb:3ee9/128
|
||||
2a13:adc0::2ed:89ff:fe58:19c5/128
|
||||
2001:4ca0:108:42::24/128
|
||||
2001:ba0:24c:a500::1/128
|
||||
2400:8901::2000:62ff:fe9a:e1c2/128
|
||||
2406:da18:525:0:a23e:e8f6:3ea1:4c2c/128
|
||||
2600:3000::/32
|
||||
2600:3c09::2000:5cff:fe99:c802/128
|
||||
2600:3c15::2000:53ff:fe31:8c0b/128
|
||||
2600:3c15::2000:9cff:fef0:8ad6/128
|
||||
2602:fa59::/40
|
||||
2a00:6340:2008:ec80:64cc:9116:beb2:1931/128
|
||||
2a00:6340:2008:ec80:be24:11ff:fe3b:4058/128
|
||||
2a00:6340:2008:ec80:be24:11ff:fe82:2775/128
|
||||
2a01:2a8:a0dd:1::1012/128
|
||||
2a01:4f8:c014:7f9e::1/128
|
||||
2a04:4e40:e000::/48
|
||||
2a04:c300::/29
|
||||
2a05:4140:3::37cd/128
|
||||
2a09:bac1:76c0:460::5e:6a/128
|
||||
2a09:bac5::/32
|
||||
2a0a:4cc0:2000:8528:c4e8:3ff:febb:3ee9/128
|
||||
2a13:adc0::2ed:89ff:fe58:19c5/128
|
||||
@@ -1,191 +1,191 @@
|
||||
copyparty log analysis report
|
||||
generated: 2026-08-06T11:51:47
|
||||
|
||||
log path: P:\copyparty
|
||||
log files: 42
|
||||
total requests: 25295
|
||||
unique IPs: 246 (IPv4 202 / IPv6 44)
|
||||
error requests: 6581
|
||||
unique denied paths: 2002
|
||||
denied requests: 6581
|
||||
banned IPs: 26
|
||||
authenticated users: {'admin': 519, 'corky': 78}
|
||||
denied-only ips: 110
|
||||
whitelisted IPs seen: 19
|
||||
block candidates: 112
|
||||
|
||||
== top 30 IPs ==
|
||||
ip total denied banned first last users whitelist
|
||||
------------------------------------------------------------------------------------
|
||||
93.123.109.101 4320 9 4264 00:35:05.539 00:40:32.578 *
|
||||
185.93.89.147 3762 8 0 19:07:14.620 08:52:41.657 *
|
||||
195.178.110.199 1258 621 0 03:02:41.078 03:02:42.924 *
|
||||
45.148.10.67 1258 621 0 20:49:39.003 20:49:41.111 *
|
||||
20.251.48.208 612 306 0 23:50:43.575 17:01:41.376 *
|
||||
20.215.216.94 516 257 0 16:16:39.439 15:21:39.387 *
|
||||
20.215.218.234 504 252 0 02:46:27.628 05:35:25.304 *
|
||||
20.198.120.225 428 214 0 10:07:52.191 10:09:25.008 *
|
||||
18.227.73.7 392 9 363 22:00:31.465 22:01:33.982 *
|
||||
20.197.178.120 374 186 0 14:54:24.411 14:54:52.938 *
|
||||
74.249.245.134 354 177 0 21:27:53.575 21:29:06.182 *
|
||||
20.151.10.161 325 162 0 17:31:38.451 17:32:27.663 *
|
||||
20.205.229.184 323 161 0 12:17:54.322 12:18:41.173 *
|
||||
4.185.41.66 323 161 0 18:18:18.046 18:18:24.319 *
|
||||
52.184.96.217 323 161 0 20:02:55.760 20:03:44.824 *
|
||||
172.213.225.181 321 160 0 13:48:04.161 13:48:11.331 *
|
||||
20.48.236.161 321 160 0 15:11:59.817 15:12:31.060 *
|
||||
158.158.32.229 316 158 0 12:33:51.566 12:34:03.712 *
|
||||
20.63.63.128 315 157 0 16:04:22.373 16:04:50.675 *
|
||||
20.206.67.15 313 156 0 05:56:36.144 05:57:20.412 *
|
||||
20.215.185.25 300 150 0 08:18:05.984 08:19:09.190 *
|
||||
20.203.243.122 294 147 0 03:58:39.580 03:58:55.359 *
|
||||
20.226.26.5 286 143 0 06:33:33.891 06:34:07.483 *
|
||||
3.79.41.12 286 9 263 04:20:16.234 04:20:22.797 *
|
||||
34.242.226.103 286 9 263 06:52:40.299 06:52:54.689 *
|
||||
54.163.186.39 286 9 263 01:39:29.740 01:40:00.874 *
|
||||
16.146.99.254 279 9 256 12:11:20.725 12:12:09.790 *
|
||||
18.142.90.109 279 9 256 17:06:23.216 17:07:15.117 *
|
||||
68.221.130.241 278 139 0 08:28:43.979 08:28:50.496 *
|
||||
74.248.33.172 257 128 0 23:32:36.049 23:32:42.718 *
|
||||
... 216 more IPs omitted
|
||||
|
||||
== top 20 denied paths ==
|
||||
52 /admin.php
|
||||
51 /.env
|
||||
44 /wp-content/plugins/hellopress/wp_filemanager.php
|
||||
44 /this_is_a_new_hello_world.php
|
||||
35 /1.php
|
||||
34 /.git/config
|
||||
33 /classwithtostring.php
|
||||
33 /222.php
|
||||
33 /wp-content/uploads
|
||||
32 /wp-content/admin.php
|
||||
29 /8.php
|
||||
27 /file.php
|
||||
27 /mac.php
|
||||
26 /wp.php
|
||||
26 /edit.php
|
||||
26 /aa.php
|
||||
25 /images.php
|
||||
25 /ops.php
|
||||
24 /f35.php
|
||||
24 /x.php
|
||||
|
||||
== Denied-only IPs (110) ==
|
||||
never authenticated -- ban candidates
|
||||
-- IPv4 (107) --
|
||||
ip total denied banned first last users whitelist
|
||||
------------------------------------------------------------------------------------
|
||||
195.178.110.199 1258 621 0 03:02:41.078 03:02:42.924 *
|
||||
45.148.10.67 1258 621 0 20:49:39.003 20:49:41.111 *
|
||||
20.251.48.208 612 306 0 23:50:43.575 17:01:41.376 *
|
||||
20.215.216.94 516 257 0 16:16:39.439 15:21:39.387 *
|
||||
20.215.218.234 504 252 0 02:46:27.628 05:35:25.304 *
|
||||
20.198.120.225 428 214 0 10:07:52.191 10:09:25.008 *
|
||||
20.197.178.120 374 186 0 14:54:24.411 14:54:52.938 *
|
||||
74.249.245.134 354 177 0 21:27:53.575 21:29:06.182 *
|
||||
20.151.10.161 325 162 0 17:31:38.451 17:32:27.663 *
|
||||
20.205.229.184 323 161 0 12:17:54.322 12:18:41.173 *
|
||||
4.185.41.66 323 161 0 18:18:18.046 18:18:24.319 *
|
||||
52.184.96.217 323 161 0 20:02:55.760 20:03:44.824 *
|
||||
172.213.225.181 321 160 0 13:48:04.161 13:48:11.331 *
|
||||
20.48.236.161 321 160 0 15:11:59.817 15:12:31.060 *
|
||||
158.158.32.229 316 158 0 12:33:51.566 12:34:03.712 *
|
||||
20.63.63.128 315 157 0 16:04:22.373 16:04:50.675 *
|
||||
20.206.67.15 313 156 0 05:56:36.144 05:57:20.412 *
|
||||
20.215.185.25 300 150 0 08:18:05.984 08:19:09.190 *
|
||||
20.203.243.122 294 147 0 03:58:39.580 03:58:55.359 *
|
||||
20.226.26.5 286 143 0 06:33:33.891 06:34:07.483 *
|
||||
68.221.130.241 278 139 0 08:28:43.979 08:28:50.496 *
|
||||
74.248.33.172 257 128 0 23:32:36.049 23:32:42.718 *
|
||||
20.203.179.12 250 125 0 17:33:20.484 17:33:29.742 *
|
||||
20.113.142.140 231 115 0 07:47:47.716 07:48:00.044 *
|
||||
158.158.105.63 208 104 0 11:24:12.912 23:00:49.043 *
|
||||
4.223.71.149 209 104 0 00:26:55.320 00:27:19.244 *
|
||||
135.225.93.215 203 101 0 02:32:24.496 02:32:32.326 *
|
||||
20.9.85.55 203 101 0 15:43:36.450 15:44:20.170 *
|
||||
20.91.208.34 203 101 0 22:07:01.428 22:07:20.883 *
|
||||
52.238.192.78 203 101 0 00:04:31.589 00:05:07.114 *
|
||||
172.213.208.13 192 96 0 13:27:56.743 19:14:00.938 *
|
||||
172.213.244.85 165 82 0 17:01:49.042 17:01:52.331 *
|
||||
20.206.105.145 157 78 0 04:06:08.085 04:06:29.772 *
|
||||
51.120.83.160 144 72 0 15:40:29.699 15:40:39.446 *
|
||||
4.223.73.90 106 53 0 19:50:04.916 19:50:11.164 *
|
||||
20.91.203.45 94 47 0 16:27:01.288 16:27:10.455 *
|
||||
20.197.192.193 88 44 0 13:45:32.377 13:45:43.108 *
|
||||
74.248.24.145 74 37 0 09:21:37.839 09:21:43.127 *
|
||||
172.213.144.209 70 35 0 07:52:16.066 07:52:17.778 *
|
||||
35.198.180.224 46 22 0 14:14:37.617 14:14:48.930 *
|
||||
45.148.10.62 98 22 40 07:53:03.360 03:15:12.651 *
|
||||
45.148.10.244 109 18 70 04:53:37.585 09:56:59.103 *
|
||||
45.148.10.120 33 16 0 14:24:06.542 17:06:11.688 *
|
||||
34.39.210.94 24 12 0 19:31:07.030 19:31:07.101 *
|
||||
195.178.110.31 49 11 20 02:27:56.164 02:27:58.425 *
|
||||
195.178.110.223 37 10 13 01:31:40.464 01:56:49.503 *
|
||||
34.95.239.96 20 10 0 11:25:18.487 11:25:18.532 *
|
||||
136.108.11.195 25 9 7 08:33:11.182 08:33:13.921 *
|
||||
139.59.118.17 180 9 157 08:21:30.247 08:22:03.812 *
|
||||
146.70.40.68 30 9 10 18:55:47.310 18:55:48.145 *
|
||||
147.182.149.75 40 9 21 21:50:17.837 21:50:45.474 *
|
||||
16.146.99.254 279 9 256 12:11:20.725 12:12:09.790 *
|
||||
163.7.11.71 93 9 72 07:24:55.235 07:25:05.144 *
|
||||
167.99.181.249 40 9 21 21:50:26.091 21:51:01.239 *
|
||||
18.142.90.109 279 9 256 17:06:23.216 17:07:15.117 *
|
||||
18.227.73.7 392 9 363 22:00:31.465 22:01:33.982 *
|
||||
207.175.20.232 25 9 7 09:43:00.775 09:43:03.604 *
|
||||
209.99.189.190 77 9 59 17:04:48.190 09:53:52.093 *
|
||||
3.79.41.12 286 9 263 04:20:16.234 04:20:22.797 *
|
||||
34.105.30.251 29 9 9 15:55:43.824 15:55:49.547 *
|
||||
34.23.104.90 25 9 7 14:40:59.025 14:41:01.713 *
|
||||
34.242.226.103 286 9 263 06:52:40.299 06:52:54.689 *
|
||||
45.67.85.190 32 9 11 19:41:44.132 19:41:46.806 *
|
||||
54.163.186.39 286 9 263 01:39:29.740 01:40:00.874 *
|
||||
85.204.70.100 30 9 10 13:55:11.862 13:55:12.567 *
|
||||
91.192.10.86 31 9 10 13:38:54.986 13:38:56.159 *
|
||||
93.123.109.101 4320 9 4264 00:35:05.539 00:40:32.578 *
|
||||
185.93.89.147 3762 8 0 19:07:14.620 08:52:41.657 *
|
||||
195.178.110.155 57 8 0 09:10:16.072 09:10:19.329 *
|
||||
45.148.10.194 58 8 0 15:46:42.822 15:46:45.473 *
|
||||
45.148.10.247 57 8 0 00:58:56.398 00:58:59.599 *
|
||||
72.146.20.230 14 7 0 03:01:31.244 03:01:31.427 *
|
||||
209.99.189.152 13 6 0 18:03:04.845 18:03:12.906 *
|
||||
162.243.79.174 11 5 0 12:20:28.790 12:20:40.350 *
|
||||
51.79.208.246 10 5 0 13:50:27.669 13:50:29.418 *
|
||||
91.92.241.196 11 5 0 13:55:12.175 13:05:16.007 *
|
||||
94.154.43.184 10 5 0 11:23:26.214 09:31:40.319 *
|
||||
195.178.110.211 8 4 0 19:35:03.504 20:22:13.338 *
|
||||
163.7.13.115 5 2 0 14:06:27.842 14:06:29.745 *
|
||||
45.138.16.114 5 2 0 03:09:59.971 03:10:00.217 *
|
||||
45.148.10.95 4 2 0 21:05:26.356 14:40:26.566 *
|
||||
91.92.41.115 8 2 0 14:44:48.975 14:44:54.158 *
|
||||
94.154.43.179 5 2 0 13:27:23.753 04:38:17.921 *
|
||||
107.170.9.103 2 1 0 00:19:26.062 00:19:26.062 *
|
||||
129.212.237.196 2 1 0 09:23:08.470 09:23:08.471 *
|
||||
134.209.162.128 2 1 0 00:43:12.731 00:43:12.731 *
|
||||
157.245.63.62 2 1 0 08:13:33.142 08:13:33.142 *
|
||||
158.101.144.198 2 1 0 14:30:06.125 14:30:06.125 *
|
||||
165.245.185.158 2 1 0 09:20:47.477 09:20:47.477 *
|
||||
195.178.110.159 2 1 0 20:41:43.691 20:41:43.691 *
|
||||
2.57.122.173 2 1 0 12:10:19.177 12:10:19.177 *
|
||||
23.180.120.147 4 1 0 13:53:30.303 13:53:30.473 *
|
||||
31.58.51.184 4 1 0 15:07:53.176 15:07:58.514 *
|
||||
34.125.42.15 2 1 0 21:39:44.709 21:39:44.709 *
|
||||
34.91.243.226 2 1 0 19:51:57.606 19:51:57.606 *
|
||||
35.231.100.82 2 1 0 15:36:23.715 15:36:23.715 *
|
||||
35.233.191.179 2 1 0 00:16:07.188 00:16:07.199 *
|
||||
35.95.56.230 3 1 0 02:29:40.010 02:29:40.562 *
|
||||
43.98.201.177 2 1 0 01:01:05.988 01:01:05.988 *
|
||||
45.139.104.172 2 1 0 03:14:49.950 03:14:49.950 *
|
||||
64.226.123.37 2 1 0 21:33:32.148 21:33:32.148 *
|
||||
8.229.130.50 2 1 0 19:23:37.001 19:23:37.002 *
|
||||
93.123.109.167 2 1 0 04:39:35.474 04:39:35.474 *
|
||||
94.154.43.183 3 1 0 21:50:39.582 00:01:42.127 *
|
||||
94.154.43.185 3 1 0 01:40:53.903 04:02:34.085 *
|
||||
94.154.43.186 3 1 0 21:07:26.439 13:43:18.923 *
|
||||
94.154.43.188 5 1 0 02:45:01.636 11:09:54.264 *
|
||||
-- IPv6 (3) --
|
||||
ip total denied banned first last users whitelist
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
2a04:4e40:e000:0:d09:97ab:43b1:a59a 4 2 0 14:41:30.905 14:41:30.922 *
|
||||
2600:3c15::2000:53ff:fe31:8c0b 2 1 0 12:35:18.643 12:35:18.643 *
|
||||
2602:fa59:10:a3a::1 2 1 0 02:10:02.531 02:10:02.532 *
|
||||
copyparty log analysis report
|
||||
generated: 2026-08-06T11:51:47
|
||||
|
||||
log path: P:\copyparty
|
||||
log files: 42
|
||||
total requests: 25295
|
||||
unique IPs: 246 (IPv4 202 / IPv6 44)
|
||||
error requests: 6581
|
||||
unique denied paths: 2002
|
||||
denied requests: 6581
|
||||
banned IPs: 26
|
||||
authenticated users: {'admin': 519, 'corky': 78}
|
||||
denied-only ips: 110
|
||||
whitelisted IPs seen: 19
|
||||
block candidates: 112
|
||||
|
||||
== top 30 IPs ==
|
||||
ip total denied banned first last users whitelist
|
||||
------------------------------------------------------------------------------------
|
||||
93.123.109.101 4320 9 4264 00:35:05.539 00:40:32.578 *
|
||||
185.93.89.147 3762 8 0 19:07:14.620 08:52:41.657 *
|
||||
195.178.110.199 1258 621 0 03:02:41.078 03:02:42.924 *
|
||||
45.148.10.67 1258 621 0 20:49:39.003 20:49:41.111 *
|
||||
20.251.48.208 612 306 0 23:50:43.575 17:01:41.376 *
|
||||
20.215.216.94 516 257 0 16:16:39.439 15:21:39.387 *
|
||||
20.215.218.234 504 252 0 02:46:27.628 05:35:25.304 *
|
||||
20.198.120.225 428 214 0 10:07:52.191 10:09:25.008 *
|
||||
18.227.73.7 392 9 363 22:00:31.465 22:01:33.982 *
|
||||
20.197.178.120 374 186 0 14:54:24.411 14:54:52.938 *
|
||||
74.249.245.134 354 177 0 21:27:53.575 21:29:06.182 *
|
||||
20.151.10.161 325 162 0 17:31:38.451 17:32:27.663 *
|
||||
20.205.229.184 323 161 0 12:17:54.322 12:18:41.173 *
|
||||
4.185.41.66 323 161 0 18:18:18.046 18:18:24.319 *
|
||||
52.184.96.217 323 161 0 20:02:55.760 20:03:44.824 *
|
||||
172.213.225.181 321 160 0 13:48:04.161 13:48:11.331 *
|
||||
20.48.236.161 321 160 0 15:11:59.817 15:12:31.060 *
|
||||
158.158.32.229 316 158 0 12:33:51.566 12:34:03.712 *
|
||||
20.63.63.128 315 157 0 16:04:22.373 16:04:50.675 *
|
||||
20.206.67.15 313 156 0 05:56:36.144 05:57:20.412 *
|
||||
20.215.185.25 300 150 0 08:18:05.984 08:19:09.190 *
|
||||
20.203.243.122 294 147 0 03:58:39.580 03:58:55.359 *
|
||||
20.226.26.5 286 143 0 06:33:33.891 06:34:07.483 *
|
||||
3.79.41.12 286 9 263 04:20:16.234 04:20:22.797 *
|
||||
34.242.226.103 286 9 263 06:52:40.299 06:52:54.689 *
|
||||
54.163.186.39 286 9 263 01:39:29.740 01:40:00.874 *
|
||||
16.146.99.254 279 9 256 12:11:20.725 12:12:09.790 *
|
||||
18.142.90.109 279 9 256 17:06:23.216 17:07:15.117 *
|
||||
68.221.130.241 278 139 0 08:28:43.979 08:28:50.496 *
|
||||
74.248.33.172 257 128 0 23:32:36.049 23:32:42.718 *
|
||||
... 216 more IPs omitted
|
||||
|
||||
== top 20 denied paths ==
|
||||
52 /admin.php
|
||||
51 /.env
|
||||
44 /wp-content/plugins/hellopress/wp_filemanager.php
|
||||
44 /this_is_a_new_hello_world.php
|
||||
35 /1.php
|
||||
34 /.git/config
|
||||
33 /classwithtostring.php
|
||||
33 /222.php
|
||||
33 /wp-content/uploads
|
||||
32 /wp-content/admin.php
|
||||
29 /8.php
|
||||
27 /file.php
|
||||
27 /mac.php
|
||||
26 /wp.php
|
||||
26 /edit.php
|
||||
26 /aa.php
|
||||
25 /images.php
|
||||
25 /ops.php
|
||||
24 /f35.php
|
||||
24 /x.php
|
||||
|
||||
== Denied-only IPs (110) ==
|
||||
never authenticated -- ban candidates
|
||||
-- IPv4 (107) --
|
||||
ip total denied banned first last users whitelist
|
||||
------------------------------------------------------------------------------------
|
||||
195.178.110.199 1258 621 0 03:02:41.078 03:02:42.924 *
|
||||
45.148.10.67 1258 621 0 20:49:39.003 20:49:41.111 *
|
||||
20.251.48.208 612 306 0 23:50:43.575 17:01:41.376 *
|
||||
20.215.216.94 516 257 0 16:16:39.439 15:21:39.387 *
|
||||
20.215.218.234 504 252 0 02:46:27.628 05:35:25.304 *
|
||||
20.198.120.225 428 214 0 10:07:52.191 10:09:25.008 *
|
||||
20.197.178.120 374 186 0 14:54:24.411 14:54:52.938 *
|
||||
74.249.245.134 354 177 0 21:27:53.575 21:29:06.182 *
|
||||
20.151.10.161 325 162 0 17:31:38.451 17:32:27.663 *
|
||||
20.205.229.184 323 161 0 12:17:54.322 12:18:41.173 *
|
||||
4.185.41.66 323 161 0 18:18:18.046 18:18:24.319 *
|
||||
52.184.96.217 323 161 0 20:02:55.760 20:03:44.824 *
|
||||
172.213.225.181 321 160 0 13:48:04.161 13:48:11.331 *
|
||||
20.48.236.161 321 160 0 15:11:59.817 15:12:31.060 *
|
||||
158.158.32.229 316 158 0 12:33:51.566 12:34:03.712 *
|
||||
20.63.63.128 315 157 0 16:04:22.373 16:04:50.675 *
|
||||
20.206.67.15 313 156 0 05:56:36.144 05:57:20.412 *
|
||||
20.215.185.25 300 150 0 08:18:05.984 08:19:09.190 *
|
||||
20.203.243.122 294 147 0 03:58:39.580 03:58:55.359 *
|
||||
20.226.26.5 286 143 0 06:33:33.891 06:34:07.483 *
|
||||
68.221.130.241 278 139 0 08:28:43.979 08:28:50.496 *
|
||||
74.248.33.172 257 128 0 23:32:36.049 23:32:42.718 *
|
||||
20.203.179.12 250 125 0 17:33:20.484 17:33:29.742 *
|
||||
20.113.142.140 231 115 0 07:47:47.716 07:48:00.044 *
|
||||
158.158.105.63 208 104 0 11:24:12.912 23:00:49.043 *
|
||||
4.223.71.149 209 104 0 00:26:55.320 00:27:19.244 *
|
||||
135.225.93.215 203 101 0 02:32:24.496 02:32:32.326 *
|
||||
20.9.85.55 203 101 0 15:43:36.450 15:44:20.170 *
|
||||
20.91.208.34 203 101 0 22:07:01.428 22:07:20.883 *
|
||||
52.238.192.78 203 101 0 00:04:31.589 00:05:07.114 *
|
||||
172.213.208.13 192 96 0 13:27:56.743 19:14:00.938 *
|
||||
172.213.244.85 165 82 0 17:01:49.042 17:01:52.331 *
|
||||
20.206.105.145 157 78 0 04:06:08.085 04:06:29.772 *
|
||||
51.120.83.160 144 72 0 15:40:29.699 15:40:39.446 *
|
||||
4.223.73.90 106 53 0 19:50:04.916 19:50:11.164 *
|
||||
20.91.203.45 94 47 0 16:27:01.288 16:27:10.455 *
|
||||
20.197.192.193 88 44 0 13:45:32.377 13:45:43.108 *
|
||||
74.248.24.145 74 37 0 09:21:37.839 09:21:43.127 *
|
||||
172.213.144.209 70 35 0 07:52:16.066 07:52:17.778 *
|
||||
35.198.180.224 46 22 0 14:14:37.617 14:14:48.930 *
|
||||
45.148.10.62 98 22 40 07:53:03.360 03:15:12.651 *
|
||||
45.148.10.244 109 18 70 04:53:37.585 09:56:59.103 *
|
||||
45.148.10.120 33 16 0 14:24:06.542 17:06:11.688 *
|
||||
34.39.210.94 24 12 0 19:31:07.030 19:31:07.101 *
|
||||
195.178.110.31 49 11 20 02:27:56.164 02:27:58.425 *
|
||||
195.178.110.223 37 10 13 01:31:40.464 01:56:49.503 *
|
||||
34.95.239.96 20 10 0 11:25:18.487 11:25:18.532 *
|
||||
136.108.11.195 25 9 7 08:33:11.182 08:33:13.921 *
|
||||
139.59.118.17 180 9 157 08:21:30.247 08:22:03.812 *
|
||||
146.70.40.68 30 9 10 18:55:47.310 18:55:48.145 *
|
||||
147.182.149.75 40 9 21 21:50:17.837 21:50:45.474 *
|
||||
16.146.99.254 279 9 256 12:11:20.725 12:12:09.790 *
|
||||
163.7.11.71 93 9 72 07:24:55.235 07:25:05.144 *
|
||||
167.99.181.249 40 9 21 21:50:26.091 21:51:01.239 *
|
||||
18.142.90.109 279 9 256 17:06:23.216 17:07:15.117 *
|
||||
18.227.73.7 392 9 363 22:00:31.465 22:01:33.982 *
|
||||
207.175.20.232 25 9 7 09:43:00.775 09:43:03.604 *
|
||||
209.99.189.190 77 9 59 17:04:48.190 09:53:52.093 *
|
||||
3.79.41.12 286 9 263 04:20:16.234 04:20:22.797 *
|
||||
34.105.30.251 29 9 9 15:55:43.824 15:55:49.547 *
|
||||
34.23.104.90 25 9 7 14:40:59.025 14:41:01.713 *
|
||||
34.242.226.103 286 9 263 06:52:40.299 06:52:54.689 *
|
||||
45.67.85.190 32 9 11 19:41:44.132 19:41:46.806 *
|
||||
54.163.186.39 286 9 263 01:39:29.740 01:40:00.874 *
|
||||
85.204.70.100 30 9 10 13:55:11.862 13:55:12.567 *
|
||||
91.192.10.86 31 9 10 13:38:54.986 13:38:56.159 *
|
||||
93.123.109.101 4320 9 4264 00:35:05.539 00:40:32.578 *
|
||||
185.93.89.147 3762 8 0 19:07:14.620 08:52:41.657 *
|
||||
195.178.110.155 57 8 0 09:10:16.072 09:10:19.329 *
|
||||
45.148.10.194 58 8 0 15:46:42.822 15:46:45.473 *
|
||||
45.148.10.247 57 8 0 00:58:56.398 00:58:59.599 *
|
||||
72.146.20.230 14 7 0 03:01:31.244 03:01:31.427 *
|
||||
209.99.189.152 13 6 0 18:03:04.845 18:03:12.906 *
|
||||
162.243.79.174 11 5 0 12:20:28.790 12:20:40.350 *
|
||||
51.79.208.246 10 5 0 13:50:27.669 13:50:29.418 *
|
||||
91.92.241.196 11 5 0 13:55:12.175 13:05:16.007 *
|
||||
94.154.43.184 10 5 0 11:23:26.214 09:31:40.319 *
|
||||
195.178.110.211 8 4 0 19:35:03.504 20:22:13.338 *
|
||||
163.7.13.115 5 2 0 14:06:27.842 14:06:29.745 *
|
||||
45.138.16.114 5 2 0 03:09:59.971 03:10:00.217 *
|
||||
45.148.10.95 4 2 0 21:05:26.356 14:40:26.566 *
|
||||
91.92.41.115 8 2 0 14:44:48.975 14:44:54.158 *
|
||||
94.154.43.179 5 2 0 13:27:23.753 04:38:17.921 *
|
||||
107.170.9.103 2 1 0 00:19:26.062 00:19:26.062 *
|
||||
129.212.237.196 2 1 0 09:23:08.470 09:23:08.471 *
|
||||
134.209.162.128 2 1 0 00:43:12.731 00:43:12.731 *
|
||||
157.245.63.62 2 1 0 08:13:33.142 08:13:33.142 *
|
||||
158.101.144.198 2 1 0 14:30:06.125 14:30:06.125 *
|
||||
165.245.185.158 2 1 0 09:20:47.477 09:20:47.477 *
|
||||
195.178.110.159 2 1 0 20:41:43.691 20:41:43.691 *
|
||||
2.57.122.173 2 1 0 12:10:19.177 12:10:19.177 *
|
||||
23.180.120.147 4 1 0 13:53:30.303 13:53:30.473 *
|
||||
31.58.51.184 4 1 0 15:07:53.176 15:07:58.514 *
|
||||
34.125.42.15 2 1 0 21:39:44.709 21:39:44.709 *
|
||||
34.91.243.226 2 1 0 19:51:57.606 19:51:57.606 *
|
||||
35.231.100.82 2 1 0 15:36:23.715 15:36:23.715 *
|
||||
35.233.191.179 2 1 0 00:16:07.188 00:16:07.199 *
|
||||
35.95.56.230 3 1 0 02:29:40.010 02:29:40.562 *
|
||||
43.98.201.177 2 1 0 01:01:05.988 01:01:05.988 *
|
||||
45.139.104.172 2 1 0 03:14:49.950 03:14:49.950 *
|
||||
64.226.123.37 2 1 0 21:33:32.148 21:33:32.148 *
|
||||
8.229.130.50 2 1 0 19:23:37.001 19:23:37.002 *
|
||||
93.123.109.167 2 1 0 04:39:35.474 04:39:35.474 *
|
||||
94.154.43.183 3 1 0 21:50:39.582 00:01:42.127 *
|
||||
94.154.43.185 3 1 0 01:40:53.903 04:02:34.085 *
|
||||
94.154.43.186 3 1 0 21:07:26.439 13:43:18.923 *
|
||||
94.154.43.188 5 1 0 02:45:01.636 11:09:54.264 *
|
||||
-- IPv6 (3) --
|
||||
ip total denied banned first last users whitelist
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
2a04:4e40:e000:0:d09:97ab:43b1:a59a 4 2 0 14:41:30.905 14:41:30.922 *
|
||||
2600:3c15::2000:53ff:fe31:8c0b 2 1 0 12:35:18.643 12:35:18.643 *
|
||||
2602:fa59:10:a3a::1 2 1 0 02:10:02.531 02:10:02.532 *
|
||||
@@ -1,24 +1,24 @@
|
||||
copyparty log analysis report
|
||||
generated: 2026-08-06T13:03:30
|
||||
|
||||
log path: P:\copyparty
|
||||
log files: 42
|
||||
total requests: 0
|
||||
unique IPs: 0 (IPv4 0 / IPv6 0)
|
||||
error requests: 0
|
||||
unique denied paths: 0
|
||||
denied requests: 0
|
||||
banned IPs: 0
|
||||
authenticated users: {}
|
||||
denied-only ips: 0
|
||||
whitelisted IPs seen: 0
|
||||
block candidates: 0
|
||||
|
||||
== top 30 IPs ==
|
||||
ip total denied banned first last users whitelist
|
||||
--------------------------------------------------------
|
||||
|
||||
== top 20 denied paths ==
|
||||
|
||||
== Denied-only IPs (0) ==
|
||||
never authenticated -- ban candidates
|
||||
copyparty log analysis report
|
||||
generated: 2026-08-06T13:03:30
|
||||
|
||||
log path: P:\copyparty
|
||||
log files: 42
|
||||
total requests: 0
|
||||
unique IPs: 0 (IPv4 0 / IPv6 0)
|
||||
error requests: 0
|
||||
unique denied paths: 0
|
||||
denied requests: 0
|
||||
banned IPs: 0
|
||||
authenticated users: {}
|
||||
denied-only ips: 0
|
||||
whitelisted IPs seen: 0
|
||||
block candidates: 0
|
||||
|
||||
== top 30 IPs ==
|
||||
ip total denied banned first last users whitelist
|
||||
--------------------------------------------------------
|
||||
|
||||
== top 20 denied paths ==
|
||||
|
||||
== Denied-only IPs (0) ==
|
||||
never authenticated -- ban candidates
|
||||
@@ -1,191 +1,191 @@
|
||||
copyparty log analysis report
|
||||
generated: 2026-08-06T13:21:41
|
||||
|
||||
log path: P:\copyparty
|
||||
log files: 42
|
||||
total requests: 25295
|
||||
unique IPs: 246 (IPv4 202 / IPv6 44)
|
||||
error requests: 6581
|
||||
unique denied paths: 2002
|
||||
denied requests: 6581
|
||||
banned IPs: 26
|
||||
authenticated users: {'admin': 519, 'corky': 78}
|
||||
denied-only ips: 110
|
||||
whitelisted IPs seen: 19
|
||||
block candidates: 112
|
||||
|
||||
== top 30 IPs ==
|
||||
ip total denied banned first last users whitelist
|
||||
------------------------------------------------------------------------------------
|
||||
93.123.109.101 4320 9 4264 00:35:05.539 00:40:32.578 *
|
||||
185.93.89.147 3762 8 0 19:07:14.620 08:52:41.657 *
|
||||
195.178.110.199 1258 621 0 03:02:41.078 03:02:42.924 *
|
||||
45.148.10.67 1258 621 0 20:49:39.003 20:49:41.111 *
|
||||
20.251.48.208 612 306 0 23:50:43.575 17:01:41.376 *
|
||||
20.215.216.94 516 257 0 16:16:39.439 15:21:39.387 *
|
||||
20.215.218.234 504 252 0 02:46:27.628 05:35:25.304 *
|
||||
20.198.120.225 428 214 0 10:07:52.191 10:09:25.008 *
|
||||
18.227.73.7 392 9 363 22:00:31.465 22:01:33.982 *
|
||||
20.197.178.120 374 186 0 14:54:24.411 14:54:52.938 *
|
||||
74.249.245.134 354 177 0 21:27:53.575 21:29:06.182 *
|
||||
20.151.10.161 325 162 0 17:31:38.451 17:32:27.663 *
|
||||
20.205.229.184 323 161 0 12:17:54.322 12:18:41.173 *
|
||||
4.185.41.66 323 161 0 18:18:18.046 18:18:24.319 *
|
||||
52.184.96.217 323 161 0 20:02:55.760 20:03:44.824 *
|
||||
172.213.225.181 321 160 0 13:48:04.161 13:48:11.331 *
|
||||
20.48.236.161 321 160 0 15:11:59.817 15:12:31.060 *
|
||||
158.158.32.229 316 158 0 12:33:51.566 12:34:03.712 *
|
||||
20.63.63.128 315 157 0 16:04:22.373 16:04:50.675 *
|
||||
20.206.67.15 313 156 0 05:56:36.144 05:57:20.412 *
|
||||
20.215.185.25 300 150 0 08:18:05.984 08:19:09.190 *
|
||||
20.203.243.122 294 147 0 03:58:39.580 03:58:55.359 *
|
||||
20.226.26.5 286 143 0 06:33:33.891 06:34:07.483 *
|
||||
3.79.41.12 286 9 263 04:20:16.234 04:20:22.797 *
|
||||
34.242.226.103 286 9 263 06:52:40.299 06:52:54.689 *
|
||||
54.163.186.39 286 9 263 01:39:29.740 01:40:00.874 *
|
||||
16.146.99.254 279 9 256 12:11:20.725 12:12:09.790 *
|
||||
18.142.90.109 279 9 256 17:06:23.216 17:07:15.117 *
|
||||
68.221.130.241 278 139 0 08:28:43.979 08:28:50.496 *
|
||||
74.248.33.172 257 128 0 23:32:36.049 23:32:42.718 *
|
||||
... 216 more IPs omitted
|
||||
|
||||
== top 20 denied paths ==
|
||||
52 /admin.php
|
||||
51 /.env
|
||||
44 /wp-content/plugins/hellopress/wp_filemanager.php
|
||||
44 /this_is_a_new_hello_world.php
|
||||
35 /1.php
|
||||
34 /.git/config
|
||||
33 /classwithtostring.php
|
||||
33 /222.php
|
||||
33 /wp-content/uploads
|
||||
32 /wp-content/admin.php
|
||||
29 /8.php
|
||||
27 /file.php
|
||||
27 /mac.php
|
||||
26 /wp.php
|
||||
26 /edit.php
|
||||
26 /aa.php
|
||||
25 /images.php
|
||||
25 /ops.php
|
||||
24 /f35.php
|
||||
24 /x.php
|
||||
|
||||
== Denied-only IPs (110) ==
|
||||
never authenticated -- ban candidates
|
||||
-- IPv4 (107) --
|
||||
ip total denied banned first last users whitelist
|
||||
------------------------------------------------------------------------------------
|
||||
195.178.110.199 1258 621 0 03:02:41.078 03:02:42.924 *
|
||||
45.148.10.67 1258 621 0 20:49:39.003 20:49:41.111 *
|
||||
20.251.48.208 612 306 0 23:50:43.575 17:01:41.376 *
|
||||
20.215.216.94 516 257 0 16:16:39.439 15:21:39.387 *
|
||||
20.215.218.234 504 252 0 02:46:27.628 05:35:25.304 *
|
||||
20.198.120.225 428 214 0 10:07:52.191 10:09:25.008 *
|
||||
20.197.178.120 374 186 0 14:54:24.411 14:54:52.938 *
|
||||
74.249.245.134 354 177 0 21:27:53.575 21:29:06.182 *
|
||||
20.151.10.161 325 162 0 17:31:38.451 17:32:27.663 *
|
||||
20.205.229.184 323 161 0 12:17:54.322 12:18:41.173 *
|
||||
4.185.41.66 323 161 0 18:18:18.046 18:18:24.319 *
|
||||
52.184.96.217 323 161 0 20:02:55.760 20:03:44.824 *
|
||||
172.213.225.181 321 160 0 13:48:04.161 13:48:11.331 *
|
||||
20.48.236.161 321 160 0 15:11:59.817 15:12:31.060 *
|
||||
158.158.32.229 316 158 0 12:33:51.566 12:34:03.712 *
|
||||
20.63.63.128 315 157 0 16:04:22.373 16:04:50.675 *
|
||||
20.206.67.15 313 156 0 05:56:36.144 05:57:20.412 *
|
||||
20.215.185.25 300 150 0 08:18:05.984 08:19:09.190 *
|
||||
20.203.243.122 294 147 0 03:58:39.580 03:58:55.359 *
|
||||
20.226.26.5 286 143 0 06:33:33.891 06:34:07.483 *
|
||||
68.221.130.241 278 139 0 08:28:43.979 08:28:50.496 *
|
||||
74.248.33.172 257 128 0 23:32:36.049 23:32:42.718 *
|
||||
20.203.179.12 250 125 0 17:33:20.484 17:33:29.742 *
|
||||
20.113.142.140 231 115 0 07:47:47.716 07:48:00.044 *
|
||||
158.158.105.63 208 104 0 11:24:12.912 23:00:49.043 *
|
||||
4.223.71.149 209 104 0 00:26:55.320 00:27:19.244 *
|
||||
135.225.93.215 203 101 0 02:32:24.496 02:32:32.326 *
|
||||
20.9.85.55 203 101 0 15:43:36.450 15:44:20.170 *
|
||||
20.91.208.34 203 101 0 22:07:01.428 22:07:20.883 *
|
||||
52.238.192.78 203 101 0 00:04:31.589 00:05:07.114 *
|
||||
172.213.208.13 192 96 0 13:27:56.743 19:14:00.938 *
|
||||
172.213.244.85 165 82 0 17:01:49.042 17:01:52.331 *
|
||||
20.206.105.145 157 78 0 04:06:08.085 04:06:29.772 *
|
||||
51.120.83.160 144 72 0 15:40:29.699 15:40:39.446 *
|
||||
4.223.73.90 106 53 0 19:50:04.916 19:50:11.164 *
|
||||
20.91.203.45 94 47 0 16:27:01.288 16:27:10.455 *
|
||||
20.197.192.193 88 44 0 13:45:32.377 13:45:43.108 *
|
||||
74.248.24.145 74 37 0 09:21:37.839 09:21:43.127 *
|
||||
172.213.144.209 70 35 0 07:52:16.066 07:52:17.778 *
|
||||
35.198.180.224 46 22 0 14:14:37.617 14:14:48.930 *
|
||||
45.148.10.62 98 22 40 07:53:03.360 03:15:12.651 *
|
||||
45.148.10.244 109 18 70 04:53:37.585 09:56:59.103 *
|
||||
45.148.10.120 33 16 0 14:24:06.542 17:06:11.688 *
|
||||
34.39.210.94 24 12 0 19:31:07.030 19:31:07.101 *
|
||||
195.178.110.31 49 11 20 02:27:56.164 02:27:58.425 *
|
||||
195.178.110.223 37 10 13 01:31:40.464 01:56:49.503 *
|
||||
34.95.239.96 20 10 0 11:25:18.487 11:25:18.532 *
|
||||
136.108.11.195 25 9 7 08:33:11.182 08:33:13.921 *
|
||||
139.59.118.17 180 9 157 08:21:30.247 08:22:03.812 *
|
||||
146.70.40.68 30 9 10 18:55:47.310 18:55:48.145 *
|
||||
147.182.149.75 40 9 21 21:50:17.837 21:50:45.474 *
|
||||
16.146.99.254 279 9 256 12:11:20.725 12:12:09.790 *
|
||||
163.7.11.71 93 9 72 07:24:55.235 07:25:05.144 *
|
||||
167.99.181.249 40 9 21 21:50:26.091 21:51:01.239 *
|
||||
18.142.90.109 279 9 256 17:06:23.216 17:07:15.117 *
|
||||
18.227.73.7 392 9 363 22:00:31.465 22:01:33.982 *
|
||||
207.175.20.232 25 9 7 09:43:00.775 09:43:03.604 *
|
||||
209.99.189.190 77 9 59 17:04:48.190 09:53:52.093 *
|
||||
3.79.41.12 286 9 263 04:20:16.234 04:20:22.797 *
|
||||
34.105.30.251 29 9 9 15:55:43.824 15:55:49.547 *
|
||||
34.23.104.90 25 9 7 14:40:59.025 14:41:01.713 *
|
||||
34.242.226.103 286 9 263 06:52:40.299 06:52:54.689 *
|
||||
45.67.85.190 32 9 11 19:41:44.132 19:41:46.806 *
|
||||
54.163.186.39 286 9 263 01:39:29.740 01:40:00.874 *
|
||||
85.204.70.100 30 9 10 13:55:11.862 13:55:12.567 *
|
||||
91.192.10.86 31 9 10 13:38:54.986 13:38:56.159 *
|
||||
93.123.109.101 4320 9 4264 00:35:05.539 00:40:32.578 *
|
||||
185.93.89.147 3762 8 0 19:07:14.620 08:52:41.657 *
|
||||
195.178.110.155 57 8 0 09:10:16.072 09:10:19.329 *
|
||||
45.148.10.194 58 8 0 15:46:42.822 15:46:45.473 *
|
||||
45.148.10.247 57 8 0 00:58:56.398 00:58:59.599 *
|
||||
72.146.20.230 14 7 0 03:01:31.244 03:01:31.427 *
|
||||
209.99.189.152 13 6 0 18:03:04.845 18:03:12.906 *
|
||||
162.243.79.174 11 5 0 12:20:28.790 12:20:40.350 *
|
||||
51.79.208.246 10 5 0 13:50:27.669 13:50:29.418 *
|
||||
91.92.241.196 11 5 0 13:55:12.175 13:05:16.007 *
|
||||
94.154.43.184 10 5 0 11:23:26.214 09:31:40.319 *
|
||||
195.178.110.211 8 4 0 19:35:03.504 20:22:13.338 *
|
||||
163.7.13.115 5 2 0 14:06:27.842 14:06:29.745 *
|
||||
45.138.16.114 5 2 0 03:09:59.971 03:10:00.217 *
|
||||
45.148.10.95 4 2 0 21:05:26.356 14:40:26.566 *
|
||||
91.92.41.115 8 2 0 14:44:48.975 14:44:54.158 *
|
||||
94.154.43.179 5 2 0 13:27:23.753 04:38:17.921 *
|
||||
107.170.9.103 2 1 0 00:19:26.062 00:19:26.062 *
|
||||
129.212.237.196 2 1 0 09:23:08.470 09:23:08.471 *
|
||||
134.209.162.128 2 1 0 00:43:12.731 00:43:12.731 *
|
||||
157.245.63.62 2 1 0 08:13:33.142 08:13:33.142 *
|
||||
158.101.144.198 2 1 0 14:30:06.125 14:30:06.125 *
|
||||
165.245.185.158 2 1 0 09:20:47.477 09:20:47.477 *
|
||||
195.178.110.159 2 1 0 20:41:43.691 20:41:43.691 *
|
||||
2.57.122.173 2 1 0 12:10:19.177 12:10:19.177 *
|
||||
23.180.120.147 4 1 0 13:53:30.303 13:53:30.473 *
|
||||
31.58.51.184 4 1 0 15:07:53.176 15:07:58.514 *
|
||||
34.125.42.15 2 1 0 21:39:44.709 21:39:44.709 *
|
||||
34.91.243.226 2 1 0 19:51:57.606 19:51:57.606 *
|
||||
35.231.100.82 2 1 0 15:36:23.715 15:36:23.715 *
|
||||
35.233.191.179 2 1 0 00:16:07.188 00:16:07.199 *
|
||||
35.95.56.230 3 1 0 02:29:40.010 02:29:40.562 *
|
||||
43.98.201.177 2 1 0 01:01:05.988 01:01:05.988 *
|
||||
45.139.104.172 2 1 0 03:14:49.950 03:14:49.950 *
|
||||
64.226.123.37 2 1 0 21:33:32.148 21:33:32.148 *
|
||||
8.229.130.50 2 1 0 19:23:37.001 19:23:37.002 *
|
||||
93.123.109.167 2 1 0 04:39:35.474 04:39:35.474 *
|
||||
94.154.43.183 3 1 0 21:50:39.582 00:01:42.127 *
|
||||
94.154.43.185 3 1 0 01:40:53.903 04:02:34.085 *
|
||||
94.154.43.186 3 1 0 21:07:26.439 13:43:18.923 *
|
||||
94.154.43.188 5 1 0 02:45:01.636 11:09:54.264 *
|
||||
-- IPv6 (3) --
|
||||
ip total denied banned first last users whitelist
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
2a04:4e40:e000:0:d09:97ab:43b1:a59a 4 2 0 14:41:30.905 14:41:30.922 *
|
||||
2600:3c15::2000:53ff:fe31:8c0b 2 1 0 12:35:18.643 12:35:18.643 *
|
||||
2602:fa59:10:a3a::1 2 1 0 02:10:02.531 02:10:02.532 *
|
||||
copyparty log analysis report
|
||||
generated: 2026-08-06T13:21:41
|
||||
|
||||
log path: P:\copyparty
|
||||
log files: 42
|
||||
total requests: 25295
|
||||
unique IPs: 246 (IPv4 202 / IPv6 44)
|
||||
error requests: 6581
|
||||
unique denied paths: 2002
|
||||
denied requests: 6581
|
||||
banned IPs: 26
|
||||
authenticated users: {'admin': 519, 'corky': 78}
|
||||
denied-only ips: 110
|
||||
whitelisted IPs seen: 19
|
||||
block candidates: 112
|
||||
|
||||
== top 30 IPs ==
|
||||
ip total denied banned first last users whitelist
|
||||
------------------------------------------------------------------------------------
|
||||
93.123.109.101 4320 9 4264 00:35:05.539 00:40:32.578 *
|
||||
185.93.89.147 3762 8 0 19:07:14.620 08:52:41.657 *
|
||||
195.178.110.199 1258 621 0 03:02:41.078 03:02:42.924 *
|
||||
45.148.10.67 1258 621 0 20:49:39.003 20:49:41.111 *
|
||||
20.251.48.208 612 306 0 23:50:43.575 17:01:41.376 *
|
||||
20.215.216.94 516 257 0 16:16:39.439 15:21:39.387 *
|
||||
20.215.218.234 504 252 0 02:46:27.628 05:35:25.304 *
|
||||
20.198.120.225 428 214 0 10:07:52.191 10:09:25.008 *
|
||||
18.227.73.7 392 9 363 22:00:31.465 22:01:33.982 *
|
||||
20.197.178.120 374 186 0 14:54:24.411 14:54:52.938 *
|
||||
74.249.245.134 354 177 0 21:27:53.575 21:29:06.182 *
|
||||
20.151.10.161 325 162 0 17:31:38.451 17:32:27.663 *
|
||||
20.205.229.184 323 161 0 12:17:54.322 12:18:41.173 *
|
||||
4.185.41.66 323 161 0 18:18:18.046 18:18:24.319 *
|
||||
52.184.96.217 323 161 0 20:02:55.760 20:03:44.824 *
|
||||
172.213.225.181 321 160 0 13:48:04.161 13:48:11.331 *
|
||||
20.48.236.161 321 160 0 15:11:59.817 15:12:31.060 *
|
||||
158.158.32.229 316 158 0 12:33:51.566 12:34:03.712 *
|
||||
20.63.63.128 315 157 0 16:04:22.373 16:04:50.675 *
|
||||
20.206.67.15 313 156 0 05:56:36.144 05:57:20.412 *
|
||||
20.215.185.25 300 150 0 08:18:05.984 08:19:09.190 *
|
||||
20.203.243.122 294 147 0 03:58:39.580 03:58:55.359 *
|
||||
20.226.26.5 286 143 0 06:33:33.891 06:34:07.483 *
|
||||
3.79.41.12 286 9 263 04:20:16.234 04:20:22.797 *
|
||||
34.242.226.103 286 9 263 06:52:40.299 06:52:54.689 *
|
||||
54.163.186.39 286 9 263 01:39:29.740 01:40:00.874 *
|
||||
16.146.99.254 279 9 256 12:11:20.725 12:12:09.790 *
|
||||
18.142.90.109 279 9 256 17:06:23.216 17:07:15.117 *
|
||||
68.221.130.241 278 139 0 08:28:43.979 08:28:50.496 *
|
||||
74.248.33.172 257 128 0 23:32:36.049 23:32:42.718 *
|
||||
... 216 more IPs omitted
|
||||
|
||||
== top 20 denied paths ==
|
||||
52 /admin.php
|
||||
51 /.env
|
||||
44 /wp-content/plugins/hellopress/wp_filemanager.php
|
||||
44 /this_is_a_new_hello_world.php
|
||||
35 /1.php
|
||||
34 /.git/config
|
||||
33 /classwithtostring.php
|
||||
33 /222.php
|
||||
33 /wp-content/uploads
|
||||
32 /wp-content/admin.php
|
||||
29 /8.php
|
||||
27 /file.php
|
||||
27 /mac.php
|
||||
26 /wp.php
|
||||
26 /edit.php
|
||||
26 /aa.php
|
||||
25 /images.php
|
||||
25 /ops.php
|
||||
24 /f35.php
|
||||
24 /x.php
|
||||
|
||||
== Denied-only IPs (110) ==
|
||||
never authenticated -- ban candidates
|
||||
-- IPv4 (107) --
|
||||
ip total denied banned first last users whitelist
|
||||
------------------------------------------------------------------------------------
|
||||
195.178.110.199 1258 621 0 03:02:41.078 03:02:42.924 *
|
||||
45.148.10.67 1258 621 0 20:49:39.003 20:49:41.111 *
|
||||
20.251.48.208 612 306 0 23:50:43.575 17:01:41.376 *
|
||||
20.215.216.94 516 257 0 16:16:39.439 15:21:39.387 *
|
||||
20.215.218.234 504 252 0 02:46:27.628 05:35:25.304 *
|
||||
20.198.120.225 428 214 0 10:07:52.191 10:09:25.008 *
|
||||
20.197.178.120 374 186 0 14:54:24.411 14:54:52.938 *
|
||||
74.249.245.134 354 177 0 21:27:53.575 21:29:06.182 *
|
||||
20.151.10.161 325 162 0 17:31:38.451 17:32:27.663 *
|
||||
20.205.229.184 323 161 0 12:17:54.322 12:18:41.173 *
|
||||
4.185.41.66 323 161 0 18:18:18.046 18:18:24.319 *
|
||||
52.184.96.217 323 161 0 20:02:55.760 20:03:44.824 *
|
||||
172.213.225.181 321 160 0 13:48:04.161 13:48:11.331 *
|
||||
20.48.236.161 321 160 0 15:11:59.817 15:12:31.060 *
|
||||
158.158.32.229 316 158 0 12:33:51.566 12:34:03.712 *
|
||||
20.63.63.128 315 157 0 16:04:22.373 16:04:50.675 *
|
||||
20.206.67.15 313 156 0 05:56:36.144 05:57:20.412 *
|
||||
20.215.185.25 300 150 0 08:18:05.984 08:19:09.190 *
|
||||
20.203.243.122 294 147 0 03:58:39.580 03:58:55.359 *
|
||||
20.226.26.5 286 143 0 06:33:33.891 06:34:07.483 *
|
||||
68.221.130.241 278 139 0 08:28:43.979 08:28:50.496 *
|
||||
74.248.33.172 257 128 0 23:32:36.049 23:32:42.718 *
|
||||
20.203.179.12 250 125 0 17:33:20.484 17:33:29.742 *
|
||||
20.113.142.140 231 115 0 07:47:47.716 07:48:00.044 *
|
||||
158.158.105.63 208 104 0 11:24:12.912 23:00:49.043 *
|
||||
4.223.71.149 209 104 0 00:26:55.320 00:27:19.244 *
|
||||
135.225.93.215 203 101 0 02:32:24.496 02:32:32.326 *
|
||||
20.9.85.55 203 101 0 15:43:36.450 15:44:20.170 *
|
||||
20.91.208.34 203 101 0 22:07:01.428 22:07:20.883 *
|
||||
52.238.192.78 203 101 0 00:04:31.589 00:05:07.114 *
|
||||
172.213.208.13 192 96 0 13:27:56.743 19:14:00.938 *
|
||||
172.213.244.85 165 82 0 17:01:49.042 17:01:52.331 *
|
||||
20.206.105.145 157 78 0 04:06:08.085 04:06:29.772 *
|
||||
51.120.83.160 144 72 0 15:40:29.699 15:40:39.446 *
|
||||
4.223.73.90 106 53 0 19:50:04.916 19:50:11.164 *
|
||||
20.91.203.45 94 47 0 16:27:01.288 16:27:10.455 *
|
||||
20.197.192.193 88 44 0 13:45:32.377 13:45:43.108 *
|
||||
74.248.24.145 74 37 0 09:21:37.839 09:21:43.127 *
|
||||
172.213.144.209 70 35 0 07:52:16.066 07:52:17.778 *
|
||||
35.198.180.224 46 22 0 14:14:37.617 14:14:48.930 *
|
||||
45.148.10.62 98 22 40 07:53:03.360 03:15:12.651 *
|
||||
45.148.10.244 109 18 70 04:53:37.585 09:56:59.103 *
|
||||
45.148.10.120 33 16 0 14:24:06.542 17:06:11.688 *
|
||||
34.39.210.94 24 12 0 19:31:07.030 19:31:07.101 *
|
||||
195.178.110.31 49 11 20 02:27:56.164 02:27:58.425 *
|
||||
195.178.110.223 37 10 13 01:31:40.464 01:56:49.503 *
|
||||
34.95.239.96 20 10 0 11:25:18.487 11:25:18.532 *
|
||||
136.108.11.195 25 9 7 08:33:11.182 08:33:13.921 *
|
||||
139.59.118.17 180 9 157 08:21:30.247 08:22:03.812 *
|
||||
146.70.40.68 30 9 10 18:55:47.310 18:55:48.145 *
|
||||
147.182.149.75 40 9 21 21:50:17.837 21:50:45.474 *
|
||||
16.146.99.254 279 9 256 12:11:20.725 12:12:09.790 *
|
||||
163.7.11.71 93 9 72 07:24:55.235 07:25:05.144 *
|
||||
167.99.181.249 40 9 21 21:50:26.091 21:51:01.239 *
|
||||
18.142.90.109 279 9 256 17:06:23.216 17:07:15.117 *
|
||||
18.227.73.7 392 9 363 22:00:31.465 22:01:33.982 *
|
||||
207.175.20.232 25 9 7 09:43:00.775 09:43:03.604 *
|
||||
209.99.189.190 77 9 59 17:04:48.190 09:53:52.093 *
|
||||
3.79.41.12 286 9 263 04:20:16.234 04:20:22.797 *
|
||||
34.105.30.251 29 9 9 15:55:43.824 15:55:49.547 *
|
||||
34.23.104.90 25 9 7 14:40:59.025 14:41:01.713 *
|
||||
34.242.226.103 286 9 263 06:52:40.299 06:52:54.689 *
|
||||
45.67.85.190 32 9 11 19:41:44.132 19:41:46.806 *
|
||||
54.163.186.39 286 9 263 01:39:29.740 01:40:00.874 *
|
||||
85.204.70.100 30 9 10 13:55:11.862 13:55:12.567 *
|
||||
91.192.10.86 31 9 10 13:38:54.986 13:38:56.159 *
|
||||
93.123.109.101 4320 9 4264 00:35:05.539 00:40:32.578 *
|
||||
185.93.89.147 3762 8 0 19:07:14.620 08:52:41.657 *
|
||||
195.178.110.155 57 8 0 09:10:16.072 09:10:19.329 *
|
||||
45.148.10.194 58 8 0 15:46:42.822 15:46:45.473 *
|
||||
45.148.10.247 57 8 0 00:58:56.398 00:58:59.599 *
|
||||
72.146.20.230 14 7 0 03:01:31.244 03:01:31.427 *
|
||||
209.99.189.152 13 6 0 18:03:04.845 18:03:12.906 *
|
||||
162.243.79.174 11 5 0 12:20:28.790 12:20:40.350 *
|
||||
51.79.208.246 10 5 0 13:50:27.669 13:50:29.418 *
|
||||
91.92.241.196 11 5 0 13:55:12.175 13:05:16.007 *
|
||||
94.154.43.184 10 5 0 11:23:26.214 09:31:40.319 *
|
||||
195.178.110.211 8 4 0 19:35:03.504 20:22:13.338 *
|
||||
163.7.13.115 5 2 0 14:06:27.842 14:06:29.745 *
|
||||
45.138.16.114 5 2 0 03:09:59.971 03:10:00.217 *
|
||||
45.148.10.95 4 2 0 21:05:26.356 14:40:26.566 *
|
||||
91.92.41.115 8 2 0 14:44:48.975 14:44:54.158 *
|
||||
94.154.43.179 5 2 0 13:27:23.753 04:38:17.921 *
|
||||
107.170.9.103 2 1 0 00:19:26.062 00:19:26.062 *
|
||||
129.212.237.196 2 1 0 09:23:08.470 09:23:08.471 *
|
||||
134.209.162.128 2 1 0 00:43:12.731 00:43:12.731 *
|
||||
157.245.63.62 2 1 0 08:13:33.142 08:13:33.142 *
|
||||
158.101.144.198 2 1 0 14:30:06.125 14:30:06.125 *
|
||||
165.245.185.158 2 1 0 09:20:47.477 09:20:47.477 *
|
||||
195.178.110.159 2 1 0 20:41:43.691 20:41:43.691 *
|
||||
2.57.122.173 2 1 0 12:10:19.177 12:10:19.177 *
|
||||
23.180.120.147 4 1 0 13:53:30.303 13:53:30.473 *
|
||||
31.58.51.184 4 1 0 15:07:53.176 15:07:58.514 *
|
||||
34.125.42.15 2 1 0 21:39:44.709 21:39:44.709 *
|
||||
34.91.243.226 2 1 0 19:51:57.606 19:51:57.606 *
|
||||
35.231.100.82 2 1 0 15:36:23.715 15:36:23.715 *
|
||||
35.233.191.179 2 1 0 00:16:07.188 00:16:07.199 *
|
||||
35.95.56.230 3 1 0 02:29:40.010 02:29:40.562 *
|
||||
43.98.201.177 2 1 0 01:01:05.988 01:01:05.988 *
|
||||
45.139.104.172 2 1 0 03:14:49.950 03:14:49.950 *
|
||||
64.226.123.37 2 1 0 21:33:32.148 21:33:32.148 *
|
||||
8.229.130.50 2 1 0 19:23:37.001 19:23:37.002 *
|
||||
93.123.109.167 2 1 0 04:39:35.474 04:39:35.474 *
|
||||
94.154.43.183 3 1 0 21:50:39.582 00:01:42.127 *
|
||||
94.154.43.185 3 1 0 01:40:53.903 04:02:34.085 *
|
||||
94.154.43.186 3 1 0 21:07:26.439 13:43:18.923 *
|
||||
94.154.43.188 5 1 0 02:45:01.636 11:09:54.264 *
|
||||
-- IPv6 (3) --
|
||||
ip total denied banned first last users whitelist
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
2a04:4e40:e000:0:d09:97ab:43b1:a59a 4 2 0 14:41:30.905 14:41:30.922 *
|
||||
2600:3c15::2000:53ff:fe31:8c0b 2 1 0 12:35:18.643 12:35:18.643 *
|
||||
2602:fa59:10:a3a::1 2 1 0 02:10:02.531 02:10:02.532 *
|
||||
@@ -1,24 +1,24 @@
|
||||
copyparty log analysis report
|
||||
generated: 2026-08-06T14:43:58
|
||||
|
||||
log path: P:\copyparty
|
||||
log files: 42
|
||||
total requests: 0
|
||||
unique IPs: 0 (IPv4 0 / IPv6 0)
|
||||
error requests: 0
|
||||
unique denied paths: 0
|
||||
denied requests: 0
|
||||
banned IPs: 0
|
||||
authenticated users: {}
|
||||
denied-only ips: 0
|
||||
whitelisted IPs seen: 0
|
||||
block candidates: 0
|
||||
|
||||
== top 30 IPs ==
|
||||
ip total denied banned first last users whitelist
|
||||
--------------------------------------------------------
|
||||
|
||||
== top 20 denied paths ==
|
||||
|
||||
== Denied-only IPs (0) ==
|
||||
never authenticated -- ban candidates
|
||||
copyparty log analysis report
|
||||
generated: 2026-08-06T14:43:58
|
||||
|
||||
log path: P:\copyparty
|
||||
log files: 42
|
||||
total requests: 0
|
||||
unique IPs: 0 (IPv4 0 / IPv6 0)
|
||||
error requests: 0
|
||||
unique denied paths: 0
|
||||
denied requests: 0
|
||||
banned IPs: 0
|
||||
authenticated users: {}
|
||||
denied-only ips: 0
|
||||
whitelisted IPs seen: 0
|
||||
block candidates: 0
|
||||
|
||||
== top 30 IPs ==
|
||||
ip total denied banned first last users whitelist
|
||||
--------------------------------------------------------
|
||||
|
||||
== top 20 denied paths ==
|
||||
|
||||
== Denied-only IPs (0) ==
|
||||
never authenticated -- ban candidates
|
||||
@@ -1,192 +1,192 @@
|
||||
copyparty log analysis report
|
||||
generated: 2026-08-06T15:09:10
|
||||
|
||||
log path: P:\copyparty
|
||||
log files: 42
|
||||
total requests: 25297
|
||||
unique IPs: 246 (IPv4 202 / IPv6 44)
|
||||
error requests: 6582
|
||||
unique denied paths: 2002
|
||||
denied requests: 6582
|
||||
banned IPs: 26
|
||||
authenticated users: {'admin': 519, 'corky': 78}
|
||||
denied-only ips: 111
|
||||
whitelisted IPs seen: 19
|
||||
block candidates: 113
|
||||
|
||||
== top 30 IPs ==
|
||||
ip total denied banned first last users whitelist
|
||||
------------------------------------------------------------------------------------
|
||||
93.123.109.101 4320 9 4264 00:35:05.539 00:40:32.578 *
|
||||
185.93.89.147 3762 8 0 19:07:14.620 08:52:41.657 *
|
||||
195.178.110.199 1258 621 0 03:02:41.078 03:02:42.924 *
|
||||
45.148.10.67 1258 621 0 20:49:39.003 20:49:41.111 *
|
||||
20.251.48.208 612 306 0 23:50:43.575 17:01:41.376 *
|
||||
20.215.216.94 516 257 0 16:16:39.439 15:21:39.387 *
|
||||
20.215.218.234 504 252 0 02:46:27.628 05:35:25.304 *
|
||||
20.198.120.225 428 214 0 10:07:52.191 10:09:25.008 *
|
||||
18.227.73.7 392 9 363 22:00:31.465 22:01:33.982 *
|
||||
20.197.178.120 374 186 0 14:54:24.411 14:54:52.938 *
|
||||
74.249.245.134 354 177 0 21:27:53.575 21:29:06.182 *
|
||||
20.151.10.161 325 162 0 17:31:38.451 17:32:27.663 *
|
||||
20.205.229.184 323 161 0 12:17:54.322 12:18:41.173 *
|
||||
4.185.41.66 323 161 0 18:18:18.046 18:18:24.319 *
|
||||
52.184.96.217 323 161 0 20:02:55.760 20:03:44.824 *
|
||||
172.213.225.181 321 160 0 13:48:04.161 13:48:11.331 *
|
||||
20.48.236.161 321 160 0 15:11:59.817 15:12:31.060 *
|
||||
158.158.32.229 316 158 0 12:33:51.566 12:34:03.712 *
|
||||
20.63.63.128 315 157 0 16:04:22.373 16:04:50.675 *
|
||||
20.206.67.15 313 156 0 05:56:36.144 05:57:20.412 *
|
||||
20.215.185.25 300 150 0 08:18:05.984 08:19:09.190 *
|
||||
20.203.243.122 294 147 0 03:58:39.580 03:58:55.359 *
|
||||
20.226.26.5 286 143 0 06:33:33.891 06:34:07.483 *
|
||||
3.79.41.12 286 9 263 04:20:16.234 04:20:22.797 *
|
||||
34.242.226.103 286 9 263 06:52:40.299 06:52:54.689 *
|
||||
54.163.186.39 286 9 263 01:39:29.740 01:40:00.874 *
|
||||
16.146.99.254 279 9 256 12:11:20.725 12:12:09.790 *
|
||||
18.142.90.109 279 9 256 17:06:23.216 17:07:15.117 *
|
||||
68.221.130.241 278 139 0 08:28:43.979 08:28:50.496 *
|
||||
74.248.33.172 257 128 0 23:32:36.049 23:32:42.718 *
|
||||
... 216 more IPs omitted
|
||||
|
||||
== top 20 denied paths ==
|
||||
52 /.env
|
||||
52 /admin.php
|
||||
44 /wp-content/plugins/hellopress/wp_filemanager.php
|
||||
44 /this_is_a_new_hello_world.php
|
||||
35 /1.php
|
||||
34 /.git/config
|
||||
33 /classwithtostring.php
|
||||
33 /222.php
|
||||
33 /wp-content/uploads
|
||||
32 /wp-content/admin.php
|
||||
29 /8.php
|
||||
27 /file.php
|
||||
27 /mac.php
|
||||
26 /wp.php
|
||||
26 /edit.php
|
||||
26 /aa.php
|
||||
25 /images.php
|
||||
25 /ops.php
|
||||
24 /f35.php
|
||||
24 /x.php
|
||||
|
||||
== Denied-only IPs (111) ==
|
||||
never authenticated -- ban candidates
|
||||
-- IPv4 (108) --
|
||||
ip total denied banned first last users whitelist
|
||||
------------------------------------------------------------------------------------
|
||||
195.178.110.199 1258 621 0 03:02:41.078 03:02:42.924 *
|
||||
45.148.10.67 1258 621 0 20:49:39.003 20:49:41.111 *
|
||||
20.251.48.208 612 306 0 23:50:43.575 17:01:41.376 *
|
||||
20.215.216.94 516 257 0 16:16:39.439 15:21:39.387 *
|
||||
20.215.218.234 504 252 0 02:46:27.628 05:35:25.304 *
|
||||
20.198.120.225 428 214 0 10:07:52.191 10:09:25.008 *
|
||||
20.197.178.120 374 186 0 14:54:24.411 14:54:52.938 *
|
||||
74.249.245.134 354 177 0 21:27:53.575 21:29:06.182 *
|
||||
20.151.10.161 325 162 0 17:31:38.451 17:32:27.663 *
|
||||
20.205.229.184 323 161 0 12:17:54.322 12:18:41.173 *
|
||||
4.185.41.66 323 161 0 18:18:18.046 18:18:24.319 *
|
||||
52.184.96.217 323 161 0 20:02:55.760 20:03:44.824 *
|
||||
172.213.225.181 321 160 0 13:48:04.161 13:48:11.331 *
|
||||
20.48.236.161 321 160 0 15:11:59.817 15:12:31.060 *
|
||||
158.158.32.229 316 158 0 12:33:51.566 12:34:03.712 *
|
||||
20.63.63.128 315 157 0 16:04:22.373 16:04:50.675 *
|
||||
20.206.67.15 313 156 0 05:56:36.144 05:57:20.412 *
|
||||
20.215.185.25 300 150 0 08:18:05.984 08:19:09.190 *
|
||||
20.203.243.122 294 147 0 03:58:39.580 03:58:55.359 *
|
||||
20.226.26.5 286 143 0 06:33:33.891 06:34:07.483 *
|
||||
68.221.130.241 278 139 0 08:28:43.979 08:28:50.496 *
|
||||
74.248.33.172 257 128 0 23:32:36.049 23:32:42.718 *
|
||||
20.203.179.12 250 125 0 17:33:20.484 17:33:29.742 *
|
||||
20.113.142.140 231 115 0 07:47:47.716 07:48:00.044 *
|
||||
158.158.105.63 208 104 0 11:24:12.912 23:00:49.043 *
|
||||
4.223.71.149 209 104 0 00:26:55.320 00:27:19.244 *
|
||||
135.225.93.215 203 101 0 02:32:24.496 02:32:32.326 *
|
||||
20.9.85.55 203 101 0 15:43:36.450 15:44:20.170 *
|
||||
20.91.208.34 203 101 0 22:07:01.428 22:07:20.883 *
|
||||
52.238.192.78 203 101 0 00:04:31.589 00:05:07.114 *
|
||||
172.213.208.13 192 96 0 13:27:56.743 19:14:00.938 *
|
||||
172.213.244.85 165 82 0 17:01:49.042 17:01:52.331 *
|
||||
20.206.105.145 157 78 0 04:06:08.085 04:06:29.772 *
|
||||
51.120.83.160 144 72 0 15:40:29.699 15:40:39.446 *
|
||||
4.223.73.90 106 53 0 19:50:04.916 19:50:11.164 *
|
||||
20.91.203.45 94 47 0 16:27:01.288 16:27:10.455 *
|
||||
20.197.192.193 88 44 0 13:45:32.377 13:45:43.108 *
|
||||
74.248.24.145 74 37 0 09:21:37.839 09:21:43.127 *
|
||||
172.213.144.209 70 35 0 07:52:16.066 07:52:17.778 *
|
||||
35.198.180.224 46 22 0 14:14:37.617 14:14:48.930 *
|
||||
45.148.10.62 98 22 40 07:53:03.360 03:15:12.651 *
|
||||
45.148.10.244 109 18 70 04:53:37.585 09:56:59.103 *
|
||||
45.148.10.120 33 16 0 14:24:06.542 17:06:11.688 *
|
||||
34.39.210.94 24 12 0 19:31:07.030 19:31:07.101 *
|
||||
195.178.110.31 49 11 20 02:27:56.164 02:27:58.425 *
|
||||
195.178.110.223 37 10 13 01:31:40.464 01:56:49.503 *
|
||||
34.95.239.96 20 10 0 11:25:18.487 11:25:18.532 *
|
||||
136.108.11.195 25 9 7 08:33:11.182 08:33:13.921 *
|
||||
139.59.118.17 180 9 157 08:21:30.247 08:22:03.812 *
|
||||
146.70.40.68 30 9 10 18:55:47.310 18:55:48.145 *
|
||||
147.182.149.75 40 9 21 21:50:17.837 21:50:45.474 *
|
||||
16.146.99.254 279 9 256 12:11:20.725 12:12:09.790 *
|
||||
163.7.11.71 93 9 72 07:24:55.235 07:25:05.144 *
|
||||
167.99.181.249 40 9 21 21:50:26.091 21:51:01.239 *
|
||||
18.142.90.109 279 9 256 17:06:23.216 17:07:15.117 *
|
||||
18.227.73.7 392 9 363 22:00:31.465 22:01:33.982 *
|
||||
207.175.20.232 25 9 7 09:43:00.775 09:43:03.604 *
|
||||
209.99.189.190 77 9 59 17:04:48.190 09:53:52.093 *
|
||||
3.79.41.12 286 9 263 04:20:16.234 04:20:22.797 *
|
||||
34.105.30.251 29 9 9 15:55:43.824 15:55:49.547 *
|
||||
34.23.104.90 25 9 7 14:40:59.025 14:41:01.713 *
|
||||
34.242.226.103 286 9 263 06:52:40.299 06:52:54.689 *
|
||||
45.67.85.190 32 9 11 19:41:44.132 19:41:46.806 *
|
||||
54.163.186.39 286 9 263 01:39:29.740 01:40:00.874 *
|
||||
85.204.70.100 30 9 10 13:55:11.862 13:55:12.567 *
|
||||
91.192.10.86 31 9 10 13:38:54.986 13:38:56.159 *
|
||||
93.123.109.101 4320 9 4264 00:35:05.539 00:40:32.578 *
|
||||
185.93.89.147 3762 8 0 19:07:14.620 08:52:41.657 *
|
||||
195.178.110.155 57 8 0 09:10:16.072 09:10:19.329 *
|
||||
45.148.10.194 58 8 0 15:46:42.822 15:46:45.473 *
|
||||
45.148.10.247 57 8 0 00:58:56.398 00:58:59.599 *
|
||||
72.146.20.230 14 7 0 03:01:31.244 03:01:31.427 *
|
||||
209.99.189.152 13 6 0 18:03:04.845 18:03:12.906 *
|
||||
162.243.79.174 11 5 0 12:20:28.790 12:20:40.350 *
|
||||
51.79.208.246 10 5 0 13:50:27.669 13:50:29.418 *
|
||||
91.92.241.196 11 5 0 13:55:12.175 13:05:16.007 *
|
||||
94.154.43.184 10 5 0 11:23:26.214 09:31:40.319 *
|
||||
195.178.110.211 8 4 0 19:35:03.504 20:22:13.338 *
|
||||
163.7.13.115 5 2 0 14:06:27.842 14:06:29.745 *
|
||||
45.138.16.114 5 2 0 03:09:59.971 03:10:00.217 *
|
||||
45.148.10.95 4 2 0 21:05:26.356 14:40:26.566 *
|
||||
91.92.41.115 8 2 0 14:44:48.975 14:44:54.158 *
|
||||
94.154.43.179 5 2 0 13:27:23.753 04:38:17.921 *
|
||||
107.170.9.103 2 1 0 00:19:26.062 00:19:26.062 *
|
||||
129.212.237.196 2 1 0 09:23:08.470 09:23:08.471 *
|
||||
134.209.162.128 2 1 0 00:43:12.731 00:43:12.731 *
|
||||
157.245.63.62 2 1 0 08:13:33.142 08:13:33.142 *
|
||||
158.101.144.198 2 1 0 14:30:06.125 14:30:06.125 *
|
||||
165.245.185.158 2 1 0 09:20:47.477 09:20:47.477 *
|
||||
195.178.110.159 2 1 0 20:41:43.691 20:41:43.691 *
|
||||
2.57.122.173 2 1 0 12:10:19.177 12:10:19.177 *
|
||||
23.180.120.147 4 1 0 13:53:30.303 13:53:30.473 *
|
||||
31.58.51.184 4 1 0 15:07:53.176 15:07:58.514 *
|
||||
34.125.42.15 2 1 0 21:39:44.709 21:39:44.709 *
|
||||
34.91.243.226 2 1 0 19:51:57.606 19:51:57.606 *
|
||||
35.231.100.82 2 1 0 15:36:23.715 15:36:23.715 *
|
||||
35.233.191.179 2 1 0 00:16:07.188 00:16:07.199 *
|
||||
35.95.56.230 3 1 0 02:29:40.010 02:29:40.562 *
|
||||
43.98.201.177 2 1 0 01:01:05.988 01:01:05.988 *
|
||||
45.139.104.172 2 1 0 03:14:49.950 03:14:49.950 *
|
||||
64.226.123.37 2 1 0 21:33:32.148 21:33:32.148 *
|
||||
8.229.130.50 2 1 0 19:23:37.001 19:23:37.002 *
|
||||
93.123.109.167 2 1 0 04:39:35.474 04:39:35.474 *
|
||||
94.154.43.183 3 1 0 21:50:39.582 00:01:42.127 *
|
||||
94.154.43.185 3 1 0 01:40:53.903 04:02:34.085 *
|
||||
94.154.43.186 3 1 0 21:07:26.439 13:43:18.923 *
|
||||
94.154.43.188 5 1 0 02:45:01.636 11:09:54.264 *
|
||||
94.154.43.229 4 1 0 14:35:26.801 12:53:30.198 *
|
||||
-- IPv6 (3) --
|
||||
ip total denied banned first last users whitelist
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
2a04:4e40:e000:0:d09:97ab:43b1:a59a 4 2 0 14:41:30.905 14:41:30.922 *
|
||||
2600:3c15::2000:53ff:fe31:8c0b 2 1 0 12:35:18.643 12:35:18.643 *
|
||||
2602:fa59:10:a3a::1 2 1 0 02:10:02.531 02:10:02.532 *
|
||||
copyparty log analysis report
|
||||
generated: 2026-08-06T15:09:10
|
||||
|
||||
log path: P:\copyparty
|
||||
log files: 42
|
||||
total requests: 25297
|
||||
unique IPs: 246 (IPv4 202 / IPv6 44)
|
||||
error requests: 6582
|
||||
unique denied paths: 2002
|
||||
denied requests: 6582
|
||||
banned IPs: 26
|
||||
authenticated users: {'admin': 519, 'corky': 78}
|
||||
denied-only ips: 111
|
||||
whitelisted IPs seen: 19
|
||||
block candidates: 113
|
||||
|
||||
== top 30 IPs ==
|
||||
ip total denied banned first last users whitelist
|
||||
------------------------------------------------------------------------------------
|
||||
93.123.109.101 4320 9 4264 00:35:05.539 00:40:32.578 *
|
||||
185.93.89.147 3762 8 0 19:07:14.620 08:52:41.657 *
|
||||
195.178.110.199 1258 621 0 03:02:41.078 03:02:42.924 *
|
||||
45.148.10.67 1258 621 0 20:49:39.003 20:49:41.111 *
|
||||
20.251.48.208 612 306 0 23:50:43.575 17:01:41.376 *
|
||||
20.215.216.94 516 257 0 16:16:39.439 15:21:39.387 *
|
||||
20.215.218.234 504 252 0 02:46:27.628 05:35:25.304 *
|
||||
20.198.120.225 428 214 0 10:07:52.191 10:09:25.008 *
|
||||
18.227.73.7 392 9 363 22:00:31.465 22:01:33.982 *
|
||||
20.197.178.120 374 186 0 14:54:24.411 14:54:52.938 *
|
||||
74.249.245.134 354 177 0 21:27:53.575 21:29:06.182 *
|
||||
20.151.10.161 325 162 0 17:31:38.451 17:32:27.663 *
|
||||
20.205.229.184 323 161 0 12:17:54.322 12:18:41.173 *
|
||||
4.185.41.66 323 161 0 18:18:18.046 18:18:24.319 *
|
||||
52.184.96.217 323 161 0 20:02:55.760 20:03:44.824 *
|
||||
172.213.225.181 321 160 0 13:48:04.161 13:48:11.331 *
|
||||
20.48.236.161 321 160 0 15:11:59.817 15:12:31.060 *
|
||||
158.158.32.229 316 158 0 12:33:51.566 12:34:03.712 *
|
||||
20.63.63.128 315 157 0 16:04:22.373 16:04:50.675 *
|
||||
20.206.67.15 313 156 0 05:56:36.144 05:57:20.412 *
|
||||
20.215.185.25 300 150 0 08:18:05.984 08:19:09.190 *
|
||||
20.203.243.122 294 147 0 03:58:39.580 03:58:55.359 *
|
||||
20.226.26.5 286 143 0 06:33:33.891 06:34:07.483 *
|
||||
3.79.41.12 286 9 263 04:20:16.234 04:20:22.797 *
|
||||
34.242.226.103 286 9 263 06:52:40.299 06:52:54.689 *
|
||||
54.163.186.39 286 9 263 01:39:29.740 01:40:00.874 *
|
||||
16.146.99.254 279 9 256 12:11:20.725 12:12:09.790 *
|
||||
18.142.90.109 279 9 256 17:06:23.216 17:07:15.117 *
|
||||
68.221.130.241 278 139 0 08:28:43.979 08:28:50.496 *
|
||||
74.248.33.172 257 128 0 23:32:36.049 23:32:42.718 *
|
||||
... 216 more IPs omitted
|
||||
|
||||
== top 20 denied paths ==
|
||||
52 /.env
|
||||
52 /admin.php
|
||||
44 /wp-content/plugins/hellopress/wp_filemanager.php
|
||||
44 /this_is_a_new_hello_world.php
|
||||
35 /1.php
|
||||
34 /.git/config
|
||||
33 /classwithtostring.php
|
||||
33 /222.php
|
||||
33 /wp-content/uploads
|
||||
32 /wp-content/admin.php
|
||||
29 /8.php
|
||||
27 /file.php
|
||||
27 /mac.php
|
||||
26 /wp.php
|
||||
26 /edit.php
|
||||
26 /aa.php
|
||||
25 /images.php
|
||||
25 /ops.php
|
||||
24 /f35.php
|
||||
24 /x.php
|
||||
|
||||
== Denied-only IPs (111) ==
|
||||
never authenticated -- ban candidates
|
||||
-- IPv4 (108) --
|
||||
ip total denied banned first last users whitelist
|
||||
------------------------------------------------------------------------------------
|
||||
195.178.110.199 1258 621 0 03:02:41.078 03:02:42.924 *
|
||||
45.148.10.67 1258 621 0 20:49:39.003 20:49:41.111 *
|
||||
20.251.48.208 612 306 0 23:50:43.575 17:01:41.376 *
|
||||
20.215.216.94 516 257 0 16:16:39.439 15:21:39.387 *
|
||||
20.215.218.234 504 252 0 02:46:27.628 05:35:25.304 *
|
||||
20.198.120.225 428 214 0 10:07:52.191 10:09:25.008 *
|
||||
20.197.178.120 374 186 0 14:54:24.411 14:54:52.938 *
|
||||
74.249.245.134 354 177 0 21:27:53.575 21:29:06.182 *
|
||||
20.151.10.161 325 162 0 17:31:38.451 17:32:27.663 *
|
||||
20.205.229.184 323 161 0 12:17:54.322 12:18:41.173 *
|
||||
4.185.41.66 323 161 0 18:18:18.046 18:18:24.319 *
|
||||
52.184.96.217 323 161 0 20:02:55.760 20:03:44.824 *
|
||||
172.213.225.181 321 160 0 13:48:04.161 13:48:11.331 *
|
||||
20.48.236.161 321 160 0 15:11:59.817 15:12:31.060 *
|
||||
158.158.32.229 316 158 0 12:33:51.566 12:34:03.712 *
|
||||
20.63.63.128 315 157 0 16:04:22.373 16:04:50.675 *
|
||||
20.206.67.15 313 156 0 05:56:36.144 05:57:20.412 *
|
||||
20.215.185.25 300 150 0 08:18:05.984 08:19:09.190 *
|
||||
20.203.243.122 294 147 0 03:58:39.580 03:58:55.359 *
|
||||
20.226.26.5 286 143 0 06:33:33.891 06:34:07.483 *
|
||||
68.221.130.241 278 139 0 08:28:43.979 08:28:50.496 *
|
||||
74.248.33.172 257 128 0 23:32:36.049 23:32:42.718 *
|
||||
20.203.179.12 250 125 0 17:33:20.484 17:33:29.742 *
|
||||
20.113.142.140 231 115 0 07:47:47.716 07:48:00.044 *
|
||||
158.158.105.63 208 104 0 11:24:12.912 23:00:49.043 *
|
||||
4.223.71.149 209 104 0 00:26:55.320 00:27:19.244 *
|
||||
135.225.93.215 203 101 0 02:32:24.496 02:32:32.326 *
|
||||
20.9.85.55 203 101 0 15:43:36.450 15:44:20.170 *
|
||||
20.91.208.34 203 101 0 22:07:01.428 22:07:20.883 *
|
||||
52.238.192.78 203 101 0 00:04:31.589 00:05:07.114 *
|
||||
172.213.208.13 192 96 0 13:27:56.743 19:14:00.938 *
|
||||
172.213.244.85 165 82 0 17:01:49.042 17:01:52.331 *
|
||||
20.206.105.145 157 78 0 04:06:08.085 04:06:29.772 *
|
||||
51.120.83.160 144 72 0 15:40:29.699 15:40:39.446 *
|
||||
4.223.73.90 106 53 0 19:50:04.916 19:50:11.164 *
|
||||
20.91.203.45 94 47 0 16:27:01.288 16:27:10.455 *
|
||||
20.197.192.193 88 44 0 13:45:32.377 13:45:43.108 *
|
||||
74.248.24.145 74 37 0 09:21:37.839 09:21:43.127 *
|
||||
172.213.144.209 70 35 0 07:52:16.066 07:52:17.778 *
|
||||
35.198.180.224 46 22 0 14:14:37.617 14:14:48.930 *
|
||||
45.148.10.62 98 22 40 07:53:03.360 03:15:12.651 *
|
||||
45.148.10.244 109 18 70 04:53:37.585 09:56:59.103 *
|
||||
45.148.10.120 33 16 0 14:24:06.542 17:06:11.688 *
|
||||
34.39.210.94 24 12 0 19:31:07.030 19:31:07.101 *
|
||||
195.178.110.31 49 11 20 02:27:56.164 02:27:58.425 *
|
||||
195.178.110.223 37 10 13 01:31:40.464 01:56:49.503 *
|
||||
34.95.239.96 20 10 0 11:25:18.487 11:25:18.532 *
|
||||
136.108.11.195 25 9 7 08:33:11.182 08:33:13.921 *
|
||||
139.59.118.17 180 9 157 08:21:30.247 08:22:03.812 *
|
||||
146.70.40.68 30 9 10 18:55:47.310 18:55:48.145 *
|
||||
147.182.149.75 40 9 21 21:50:17.837 21:50:45.474 *
|
||||
16.146.99.254 279 9 256 12:11:20.725 12:12:09.790 *
|
||||
163.7.11.71 93 9 72 07:24:55.235 07:25:05.144 *
|
||||
167.99.181.249 40 9 21 21:50:26.091 21:51:01.239 *
|
||||
18.142.90.109 279 9 256 17:06:23.216 17:07:15.117 *
|
||||
18.227.73.7 392 9 363 22:00:31.465 22:01:33.982 *
|
||||
207.175.20.232 25 9 7 09:43:00.775 09:43:03.604 *
|
||||
209.99.189.190 77 9 59 17:04:48.190 09:53:52.093 *
|
||||
3.79.41.12 286 9 263 04:20:16.234 04:20:22.797 *
|
||||
34.105.30.251 29 9 9 15:55:43.824 15:55:49.547 *
|
||||
34.23.104.90 25 9 7 14:40:59.025 14:41:01.713 *
|
||||
34.242.226.103 286 9 263 06:52:40.299 06:52:54.689 *
|
||||
45.67.85.190 32 9 11 19:41:44.132 19:41:46.806 *
|
||||
54.163.186.39 286 9 263 01:39:29.740 01:40:00.874 *
|
||||
85.204.70.100 30 9 10 13:55:11.862 13:55:12.567 *
|
||||
91.192.10.86 31 9 10 13:38:54.986 13:38:56.159 *
|
||||
93.123.109.101 4320 9 4264 00:35:05.539 00:40:32.578 *
|
||||
185.93.89.147 3762 8 0 19:07:14.620 08:52:41.657 *
|
||||
195.178.110.155 57 8 0 09:10:16.072 09:10:19.329 *
|
||||
45.148.10.194 58 8 0 15:46:42.822 15:46:45.473 *
|
||||
45.148.10.247 57 8 0 00:58:56.398 00:58:59.599 *
|
||||
72.146.20.230 14 7 0 03:01:31.244 03:01:31.427 *
|
||||
209.99.189.152 13 6 0 18:03:04.845 18:03:12.906 *
|
||||
162.243.79.174 11 5 0 12:20:28.790 12:20:40.350 *
|
||||
51.79.208.246 10 5 0 13:50:27.669 13:50:29.418 *
|
||||
91.92.241.196 11 5 0 13:55:12.175 13:05:16.007 *
|
||||
94.154.43.184 10 5 0 11:23:26.214 09:31:40.319 *
|
||||
195.178.110.211 8 4 0 19:35:03.504 20:22:13.338 *
|
||||
163.7.13.115 5 2 0 14:06:27.842 14:06:29.745 *
|
||||
45.138.16.114 5 2 0 03:09:59.971 03:10:00.217 *
|
||||
45.148.10.95 4 2 0 21:05:26.356 14:40:26.566 *
|
||||
91.92.41.115 8 2 0 14:44:48.975 14:44:54.158 *
|
||||
94.154.43.179 5 2 0 13:27:23.753 04:38:17.921 *
|
||||
107.170.9.103 2 1 0 00:19:26.062 00:19:26.062 *
|
||||
129.212.237.196 2 1 0 09:23:08.470 09:23:08.471 *
|
||||
134.209.162.128 2 1 0 00:43:12.731 00:43:12.731 *
|
||||
157.245.63.62 2 1 0 08:13:33.142 08:13:33.142 *
|
||||
158.101.144.198 2 1 0 14:30:06.125 14:30:06.125 *
|
||||
165.245.185.158 2 1 0 09:20:47.477 09:20:47.477 *
|
||||
195.178.110.159 2 1 0 20:41:43.691 20:41:43.691 *
|
||||
2.57.122.173 2 1 0 12:10:19.177 12:10:19.177 *
|
||||
23.180.120.147 4 1 0 13:53:30.303 13:53:30.473 *
|
||||
31.58.51.184 4 1 0 15:07:53.176 15:07:58.514 *
|
||||
34.125.42.15 2 1 0 21:39:44.709 21:39:44.709 *
|
||||
34.91.243.226 2 1 0 19:51:57.606 19:51:57.606 *
|
||||
35.231.100.82 2 1 0 15:36:23.715 15:36:23.715 *
|
||||
35.233.191.179 2 1 0 00:16:07.188 00:16:07.199 *
|
||||
35.95.56.230 3 1 0 02:29:40.010 02:29:40.562 *
|
||||
43.98.201.177 2 1 0 01:01:05.988 01:01:05.988 *
|
||||
45.139.104.172 2 1 0 03:14:49.950 03:14:49.950 *
|
||||
64.226.123.37 2 1 0 21:33:32.148 21:33:32.148 *
|
||||
8.229.130.50 2 1 0 19:23:37.001 19:23:37.002 *
|
||||
93.123.109.167 2 1 0 04:39:35.474 04:39:35.474 *
|
||||
94.154.43.183 3 1 0 21:50:39.582 00:01:42.127 *
|
||||
94.154.43.185 3 1 0 01:40:53.903 04:02:34.085 *
|
||||
94.154.43.186 3 1 0 21:07:26.439 13:43:18.923 *
|
||||
94.154.43.188 5 1 0 02:45:01.636 11:09:54.264 *
|
||||
94.154.43.229 4 1 0 14:35:26.801 12:53:30.198 *
|
||||
-- IPv6 (3) --
|
||||
ip total denied banned first last users whitelist
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
2a04:4e40:e000:0:d09:97ab:43b1:a59a 4 2 0 14:41:30.905 14:41:30.922 *
|
||||
2600:3c15::2000:53ff:fe31:8c0b 2 1 0 12:35:18.643 12:35:18.643 *
|
||||
2602:fa59:10:a3a::1 2 1 0 02:10:02.531 02:10:02.532 *
|
||||
@@ -1,70 +1,70 @@
|
||||
copyparty log analysis report
|
||||
generated: 2026-08-07T19:48:03
|
||||
|
||||
log path: P:\copyparty
|
||||
log files: 43
|
||||
total requests: 1227
|
||||
unique IPs: 14 (IPv4 14 / IPv6 0)
|
||||
error requests: 279
|
||||
unique denied paths: 182
|
||||
denied requests: 279
|
||||
banned IPs: 3
|
||||
authenticated users: {}
|
||||
denied-only ips: 9
|
||||
whitelisted IPs seen: 0
|
||||
block candidates: 9
|
||||
|
||||
== top 30 IPs ==
|
||||
ip total denied banned first last users whitelist
|
||||
------------------------------------------------------------------------------------
|
||||
34.140.123.172 434 6 411 21:34:17.485 21:35:45.084 *
|
||||
20.100.172.153 275 137 0 09:10:06.751 09:10:17.835 *
|
||||
34.9.173.20 245 9 224 16:55:22.164 16:55:30.344 *
|
||||
172.213.153.79 114 57 0 18:40:13.799 18:40:20.149 *
|
||||
20.91.239.158 114 57 0 13:42:20.392 13:42:24.986 *
|
||||
207.175.159.248 25 9 7 03:52:06.643 03:52:07.542 *
|
||||
35.196.132.85 6 0 0 14:20:00.708 16:50:00.731 *
|
||||
91.92.241.196 4 2 0 15:50:20.187 15:50:21.628 *
|
||||
157.245.63.62 2 1 0 13:04:56.122 13:04:56.122 *
|
||||
35.227.62.178 2 0 0 15:20:01.556 15:20:01.557 *
|
||||
35.237.169.55 2 0 0 13:53:04.249 13:53:04.250 *
|
||||
94.154.43.229 2 1 0 12:53:30.198 12:53:30.198 *
|
||||
34.85.209.183 1 0 0 15:59:40.864 15:59:40.864 *
|
||||
94.154.43.178 1 0 0 16:14:12.910 16:14:12.910 *
|
||||
|
||||
== top 20 denied paths ==
|
||||
5 /admin.php
|
||||
3 /wp-content/plugins/hellopress/wp_filemanager.php
|
||||
3 /this_is_a_new_hello_world.php
|
||||
3 /av.php
|
||||
3 /media.php
|
||||
3 /images.php
|
||||
3 /222.php
|
||||
3 /mac.php
|
||||
3 /ops.php
|
||||
3 /8.php
|
||||
3 /biufile.php
|
||||
3 /coffexium.php
|
||||
3 /1.php
|
||||
3 /classwithtostring.php
|
||||
3 /wp-ws68.php
|
||||
3 /mgrr.php
|
||||
3 /yj09.php
|
||||
3 /3PJcpMFsD8B.php
|
||||
3 /BDKR28WP.php
|
||||
3 /shiny.php
|
||||
|
||||
== Denied-only IPs (9) ==
|
||||
never authenticated -- ban candidates
|
||||
-- IPv4 (9) --
|
||||
ip total denied banned first last users whitelist
|
||||
------------------------------------------------------------------------------------
|
||||
20.100.172.153 275 137 0 09:10:06.751 09:10:17.835 *
|
||||
172.213.153.79 114 57 0 18:40:13.799 18:40:20.149 *
|
||||
20.91.239.158 114 57 0 13:42:20.392 13:42:24.986 *
|
||||
207.175.159.248 25 9 7 03:52:06.643 03:52:07.542 *
|
||||
34.9.173.20 245 9 224 16:55:22.164 16:55:30.344 *
|
||||
34.140.123.172 434 6 411 21:34:17.485 21:35:45.084 *
|
||||
91.92.241.196 4 2 0 15:50:20.187 15:50:21.628 *
|
||||
157.245.63.62 2 1 0 13:04:56.122 13:04:56.122 *
|
||||
94.154.43.229 2 1 0 12:53:30.198 12:53:30.198 *
|
||||
copyparty log analysis report
|
||||
generated: 2026-08-07T19:48:03
|
||||
|
||||
log path: P:\copyparty
|
||||
log files: 43
|
||||
total requests: 1227
|
||||
unique IPs: 14 (IPv4 14 / IPv6 0)
|
||||
error requests: 279
|
||||
unique denied paths: 182
|
||||
denied requests: 279
|
||||
banned IPs: 3
|
||||
authenticated users: {}
|
||||
denied-only ips: 9
|
||||
whitelisted IPs seen: 0
|
||||
block candidates: 9
|
||||
|
||||
== top 30 IPs ==
|
||||
ip total denied banned first last users whitelist
|
||||
------------------------------------------------------------------------------------
|
||||
34.140.123.172 434 6 411 21:34:17.485 21:35:45.084 *
|
||||
20.100.172.153 275 137 0 09:10:06.751 09:10:17.835 *
|
||||
34.9.173.20 245 9 224 16:55:22.164 16:55:30.344 *
|
||||
172.213.153.79 114 57 0 18:40:13.799 18:40:20.149 *
|
||||
20.91.239.158 114 57 0 13:42:20.392 13:42:24.986 *
|
||||
207.175.159.248 25 9 7 03:52:06.643 03:52:07.542 *
|
||||
35.196.132.85 6 0 0 14:20:00.708 16:50:00.731 *
|
||||
91.92.241.196 4 2 0 15:50:20.187 15:50:21.628 *
|
||||
157.245.63.62 2 1 0 13:04:56.122 13:04:56.122 *
|
||||
35.227.62.178 2 0 0 15:20:01.556 15:20:01.557 *
|
||||
35.237.169.55 2 0 0 13:53:04.249 13:53:04.250 *
|
||||
94.154.43.229 2 1 0 12:53:30.198 12:53:30.198 *
|
||||
34.85.209.183 1 0 0 15:59:40.864 15:59:40.864 *
|
||||
94.154.43.178 1 0 0 16:14:12.910 16:14:12.910 *
|
||||
|
||||
== top 20 denied paths ==
|
||||
5 /admin.php
|
||||
3 /wp-content/plugins/hellopress/wp_filemanager.php
|
||||
3 /this_is_a_new_hello_world.php
|
||||
3 /av.php
|
||||
3 /media.php
|
||||
3 /images.php
|
||||
3 /222.php
|
||||
3 /mac.php
|
||||
3 /ops.php
|
||||
3 /8.php
|
||||
3 /biufile.php
|
||||
3 /coffexium.php
|
||||
3 /1.php
|
||||
3 /classwithtostring.php
|
||||
3 /wp-ws68.php
|
||||
3 /mgrr.php
|
||||
3 /yj09.php
|
||||
3 /3PJcpMFsD8B.php
|
||||
3 /BDKR28WP.php
|
||||
3 /shiny.php
|
||||
|
||||
== Denied-only IPs (9) ==
|
||||
never authenticated -- ban candidates
|
||||
-- IPv4 (9) --
|
||||
ip total denied banned first last users whitelist
|
||||
------------------------------------------------------------------------------------
|
||||
20.100.172.153 275 137 0 09:10:06.751 09:10:17.835 *
|
||||
172.213.153.79 114 57 0 18:40:13.799 18:40:20.149 *
|
||||
20.91.239.158 114 57 0 13:42:20.392 13:42:24.986 *
|
||||
207.175.159.248 25 9 7 03:52:06.643 03:52:07.542 *
|
||||
34.9.173.20 245 9 224 16:55:22.164 16:55:30.344 *
|
||||
34.140.123.172 434 6 411 21:34:17.485 21:35:45.084 *
|
||||
91.92.241.196 4 2 0 15:50:20.187 15:50:21.628 *
|
||||
157.245.63.62 2 1 0 13:04:56.122 13:04:56.122 *
|
||||
94.154.43.229 2 1 0 12:53:30.198 12:53:30.198 *
|
||||
@@ -1,198 +1,198 @@
|
||||
copyparty log analysis report
|
||||
generated: 2026-08-07T19:48:44
|
||||
|
||||
log path: P:\copyparty
|
||||
log files: 43
|
||||
total requests: 26522
|
||||
unique IPs: 253 (IPv4 209 / IPv6 44)
|
||||
error requests: 6860
|
||||
unique denied paths: 2022
|
||||
denied requests: 6860
|
||||
banned IPs: 29
|
||||
authenticated users: {'admin': 519, 'corky': 78}
|
||||
denied-only ips: 117
|
||||
whitelisted IPs seen: 19
|
||||
block candidates: 119
|
||||
|
||||
== top 30 IPs ==
|
||||
ip total denied banned first last users whitelist
|
||||
------------------------------------------------------------------------------------
|
||||
93.123.109.101 4320 9 4264 00:35:05.539 00:40:32.578 *
|
||||
185.93.89.147 3762 8 0 19:07:14.620 08:52:41.657 *
|
||||
195.178.110.199 1258 621 0 03:02:41.078 03:02:42.924 *
|
||||
45.148.10.67 1258 621 0 20:49:39.003 20:49:41.111 *
|
||||
20.251.48.208 612 306 0 23:50:43.575 17:01:41.376 *
|
||||
20.215.216.94 516 257 0 16:16:39.439 15:21:39.387 *
|
||||
20.215.218.234 504 252 0 02:46:27.628 05:35:25.304 *
|
||||
34.140.123.172 434 6 411 21:34:17.485 21:35:45.084 *
|
||||
20.198.120.225 428 214 0 10:07:52.191 10:09:25.008 *
|
||||
18.227.73.7 392 9 363 22:00:31.465 22:01:33.982 *
|
||||
20.197.178.120 374 186 0 14:54:24.411 14:54:52.938 *
|
||||
74.249.245.134 354 177 0 21:27:53.575 21:29:06.182 *
|
||||
20.151.10.161 325 162 0 17:31:38.451 17:32:27.663 *
|
||||
20.205.229.184 323 161 0 12:17:54.322 12:18:41.173 *
|
||||
4.185.41.66 323 161 0 18:18:18.046 18:18:24.319 *
|
||||
52.184.96.217 323 161 0 20:02:55.760 20:03:44.824 *
|
||||
172.213.225.181 321 160 0 13:48:04.161 13:48:11.331 *
|
||||
20.48.236.161 321 160 0 15:11:59.817 15:12:31.060 *
|
||||
158.158.32.229 316 158 0 12:33:51.566 12:34:03.712 *
|
||||
20.63.63.128 315 157 0 16:04:22.373 16:04:50.675 *
|
||||
20.206.67.15 313 156 0 05:56:36.144 05:57:20.412 *
|
||||
20.215.185.25 300 150 0 08:18:05.984 08:19:09.190 *
|
||||
20.203.243.122 294 147 0 03:58:39.580 03:58:55.359 *
|
||||
20.226.26.5 286 143 0 06:33:33.891 06:34:07.483 *
|
||||
3.79.41.12 286 9 263 04:20:16.234 04:20:22.797 *
|
||||
34.242.226.103 286 9 263 06:52:40.299 06:52:54.689 *
|
||||
54.163.186.39 286 9 263 01:39:29.740 01:40:00.874 *
|
||||
16.146.99.254 279 9 256 12:11:20.725 12:12:09.790 *
|
||||
18.142.90.109 279 9 256 17:06:23.216 17:07:15.117 *
|
||||
68.221.130.241 278 139 0 08:28:43.979 08:28:50.496 *
|
||||
... 223 more IPs omitted
|
||||
|
||||
== top 20 denied paths ==
|
||||
57 /admin.php
|
||||
52 /.env
|
||||
47 /wp-content/plugins/hellopress/wp_filemanager.php
|
||||
47 /this_is_a_new_hello_world.php
|
||||
38 /1.php
|
||||
36 /.git/config
|
||||
36 /classwithtostring.php
|
||||
36 /222.php
|
||||
34 /wp-content/uploads
|
||||
33 /wp-content/admin.php
|
||||
32 /8.php
|
||||
30 /mac.php
|
||||
28 /aa.php
|
||||
28 /images.php
|
||||
28 /ops.php
|
||||
27 /wp.php
|
||||
27 /file.php
|
||||
27 /edit.php
|
||||
26 /coffexium.php
|
||||
25 /f35.php
|
||||
|
||||
== Denied-only IPs (117) ==
|
||||
never authenticated -- ban candidates
|
||||
-- IPv4 (114) --
|
||||
ip total denied banned first last users whitelist
|
||||
------------------------------------------------------------------------------------
|
||||
195.178.110.199 1258 621 0 03:02:41.078 03:02:42.924 *
|
||||
45.148.10.67 1258 621 0 20:49:39.003 20:49:41.111 *
|
||||
20.251.48.208 612 306 0 23:50:43.575 17:01:41.376 *
|
||||
20.215.216.94 516 257 0 16:16:39.439 15:21:39.387 *
|
||||
20.215.218.234 504 252 0 02:46:27.628 05:35:25.304 *
|
||||
20.198.120.225 428 214 0 10:07:52.191 10:09:25.008 *
|
||||
20.197.178.120 374 186 0 14:54:24.411 14:54:52.938 *
|
||||
74.249.245.134 354 177 0 21:27:53.575 21:29:06.182 *
|
||||
20.151.10.161 325 162 0 17:31:38.451 17:32:27.663 *
|
||||
20.205.229.184 323 161 0 12:17:54.322 12:18:41.173 *
|
||||
4.185.41.66 323 161 0 18:18:18.046 18:18:24.319 *
|
||||
52.184.96.217 323 161 0 20:02:55.760 20:03:44.824 *
|
||||
172.213.225.181 321 160 0 13:48:04.161 13:48:11.331 *
|
||||
20.48.236.161 321 160 0 15:11:59.817 15:12:31.060 *
|
||||
158.158.32.229 316 158 0 12:33:51.566 12:34:03.712 *
|
||||
20.63.63.128 315 157 0 16:04:22.373 16:04:50.675 *
|
||||
20.206.67.15 313 156 0 05:56:36.144 05:57:20.412 *
|
||||
20.215.185.25 300 150 0 08:18:05.984 08:19:09.190 *
|
||||
20.203.243.122 294 147 0 03:58:39.580 03:58:55.359 *
|
||||
20.226.26.5 286 143 0 06:33:33.891 06:34:07.483 *
|
||||
68.221.130.241 278 139 0 08:28:43.979 08:28:50.496 *
|
||||
20.100.172.153 275 137 0 09:10:06.751 09:10:17.835 *
|
||||
74.248.33.172 257 128 0 23:32:36.049 23:32:42.718 *
|
||||
20.203.179.12 250 125 0 17:33:20.484 17:33:29.742 *
|
||||
20.113.142.140 231 115 0 07:47:47.716 07:48:00.044 *
|
||||
158.158.105.63 208 104 0 11:24:12.912 23:00:49.043 *
|
||||
4.223.71.149 209 104 0 00:26:55.320 00:27:19.244 *
|
||||
135.225.93.215 203 101 0 02:32:24.496 02:32:32.326 *
|
||||
20.9.85.55 203 101 0 15:43:36.450 15:44:20.170 *
|
||||
20.91.208.34 203 101 0 22:07:01.428 22:07:20.883 *
|
||||
52.238.192.78 203 101 0 00:04:31.589 00:05:07.114 *
|
||||
172.213.208.13 192 96 0 13:27:56.743 19:14:00.938 *
|
||||
172.213.244.85 165 82 0 17:01:49.042 17:01:52.331 *
|
||||
20.206.105.145 157 78 0 04:06:08.085 04:06:29.772 *
|
||||
51.120.83.160 144 72 0 15:40:29.699 15:40:39.446 *
|
||||
172.213.153.79 114 57 0 18:40:13.799 18:40:20.149 *
|
||||
20.91.239.158 114 57 0 13:42:20.392 13:42:24.986 *
|
||||
4.223.73.90 106 53 0 19:50:04.916 19:50:11.164 *
|
||||
20.91.203.45 94 47 0 16:27:01.288 16:27:10.455 *
|
||||
20.197.192.193 88 44 0 13:45:32.377 13:45:43.108 *
|
||||
74.248.24.145 74 37 0 09:21:37.839 09:21:43.127 *
|
||||
172.213.144.209 70 35 0 07:52:16.066 07:52:17.778 *
|
||||
35.198.180.224 46 22 0 14:14:37.617 14:14:48.930 *
|
||||
45.148.10.62 98 22 40 07:53:03.360 03:15:12.651 *
|
||||
45.148.10.244 109 18 70 04:53:37.585 09:56:59.103 *
|
||||
45.148.10.120 33 16 0 14:24:06.542 17:06:11.688 *
|
||||
34.39.210.94 24 12 0 19:31:07.030 19:31:07.101 *
|
||||
195.178.110.31 49 11 20 02:27:56.164 02:27:58.425 *
|
||||
195.178.110.223 37 10 13 01:31:40.464 01:56:49.503 *
|
||||
34.95.239.96 20 10 0 11:25:18.487 11:25:18.532 *
|
||||
136.108.11.195 25 9 7 08:33:11.182 08:33:13.921 *
|
||||
139.59.118.17 180 9 157 08:21:30.247 08:22:03.812 *
|
||||
146.70.40.68 30 9 10 18:55:47.310 18:55:48.145 *
|
||||
147.182.149.75 40 9 21 21:50:17.837 21:50:45.474 *
|
||||
16.146.99.254 279 9 256 12:11:20.725 12:12:09.790 *
|
||||
163.7.11.71 93 9 72 07:24:55.235 07:25:05.144 *
|
||||
167.99.181.249 40 9 21 21:50:26.091 21:51:01.239 *
|
||||
18.142.90.109 279 9 256 17:06:23.216 17:07:15.117 *
|
||||
18.227.73.7 392 9 363 22:00:31.465 22:01:33.982 *
|
||||
207.175.159.248 25 9 7 03:52:06.643 03:52:07.542 *
|
||||
207.175.20.232 25 9 7 09:43:00.775 09:43:03.604 *
|
||||
209.99.189.190 77 9 59 17:04:48.190 09:53:52.093 *
|
||||
3.79.41.12 286 9 263 04:20:16.234 04:20:22.797 *
|
||||
34.105.30.251 29 9 9 15:55:43.824 15:55:49.547 *
|
||||
34.23.104.90 25 9 7 14:40:59.025 14:41:01.713 *
|
||||
34.242.226.103 286 9 263 06:52:40.299 06:52:54.689 *
|
||||
34.9.173.20 245 9 224 16:55:22.164 16:55:30.344 *
|
||||
45.67.85.190 32 9 11 19:41:44.132 19:41:46.806 *
|
||||
54.163.186.39 286 9 263 01:39:29.740 01:40:00.874 *
|
||||
85.204.70.100 30 9 10 13:55:11.862 13:55:12.567 *
|
||||
91.192.10.86 31 9 10 13:38:54.986 13:38:56.159 *
|
||||
93.123.109.101 4320 9 4264 00:35:05.539 00:40:32.578 *
|
||||
185.93.89.147 3762 8 0 19:07:14.620 08:52:41.657 *
|
||||
195.178.110.155 57 8 0 09:10:16.072 09:10:19.329 *
|
||||
45.148.10.194 58 8 0 15:46:42.822 15:46:45.473 *
|
||||
45.148.10.247 57 8 0 00:58:56.398 00:58:59.599 *
|
||||
72.146.20.230 14 7 0 03:01:31.244 03:01:31.427 *
|
||||
91.92.241.196 15 7 0 13:55:12.175 15:50:21.628 *
|
||||
209.99.189.152 13 6 0 18:03:04.845 18:03:12.906 *
|
||||
34.140.123.172 434 6 411 21:34:17.485 21:35:45.084 *
|
||||
162.243.79.174 11 5 0 12:20:28.790 12:20:40.350 *
|
||||
51.79.208.246 10 5 0 13:50:27.669 13:50:29.418 *
|
||||
94.154.43.184 10 5 0 11:23:26.214 09:31:40.319 *
|
||||
195.178.110.211 8 4 0 19:35:03.504 20:22:13.338 *
|
||||
157.245.63.62 4 2 0 08:13:33.142 13:04:56.122 *
|
||||
163.7.13.115 5 2 0 14:06:27.842 14:06:29.745 *
|
||||
45.138.16.114 5 2 0 03:09:59.971 03:10:00.217 *
|
||||
45.148.10.95 4 2 0 21:05:26.356 14:40:26.566 *
|
||||
91.92.41.115 8 2 0 14:44:48.975 14:44:54.158 *
|
||||
94.154.43.179 5 2 0 13:27:23.753 04:38:17.921 *
|
||||
107.170.9.103 2 1 0 00:19:26.062 00:19:26.062 *
|
||||
129.212.237.196 2 1 0 09:23:08.470 09:23:08.471 *
|
||||
134.209.162.128 2 1 0 00:43:12.731 00:43:12.731 *
|
||||
158.101.144.198 2 1 0 14:30:06.125 14:30:06.125 *
|
||||
165.245.185.158 2 1 0 09:20:47.477 09:20:47.477 *
|
||||
195.178.110.159 2 1 0 20:41:43.691 20:41:43.691 *
|
||||
2.57.122.173 2 1 0 12:10:19.177 12:10:19.177 *
|
||||
23.180.120.147 4 1 0 13:53:30.303 13:53:30.473 *
|
||||
31.58.51.184 4 1 0 15:07:53.176 15:07:58.514 *
|
||||
34.125.42.15 2 1 0 21:39:44.709 21:39:44.709 *
|
||||
34.91.243.226 2 1 0 19:51:57.606 19:51:57.606 *
|
||||
35.231.100.82 2 1 0 15:36:23.715 15:36:23.715 *
|
||||
35.233.191.179 2 1 0 00:16:07.188 00:16:07.199 *
|
||||
35.95.56.230 3 1 0 02:29:40.010 02:29:40.562 *
|
||||
43.98.201.177 2 1 0 01:01:05.988 01:01:05.988 *
|
||||
45.139.104.172 2 1 0 03:14:49.950 03:14:49.950 *
|
||||
64.226.123.37 2 1 0 21:33:32.148 21:33:32.148 *
|
||||
8.229.130.50 2 1 0 19:23:37.001 19:23:37.002 *
|
||||
93.123.109.167 2 1 0 04:39:35.474 04:39:35.474 *
|
||||
94.154.43.183 3 1 0 21:50:39.582 00:01:42.127 *
|
||||
94.154.43.185 3 1 0 01:40:53.903 04:02:34.085 *
|
||||
94.154.43.186 3 1 0 21:07:26.439 13:43:18.923 *
|
||||
94.154.43.188 5 1 0 02:45:01.636 11:09:54.264 *
|
||||
94.154.43.229 4 1 0 14:35:26.801 12:53:30.198 *
|
||||
-- IPv6 (3) --
|
||||
ip total denied banned first last users whitelist
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
2a04:4e40:e000:0:d09:97ab:43b1:a59a 4 2 0 14:41:30.905 14:41:30.922 *
|
||||
2600:3c15::2000:53ff:fe31:8c0b 2 1 0 12:35:18.643 12:35:18.643 *
|
||||
2602:fa59:10:a3a::1 2 1 0 02:10:02.531 02:10:02.532 *
|
||||
copyparty log analysis report
|
||||
generated: 2026-08-07T19:48:44
|
||||
|
||||
log path: P:\copyparty
|
||||
log files: 43
|
||||
total requests: 26522
|
||||
unique IPs: 253 (IPv4 209 / IPv6 44)
|
||||
error requests: 6860
|
||||
unique denied paths: 2022
|
||||
denied requests: 6860
|
||||
banned IPs: 29
|
||||
authenticated users: {'admin': 519, 'corky': 78}
|
||||
denied-only ips: 117
|
||||
whitelisted IPs seen: 19
|
||||
block candidates: 119
|
||||
|
||||
== top 30 IPs ==
|
||||
ip total denied banned first last users whitelist
|
||||
------------------------------------------------------------------------------------
|
||||
93.123.109.101 4320 9 4264 00:35:05.539 00:40:32.578 *
|
||||
185.93.89.147 3762 8 0 19:07:14.620 08:52:41.657 *
|
||||
195.178.110.199 1258 621 0 03:02:41.078 03:02:42.924 *
|
||||
45.148.10.67 1258 621 0 20:49:39.003 20:49:41.111 *
|
||||
20.251.48.208 612 306 0 23:50:43.575 17:01:41.376 *
|
||||
20.215.216.94 516 257 0 16:16:39.439 15:21:39.387 *
|
||||
20.215.218.234 504 252 0 02:46:27.628 05:35:25.304 *
|
||||
34.140.123.172 434 6 411 21:34:17.485 21:35:45.084 *
|
||||
20.198.120.225 428 214 0 10:07:52.191 10:09:25.008 *
|
||||
18.227.73.7 392 9 363 22:00:31.465 22:01:33.982 *
|
||||
20.197.178.120 374 186 0 14:54:24.411 14:54:52.938 *
|
||||
74.249.245.134 354 177 0 21:27:53.575 21:29:06.182 *
|
||||
20.151.10.161 325 162 0 17:31:38.451 17:32:27.663 *
|
||||
20.205.229.184 323 161 0 12:17:54.322 12:18:41.173 *
|
||||
4.185.41.66 323 161 0 18:18:18.046 18:18:24.319 *
|
||||
52.184.96.217 323 161 0 20:02:55.760 20:03:44.824 *
|
||||
172.213.225.181 321 160 0 13:48:04.161 13:48:11.331 *
|
||||
20.48.236.161 321 160 0 15:11:59.817 15:12:31.060 *
|
||||
158.158.32.229 316 158 0 12:33:51.566 12:34:03.712 *
|
||||
20.63.63.128 315 157 0 16:04:22.373 16:04:50.675 *
|
||||
20.206.67.15 313 156 0 05:56:36.144 05:57:20.412 *
|
||||
20.215.185.25 300 150 0 08:18:05.984 08:19:09.190 *
|
||||
20.203.243.122 294 147 0 03:58:39.580 03:58:55.359 *
|
||||
20.226.26.5 286 143 0 06:33:33.891 06:34:07.483 *
|
||||
3.79.41.12 286 9 263 04:20:16.234 04:20:22.797 *
|
||||
34.242.226.103 286 9 263 06:52:40.299 06:52:54.689 *
|
||||
54.163.186.39 286 9 263 01:39:29.740 01:40:00.874 *
|
||||
16.146.99.254 279 9 256 12:11:20.725 12:12:09.790 *
|
||||
18.142.90.109 279 9 256 17:06:23.216 17:07:15.117 *
|
||||
68.221.130.241 278 139 0 08:28:43.979 08:28:50.496 *
|
||||
... 223 more IPs omitted
|
||||
|
||||
== top 20 denied paths ==
|
||||
57 /admin.php
|
||||
52 /.env
|
||||
47 /wp-content/plugins/hellopress/wp_filemanager.php
|
||||
47 /this_is_a_new_hello_world.php
|
||||
38 /1.php
|
||||
36 /.git/config
|
||||
36 /classwithtostring.php
|
||||
36 /222.php
|
||||
34 /wp-content/uploads
|
||||
33 /wp-content/admin.php
|
||||
32 /8.php
|
||||
30 /mac.php
|
||||
28 /aa.php
|
||||
28 /images.php
|
||||
28 /ops.php
|
||||
27 /wp.php
|
||||
27 /file.php
|
||||
27 /edit.php
|
||||
26 /coffexium.php
|
||||
25 /f35.php
|
||||
|
||||
== Denied-only IPs (117) ==
|
||||
never authenticated -- ban candidates
|
||||
-- IPv4 (114) --
|
||||
ip total denied banned first last users whitelist
|
||||
------------------------------------------------------------------------------------
|
||||
195.178.110.199 1258 621 0 03:02:41.078 03:02:42.924 *
|
||||
45.148.10.67 1258 621 0 20:49:39.003 20:49:41.111 *
|
||||
20.251.48.208 612 306 0 23:50:43.575 17:01:41.376 *
|
||||
20.215.216.94 516 257 0 16:16:39.439 15:21:39.387 *
|
||||
20.215.218.234 504 252 0 02:46:27.628 05:35:25.304 *
|
||||
20.198.120.225 428 214 0 10:07:52.191 10:09:25.008 *
|
||||
20.197.178.120 374 186 0 14:54:24.411 14:54:52.938 *
|
||||
74.249.245.134 354 177 0 21:27:53.575 21:29:06.182 *
|
||||
20.151.10.161 325 162 0 17:31:38.451 17:32:27.663 *
|
||||
20.205.229.184 323 161 0 12:17:54.322 12:18:41.173 *
|
||||
4.185.41.66 323 161 0 18:18:18.046 18:18:24.319 *
|
||||
52.184.96.217 323 161 0 20:02:55.760 20:03:44.824 *
|
||||
172.213.225.181 321 160 0 13:48:04.161 13:48:11.331 *
|
||||
20.48.236.161 321 160 0 15:11:59.817 15:12:31.060 *
|
||||
158.158.32.229 316 158 0 12:33:51.566 12:34:03.712 *
|
||||
20.63.63.128 315 157 0 16:04:22.373 16:04:50.675 *
|
||||
20.206.67.15 313 156 0 05:56:36.144 05:57:20.412 *
|
||||
20.215.185.25 300 150 0 08:18:05.984 08:19:09.190 *
|
||||
20.203.243.122 294 147 0 03:58:39.580 03:58:55.359 *
|
||||
20.226.26.5 286 143 0 06:33:33.891 06:34:07.483 *
|
||||
68.221.130.241 278 139 0 08:28:43.979 08:28:50.496 *
|
||||
20.100.172.153 275 137 0 09:10:06.751 09:10:17.835 *
|
||||
74.248.33.172 257 128 0 23:32:36.049 23:32:42.718 *
|
||||
20.203.179.12 250 125 0 17:33:20.484 17:33:29.742 *
|
||||
20.113.142.140 231 115 0 07:47:47.716 07:48:00.044 *
|
||||
158.158.105.63 208 104 0 11:24:12.912 23:00:49.043 *
|
||||
4.223.71.149 209 104 0 00:26:55.320 00:27:19.244 *
|
||||
135.225.93.215 203 101 0 02:32:24.496 02:32:32.326 *
|
||||
20.9.85.55 203 101 0 15:43:36.450 15:44:20.170 *
|
||||
20.91.208.34 203 101 0 22:07:01.428 22:07:20.883 *
|
||||
52.238.192.78 203 101 0 00:04:31.589 00:05:07.114 *
|
||||
172.213.208.13 192 96 0 13:27:56.743 19:14:00.938 *
|
||||
172.213.244.85 165 82 0 17:01:49.042 17:01:52.331 *
|
||||
20.206.105.145 157 78 0 04:06:08.085 04:06:29.772 *
|
||||
51.120.83.160 144 72 0 15:40:29.699 15:40:39.446 *
|
||||
172.213.153.79 114 57 0 18:40:13.799 18:40:20.149 *
|
||||
20.91.239.158 114 57 0 13:42:20.392 13:42:24.986 *
|
||||
4.223.73.90 106 53 0 19:50:04.916 19:50:11.164 *
|
||||
20.91.203.45 94 47 0 16:27:01.288 16:27:10.455 *
|
||||
20.197.192.193 88 44 0 13:45:32.377 13:45:43.108 *
|
||||
74.248.24.145 74 37 0 09:21:37.839 09:21:43.127 *
|
||||
172.213.144.209 70 35 0 07:52:16.066 07:52:17.778 *
|
||||
35.198.180.224 46 22 0 14:14:37.617 14:14:48.930 *
|
||||
45.148.10.62 98 22 40 07:53:03.360 03:15:12.651 *
|
||||
45.148.10.244 109 18 70 04:53:37.585 09:56:59.103 *
|
||||
45.148.10.120 33 16 0 14:24:06.542 17:06:11.688 *
|
||||
34.39.210.94 24 12 0 19:31:07.030 19:31:07.101 *
|
||||
195.178.110.31 49 11 20 02:27:56.164 02:27:58.425 *
|
||||
195.178.110.223 37 10 13 01:31:40.464 01:56:49.503 *
|
||||
34.95.239.96 20 10 0 11:25:18.487 11:25:18.532 *
|
||||
136.108.11.195 25 9 7 08:33:11.182 08:33:13.921 *
|
||||
139.59.118.17 180 9 157 08:21:30.247 08:22:03.812 *
|
||||
146.70.40.68 30 9 10 18:55:47.310 18:55:48.145 *
|
||||
147.182.149.75 40 9 21 21:50:17.837 21:50:45.474 *
|
||||
16.146.99.254 279 9 256 12:11:20.725 12:12:09.790 *
|
||||
163.7.11.71 93 9 72 07:24:55.235 07:25:05.144 *
|
||||
167.99.181.249 40 9 21 21:50:26.091 21:51:01.239 *
|
||||
18.142.90.109 279 9 256 17:06:23.216 17:07:15.117 *
|
||||
18.227.73.7 392 9 363 22:00:31.465 22:01:33.982 *
|
||||
207.175.159.248 25 9 7 03:52:06.643 03:52:07.542 *
|
||||
207.175.20.232 25 9 7 09:43:00.775 09:43:03.604 *
|
||||
209.99.189.190 77 9 59 17:04:48.190 09:53:52.093 *
|
||||
3.79.41.12 286 9 263 04:20:16.234 04:20:22.797 *
|
||||
34.105.30.251 29 9 9 15:55:43.824 15:55:49.547 *
|
||||
34.23.104.90 25 9 7 14:40:59.025 14:41:01.713 *
|
||||
34.242.226.103 286 9 263 06:52:40.299 06:52:54.689 *
|
||||
34.9.173.20 245 9 224 16:55:22.164 16:55:30.344 *
|
||||
45.67.85.190 32 9 11 19:41:44.132 19:41:46.806 *
|
||||
54.163.186.39 286 9 263 01:39:29.740 01:40:00.874 *
|
||||
85.204.70.100 30 9 10 13:55:11.862 13:55:12.567 *
|
||||
91.192.10.86 31 9 10 13:38:54.986 13:38:56.159 *
|
||||
93.123.109.101 4320 9 4264 00:35:05.539 00:40:32.578 *
|
||||
185.93.89.147 3762 8 0 19:07:14.620 08:52:41.657 *
|
||||
195.178.110.155 57 8 0 09:10:16.072 09:10:19.329 *
|
||||
45.148.10.194 58 8 0 15:46:42.822 15:46:45.473 *
|
||||
45.148.10.247 57 8 0 00:58:56.398 00:58:59.599 *
|
||||
72.146.20.230 14 7 0 03:01:31.244 03:01:31.427 *
|
||||
91.92.241.196 15 7 0 13:55:12.175 15:50:21.628 *
|
||||
209.99.189.152 13 6 0 18:03:04.845 18:03:12.906 *
|
||||
34.140.123.172 434 6 411 21:34:17.485 21:35:45.084 *
|
||||
162.243.79.174 11 5 0 12:20:28.790 12:20:40.350 *
|
||||
51.79.208.246 10 5 0 13:50:27.669 13:50:29.418 *
|
||||
94.154.43.184 10 5 0 11:23:26.214 09:31:40.319 *
|
||||
195.178.110.211 8 4 0 19:35:03.504 20:22:13.338 *
|
||||
157.245.63.62 4 2 0 08:13:33.142 13:04:56.122 *
|
||||
163.7.13.115 5 2 0 14:06:27.842 14:06:29.745 *
|
||||
45.138.16.114 5 2 0 03:09:59.971 03:10:00.217 *
|
||||
45.148.10.95 4 2 0 21:05:26.356 14:40:26.566 *
|
||||
91.92.41.115 8 2 0 14:44:48.975 14:44:54.158 *
|
||||
94.154.43.179 5 2 0 13:27:23.753 04:38:17.921 *
|
||||
107.170.9.103 2 1 0 00:19:26.062 00:19:26.062 *
|
||||
129.212.237.196 2 1 0 09:23:08.470 09:23:08.471 *
|
||||
134.209.162.128 2 1 0 00:43:12.731 00:43:12.731 *
|
||||
158.101.144.198 2 1 0 14:30:06.125 14:30:06.125 *
|
||||
165.245.185.158 2 1 0 09:20:47.477 09:20:47.477 *
|
||||
195.178.110.159 2 1 0 20:41:43.691 20:41:43.691 *
|
||||
2.57.122.173 2 1 0 12:10:19.177 12:10:19.177 *
|
||||
23.180.120.147 4 1 0 13:53:30.303 13:53:30.473 *
|
||||
31.58.51.184 4 1 0 15:07:53.176 15:07:58.514 *
|
||||
34.125.42.15 2 1 0 21:39:44.709 21:39:44.709 *
|
||||
34.91.243.226 2 1 0 19:51:57.606 19:51:57.606 *
|
||||
35.231.100.82 2 1 0 15:36:23.715 15:36:23.715 *
|
||||
35.233.191.179 2 1 0 00:16:07.188 00:16:07.199 *
|
||||
35.95.56.230 3 1 0 02:29:40.010 02:29:40.562 *
|
||||
43.98.201.177 2 1 0 01:01:05.988 01:01:05.988 *
|
||||
45.139.104.172 2 1 0 03:14:49.950 03:14:49.950 *
|
||||
64.226.123.37 2 1 0 21:33:32.148 21:33:32.148 *
|
||||
8.229.130.50 2 1 0 19:23:37.001 19:23:37.002 *
|
||||
93.123.109.167 2 1 0 04:39:35.474 04:39:35.474 *
|
||||
94.154.43.183 3 1 0 21:50:39.582 00:01:42.127 *
|
||||
94.154.43.185 3 1 0 01:40:53.903 04:02:34.085 *
|
||||
94.154.43.186 3 1 0 21:07:26.439 13:43:18.923 *
|
||||
94.154.43.188 5 1 0 02:45:01.636 11:09:54.264 *
|
||||
94.154.43.229 4 1 0 14:35:26.801 12:53:30.198 *
|
||||
-- IPv6 (3) --
|
||||
ip total denied banned first last users whitelist
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
2a04:4e40:e000:0:d09:97ab:43b1:a59a 4 2 0 14:41:30.905 14:41:30.922 *
|
||||
2600:3c15::2000:53ff:fe31:8c0b 2 1 0 12:35:18.643 12:35:18.643 *
|
||||
2602:fa59:10:a3a::1 2 1 0 02:10:02.531 02:10:02.532 *
|
||||
@@ -1,201 +1,201 @@
|
||||
copyparty log analysis report
|
||||
generated: 2026-08-08T14:31:22
|
||||
|
||||
log path: P:\copyparty
|
||||
log files: 44
|
||||
total requests: 26784
|
||||
unique IPs: 263 (IPv4 218 / IPv6 45)
|
||||
error requests: 6976
|
||||
unique denied paths: 2059
|
||||
denied requests: 6976
|
||||
banned IPs: 30
|
||||
authenticated users: {'admin': 523, 'corky': 78}
|
||||
denied-only ips: 120
|
||||
whitelisted IPs seen: 21
|
||||
block candidates: 122
|
||||
|
||||
== top 30 IPs ==
|
||||
ip total denied banned first last users whitelist
|
||||
------------------------------------------------------------------------------------
|
||||
93.123.109.101 4320 9 4264 00:35:05.539 00:40:32.578 *
|
||||
185.93.89.147 3762 8 0 19:07:14.620 08:52:41.657 *
|
||||
195.178.110.199 1258 621 0 03:02:41.078 03:02:42.924 *
|
||||
45.148.10.67 1258 621 0 20:49:39.003 20:49:41.111 *
|
||||
20.251.48.208 612 306 0 23:50:43.575 17:01:41.376 *
|
||||
20.215.216.94 516 257 0 16:16:39.439 15:21:39.387 *
|
||||
20.215.218.234 504 252 0 02:46:27.628 05:35:25.304 *
|
||||
34.140.123.172 434 6 411 21:34:17.485 21:35:45.084 *
|
||||
20.198.120.225 428 214 0 10:07:52.191 10:09:25.008 *
|
||||
18.227.73.7 392 9 363 22:00:31.465 22:01:33.982 *
|
||||
20.197.178.120 374 186 0 14:54:24.411 14:54:52.938 *
|
||||
74.249.245.134 354 177 0 21:27:53.575 21:29:06.182 *
|
||||
20.151.10.161 325 162 0 17:31:38.451 17:32:27.663 *
|
||||
20.205.229.184 323 161 0 12:17:54.322 12:18:41.173 *
|
||||
4.185.41.66 323 161 0 18:18:18.046 18:18:24.319 *
|
||||
52.184.96.217 323 161 0 20:02:55.760 20:03:44.824 *
|
||||
172.213.225.181 321 160 0 13:48:04.161 13:48:11.331 *
|
||||
20.48.236.161 321 160 0 15:11:59.817 15:12:31.060 *
|
||||
158.158.32.229 316 158 0 12:33:51.566 12:34:03.712 *
|
||||
20.63.63.128 315 157 0 16:04:22.373 16:04:50.675 *
|
||||
20.206.67.15 313 156 0 05:56:36.144 05:57:20.412 *
|
||||
20.215.185.25 300 150 0 08:18:05.984 08:19:09.190 *
|
||||
20.203.243.122 294 147 0 03:58:39.580 03:58:55.359 *
|
||||
20.226.26.5 286 143 0 06:33:33.891 06:34:07.483 *
|
||||
3.79.41.12 286 9 263 04:20:16.234 04:20:22.797 *
|
||||
34.242.226.103 286 9 263 06:52:40.299 06:52:54.689 *
|
||||
54.163.186.39 286 9 263 01:39:29.740 01:40:00.874 *
|
||||
16.146.99.254 279 9 256 12:11:20.725 12:12:09.790 *
|
||||
18.142.90.109 279 9 256 17:06:23.216 17:07:15.117 *
|
||||
68.221.130.241 278 139 0 08:28:43.979 08:28:50.496 *
|
||||
... 233 more IPs omitted
|
||||
|
||||
== top 20 denied paths ==
|
||||
58 /admin.php
|
||||
53 /.env
|
||||
49 /wp-content/plugins/hellopress/wp_filemanager.php
|
||||
49 /this_is_a_new_hello_world.php
|
||||
39 /1.php
|
||||
37 /classwithtostring.php
|
||||
37 /222.php
|
||||
36 /.git/config
|
||||
34 /wp-content/uploads
|
||||
33 /8.php
|
||||
33 /wp-content/admin.php
|
||||
31 /mac.php
|
||||
29 /aa.php
|
||||
29 /images.php
|
||||
29 /ops.php
|
||||
28 /wp.php
|
||||
28 /edit.php
|
||||
27 /file.php
|
||||
27 /coffexium.php
|
||||
25 /f35.php
|
||||
|
||||
== Denied-only IPs (120) ==
|
||||
never authenticated -- ban candidates
|
||||
-- IPv4 (117) --
|
||||
ip total denied banned first last users whitelist
|
||||
------------------------------------------------------------------------------------
|
||||
195.178.110.199 1258 621 0 03:02:41.078 03:02:42.924 *
|
||||
45.148.10.67 1258 621 0 20:49:39.003 20:49:41.111 *
|
||||
20.251.48.208 612 306 0 23:50:43.575 17:01:41.376 *
|
||||
20.215.216.94 516 257 0 16:16:39.439 15:21:39.387 *
|
||||
20.215.218.234 504 252 0 02:46:27.628 05:35:25.304 *
|
||||
20.198.120.225 428 214 0 10:07:52.191 10:09:25.008 *
|
||||
20.197.178.120 374 186 0 14:54:24.411 14:54:52.938 *
|
||||
74.249.245.134 354 177 0 21:27:53.575 21:29:06.182 *
|
||||
20.151.10.161 325 162 0 17:31:38.451 17:32:27.663 *
|
||||
20.205.229.184 323 161 0 12:17:54.322 12:18:41.173 *
|
||||
4.185.41.66 323 161 0 18:18:18.046 18:18:24.319 *
|
||||
52.184.96.217 323 161 0 20:02:55.760 20:03:44.824 *
|
||||
172.213.225.181 321 160 0 13:48:04.161 13:48:11.331 *
|
||||
20.48.236.161 321 160 0 15:11:59.817 15:12:31.060 *
|
||||
158.158.32.229 316 158 0 12:33:51.566 12:34:03.712 *
|
||||
20.63.63.128 315 157 0 16:04:22.373 16:04:50.675 *
|
||||
20.206.67.15 313 156 0 05:56:36.144 05:57:20.412 *
|
||||
20.215.185.25 300 150 0 08:18:05.984 08:19:09.190 *
|
||||
20.203.243.122 294 147 0 03:58:39.580 03:58:55.359 *
|
||||
20.226.26.5 286 143 0 06:33:33.891 06:34:07.483 *
|
||||
68.221.130.241 278 139 0 08:28:43.979 08:28:50.496 *
|
||||
20.100.172.153 275 137 0 09:10:06.751 09:10:17.835 *
|
||||
74.248.33.172 257 128 0 23:32:36.049 23:32:42.718 *
|
||||
20.203.179.12 250 125 0 17:33:20.484 17:33:29.742 *
|
||||
20.113.142.140 231 115 0 07:47:47.716 07:48:00.044 *
|
||||
158.158.105.63 208 104 0 11:24:12.912 23:00:49.043 *
|
||||
4.223.71.149 209 104 0 00:26:55.320 00:27:19.244 *
|
||||
135.225.93.215 203 101 0 02:32:24.496 02:32:32.326 *
|
||||
20.9.85.55 203 101 0 15:43:36.450 15:44:20.170 *
|
||||
20.91.208.34 203 101 0 22:07:01.428 22:07:20.883 *
|
||||
52.238.192.78 203 101 0 00:04:31.589 00:05:07.114 *
|
||||
172.213.208.13 192 96 0 13:27:56.743 19:14:00.938 *
|
||||
172.213.244.85 165 82 0 17:01:49.042 17:01:52.331 *
|
||||
20.206.105.145 157 78 0 04:06:08.085 04:06:29.772 *
|
||||
51.120.83.160 144 72 0 15:40:29.699 15:40:39.446 *
|
||||
172.213.153.79 114 57 0 18:40:13.799 18:40:20.149 *
|
||||
20.91.239.158 114 57 0 13:42:20.392 13:42:24.986 *
|
||||
172.213.227.73 108 54 0 03:00:13.592 03:00:18.810 *
|
||||
4.223.73.90 106 53 0 19:50:04.916 19:50:11.164 *
|
||||
4.232.185.87 110 53 0 21:23:31.012 21:23:33.019 *
|
||||
20.91.203.45 94 47 0 16:27:01.288 16:27:10.455 *
|
||||
20.197.192.193 88 44 0 13:45:32.377 13:45:43.108 *
|
||||
74.248.24.145 74 37 0 09:21:37.839 09:21:43.127 *
|
||||
172.213.144.209 70 35 0 07:52:16.066 07:52:17.778 *
|
||||
35.198.180.224 46 22 0 14:14:37.617 14:14:48.930 *
|
||||
45.148.10.62 98 22 40 07:53:03.360 03:15:12.651 *
|
||||
45.148.10.244 109 18 70 04:53:37.585 09:56:59.103 *
|
||||
45.148.10.120 33 16 0 14:24:06.542 17:06:11.688 *
|
||||
34.39.210.94 24 12 0 19:31:07.030 19:31:07.101 *
|
||||
195.178.110.31 49 11 20 02:27:56.164 02:27:58.425 *
|
||||
195.178.110.223 37 10 13 01:31:40.464 01:56:49.503 *
|
||||
34.95.239.96 20 10 0 11:25:18.487 11:25:18.532 *
|
||||
107.173.254.55 29 9 9 07:04:56.768 07:05:17.755 *
|
||||
136.108.11.195 25 9 7 08:33:11.182 08:33:13.921 *
|
||||
139.59.118.17 180 9 157 08:21:30.247 08:22:03.812 *
|
||||
146.70.40.68 30 9 10 18:55:47.310 18:55:48.145 *
|
||||
147.182.149.75 40 9 21 21:50:17.837 21:50:45.474 *
|
||||
16.146.99.254 279 9 256 12:11:20.725 12:12:09.790 *
|
||||
163.7.11.71 93 9 72 07:24:55.235 07:25:05.144 *
|
||||
167.99.181.249 40 9 21 21:50:26.091 21:51:01.239 *
|
||||
18.142.90.109 279 9 256 17:06:23.216 17:07:15.117 *
|
||||
18.227.73.7 392 9 363 22:00:31.465 22:01:33.982 *
|
||||
207.175.159.248 25 9 7 03:52:06.643 03:52:07.542 *
|
||||
207.175.20.232 25 9 7 09:43:00.775 09:43:03.604 *
|
||||
209.99.189.190 77 9 59 17:04:48.190 09:53:52.093 *
|
||||
3.79.41.12 286 9 263 04:20:16.234 04:20:22.797 *
|
||||
34.105.30.251 29 9 9 15:55:43.824 15:55:49.547 *
|
||||
34.23.104.90 25 9 7 14:40:59.025 14:41:01.713 *
|
||||
34.242.226.103 286 9 263 06:52:40.299 06:52:54.689 *
|
||||
34.9.173.20 245 9 224 16:55:22.164 16:55:30.344 *
|
||||
45.67.85.190 32 9 11 19:41:44.132 19:41:46.806 *
|
||||
54.163.186.39 286 9 263 01:39:29.740 01:40:00.874 *
|
||||
85.204.70.100 30 9 10 13:55:11.862 13:55:12.567 *
|
||||
91.192.10.86 31 9 10 13:38:54.986 13:38:56.159 *
|
||||
93.123.109.101 4320 9 4264 00:35:05.539 00:40:32.578 *
|
||||
185.93.89.147 3762 8 0 19:07:14.620 08:52:41.657 *
|
||||
195.178.110.155 57 8 0 09:10:16.072 09:10:19.329 *
|
||||
45.148.10.194 58 8 0 15:46:42.822 15:46:45.473 *
|
||||
45.148.10.247 57 8 0 00:58:56.398 00:58:59.599 *
|
||||
72.146.20.230 14 7 0 03:01:31.244 03:01:31.427 *
|
||||
91.92.241.196 15 7 0 13:55:12.175 15:50:21.628 *
|
||||
209.99.189.152 13 6 0 18:03:04.845 18:03:12.906 *
|
||||
34.140.123.172 434 6 411 21:34:17.485 21:35:45.084 *
|
||||
162.243.79.174 11 5 0 12:20:28.790 12:20:40.350 *
|
||||
51.79.208.246 10 5 0 13:50:27.669 13:50:29.418 *
|
||||
94.154.43.184 10 5 0 11:23:26.214 09:31:40.319 *
|
||||
195.178.110.211 8 4 0 19:35:03.504 20:22:13.338 *
|
||||
157.245.63.62 4 2 0 08:13:33.142 13:04:56.122 *
|
||||
163.7.13.115 5 2 0 14:06:27.842 14:06:29.745 *
|
||||
45.138.16.114 5 2 0 03:09:59.971 03:10:00.217 *
|
||||
45.148.10.95 4 2 0 21:05:26.356 14:40:26.566 *
|
||||
91.92.41.115 8 2 0 14:44:48.975 14:44:54.158 *
|
||||
94.154.43.179 5 2 0 13:27:23.753 04:38:17.921 *
|
||||
107.170.9.103 2 1 0 00:19:26.062 00:19:26.062 *
|
||||
129.212.237.196 2 1 0 09:23:08.470 09:23:08.471 *
|
||||
134.209.162.128 2 1 0 00:43:12.731 00:43:12.731 *
|
||||
158.101.144.198 2 1 0 14:30:06.125 14:30:06.125 *
|
||||
165.245.185.158 2 1 0 09:20:47.477 09:20:47.477 *
|
||||
195.178.110.159 2 1 0 20:41:43.691 20:41:43.691 *
|
||||
2.57.122.173 2 1 0 12:10:19.177 12:10:19.177 *
|
||||
23.180.120.147 4 1 0 13:53:30.303 13:53:30.473 *
|
||||
31.58.51.184 4 1 0 15:07:53.176 15:07:58.514 *
|
||||
34.125.42.15 2 1 0 21:39:44.709 21:39:44.709 *
|
||||
34.91.243.226 2 1 0 19:51:57.606 19:51:57.606 *
|
||||
35.231.100.82 2 1 0 15:36:23.715 15:36:23.715 *
|
||||
35.233.191.179 2 1 0 00:16:07.188 00:16:07.199 *
|
||||
35.95.56.230 3 1 0 02:29:40.010 02:29:40.562 *
|
||||
43.98.201.177 2 1 0 01:01:05.988 01:01:05.988 *
|
||||
45.139.104.172 2 1 0 03:14:49.950 03:14:49.950 *
|
||||
64.226.123.37 2 1 0 21:33:32.148 21:33:32.148 *
|
||||
8.229.130.50 2 1 0 19:23:37.001 19:23:37.002 *
|
||||
93.123.109.167 2 1 0 04:39:35.474 04:39:35.474 *
|
||||
94.154.43.183 3 1 0 21:50:39.582 00:01:42.127 *
|
||||
94.154.43.185 3 1 0 01:40:53.903 04:02:34.085 *
|
||||
94.154.43.186 3 1 0 21:07:26.439 13:43:18.923 *
|
||||
94.154.43.188 5 1 0 02:45:01.636 11:09:54.264 *
|
||||
94.154.43.229 4 1 0 14:35:26.801 12:53:30.198 *
|
||||
-- IPv6 (3) --
|
||||
ip total denied banned first last users whitelist
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
2a04:4e40:e000:0:d09:97ab:43b1:a59a 4 2 0 14:41:30.905 14:41:30.922 *
|
||||
2600:3c15::2000:53ff:fe31:8c0b 2 1 0 12:35:18.643 12:35:18.643 *
|
||||
2602:fa59:10:a3a::1 2 1 0 02:10:02.531 02:10:02.532 *
|
||||
copyparty log analysis report
|
||||
generated: 2026-08-08T14:31:22
|
||||
|
||||
log path: P:\copyparty
|
||||
log files: 44
|
||||
total requests: 26784
|
||||
unique IPs: 263 (IPv4 218 / IPv6 45)
|
||||
error requests: 6976
|
||||
unique denied paths: 2059
|
||||
denied requests: 6976
|
||||
banned IPs: 30
|
||||
authenticated users: {'admin': 523, 'corky': 78}
|
||||
denied-only ips: 120
|
||||
whitelisted IPs seen: 21
|
||||
block candidates: 122
|
||||
|
||||
== top 30 IPs ==
|
||||
ip total denied banned first last users whitelist
|
||||
------------------------------------------------------------------------------------
|
||||
93.123.109.101 4320 9 4264 00:35:05.539 00:40:32.578 *
|
||||
185.93.89.147 3762 8 0 19:07:14.620 08:52:41.657 *
|
||||
195.178.110.199 1258 621 0 03:02:41.078 03:02:42.924 *
|
||||
45.148.10.67 1258 621 0 20:49:39.003 20:49:41.111 *
|
||||
20.251.48.208 612 306 0 23:50:43.575 17:01:41.376 *
|
||||
20.215.216.94 516 257 0 16:16:39.439 15:21:39.387 *
|
||||
20.215.218.234 504 252 0 02:46:27.628 05:35:25.304 *
|
||||
34.140.123.172 434 6 411 21:34:17.485 21:35:45.084 *
|
||||
20.198.120.225 428 214 0 10:07:52.191 10:09:25.008 *
|
||||
18.227.73.7 392 9 363 22:00:31.465 22:01:33.982 *
|
||||
20.197.178.120 374 186 0 14:54:24.411 14:54:52.938 *
|
||||
74.249.245.134 354 177 0 21:27:53.575 21:29:06.182 *
|
||||
20.151.10.161 325 162 0 17:31:38.451 17:32:27.663 *
|
||||
20.205.229.184 323 161 0 12:17:54.322 12:18:41.173 *
|
||||
4.185.41.66 323 161 0 18:18:18.046 18:18:24.319 *
|
||||
52.184.96.217 323 161 0 20:02:55.760 20:03:44.824 *
|
||||
172.213.225.181 321 160 0 13:48:04.161 13:48:11.331 *
|
||||
20.48.236.161 321 160 0 15:11:59.817 15:12:31.060 *
|
||||
158.158.32.229 316 158 0 12:33:51.566 12:34:03.712 *
|
||||
20.63.63.128 315 157 0 16:04:22.373 16:04:50.675 *
|
||||
20.206.67.15 313 156 0 05:56:36.144 05:57:20.412 *
|
||||
20.215.185.25 300 150 0 08:18:05.984 08:19:09.190 *
|
||||
20.203.243.122 294 147 0 03:58:39.580 03:58:55.359 *
|
||||
20.226.26.5 286 143 0 06:33:33.891 06:34:07.483 *
|
||||
3.79.41.12 286 9 263 04:20:16.234 04:20:22.797 *
|
||||
34.242.226.103 286 9 263 06:52:40.299 06:52:54.689 *
|
||||
54.163.186.39 286 9 263 01:39:29.740 01:40:00.874 *
|
||||
16.146.99.254 279 9 256 12:11:20.725 12:12:09.790 *
|
||||
18.142.90.109 279 9 256 17:06:23.216 17:07:15.117 *
|
||||
68.221.130.241 278 139 0 08:28:43.979 08:28:50.496 *
|
||||
... 233 more IPs omitted
|
||||
|
||||
== top 20 denied paths ==
|
||||
58 /admin.php
|
||||
53 /.env
|
||||
49 /wp-content/plugins/hellopress/wp_filemanager.php
|
||||
49 /this_is_a_new_hello_world.php
|
||||
39 /1.php
|
||||
37 /classwithtostring.php
|
||||
37 /222.php
|
||||
36 /.git/config
|
||||
34 /wp-content/uploads
|
||||
33 /8.php
|
||||
33 /wp-content/admin.php
|
||||
31 /mac.php
|
||||
29 /aa.php
|
||||
29 /images.php
|
||||
29 /ops.php
|
||||
28 /wp.php
|
||||
28 /edit.php
|
||||
27 /file.php
|
||||
27 /coffexium.php
|
||||
25 /f35.php
|
||||
|
||||
== Denied-only IPs (120) ==
|
||||
never authenticated -- ban candidates
|
||||
-- IPv4 (117) --
|
||||
ip total denied banned first last users whitelist
|
||||
------------------------------------------------------------------------------------
|
||||
195.178.110.199 1258 621 0 03:02:41.078 03:02:42.924 *
|
||||
45.148.10.67 1258 621 0 20:49:39.003 20:49:41.111 *
|
||||
20.251.48.208 612 306 0 23:50:43.575 17:01:41.376 *
|
||||
20.215.216.94 516 257 0 16:16:39.439 15:21:39.387 *
|
||||
20.215.218.234 504 252 0 02:46:27.628 05:35:25.304 *
|
||||
20.198.120.225 428 214 0 10:07:52.191 10:09:25.008 *
|
||||
20.197.178.120 374 186 0 14:54:24.411 14:54:52.938 *
|
||||
74.249.245.134 354 177 0 21:27:53.575 21:29:06.182 *
|
||||
20.151.10.161 325 162 0 17:31:38.451 17:32:27.663 *
|
||||
20.205.229.184 323 161 0 12:17:54.322 12:18:41.173 *
|
||||
4.185.41.66 323 161 0 18:18:18.046 18:18:24.319 *
|
||||
52.184.96.217 323 161 0 20:02:55.760 20:03:44.824 *
|
||||
172.213.225.181 321 160 0 13:48:04.161 13:48:11.331 *
|
||||
20.48.236.161 321 160 0 15:11:59.817 15:12:31.060 *
|
||||
158.158.32.229 316 158 0 12:33:51.566 12:34:03.712 *
|
||||
20.63.63.128 315 157 0 16:04:22.373 16:04:50.675 *
|
||||
20.206.67.15 313 156 0 05:56:36.144 05:57:20.412 *
|
||||
20.215.185.25 300 150 0 08:18:05.984 08:19:09.190 *
|
||||
20.203.243.122 294 147 0 03:58:39.580 03:58:55.359 *
|
||||
20.226.26.5 286 143 0 06:33:33.891 06:34:07.483 *
|
||||
68.221.130.241 278 139 0 08:28:43.979 08:28:50.496 *
|
||||
20.100.172.153 275 137 0 09:10:06.751 09:10:17.835 *
|
||||
74.248.33.172 257 128 0 23:32:36.049 23:32:42.718 *
|
||||
20.203.179.12 250 125 0 17:33:20.484 17:33:29.742 *
|
||||
20.113.142.140 231 115 0 07:47:47.716 07:48:00.044 *
|
||||
158.158.105.63 208 104 0 11:24:12.912 23:00:49.043 *
|
||||
4.223.71.149 209 104 0 00:26:55.320 00:27:19.244 *
|
||||
135.225.93.215 203 101 0 02:32:24.496 02:32:32.326 *
|
||||
20.9.85.55 203 101 0 15:43:36.450 15:44:20.170 *
|
||||
20.91.208.34 203 101 0 22:07:01.428 22:07:20.883 *
|
||||
52.238.192.78 203 101 0 00:04:31.589 00:05:07.114 *
|
||||
172.213.208.13 192 96 0 13:27:56.743 19:14:00.938 *
|
||||
172.213.244.85 165 82 0 17:01:49.042 17:01:52.331 *
|
||||
20.206.105.145 157 78 0 04:06:08.085 04:06:29.772 *
|
||||
51.120.83.160 144 72 0 15:40:29.699 15:40:39.446 *
|
||||
172.213.153.79 114 57 0 18:40:13.799 18:40:20.149 *
|
||||
20.91.239.158 114 57 0 13:42:20.392 13:42:24.986 *
|
||||
172.213.227.73 108 54 0 03:00:13.592 03:00:18.810 *
|
||||
4.223.73.90 106 53 0 19:50:04.916 19:50:11.164 *
|
||||
4.232.185.87 110 53 0 21:23:31.012 21:23:33.019 *
|
||||
20.91.203.45 94 47 0 16:27:01.288 16:27:10.455 *
|
||||
20.197.192.193 88 44 0 13:45:32.377 13:45:43.108 *
|
||||
74.248.24.145 74 37 0 09:21:37.839 09:21:43.127 *
|
||||
172.213.144.209 70 35 0 07:52:16.066 07:52:17.778 *
|
||||
35.198.180.224 46 22 0 14:14:37.617 14:14:48.930 *
|
||||
45.148.10.62 98 22 40 07:53:03.360 03:15:12.651 *
|
||||
45.148.10.244 109 18 70 04:53:37.585 09:56:59.103 *
|
||||
45.148.10.120 33 16 0 14:24:06.542 17:06:11.688 *
|
||||
34.39.210.94 24 12 0 19:31:07.030 19:31:07.101 *
|
||||
195.178.110.31 49 11 20 02:27:56.164 02:27:58.425 *
|
||||
195.178.110.223 37 10 13 01:31:40.464 01:56:49.503 *
|
||||
34.95.239.96 20 10 0 11:25:18.487 11:25:18.532 *
|
||||
107.173.254.55 29 9 9 07:04:56.768 07:05:17.755 *
|
||||
136.108.11.195 25 9 7 08:33:11.182 08:33:13.921 *
|
||||
139.59.118.17 180 9 157 08:21:30.247 08:22:03.812 *
|
||||
146.70.40.68 30 9 10 18:55:47.310 18:55:48.145 *
|
||||
147.182.149.75 40 9 21 21:50:17.837 21:50:45.474 *
|
||||
16.146.99.254 279 9 256 12:11:20.725 12:12:09.790 *
|
||||
163.7.11.71 93 9 72 07:24:55.235 07:25:05.144 *
|
||||
167.99.181.249 40 9 21 21:50:26.091 21:51:01.239 *
|
||||
18.142.90.109 279 9 256 17:06:23.216 17:07:15.117 *
|
||||
18.227.73.7 392 9 363 22:00:31.465 22:01:33.982 *
|
||||
207.175.159.248 25 9 7 03:52:06.643 03:52:07.542 *
|
||||
207.175.20.232 25 9 7 09:43:00.775 09:43:03.604 *
|
||||
209.99.189.190 77 9 59 17:04:48.190 09:53:52.093 *
|
||||
3.79.41.12 286 9 263 04:20:16.234 04:20:22.797 *
|
||||
34.105.30.251 29 9 9 15:55:43.824 15:55:49.547 *
|
||||
34.23.104.90 25 9 7 14:40:59.025 14:41:01.713 *
|
||||
34.242.226.103 286 9 263 06:52:40.299 06:52:54.689 *
|
||||
34.9.173.20 245 9 224 16:55:22.164 16:55:30.344 *
|
||||
45.67.85.190 32 9 11 19:41:44.132 19:41:46.806 *
|
||||
54.163.186.39 286 9 263 01:39:29.740 01:40:00.874 *
|
||||
85.204.70.100 30 9 10 13:55:11.862 13:55:12.567 *
|
||||
91.192.10.86 31 9 10 13:38:54.986 13:38:56.159 *
|
||||
93.123.109.101 4320 9 4264 00:35:05.539 00:40:32.578 *
|
||||
185.93.89.147 3762 8 0 19:07:14.620 08:52:41.657 *
|
||||
195.178.110.155 57 8 0 09:10:16.072 09:10:19.329 *
|
||||
45.148.10.194 58 8 0 15:46:42.822 15:46:45.473 *
|
||||
45.148.10.247 57 8 0 00:58:56.398 00:58:59.599 *
|
||||
72.146.20.230 14 7 0 03:01:31.244 03:01:31.427 *
|
||||
91.92.241.196 15 7 0 13:55:12.175 15:50:21.628 *
|
||||
209.99.189.152 13 6 0 18:03:04.845 18:03:12.906 *
|
||||
34.140.123.172 434 6 411 21:34:17.485 21:35:45.084 *
|
||||
162.243.79.174 11 5 0 12:20:28.790 12:20:40.350 *
|
||||
51.79.208.246 10 5 0 13:50:27.669 13:50:29.418 *
|
||||
94.154.43.184 10 5 0 11:23:26.214 09:31:40.319 *
|
||||
195.178.110.211 8 4 0 19:35:03.504 20:22:13.338 *
|
||||
157.245.63.62 4 2 0 08:13:33.142 13:04:56.122 *
|
||||
163.7.13.115 5 2 0 14:06:27.842 14:06:29.745 *
|
||||
45.138.16.114 5 2 0 03:09:59.971 03:10:00.217 *
|
||||
45.148.10.95 4 2 0 21:05:26.356 14:40:26.566 *
|
||||
91.92.41.115 8 2 0 14:44:48.975 14:44:54.158 *
|
||||
94.154.43.179 5 2 0 13:27:23.753 04:38:17.921 *
|
||||
107.170.9.103 2 1 0 00:19:26.062 00:19:26.062 *
|
||||
129.212.237.196 2 1 0 09:23:08.470 09:23:08.471 *
|
||||
134.209.162.128 2 1 0 00:43:12.731 00:43:12.731 *
|
||||
158.101.144.198 2 1 0 14:30:06.125 14:30:06.125 *
|
||||
165.245.185.158 2 1 0 09:20:47.477 09:20:47.477 *
|
||||
195.178.110.159 2 1 0 20:41:43.691 20:41:43.691 *
|
||||
2.57.122.173 2 1 0 12:10:19.177 12:10:19.177 *
|
||||
23.180.120.147 4 1 0 13:53:30.303 13:53:30.473 *
|
||||
31.58.51.184 4 1 0 15:07:53.176 15:07:58.514 *
|
||||
34.125.42.15 2 1 0 21:39:44.709 21:39:44.709 *
|
||||
34.91.243.226 2 1 0 19:51:57.606 19:51:57.606 *
|
||||
35.231.100.82 2 1 0 15:36:23.715 15:36:23.715 *
|
||||
35.233.191.179 2 1 0 00:16:07.188 00:16:07.199 *
|
||||
35.95.56.230 3 1 0 02:29:40.010 02:29:40.562 *
|
||||
43.98.201.177 2 1 0 01:01:05.988 01:01:05.988 *
|
||||
45.139.104.172 2 1 0 03:14:49.950 03:14:49.950 *
|
||||
64.226.123.37 2 1 0 21:33:32.148 21:33:32.148 *
|
||||
8.229.130.50 2 1 0 19:23:37.001 19:23:37.002 *
|
||||
93.123.109.167 2 1 0 04:39:35.474 04:39:35.474 *
|
||||
94.154.43.183 3 1 0 21:50:39.582 00:01:42.127 *
|
||||
94.154.43.185 3 1 0 01:40:53.903 04:02:34.085 *
|
||||
94.154.43.186 3 1 0 21:07:26.439 13:43:18.923 *
|
||||
94.154.43.188 5 1 0 02:45:01.636 11:09:54.264 *
|
||||
94.154.43.229 4 1 0 14:35:26.801 12:53:30.198 *
|
||||
-- IPv6 (3) --
|
||||
ip total denied banned first last users whitelist
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
2a04:4e40:e000:0:d09:97ab:43b1:a59a 4 2 0 14:41:30.905 14:41:30.922 *
|
||||
2600:3c15::2000:53ff:fe31:8c0b 2 1 0 12:35:18.643 12:35:18.643 *
|
||||
2602:fa59:10:a3a::1 2 1 0 02:10:02.531 02:10:02.532 *
|
||||
@@ -1,210 +1,210 @@
|
||||
copyparty log analysis report
|
||||
generated: 2026-08-11T11:43:46
|
||||
|
||||
log path: \\naspve\nas\projects\copyparty
|
||||
log files: 48
|
||||
total requests: 30034
|
||||
unique IPs: 277 (IPv4 230 / IPv6 47)
|
||||
error requests: 7738
|
||||
unique denied paths: 2126
|
||||
denied requests: 7738
|
||||
banned IPs: 32
|
||||
authenticated users: {'admin': 537, 'corky': 78}
|
||||
denied-only ips: 129
|
||||
whitelisted IPs seen: 23
|
||||
block candidates: 131
|
||||
|
||||
== top 30 IPs ==
|
||||
ip total denied banned first last users whitelist
|
||||
------------------------------------------------------------------------------------
|
||||
93.123.109.101 4320 9 4264 00:35:05.539 00:40:32.578 *
|
||||
185.93.89.147 3762 8 0 19:07:14.620 08:52:41.657 *
|
||||
192.168.88.8 1736 0 0 13:31:27.246 09:40:39.082 -
|
||||
195.178.110.199 1258 621 0 03:02:41.078 03:02:42.924 *
|
||||
45.148.10.67 1258 621 0 20:49:39.003 20:49:41.111 *
|
||||
20.251.48.208 612 306 0 23:50:43.575 17:01:41.376 *
|
||||
20.215.216.94 516 257 0 16:16:39.439 15:21:39.387 *
|
||||
20.215.218.234 504 252 0 02:46:27.628 05:35:25.304 *
|
||||
34.140.123.172 434 6 411 21:34:17.485 21:35:45.084 *
|
||||
20.198.120.225 428 214 0 10:07:52.191 10:09:25.008 *
|
||||
18.227.73.7 392 9 363 22:00:31.465 22:01:33.982 *
|
||||
172.213.227.73 382 191 0 03:00:13.592 01:13:37.755 *
|
||||
20.197.178.120 374 186 0 14:54:24.411 14:54:52.938 *
|
||||
74.249.245.134 354 177 0 21:27:53.575 21:29:06.182 *
|
||||
20.151.10.161 325 162 0 17:31:38.451 17:32:27.663 *
|
||||
20.205.229.184 323 161 0 12:17:54.322 12:18:41.173 *
|
||||
4.185.41.66 323 161 0 18:18:18.046 18:18:24.319 *
|
||||
52.184.96.217 323 161 0 20:02:55.760 20:03:44.824 *
|
||||
172.213.225.181 321 160 0 13:48:04.161 13:48:11.331 *
|
||||
20.48.236.161 321 160 0 15:11:59.817 15:12:31.060 *
|
||||
158.158.32.229 316 158 0 12:33:51.566 12:34:03.712 *
|
||||
20.63.63.128 315 157 0 16:04:22.373 16:04:50.675 *
|
||||
20.206.67.15 313 156 0 05:56:36.144 05:57:20.412 *
|
||||
20.215.185.25 300 150 0 08:18:05.984 08:19:09.190 *
|
||||
20.203.243.122 294 147 0 03:58:39.580 03:58:55.359 *
|
||||
20.52.171.102 292 146 0 20:01:30.635 20:01:36.800 *
|
||||
20.226.26.5 286 143 0 06:33:33.891 06:34:07.483 *
|
||||
3.79.41.12 286 9 263 04:20:16.234 04:20:22.797 *
|
||||
34.242.226.103 286 9 263 06:52:40.299 06:52:54.689 *
|
||||
54.163.186.39 286 9 263 01:39:29.740 01:40:00.874 *
|
||||
... 247 more IPs omitted
|
||||
|
||||
== top 20 denied paths ==
|
||||
67 /admin.php
|
||||
56 /wp-content/plugins/hellopress/wp_filemanager.php
|
||||
56 /this_is_a_new_hello_world.php
|
||||
54 /.env
|
||||
46 /1.php
|
||||
44 /classwithtostring.php
|
||||
42 /222.php
|
||||
38 /8.php
|
||||
37 /.git/config
|
||||
37 /wp-content/uploads
|
||||
37 /wp-content/admin.php
|
||||
35 /mac.php
|
||||
34 /aa.php
|
||||
34 /images.php
|
||||
33 /ops.php
|
||||
32 /wp.php
|
||||
31 /edit.php
|
||||
31 /coffexium.php
|
||||
29 /file.php
|
||||
29 /inputs.php
|
||||
|
||||
== Denied-only IPs (129) ==
|
||||
never authenticated -- ban candidates
|
||||
-- IPv4 (126) --
|
||||
ip total denied banned first last users whitelist
|
||||
------------------------------------------------------------------------------------
|
||||
195.178.110.199 1258 621 0 03:02:41.078 03:02:42.924 *
|
||||
45.148.10.67 1258 621 0 20:49:39.003 20:49:41.111 *
|
||||
20.251.48.208 612 306 0 23:50:43.575 17:01:41.376 *
|
||||
20.215.216.94 516 257 0 16:16:39.439 15:21:39.387 *
|
||||
20.215.218.234 504 252 0 02:46:27.628 05:35:25.304 *
|
||||
20.198.120.225 428 214 0 10:07:52.191 10:09:25.008 *
|
||||
172.213.227.73 382 191 0 03:00:13.592 01:13:37.755 *
|
||||
20.197.178.120 374 186 0 14:54:24.411 14:54:52.938 *
|
||||
74.249.245.134 354 177 0 21:27:53.575 21:29:06.182 *
|
||||
20.151.10.161 325 162 0 17:31:38.451 17:32:27.663 *
|
||||
20.205.229.184 323 161 0 12:17:54.322 12:18:41.173 *
|
||||
4.185.41.66 323 161 0 18:18:18.046 18:18:24.319 *
|
||||
52.184.96.217 323 161 0 20:02:55.760 20:03:44.824 *
|
||||
172.213.225.181 321 160 0 13:48:04.161 13:48:11.331 *
|
||||
20.48.236.161 321 160 0 15:11:59.817 15:12:31.060 *
|
||||
158.158.32.229 316 158 0 12:33:51.566 12:34:03.712 *
|
||||
20.63.63.128 315 157 0 16:04:22.373 16:04:50.675 *
|
||||
20.206.67.15 313 156 0 05:56:36.144 05:57:20.412 *
|
||||
20.215.185.25 300 150 0 08:18:05.984 08:19:09.190 *
|
||||
20.203.243.122 294 147 0 03:58:39.580 03:58:55.359 *
|
||||
20.52.171.102 292 146 0 20:01:30.635 20:01:36.800 *
|
||||
20.226.26.5 286 143 0 06:33:33.891 06:34:07.483 *
|
||||
68.221.130.241 278 139 0 08:28:43.979 08:28:50.496 *
|
||||
20.100.172.153 275 137 0 09:10:06.751 09:10:17.835 *
|
||||
51.107.190.246 274 137 0 01:44:18.242 01:44:28.832 *
|
||||
74.248.33.172 257 128 0 23:32:36.049 23:32:42.718 *
|
||||
20.203.179.12 250 125 0 17:33:20.484 17:33:29.742 *
|
||||
20.113.142.140 231 115 0 07:47:47.716 07:48:00.044 *
|
||||
74.248.97.169 231 115 0 13:25:17.217 13:25:31.602 *
|
||||
20.251.112.224 215 107 0 06:52:51.081 06:53:05.602 *
|
||||
158.158.105.63 208 104 0 11:24:12.912 23:00:49.043 *
|
||||
4.223.71.149 209 104 0 00:26:55.320 00:27:19.244 *
|
||||
4.223.73.90 204 102 0 19:50:04.916 18:12:09.187 *
|
||||
135.225.93.215 203 101 0 02:32:24.496 02:32:32.326 *
|
||||
20.9.85.55 203 101 0 15:43:36.450 15:44:20.170 *
|
||||
20.91.208.34 203 101 0 22:07:01.428 22:07:20.883 *
|
||||
52.238.192.78 203 101 0 00:04:31.589 00:05:07.114 *
|
||||
172.213.208.13 192 96 0 13:27:56.743 19:14:00.938 *
|
||||
172.213.244.85 165 82 0 17:01:49.042 17:01:52.331 *
|
||||
20.206.105.145 157 78 0 04:06:08.085 04:06:29.772 *
|
||||
51.120.83.160 144 72 0 15:40:29.699 15:40:39.446 *
|
||||
172.213.153.79 114 57 0 18:40:13.799 18:40:20.149 *
|
||||
20.91.239.158 114 57 0 13:42:20.392 13:42:24.986 *
|
||||
4.232.185.87 110 53 0 21:23:31.012 21:23:33.019 *
|
||||
20.218.73.95 98 49 0 04:39:44.907 04:39:46.708 *
|
||||
20.91.203.45 94 47 0 16:27:01.288 16:27:10.455 *
|
||||
20.197.192.193 88 44 0 13:45:32.377 13:45:43.108 *
|
||||
74.248.24.145 74 37 0 09:21:37.839 09:21:43.127 *
|
||||
172.213.144.209 70 35 0 07:52:16.066 07:52:17.778 *
|
||||
35.198.180.224 46 22 0 14:14:37.617 14:14:48.930 *
|
||||
45.148.10.62 98 22 40 07:53:03.360 03:15:12.651 *
|
||||
45.148.10.244 109 18 70 04:53:37.585 09:56:59.103 *
|
||||
45.148.10.120 33 16 0 14:24:06.542 17:06:11.688 *
|
||||
34.39.210.94 24 12 0 19:31:07.030 19:31:07.101 *
|
||||
195.178.110.31 49 11 20 02:27:56.164 02:27:58.425 *
|
||||
195.178.110.223 37 10 13 01:31:40.464 01:56:49.503 *
|
||||
34.95.239.96 20 10 0 11:25:18.487 11:25:18.532 *
|
||||
107.173.254.55 29 9 9 07:04:56.768 07:05:17.755 *
|
||||
136.108.11.195 25 9 7 08:33:11.182 08:33:13.921 *
|
||||
139.59.118.17 180 9 157 08:21:30.247 08:22:03.812 *
|
||||
146.70.40.68 30 9 10 18:55:47.310 18:55:48.145 *
|
||||
147.182.149.75 40 9 21 21:50:17.837 21:50:45.474 *
|
||||
16.146.99.254 279 9 256 12:11:20.725 12:12:09.790 *
|
||||
163.7.11.71 93 9 72 07:24:55.235 07:25:05.144 *
|
||||
167.99.181.249 40 9 21 21:50:26.091 21:51:01.239 *
|
||||
18.142.90.109 279 9 256 17:06:23.216 17:07:15.117 *
|
||||
18.227.73.7 392 9 363 22:00:31.465 22:01:33.982 *
|
||||
207.175.159.248 25 9 7 03:52:06.643 03:52:07.542 *
|
||||
207.175.20.232 25 9 7 09:43:00.775 09:43:03.604 *
|
||||
209.99.189.190 77 9 59 17:04:48.190 09:53:52.093 *
|
||||
3.79.41.12 286 9 263 04:20:16.234 04:20:22.797 *
|
||||
34.105.30.251 29 9 9 15:55:43.824 15:55:49.547 *
|
||||
34.23.104.90 25 9 7 14:40:59.025 14:41:01.713 *
|
||||
34.242.226.103 286 9 263 06:52:40.299 06:52:54.689 *
|
||||
34.9.173.20 245 9 224 16:55:22.164 16:55:30.344 *
|
||||
45.67.85.190 32 9 11 19:41:44.132 19:41:46.806 *
|
||||
54.163.186.39 286 9 263 01:39:29.740 01:40:00.874 *
|
||||
82.102.18.116 30 9 10 04:49:33.098 04:49:34.184 *
|
||||
85.204.70.100 30 9 10 13:55:11.862 13:55:12.567 *
|
||||
88.151.32.7 88 9 69 18:43:38.911 19:04:03.160 *
|
||||
91.192.10.86 31 9 10 13:38:54.986 13:38:56.159 *
|
||||
93.123.109.101 4320 9 4264 00:35:05.539 00:40:32.578 *
|
||||
185.93.89.147 3762 8 0 19:07:14.620 08:52:41.657 *
|
||||
195.178.110.155 57 8 0 09:10:16.072 09:10:19.329 *
|
||||
45.148.10.194 58 8 0 15:46:42.822 15:46:45.473 *
|
||||
45.148.10.247 57 8 0 00:58:56.398 00:58:59.599 *
|
||||
72.146.20.230 14 7 0 03:01:31.244 03:01:31.427 *
|
||||
91.92.241.196 15 7 0 13:55:12.175 15:50:21.628 *
|
||||
209.99.189.152 13 6 0 18:03:04.845 18:03:12.906 *
|
||||
34.140.123.172 434 6 411 21:34:17.485 21:35:45.084 *
|
||||
162.243.79.174 11 5 0 12:20:28.790 12:20:40.350 *
|
||||
51.79.208.246 10 5 0 13:50:27.669 13:50:29.418 *
|
||||
94.154.43.184 10 5 0 11:23:26.214 09:31:40.319 *
|
||||
195.178.110.211 8 4 0 19:35:03.504 20:22:13.338 *
|
||||
45.148.10.119 11 3 0 02:36:55.008 07:16:27.585 *
|
||||
157.245.63.62 4 2 0 08:13:33.142 13:04:56.122 *
|
||||
163.7.13.115 5 2 0 14:06:27.842 14:06:29.745 *
|
||||
45.138.16.114 5 2 0 03:09:59.971 03:10:00.217 *
|
||||
45.148.10.95 4 2 0 21:05:26.356 14:40:26.566 *
|
||||
91.92.41.115 8 2 0 14:44:48.975 14:44:54.158 *
|
||||
94.154.43.179 5 2 0 13:27:23.753 04:38:17.921 *
|
||||
107.170.9.103 2 1 0 00:19:26.062 00:19:26.062 *
|
||||
129.212.237.196 2 1 0 09:23:08.470 09:23:08.471 *
|
||||
134.209.162.128 2 1 0 00:43:12.731 00:43:12.731 *
|
||||
158.101.144.198 2 1 0 14:30:06.125 14:30:06.125 *
|
||||
165.245.185.158 2 1 0 09:20:47.477 09:20:47.477 *
|
||||
176.65.132.38 3 1 0 20:33:22.070 05:08:32.533 *
|
||||
195.178.110.159 2 1 0 20:41:43.691 20:41:43.691 *
|
||||
2.57.122.173 2 1 0 12:10:19.177 12:10:19.177 *
|
||||
23.180.120.147 4 1 0 13:53:30.303 13:53:30.473 *
|
||||
31.58.51.184 4 1 0 15:07:53.176 15:07:58.514 *
|
||||
34.125.42.15 2 1 0 21:39:44.709 21:39:44.709 *
|
||||
34.91.243.226 2 1 0 19:51:57.606 19:51:57.606 *
|
||||
35.231.100.82 2 1 0 15:36:23.715 15:36:23.715 *
|
||||
35.233.191.179 2 1 0 00:16:07.188 00:16:07.199 *
|
||||
35.95.56.230 3 1 0 02:29:40.010 02:29:40.562 *
|
||||
43.98.201.177 2 1 0 01:01:05.988 01:01:05.988 *
|
||||
45.139.104.172 2 1 0 03:14:49.950 03:14:49.950 *
|
||||
64.226.123.37 2 1 0 21:33:32.148 21:33:32.148 *
|
||||
8.229.130.50 2 1 0 19:23:37.001 19:23:37.002 *
|
||||
93.123.109.167 2 1 0 04:39:35.474 04:39:35.474 *
|
||||
94.154.43.183 3 1 0 21:50:39.582 00:01:42.127 *
|
||||
94.154.43.185 3 1 0 01:40:53.903 04:02:34.085 *
|
||||
94.154.43.186 3 1 0 21:07:26.439 13:43:18.923 *
|
||||
94.154.43.188 5 1 0 02:45:01.636 11:09:54.264 *
|
||||
94.154.43.229 4 1 0 14:35:26.801 12:53:30.198 *
|
||||
-- IPv6 (3) --
|
||||
ip total denied banned first last users whitelist
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
2a04:4e40:e000:0:d09:97ab:43b1:a59a 4 2 0 14:41:30.905 14:41:30.922 *
|
||||
2600:3c15::2000:53ff:fe31:8c0b 2 1 0 12:35:18.643 12:35:18.643 *
|
||||
2602:fa59:10:a3a::1 2 1 0 02:10:02.531 02:10:02.532 *
|
||||
copyparty log analysis report
|
||||
generated: 2026-08-11T11:43:46
|
||||
|
||||
log path: \\naspve\nas\projects\copyparty
|
||||
log files: 48
|
||||
total requests: 30034
|
||||
unique IPs: 277 (IPv4 230 / IPv6 47)
|
||||
error requests: 7738
|
||||
unique denied paths: 2126
|
||||
denied requests: 7738
|
||||
banned IPs: 32
|
||||
authenticated users: {'admin': 537, 'corky': 78}
|
||||
denied-only ips: 129
|
||||
whitelisted IPs seen: 23
|
||||
block candidates: 131
|
||||
|
||||
== top 30 IPs ==
|
||||
ip total denied banned first last users whitelist
|
||||
------------------------------------------------------------------------------------
|
||||
93.123.109.101 4320 9 4264 00:35:05.539 00:40:32.578 *
|
||||
185.93.89.147 3762 8 0 19:07:14.620 08:52:41.657 *
|
||||
192.168.88.8 1736 0 0 13:31:27.246 09:40:39.082 -
|
||||
195.178.110.199 1258 621 0 03:02:41.078 03:02:42.924 *
|
||||
45.148.10.67 1258 621 0 20:49:39.003 20:49:41.111 *
|
||||
20.251.48.208 612 306 0 23:50:43.575 17:01:41.376 *
|
||||
20.215.216.94 516 257 0 16:16:39.439 15:21:39.387 *
|
||||
20.215.218.234 504 252 0 02:46:27.628 05:35:25.304 *
|
||||
34.140.123.172 434 6 411 21:34:17.485 21:35:45.084 *
|
||||
20.198.120.225 428 214 0 10:07:52.191 10:09:25.008 *
|
||||
18.227.73.7 392 9 363 22:00:31.465 22:01:33.982 *
|
||||
172.213.227.73 382 191 0 03:00:13.592 01:13:37.755 *
|
||||
20.197.178.120 374 186 0 14:54:24.411 14:54:52.938 *
|
||||
74.249.245.134 354 177 0 21:27:53.575 21:29:06.182 *
|
||||
20.151.10.161 325 162 0 17:31:38.451 17:32:27.663 *
|
||||
20.205.229.184 323 161 0 12:17:54.322 12:18:41.173 *
|
||||
4.185.41.66 323 161 0 18:18:18.046 18:18:24.319 *
|
||||
52.184.96.217 323 161 0 20:02:55.760 20:03:44.824 *
|
||||
172.213.225.181 321 160 0 13:48:04.161 13:48:11.331 *
|
||||
20.48.236.161 321 160 0 15:11:59.817 15:12:31.060 *
|
||||
158.158.32.229 316 158 0 12:33:51.566 12:34:03.712 *
|
||||
20.63.63.128 315 157 0 16:04:22.373 16:04:50.675 *
|
||||
20.206.67.15 313 156 0 05:56:36.144 05:57:20.412 *
|
||||
20.215.185.25 300 150 0 08:18:05.984 08:19:09.190 *
|
||||
20.203.243.122 294 147 0 03:58:39.580 03:58:55.359 *
|
||||
20.52.171.102 292 146 0 20:01:30.635 20:01:36.800 *
|
||||
20.226.26.5 286 143 0 06:33:33.891 06:34:07.483 *
|
||||
3.79.41.12 286 9 263 04:20:16.234 04:20:22.797 *
|
||||
34.242.226.103 286 9 263 06:52:40.299 06:52:54.689 *
|
||||
54.163.186.39 286 9 263 01:39:29.740 01:40:00.874 *
|
||||
... 247 more IPs omitted
|
||||
|
||||
== top 20 denied paths ==
|
||||
67 /admin.php
|
||||
56 /wp-content/plugins/hellopress/wp_filemanager.php
|
||||
56 /this_is_a_new_hello_world.php
|
||||
54 /.env
|
||||
46 /1.php
|
||||
44 /classwithtostring.php
|
||||
42 /222.php
|
||||
38 /8.php
|
||||
37 /.git/config
|
||||
37 /wp-content/uploads
|
||||
37 /wp-content/admin.php
|
||||
35 /mac.php
|
||||
34 /aa.php
|
||||
34 /images.php
|
||||
33 /ops.php
|
||||
32 /wp.php
|
||||
31 /edit.php
|
||||
31 /coffexium.php
|
||||
29 /file.php
|
||||
29 /inputs.php
|
||||
|
||||
== Denied-only IPs (129) ==
|
||||
never authenticated -- ban candidates
|
||||
-- IPv4 (126) --
|
||||
ip total denied banned first last users whitelist
|
||||
------------------------------------------------------------------------------------
|
||||
195.178.110.199 1258 621 0 03:02:41.078 03:02:42.924 *
|
||||
45.148.10.67 1258 621 0 20:49:39.003 20:49:41.111 *
|
||||
20.251.48.208 612 306 0 23:50:43.575 17:01:41.376 *
|
||||
20.215.216.94 516 257 0 16:16:39.439 15:21:39.387 *
|
||||
20.215.218.234 504 252 0 02:46:27.628 05:35:25.304 *
|
||||
20.198.120.225 428 214 0 10:07:52.191 10:09:25.008 *
|
||||
172.213.227.73 382 191 0 03:00:13.592 01:13:37.755 *
|
||||
20.197.178.120 374 186 0 14:54:24.411 14:54:52.938 *
|
||||
74.249.245.134 354 177 0 21:27:53.575 21:29:06.182 *
|
||||
20.151.10.161 325 162 0 17:31:38.451 17:32:27.663 *
|
||||
20.205.229.184 323 161 0 12:17:54.322 12:18:41.173 *
|
||||
4.185.41.66 323 161 0 18:18:18.046 18:18:24.319 *
|
||||
52.184.96.217 323 161 0 20:02:55.760 20:03:44.824 *
|
||||
172.213.225.181 321 160 0 13:48:04.161 13:48:11.331 *
|
||||
20.48.236.161 321 160 0 15:11:59.817 15:12:31.060 *
|
||||
158.158.32.229 316 158 0 12:33:51.566 12:34:03.712 *
|
||||
20.63.63.128 315 157 0 16:04:22.373 16:04:50.675 *
|
||||
20.206.67.15 313 156 0 05:56:36.144 05:57:20.412 *
|
||||
20.215.185.25 300 150 0 08:18:05.984 08:19:09.190 *
|
||||
20.203.243.122 294 147 0 03:58:39.580 03:58:55.359 *
|
||||
20.52.171.102 292 146 0 20:01:30.635 20:01:36.800 *
|
||||
20.226.26.5 286 143 0 06:33:33.891 06:34:07.483 *
|
||||
68.221.130.241 278 139 0 08:28:43.979 08:28:50.496 *
|
||||
20.100.172.153 275 137 0 09:10:06.751 09:10:17.835 *
|
||||
51.107.190.246 274 137 0 01:44:18.242 01:44:28.832 *
|
||||
74.248.33.172 257 128 0 23:32:36.049 23:32:42.718 *
|
||||
20.203.179.12 250 125 0 17:33:20.484 17:33:29.742 *
|
||||
20.113.142.140 231 115 0 07:47:47.716 07:48:00.044 *
|
||||
74.248.97.169 231 115 0 13:25:17.217 13:25:31.602 *
|
||||
20.251.112.224 215 107 0 06:52:51.081 06:53:05.602 *
|
||||
158.158.105.63 208 104 0 11:24:12.912 23:00:49.043 *
|
||||
4.223.71.149 209 104 0 00:26:55.320 00:27:19.244 *
|
||||
4.223.73.90 204 102 0 19:50:04.916 18:12:09.187 *
|
||||
135.225.93.215 203 101 0 02:32:24.496 02:32:32.326 *
|
||||
20.9.85.55 203 101 0 15:43:36.450 15:44:20.170 *
|
||||
20.91.208.34 203 101 0 22:07:01.428 22:07:20.883 *
|
||||
52.238.192.78 203 101 0 00:04:31.589 00:05:07.114 *
|
||||
172.213.208.13 192 96 0 13:27:56.743 19:14:00.938 *
|
||||
172.213.244.85 165 82 0 17:01:49.042 17:01:52.331 *
|
||||
20.206.105.145 157 78 0 04:06:08.085 04:06:29.772 *
|
||||
51.120.83.160 144 72 0 15:40:29.699 15:40:39.446 *
|
||||
172.213.153.79 114 57 0 18:40:13.799 18:40:20.149 *
|
||||
20.91.239.158 114 57 0 13:42:20.392 13:42:24.986 *
|
||||
4.232.185.87 110 53 0 21:23:31.012 21:23:33.019 *
|
||||
20.218.73.95 98 49 0 04:39:44.907 04:39:46.708 *
|
||||
20.91.203.45 94 47 0 16:27:01.288 16:27:10.455 *
|
||||
20.197.192.193 88 44 0 13:45:32.377 13:45:43.108 *
|
||||
74.248.24.145 74 37 0 09:21:37.839 09:21:43.127 *
|
||||
172.213.144.209 70 35 0 07:52:16.066 07:52:17.778 *
|
||||
35.198.180.224 46 22 0 14:14:37.617 14:14:48.930 *
|
||||
45.148.10.62 98 22 40 07:53:03.360 03:15:12.651 *
|
||||
45.148.10.244 109 18 70 04:53:37.585 09:56:59.103 *
|
||||
45.148.10.120 33 16 0 14:24:06.542 17:06:11.688 *
|
||||
34.39.210.94 24 12 0 19:31:07.030 19:31:07.101 *
|
||||
195.178.110.31 49 11 20 02:27:56.164 02:27:58.425 *
|
||||
195.178.110.223 37 10 13 01:31:40.464 01:56:49.503 *
|
||||
34.95.239.96 20 10 0 11:25:18.487 11:25:18.532 *
|
||||
107.173.254.55 29 9 9 07:04:56.768 07:05:17.755 *
|
||||
136.108.11.195 25 9 7 08:33:11.182 08:33:13.921 *
|
||||
139.59.118.17 180 9 157 08:21:30.247 08:22:03.812 *
|
||||
146.70.40.68 30 9 10 18:55:47.310 18:55:48.145 *
|
||||
147.182.149.75 40 9 21 21:50:17.837 21:50:45.474 *
|
||||
16.146.99.254 279 9 256 12:11:20.725 12:12:09.790 *
|
||||
163.7.11.71 93 9 72 07:24:55.235 07:25:05.144 *
|
||||
167.99.181.249 40 9 21 21:50:26.091 21:51:01.239 *
|
||||
18.142.90.109 279 9 256 17:06:23.216 17:07:15.117 *
|
||||
18.227.73.7 392 9 363 22:00:31.465 22:01:33.982 *
|
||||
207.175.159.248 25 9 7 03:52:06.643 03:52:07.542 *
|
||||
207.175.20.232 25 9 7 09:43:00.775 09:43:03.604 *
|
||||
209.99.189.190 77 9 59 17:04:48.190 09:53:52.093 *
|
||||
3.79.41.12 286 9 263 04:20:16.234 04:20:22.797 *
|
||||
34.105.30.251 29 9 9 15:55:43.824 15:55:49.547 *
|
||||
34.23.104.90 25 9 7 14:40:59.025 14:41:01.713 *
|
||||
34.242.226.103 286 9 263 06:52:40.299 06:52:54.689 *
|
||||
34.9.173.20 245 9 224 16:55:22.164 16:55:30.344 *
|
||||
45.67.85.190 32 9 11 19:41:44.132 19:41:46.806 *
|
||||
54.163.186.39 286 9 263 01:39:29.740 01:40:00.874 *
|
||||
82.102.18.116 30 9 10 04:49:33.098 04:49:34.184 *
|
||||
85.204.70.100 30 9 10 13:55:11.862 13:55:12.567 *
|
||||
88.151.32.7 88 9 69 18:43:38.911 19:04:03.160 *
|
||||
91.192.10.86 31 9 10 13:38:54.986 13:38:56.159 *
|
||||
93.123.109.101 4320 9 4264 00:35:05.539 00:40:32.578 *
|
||||
185.93.89.147 3762 8 0 19:07:14.620 08:52:41.657 *
|
||||
195.178.110.155 57 8 0 09:10:16.072 09:10:19.329 *
|
||||
45.148.10.194 58 8 0 15:46:42.822 15:46:45.473 *
|
||||
45.148.10.247 57 8 0 00:58:56.398 00:58:59.599 *
|
||||
72.146.20.230 14 7 0 03:01:31.244 03:01:31.427 *
|
||||
91.92.241.196 15 7 0 13:55:12.175 15:50:21.628 *
|
||||
209.99.189.152 13 6 0 18:03:04.845 18:03:12.906 *
|
||||
34.140.123.172 434 6 411 21:34:17.485 21:35:45.084 *
|
||||
162.243.79.174 11 5 0 12:20:28.790 12:20:40.350 *
|
||||
51.79.208.246 10 5 0 13:50:27.669 13:50:29.418 *
|
||||
94.154.43.184 10 5 0 11:23:26.214 09:31:40.319 *
|
||||
195.178.110.211 8 4 0 19:35:03.504 20:22:13.338 *
|
||||
45.148.10.119 11 3 0 02:36:55.008 07:16:27.585 *
|
||||
157.245.63.62 4 2 0 08:13:33.142 13:04:56.122 *
|
||||
163.7.13.115 5 2 0 14:06:27.842 14:06:29.745 *
|
||||
45.138.16.114 5 2 0 03:09:59.971 03:10:00.217 *
|
||||
45.148.10.95 4 2 0 21:05:26.356 14:40:26.566 *
|
||||
91.92.41.115 8 2 0 14:44:48.975 14:44:54.158 *
|
||||
94.154.43.179 5 2 0 13:27:23.753 04:38:17.921 *
|
||||
107.170.9.103 2 1 0 00:19:26.062 00:19:26.062 *
|
||||
129.212.237.196 2 1 0 09:23:08.470 09:23:08.471 *
|
||||
134.209.162.128 2 1 0 00:43:12.731 00:43:12.731 *
|
||||
158.101.144.198 2 1 0 14:30:06.125 14:30:06.125 *
|
||||
165.245.185.158 2 1 0 09:20:47.477 09:20:47.477 *
|
||||
176.65.132.38 3 1 0 20:33:22.070 05:08:32.533 *
|
||||
195.178.110.159 2 1 0 20:41:43.691 20:41:43.691 *
|
||||
2.57.122.173 2 1 0 12:10:19.177 12:10:19.177 *
|
||||
23.180.120.147 4 1 0 13:53:30.303 13:53:30.473 *
|
||||
31.58.51.184 4 1 0 15:07:53.176 15:07:58.514 *
|
||||
34.125.42.15 2 1 0 21:39:44.709 21:39:44.709 *
|
||||
34.91.243.226 2 1 0 19:51:57.606 19:51:57.606 *
|
||||
35.231.100.82 2 1 0 15:36:23.715 15:36:23.715 *
|
||||
35.233.191.179 2 1 0 00:16:07.188 00:16:07.199 *
|
||||
35.95.56.230 3 1 0 02:29:40.010 02:29:40.562 *
|
||||
43.98.201.177 2 1 0 01:01:05.988 01:01:05.988 *
|
||||
45.139.104.172 2 1 0 03:14:49.950 03:14:49.950 *
|
||||
64.226.123.37 2 1 0 21:33:32.148 21:33:32.148 *
|
||||
8.229.130.50 2 1 0 19:23:37.001 19:23:37.002 *
|
||||
93.123.109.167 2 1 0 04:39:35.474 04:39:35.474 *
|
||||
94.154.43.183 3 1 0 21:50:39.582 00:01:42.127 *
|
||||
94.154.43.185 3 1 0 01:40:53.903 04:02:34.085 *
|
||||
94.154.43.186 3 1 0 21:07:26.439 13:43:18.923 *
|
||||
94.154.43.188 5 1 0 02:45:01.636 11:09:54.264 *
|
||||
94.154.43.229 4 1 0 14:35:26.801 12:53:30.198 *
|
||||
-- IPv6 (3) --
|
||||
ip total denied banned first last users whitelist
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
2a04:4e40:e000:0:d09:97ab:43b1:a59a 4 2 0 14:41:30.905 14:41:30.922 *
|
||||
2600:3c15::2000:53ff:fe31:8c0b 2 1 0 12:35:18.643 12:35:18.643 *
|
||||
2602:fa59:10:a3a::1 2 1 0 02:10:02.531 02:10:02.532 *
|
||||
@@ -1,210 +1,210 @@
|
||||
copyparty log analysis report
|
||||
generated: 2026-08-11T11:44:39
|
||||
|
||||
log path: \\naspve\nas\projects\copyparty
|
||||
log files: 48
|
||||
total requests: 30034
|
||||
unique IPs: 277 (IPv4 230 / IPv6 47)
|
||||
error requests: 7738
|
||||
unique denied paths: 2126
|
||||
denied requests: 7738
|
||||
banned IPs: 32
|
||||
authenticated users: {'admin': 537, 'corky': 78}
|
||||
denied-only ips: 129
|
||||
whitelisted IPs seen: 23
|
||||
block candidates: 131
|
||||
|
||||
== top 30 IPs ==
|
||||
ip total denied banned first last users whitelist
|
||||
------------------------------------------------------------------------------------
|
||||
93.123.109.101 4320 9 4264 00:35:05.539 00:40:32.578 *
|
||||
185.93.89.147 3762 8 0 19:07:14.620 08:52:41.657 *
|
||||
192.168.88.8 1736 0 0 13:31:27.246 09:40:39.082 -
|
||||
195.178.110.199 1258 621 0 03:02:41.078 03:02:42.924 *
|
||||
45.148.10.67 1258 621 0 20:49:39.003 20:49:41.111 *
|
||||
20.251.48.208 612 306 0 23:50:43.575 17:01:41.376 *
|
||||
20.215.216.94 516 257 0 16:16:39.439 15:21:39.387 *
|
||||
20.215.218.234 504 252 0 02:46:27.628 05:35:25.304 *
|
||||
34.140.123.172 434 6 411 21:34:17.485 21:35:45.084 *
|
||||
20.198.120.225 428 214 0 10:07:52.191 10:09:25.008 *
|
||||
18.227.73.7 392 9 363 22:00:31.465 22:01:33.982 *
|
||||
172.213.227.73 382 191 0 03:00:13.592 01:13:37.755 *
|
||||
20.197.178.120 374 186 0 14:54:24.411 14:54:52.938 *
|
||||
74.249.245.134 354 177 0 21:27:53.575 21:29:06.182 *
|
||||
20.151.10.161 325 162 0 17:31:38.451 17:32:27.663 *
|
||||
20.205.229.184 323 161 0 12:17:54.322 12:18:41.173 *
|
||||
4.185.41.66 323 161 0 18:18:18.046 18:18:24.319 *
|
||||
52.184.96.217 323 161 0 20:02:55.760 20:03:44.824 *
|
||||
172.213.225.181 321 160 0 13:48:04.161 13:48:11.331 *
|
||||
20.48.236.161 321 160 0 15:11:59.817 15:12:31.060 *
|
||||
158.158.32.229 316 158 0 12:33:51.566 12:34:03.712 *
|
||||
20.63.63.128 315 157 0 16:04:22.373 16:04:50.675 *
|
||||
20.206.67.15 313 156 0 05:56:36.144 05:57:20.412 *
|
||||
20.215.185.25 300 150 0 08:18:05.984 08:19:09.190 *
|
||||
20.203.243.122 294 147 0 03:58:39.580 03:58:55.359 *
|
||||
20.52.171.102 292 146 0 20:01:30.635 20:01:36.800 *
|
||||
20.226.26.5 286 143 0 06:33:33.891 06:34:07.483 *
|
||||
3.79.41.12 286 9 263 04:20:16.234 04:20:22.797 *
|
||||
34.242.226.103 286 9 263 06:52:40.299 06:52:54.689 *
|
||||
54.163.186.39 286 9 263 01:39:29.740 01:40:00.874 *
|
||||
... 247 more IPs omitted
|
||||
|
||||
== top 20 denied paths ==
|
||||
67 /admin.php
|
||||
56 /wp-content/plugins/hellopress/wp_filemanager.php
|
||||
56 /this_is_a_new_hello_world.php
|
||||
54 /.env
|
||||
46 /1.php
|
||||
44 /classwithtostring.php
|
||||
42 /222.php
|
||||
38 /8.php
|
||||
37 /.git/config
|
||||
37 /wp-content/uploads
|
||||
37 /wp-content/admin.php
|
||||
35 /mac.php
|
||||
34 /aa.php
|
||||
34 /images.php
|
||||
33 /ops.php
|
||||
32 /wp.php
|
||||
31 /edit.php
|
||||
31 /coffexium.php
|
||||
29 /file.php
|
||||
29 /inputs.php
|
||||
|
||||
== Denied-only IPs (129) ==
|
||||
never authenticated -- ban candidates
|
||||
-- IPv4 (126) --
|
||||
ip total denied banned first last users whitelist
|
||||
------------------------------------------------------------------------------------
|
||||
195.178.110.199 1258 621 0 03:02:41.078 03:02:42.924 *
|
||||
45.148.10.67 1258 621 0 20:49:39.003 20:49:41.111 *
|
||||
20.251.48.208 612 306 0 23:50:43.575 17:01:41.376 *
|
||||
20.215.216.94 516 257 0 16:16:39.439 15:21:39.387 *
|
||||
20.215.218.234 504 252 0 02:46:27.628 05:35:25.304 *
|
||||
20.198.120.225 428 214 0 10:07:52.191 10:09:25.008 *
|
||||
172.213.227.73 382 191 0 03:00:13.592 01:13:37.755 *
|
||||
20.197.178.120 374 186 0 14:54:24.411 14:54:52.938 *
|
||||
74.249.245.134 354 177 0 21:27:53.575 21:29:06.182 *
|
||||
20.151.10.161 325 162 0 17:31:38.451 17:32:27.663 *
|
||||
20.205.229.184 323 161 0 12:17:54.322 12:18:41.173 *
|
||||
4.185.41.66 323 161 0 18:18:18.046 18:18:24.319 *
|
||||
52.184.96.217 323 161 0 20:02:55.760 20:03:44.824 *
|
||||
172.213.225.181 321 160 0 13:48:04.161 13:48:11.331 *
|
||||
20.48.236.161 321 160 0 15:11:59.817 15:12:31.060 *
|
||||
158.158.32.229 316 158 0 12:33:51.566 12:34:03.712 *
|
||||
20.63.63.128 315 157 0 16:04:22.373 16:04:50.675 *
|
||||
20.206.67.15 313 156 0 05:56:36.144 05:57:20.412 *
|
||||
20.215.185.25 300 150 0 08:18:05.984 08:19:09.190 *
|
||||
20.203.243.122 294 147 0 03:58:39.580 03:58:55.359 *
|
||||
20.52.171.102 292 146 0 20:01:30.635 20:01:36.800 *
|
||||
20.226.26.5 286 143 0 06:33:33.891 06:34:07.483 *
|
||||
68.221.130.241 278 139 0 08:28:43.979 08:28:50.496 *
|
||||
20.100.172.153 275 137 0 09:10:06.751 09:10:17.835 *
|
||||
51.107.190.246 274 137 0 01:44:18.242 01:44:28.832 *
|
||||
74.248.33.172 257 128 0 23:32:36.049 23:32:42.718 *
|
||||
20.203.179.12 250 125 0 17:33:20.484 17:33:29.742 *
|
||||
20.113.142.140 231 115 0 07:47:47.716 07:48:00.044 *
|
||||
74.248.97.169 231 115 0 13:25:17.217 13:25:31.602 *
|
||||
20.251.112.224 215 107 0 06:52:51.081 06:53:05.602 *
|
||||
158.158.105.63 208 104 0 11:24:12.912 23:00:49.043 *
|
||||
4.223.71.149 209 104 0 00:26:55.320 00:27:19.244 *
|
||||
4.223.73.90 204 102 0 19:50:04.916 18:12:09.187 *
|
||||
135.225.93.215 203 101 0 02:32:24.496 02:32:32.326 *
|
||||
20.9.85.55 203 101 0 15:43:36.450 15:44:20.170 *
|
||||
20.91.208.34 203 101 0 22:07:01.428 22:07:20.883 *
|
||||
52.238.192.78 203 101 0 00:04:31.589 00:05:07.114 *
|
||||
172.213.208.13 192 96 0 13:27:56.743 19:14:00.938 *
|
||||
172.213.244.85 165 82 0 17:01:49.042 17:01:52.331 *
|
||||
20.206.105.145 157 78 0 04:06:08.085 04:06:29.772 *
|
||||
51.120.83.160 144 72 0 15:40:29.699 15:40:39.446 *
|
||||
172.213.153.79 114 57 0 18:40:13.799 18:40:20.149 *
|
||||
20.91.239.158 114 57 0 13:42:20.392 13:42:24.986 *
|
||||
4.232.185.87 110 53 0 21:23:31.012 21:23:33.019 *
|
||||
20.218.73.95 98 49 0 04:39:44.907 04:39:46.708 *
|
||||
20.91.203.45 94 47 0 16:27:01.288 16:27:10.455 *
|
||||
20.197.192.193 88 44 0 13:45:32.377 13:45:43.108 *
|
||||
74.248.24.145 74 37 0 09:21:37.839 09:21:43.127 *
|
||||
172.213.144.209 70 35 0 07:52:16.066 07:52:17.778 *
|
||||
35.198.180.224 46 22 0 14:14:37.617 14:14:48.930 *
|
||||
45.148.10.62 98 22 40 07:53:03.360 03:15:12.651 *
|
||||
45.148.10.244 109 18 70 04:53:37.585 09:56:59.103 *
|
||||
45.148.10.120 33 16 0 14:24:06.542 17:06:11.688 *
|
||||
34.39.210.94 24 12 0 19:31:07.030 19:31:07.101 *
|
||||
195.178.110.31 49 11 20 02:27:56.164 02:27:58.425 *
|
||||
195.178.110.223 37 10 13 01:31:40.464 01:56:49.503 *
|
||||
34.95.239.96 20 10 0 11:25:18.487 11:25:18.532 *
|
||||
107.173.254.55 29 9 9 07:04:56.768 07:05:17.755 *
|
||||
136.108.11.195 25 9 7 08:33:11.182 08:33:13.921 *
|
||||
139.59.118.17 180 9 157 08:21:30.247 08:22:03.812 *
|
||||
146.70.40.68 30 9 10 18:55:47.310 18:55:48.145 *
|
||||
147.182.149.75 40 9 21 21:50:17.837 21:50:45.474 *
|
||||
16.146.99.254 279 9 256 12:11:20.725 12:12:09.790 *
|
||||
163.7.11.71 93 9 72 07:24:55.235 07:25:05.144 *
|
||||
167.99.181.249 40 9 21 21:50:26.091 21:51:01.239 *
|
||||
18.142.90.109 279 9 256 17:06:23.216 17:07:15.117 *
|
||||
18.227.73.7 392 9 363 22:00:31.465 22:01:33.982 *
|
||||
207.175.159.248 25 9 7 03:52:06.643 03:52:07.542 *
|
||||
207.175.20.232 25 9 7 09:43:00.775 09:43:03.604 *
|
||||
209.99.189.190 77 9 59 17:04:48.190 09:53:52.093 *
|
||||
3.79.41.12 286 9 263 04:20:16.234 04:20:22.797 *
|
||||
34.105.30.251 29 9 9 15:55:43.824 15:55:49.547 *
|
||||
34.23.104.90 25 9 7 14:40:59.025 14:41:01.713 *
|
||||
34.242.226.103 286 9 263 06:52:40.299 06:52:54.689 *
|
||||
34.9.173.20 245 9 224 16:55:22.164 16:55:30.344 *
|
||||
45.67.85.190 32 9 11 19:41:44.132 19:41:46.806 *
|
||||
54.163.186.39 286 9 263 01:39:29.740 01:40:00.874 *
|
||||
82.102.18.116 30 9 10 04:49:33.098 04:49:34.184 *
|
||||
85.204.70.100 30 9 10 13:55:11.862 13:55:12.567 *
|
||||
88.151.32.7 88 9 69 18:43:38.911 19:04:03.160 *
|
||||
91.192.10.86 31 9 10 13:38:54.986 13:38:56.159 *
|
||||
93.123.109.101 4320 9 4264 00:35:05.539 00:40:32.578 *
|
||||
185.93.89.147 3762 8 0 19:07:14.620 08:52:41.657 *
|
||||
195.178.110.155 57 8 0 09:10:16.072 09:10:19.329 *
|
||||
45.148.10.194 58 8 0 15:46:42.822 15:46:45.473 *
|
||||
45.148.10.247 57 8 0 00:58:56.398 00:58:59.599 *
|
||||
72.146.20.230 14 7 0 03:01:31.244 03:01:31.427 *
|
||||
91.92.241.196 15 7 0 13:55:12.175 15:50:21.628 *
|
||||
209.99.189.152 13 6 0 18:03:04.845 18:03:12.906 *
|
||||
34.140.123.172 434 6 411 21:34:17.485 21:35:45.084 *
|
||||
162.243.79.174 11 5 0 12:20:28.790 12:20:40.350 *
|
||||
51.79.208.246 10 5 0 13:50:27.669 13:50:29.418 *
|
||||
94.154.43.184 10 5 0 11:23:26.214 09:31:40.319 *
|
||||
195.178.110.211 8 4 0 19:35:03.504 20:22:13.338 *
|
||||
45.148.10.119 11 3 0 02:36:55.008 07:16:27.585 *
|
||||
157.245.63.62 4 2 0 08:13:33.142 13:04:56.122 *
|
||||
163.7.13.115 5 2 0 14:06:27.842 14:06:29.745 *
|
||||
45.138.16.114 5 2 0 03:09:59.971 03:10:00.217 *
|
||||
45.148.10.95 4 2 0 21:05:26.356 14:40:26.566 *
|
||||
91.92.41.115 8 2 0 14:44:48.975 14:44:54.158 *
|
||||
94.154.43.179 5 2 0 13:27:23.753 04:38:17.921 *
|
||||
107.170.9.103 2 1 0 00:19:26.062 00:19:26.062 *
|
||||
129.212.237.196 2 1 0 09:23:08.470 09:23:08.471 *
|
||||
134.209.162.128 2 1 0 00:43:12.731 00:43:12.731 *
|
||||
158.101.144.198 2 1 0 14:30:06.125 14:30:06.125 *
|
||||
165.245.185.158 2 1 0 09:20:47.477 09:20:47.477 *
|
||||
176.65.132.38 3 1 0 20:33:22.070 05:08:32.533 *
|
||||
195.178.110.159 2 1 0 20:41:43.691 20:41:43.691 *
|
||||
2.57.122.173 2 1 0 12:10:19.177 12:10:19.177 *
|
||||
23.180.120.147 4 1 0 13:53:30.303 13:53:30.473 *
|
||||
31.58.51.184 4 1 0 15:07:53.176 15:07:58.514 *
|
||||
34.125.42.15 2 1 0 21:39:44.709 21:39:44.709 *
|
||||
34.91.243.226 2 1 0 19:51:57.606 19:51:57.606 *
|
||||
35.231.100.82 2 1 0 15:36:23.715 15:36:23.715 *
|
||||
35.233.191.179 2 1 0 00:16:07.188 00:16:07.199 *
|
||||
35.95.56.230 3 1 0 02:29:40.010 02:29:40.562 *
|
||||
43.98.201.177 2 1 0 01:01:05.988 01:01:05.988 *
|
||||
45.139.104.172 2 1 0 03:14:49.950 03:14:49.950 *
|
||||
64.226.123.37 2 1 0 21:33:32.148 21:33:32.148 *
|
||||
8.229.130.50 2 1 0 19:23:37.001 19:23:37.002 *
|
||||
93.123.109.167 2 1 0 04:39:35.474 04:39:35.474 *
|
||||
94.154.43.183 3 1 0 21:50:39.582 00:01:42.127 *
|
||||
94.154.43.185 3 1 0 01:40:53.903 04:02:34.085 *
|
||||
94.154.43.186 3 1 0 21:07:26.439 13:43:18.923 *
|
||||
94.154.43.188 5 1 0 02:45:01.636 11:09:54.264 *
|
||||
94.154.43.229 4 1 0 14:35:26.801 12:53:30.198 *
|
||||
-- IPv6 (3) --
|
||||
ip total denied banned first last users whitelist
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
2a04:4e40:e000:0:d09:97ab:43b1:a59a 4 2 0 14:41:30.905 14:41:30.922 *
|
||||
2600:3c15::2000:53ff:fe31:8c0b 2 1 0 12:35:18.643 12:35:18.643 *
|
||||
2602:fa59:10:a3a::1 2 1 0 02:10:02.531 02:10:02.532 *
|
||||
copyparty log analysis report
|
||||
generated: 2026-08-11T11:44:39
|
||||
|
||||
log path: \\naspve\nas\projects\copyparty
|
||||
log files: 48
|
||||
total requests: 30034
|
||||
unique IPs: 277 (IPv4 230 / IPv6 47)
|
||||
error requests: 7738
|
||||
unique denied paths: 2126
|
||||
denied requests: 7738
|
||||
banned IPs: 32
|
||||
authenticated users: {'admin': 537, 'corky': 78}
|
||||
denied-only ips: 129
|
||||
whitelisted IPs seen: 23
|
||||
block candidates: 131
|
||||
|
||||
== top 30 IPs ==
|
||||
ip total denied banned first last users whitelist
|
||||
------------------------------------------------------------------------------------
|
||||
93.123.109.101 4320 9 4264 00:35:05.539 00:40:32.578 *
|
||||
185.93.89.147 3762 8 0 19:07:14.620 08:52:41.657 *
|
||||
192.168.88.8 1736 0 0 13:31:27.246 09:40:39.082 -
|
||||
195.178.110.199 1258 621 0 03:02:41.078 03:02:42.924 *
|
||||
45.148.10.67 1258 621 0 20:49:39.003 20:49:41.111 *
|
||||
20.251.48.208 612 306 0 23:50:43.575 17:01:41.376 *
|
||||
20.215.216.94 516 257 0 16:16:39.439 15:21:39.387 *
|
||||
20.215.218.234 504 252 0 02:46:27.628 05:35:25.304 *
|
||||
34.140.123.172 434 6 411 21:34:17.485 21:35:45.084 *
|
||||
20.198.120.225 428 214 0 10:07:52.191 10:09:25.008 *
|
||||
18.227.73.7 392 9 363 22:00:31.465 22:01:33.982 *
|
||||
172.213.227.73 382 191 0 03:00:13.592 01:13:37.755 *
|
||||
20.197.178.120 374 186 0 14:54:24.411 14:54:52.938 *
|
||||
74.249.245.134 354 177 0 21:27:53.575 21:29:06.182 *
|
||||
20.151.10.161 325 162 0 17:31:38.451 17:32:27.663 *
|
||||
20.205.229.184 323 161 0 12:17:54.322 12:18:41.173 *
|
||||
4.185.41.66 323 161 0 18:18:18.046 18:18:24.319 *
|
||||
52.184.96.217 323 161 0 20:02:55.760 20:03:44.824 *
|
||||
172.213.225.181 321 160 0 13:48:04.161 13:48:11.331 *
|
||||
20.48.236.161 321 160 0 15:11:59.817 15:12:31.060 *
|
||||
158.158.32.229 316 158 0 12:33:51.566 12:34:03.712 *
|
||||
20.63.63.128 315 157 0 16:04:22.373 16:04:50.675 *
|
||||
20.206.67.15 313 156 0 05:56:36.144 05:57:20.412 *
|
||||
20.215.185.25 300 150 0 08:18:05.984 08:19:09.190 *
|
||||
20.203.243.122 294 147 0 03:58:39.580 03:58:55.359 *
|
||||
20.52.171.102 292 146 0 20:01:30.635 20:01:36.800 *
|
||||
20.226.26.5 286 143 0 06:33:33.891 06:34:07.483 *
|
||||
3.79.41.12 286 9 263 04:20:16.234 04:20:22.797 *
|
||||
34.242.226.103 286 9 263 06:52:40.299 06:52:54.689 *
|
||||
54.163.186.39 286 9 263 01:39:29.740 01:40:00.874 *
|
||||
... 247 more IPs omitted
|
||||
|
||||
== top 20 denied paths ==
|
||||
67 /admin.php
|
||||
56 /wp-content/plugins/hellopress/wp_filemanager.php
|
||||
56 /this_is_a_new_hello_world.php
|
||||
54 /.env
|
||||
46 /1.php
|
||||
44 /classwithtostring.php
|
||||
42 /222.php
|
||||
38 /8.php
|
||||
37 /.git/config
|
||||
37 /wp-content/uploads
|
||||
37 /wp-content/admin.php
|
||||
35 /mac.php
|
||||
34 /aa.php
|
||||
34 /images.php
|
||||
33 /ops.php
|
||||
32 /wp.php
|
||||
31 /edit.php
|
||||
31 /coffexium.php
|
||||
29 /file.php
|
||||
29 /inputs.php
|
||||
|
||||
== Denied-only IPs (129) ==
|
||||
never authenticated -- ban candidates
|
||||
-- IPv4 (126) --
|
||||
ip total denied banned first last users whitelist
|
||||
------------------------------------------------------------------------------------
|
||||
195.178.110.199 1258 621 0 03:02:41.078 03:02:42.924 *
|
||||
45.148.10.67 1258 621 0 20:49:39.003 20:49:41.111 *
|
||||
20.251.48.208 612 306 0 23:50:43.575 17:01:41.376 *
|
||||
20.215.216.94 516 257 0 16:16:39.439 15:21:39.387 *
|
||||
20.215.218.234 504 252 0 02:46:27.628 05:35:25.304 *
|
||||
20.198.120.225 428 214 0 10:07:52.191 10:09:25.008 *
|
||||
172.213.227.73 382 191 0 03:00:13.592 01:13:37.755 *
|
||||
20.197.178.120 374 186 0 14:54:24.411 14:54:52.938 *
|
||||
74.249.245.134 354 177 0 21:27:53.575 21:29:06.182 *
|
||||
20.151.10.161 325 162 0 17:31:38.451 17:32:27.663 *
|
||||
20.205.229.184 323 161 0 12:17:54.322 12:18:41.173 *
|
||||
4.185.41.66 323 161 0 18:18:18.046 18:18:24.319 *
|
||||
52.184.96.217 323 161 0 20:02:55.760 20:03:44.824 *
|
||||
172.213.225.181 321 160 0 13:48:04.161 13:48:11.331 *
|
||||
20.48.236.161 321 160 0 15:11:59.817 15:12:31.060 *
|
||||
158.158.32.229 316 158 0 12:33:51.566 12:34:03.712 *
|
||||
20.63.63.128 315 157 0 16:04:22.373 16:04:50.675 *
|
||||
20.206.67.15 313 156 0 05:56:36.144 05:57:20.412 *
|
||||
20.215.185.25 300 150 0 08:18:05.984 08:19:09.190 *
|
||||
20.203.243.122 294 147 0 03:58:39.580 03:58:55.359 *
|
||||
20.52.171.102 292 146 0 20:01:30.635 20:01:36.800 *
|
||||
20.226.26.5 286 143 0 06:33:33.891 06:34:07.483 *
|
||||
68.221.130.241 278 139 0 08:28:43.979 08:28:50.496 *
|
||||
20.100.172.153 275 137 0 09:10:06.751 09:10:17.835 *
|
||||
51.107.190.246 274 137 0 01:44:18.242 01:44:28.832 *
|
||||
74.248.33.172 257 128 0 23:32:36.049 23:32:42.718 *
|
||||
20.203.179.12 250 125 0 17:33:20.484 17:33:29.742 *
|
||||
20.113.142.140 231 115 0 07:47:47.716 07:48:00.044 *
|
||||
74.248.97.169 231 115 0 13:25:17.217 13:25:31.602 *
|
||||
20.251.112.224 215 107 0 06:52:51.081 06:53:05.602 *
|
||||
158.158.105.63 208 104 0 11:24:12.912 23:00:49.043 *
|
||||
4.223.71.149 209 104 0 00:26:55.320 00:27:19.244 *
|
||||
4.223.73.90 204 102 0 19:50:04.916 18:12:09.187 *
|
||||
135.225.93.215 203 101 0 02:32:24.496 02:32:32.326 *
|
||||
20.9.85.55 203 101 0 15:43:36.450 15:44:20.170 *
|
||||
20.91.208.34 203 101 0 22:07:01.428 22:07:20.883 *
|
||||
52.238.192.78 203 101 0 00:04:31.589 00:05:07.114 *
|
||||
172.213.208.13 192 96 0 13:27:56.743 19:14:00.938 *
|
||||
172.213.244.85 165 82 0 17:01:49.042 17:01:52.331 *
|
||||
20.206.105.145 157 78 0 04:06:08.085 04:06:29.772 *
|
||||
51.120.83.160 144 72 0 15:40:29.699 15:40:39.446 *
|
||||
172.213.153.79 114 57 0 18:40:13.799 18:40:20.149 *
|
||||
20.91.239.158 114 57 0 13:42:20.392 13:42:24.986 *
|
||||
4.232.185.87 110 53 0 21:23:31.012 21:23:33.019 *
|
||||
20.218.73.95 98 49 0 04:39:44.907 04:39:46.708 *
|
||||
20.91.203.45 94 47 0 16:27:01.288 16:27:10.455 *
|
||||
20.197.192.193 88 44 0 13:45:32.377 13:45:43.108 *
|
||||
74.248.24.145 74 37 0 09:21:37.839 09:21:43.127 *
|
||||
172.213.144.209 70 35 0 07:52:16.066 07:52:17.778 *
|
||||
35.198.180.224 46 22 0 14:14:37.617 14:14:48.930 *
|
||||
45.148.10.62 98 22 40 07:53:03.360 03:15:12.651 *
|
||||
45.148.10.244 109 18 70 04:53:37.585 09:56:59.103 *
|
||||
45.148.10.120 33 16 0 14:24:06.542 17:06:11.688 *
|
||||
34.39.210.94 24 12 0 19:31:07.030 19:31:07.101 *
|
||||
195.178.110.31 49 11 20 02:27:56.164 02:27:58.425 *
|
||||
195.178.110.223 37 10 13 01:31:40.464 01:56:49.503 *
|
||||
34.95.239.96 20 10 0 11:25:18.487 11:25:18.532 *
|
||||
107.173.254.55 29 9 9 07:04:56.768 07:05:17.755 *
|
||||
136.108.11.195 25 9 7 08:33:11.182 08:33:13.921 *
|
||||
139.59.118.17 180 9 157 08:21:30.247 08:22:03.812 *
|
||||
146.70.40.68 30 9 10 18:55:47.310 18:55:48.145 *
|
||||
147.182.149.75 40 9 21 21:50:17.837 21:50:45.474 *
|
||||
16.146.99.254 279 9 256 12:11:20.725 12:12:09.790 *
|
||||
163.7.11.71 93 9 72 07:24:55.235 07:25:05.144 *
|
||||
167.99.181.249 40 9 21 21:50:26.091 21:51:01.239 *
|
||||
18.142.90.109 279 9 256 17:06:23.216 17:07:15.117 *
|
||||
18.227.73.7 392 9 363 22:00:31.465 22:01:33.982 *
|
||||
207.175.159.248 25 9 7 03:52:06.643 03:52:07.542 *
|
||||
207.175.20.232 25 9 7 09:43:00.775 09:43:03.604 *
|
||||
209.99.189.190 77 9 59 17:04:48.190 09:53:52.093 *
|
||||
3.79.41.12 286 9 263 04:20:16.234 04:20:22.797 *
|
||||
34.105.30.251 29 9 9 15:55:43.824 15:55:49.547 *
|
||||
34.23.104.90 25 9 7 14:40:59.025 14:41:01.713 *
|
||||
34.242.226.103 286 9 263 06:52:40.299 06:52:54.689 *
|
||||
34.9.173.20 245 9 224 16:55:22.164 16:55:30.344 *
|
||||
45.67.85.190 32 9 11 19:41:44.132 19:41:46.806 *
|
||||
54.163.186.39 286 9 263 01:39:29.740 01:40:00.874 *
|
||||
82.102.18.116 30 9 10 04:49:33.098 04:49:34.184 *
|
||||
85.204.70.100 30 9 10 13:55:11.862 13:55:12.567 *
|
||||
88.151.32.7 88 9 69 18:43:38.911 19:04:03.160 *
|
||||
91.192.10.86 31 9 10 13:38:54.986 13:38:56.159 *
|
||||
93.123.109.101 4320 9 4264 00:35:05.539 00:40:32.578 *
|
||||
185.93.89.147 3762 8 0 19:07:14.620 08:52:41.657 *
|
||||
195.178.110.155 57 8 0 09:10:16.072 09:10:19.329 *
|
||||
45.148.10.194 58 8 0 15:46:42.822 15:46:45.473 *
|
||||
45.148.10.247 57 8 0 00:58:56.398 00:58:59.599 *
|
||||
72.146.20.230 14 7 0 03:01:31.244 03:01:31.427 *
|
||||
91.92.241.196 15 7 0 13:55:12.175 15:50:21.628 *
|
||||
209.99.189.152 13 6 0 18:03:04.845 18:03:12.906 *
|
||||
34.140.123.172 434 6 411 21:34:17.485 21:35:45.084 *
|
||||
162.243.79.174 11 5 0 12:20:28.790 12:20:40.350 *
|
||||
51.79.208.246 10 5 0 13:50:27.669 13:50:29.418 *
|
||||
94.154.43.184 10 5 0 11:23:26.214 09:31:40.319 *
|
||||
195.178.110.211 8 4 0 19:35:03.504 20:22:13.338 *
|
||||
45.148.10.119 11 3 0 02:36:55.008 07:16:27.585 *
|
||||
157.245.63.62 4 2 0 08:13:33.142 13:04:56.122 *
|
||||
163.7.13.115 5 2 0 14:06:27.842 14:06:29.745 *
|
||||
45.138.16.114 5 2 0 03:09:59.971 03:10:00.217 *
|
||||
45.148.10.95 4 2 0 21:05:26.356 14:40:26.566 *
|
||||
91.92.41.115 8 2 0 14:44:48.975 14:44:54.158 *
|
||||
94.154.43.179 5 2 0 13:27:23.753 04:38:17.921 *
|
||||
107.170.9.103 2 1 0 00:19:26.062 00:19:26.062 *
|
||||
129.212.237.196 2 1 0 09:23:08.470 09:23:08.471 *
|
||||
134.209.162.128 2 1 0 00:43:12.731 00:43:12.731 *
|
||||
158.101.144.198 2 1 0 14:30:06.125 14:30:06.125 *
|
||||
165.245.185.158 2 1 0 09:20:47.477 09:20:47.477 *
|
||||
176.65.132.38 3 1 0 20:33:22.070 05:08:32.533 *
|
||||
195.178.110.159 2 1 0 20:41:43.691 20:41:43.691 *
|
||||
2.57.122.173 2 1 0 12:10:19.177 12:10:19.177 *
|
||||
23.180.120.147 4 1 0 13:53:30.303 13:53:30.473 *
|
||||
31.58.51.184 4 1 0 15:07:53.176 15:07:58.514 *
|
||||
34.125.42.15 2 1 0 21:39:44.709 21:39:44.709 *
|
||||
34.91.243.226 2 1 0 19:51:57.606 19:51:57.606 *
|
||||
35.231.100.82 2 1 0 15:36:23.715 15:36:23.715 *
|
||||
35.233.191.179 2 1 0 00:16:07.188 00:16:07.199 *
|
||||
35.95.56.230 3 1 0 02:29:40.010 02:29:40.562 *
|
||||
43.98.201.177 2 1 0 01:01:05.988 01:01:05.988 *
|
||||
45.139.104.172 2 1 0 03:14:49.950 03:14:49.950 *
|
||||
64.226.123.37 2 1 0 21:33:32.148 21:33:32.148 *
|
||||
8.229.130.50 2 1 0 19:23:37.001 19:23:37.002 *
|
||||
93.123.109.167 2 1 0 04:39:35.474 04:39:35.474 *
|
||||
94.154.43.183 3 1 0 21:50:39.582 00:01:42.127 *
|
||||
94.154.43.185 3 1 0 01:40:53.903 04:02:34.085 *
|
||||
94.154.43.186 3 1 0 21:07:26.439 13:43:18.923 *
|
||||
94.154.43.188 5 1 0 02:45:01.636 11:09:54.264 *
|
||||
94.154.43.229 4 1 0 14:35:26.801 12:53:30.198 *
|
||||
-- IPv6 (3) --
|
||||
ip total denied banned first last users whitelist
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
2a04:4e40:e000:0:d09:97ab:43b1:a59a 4 2 0 14:41:30.905 14:41:30.922 *
|
||||
2600:3c15::2000:53ff:fe31:8c0b 2 1 0 12:35:18.643 12:35:18.643 *
|
||||
2602:fa59:10:a3a::1 2 1 0 02:10:02.531 02:10:02.532 *
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"admin": 537,
|
||||
"corky": 78
|
||||
{
|
||||
"admin": 537,
|
||||
"corky": 78
|
||||
}
|
||||
@@ -1,32 +1,32 @@
|
||||
3.79.41.12
|
||||
16.146.99.254
|
||||
18.142.90.109
|
||||
18.227.73.7
|
||||
34.9.173.20
|
||||
34.23.104.90
|
||||
34.105.30.251
|
||||
34.140.123.172
|
||||
34.242.226.103
|
||||
45.67.85.190
|
||||
45.148.10.62
|
||||
45.148.10.244
|
||||
54.163.186.39
|
||||
82.102.18.116
|
||||
85.204.70.100
|
||||
88.151.32.7
|
||||
91.192.10.86
|
||||
93.123.109.101
|
||||
107.173.254.55
|
||||
136.108.11.195
|
||||
139.59.118.17
|
||||
146.70.40.68
|
||||
147.182.149.75
|
||||
163.7.11.71
|
||||
167.99.181.249
|
||||
195.178.110.31
|
||||
195.178.110.104
|
||||
195.178.110.135
|
||||
195.178.110.223
|
||||
207.175.20.232
|
||||
207.175.159.248
|
||||
209.99.189.190
|
||||
3.79.41.12
|
||||
16.146.99.254
|
||||
18.142.90.109
|
||||
18.227.73.7
|
||||
34.9.173.20
|
||||
34.23.104.90
|
||||
34.105.30.251
|
||||
34.140.123.172
|
||||
34.242.226.103
|
||||
45.67.85.190
|
||||
45.148.10.62
|
||||
45.148.10.244
|
||||
54.163.186.39
|
||||
82.102.18.116
|
||||
85.204.70.100
|
||||
88.151.32.7
|
||||
91.192.10.86
|
||||
93.123.109.101
|
||||
107.173.254.55
|
||||
136.108.11.195
|
||||
139.59.118.17
|
||||
146.70.40.68
|
||||
147.182.149.75
|
||||
163.7.11.71
|
||||
167.99.181.249
|
||||
195.178.110.31
|
||||
195.178.110.104
|
||||
195.178.110.135
|
||||
195.178.110.223
|
||||
207.175.20.232
|
||||
207.175.159.248
|
||||
209.99.189.190
|
||||
@@ -1,128 +1,128 @@
|
||||
2.57.122.173
|
||||
3.79.41.12
|
||||
4.185.41.66
|
||||
4.223.71.149
|
||||
4.223.73.90
|
||||
4.232.185.87
|
||||
8.229.130.50
|
||||
16.146.99.254
|
||||
18.142.90.109
|
||||
18.227.73.7
|
||||
20.9.85.55
|
||||
20.48.236.161
|
||||
20.52.171.102
|
||||
20.63.63.128
|
||||
20.91.203.45
|
||||
20.91.208.34
|
||||
20.91.239.158
|
||||
20.100.172.153
|
||||
20.113.142.140
|
||||
20.151.10.161
|
||||
20.197.178.120
|
||||
20.197.192.193
|
||||
20.198.120.225
|
||||
20.203.179.12
|
||||
20.203.243.122
|
||||
20.205.229.184
|
||||
20.206.67.15
|
||||
20.206.105.145
|
||||
20.215.185.25
|
||||
20.215.216.94
|
||||
20.215.218.234
|
||||
20.218.73.95
|
||||
20.226.26.5
|
||||
20.251.48.208
|
||||
20.251.112.224
|
||||
23.180.120.147
|
||||
31.58.51.184
|
||||
34.9.173.20
|
||||
34.23.104.90
|
||||
34.39.210.94
|
||||
34.91.243.226
|
||||
34.95.239.96
|
||||
34.105.30.251
|
||||
34.125.42.15
|
||||
34.140.123.172
|
||||
34.242.226.103
|
||||
35.95.56.230
|
||||
35.198.180.224
|
||||
35.231.100.82
|
||||
35.233.191.179
|
||||
43.98.201.177
|
||||
45.67.85.190
|
||||
45.138.16.114
|
||||
45.139.104.172
|
||||
45.148.10.62
|
||||
45.148.10.67
|
||||
45.148.10.95
|
||||
45.148.10.119
|
||||
45.148.10.120
|
||||
45.148.10.194
|
||||
45.148.10.244
|
||||
45.148.10.247
|
||||
51.79.208.246
|
||||
51.107.190.246
|
||||
51.120.83.160
|
||||
52.184.96.217
|
||||
52.238.192.78
|
||||
54.163.186.39
|
||||
64.226.123.37
|
||||
68.221.130.241
|
||||
72.146.20.230
|
||||
74.248.24.145
|
||||
74.248.33.172
|
||||
74.248.97.169
|
||||
74.249.245.134
|
||||
82.102.18.116
|
||||
85.204.70.100
|
||||
88.151.32.7
|
||||
91.92.41.115
|
||||
91.92.241.196
|
||||
91.192.10.86
|
||||
93.123.109.101
|
||||
93.123.109.167
|
||||
94.154.43.179
|
||||
94.154.43.183
|
||||
94.154.43.184
|
||||
94.154.43.185
|
||||
94.154.43.186
|
||||
94.154.43.188
|
||||
94.154.43.229
|
||||
107.170.9.103
|
||||
107.173.254.55
|
||||
129.212.237.196
|
||||
134.209.162.128
|
||||
135.225.93.215
|
||||
136.108.11.195
|
||||
139.59.118.17
|
||||
146.70.40.68
|
||||
147.182.149.75
|
||||
157.245.63.62
|
||||
158.101.144.198
|
||||
158.158.32.229
|
||||
158.158.105.63
|
||||
162.243.79.174
|
||||
163.7.11.71
|
||||
163.7.13.115
|
||||
165.245.185.158
|
||||
167.99.181.249
|
||||
172.213.144.209
|
||||
172.213.153.79
|
||||
172.213.208.13
|
||||
172.213.225.181
|
||||
172.213.227.73
|
||||
172.213.244.85
|
||||
176.65.132.38
|
||||
185.93.89.147
|
||||
195.178.110.31
|
||||
195.178.110.104
|
||||
195.178.110.135
|
||||
195.178.110.155
|
||||
195.178.110.159
|
||||
195.178.110.199
|
||||
195.178.110.211
|
||||
195.178.110.223
|
||||
207.175.20.232
|
||||
207.175.159.248
|
||||
209.99.189.152
|
||||
209.99.189.190
|
||||
2.57.122.173
|
||||
3.79.41.12
|
||||
4.185.41.66
|
||||
4.223.71.149
|
||||
4.223.73.90
|
||||
4.232.185.87
|
||||
8.229.130.50
|
||||
16.146.99.254
|
||||
18.142.90.109
|
||||
18.227.73.7
|
||||
20.9.85.55
|
||||
20.48.236.161
|
||||
20.52.171.102
|
||||
20.63.63.128
|
||||
20.91.203.45
|
||||
20.91.208.34
|
||||
20.91.239.158
|
||||
20.100.172.153
|
||||
20.113.142.140
|
||||
20.151.10.161
|
||||
20.197.178.120
|
||||
20.197.192.193
|
||||
20.198.120.225
|
||||
20.203.179.12
|
||||
20.203.243.122
|
||||
20.205.229.184
|
||||
20.206.67.15
|
||||
20.206.105.145
|
||||
20.215.185.25
|
||||
20.215.216.94
|
||||
20.215.218.234
|
||||
20.218.73.95
|
||||
20.226.26.5
|
||||
20.251.48.208
|
||||
20.251.112.224
|
||||
23.180.120.147
|
||||
31.58.51.184
|
||||
34.9.173.20
|
||||
34.23.104.90
|
||||
34.39.210.94
|
||||
34.91.243.226
|
||||
34.95.239.96
|
||||
34.105.30.251
|
||||
34.125.42.15
|
||||
34.140.123.172
|
||||
34.242.226.103
|
||||
35.95.56.230
|
||||
35.198.180.224
|
||||
35.231.100.82
|
||||
35.233.191.179
|
||||
43.98.201.177
|
||||
45.67.85.190
|
||||
45.138.16.114
|
||||
45.139.104.172
|
||||
45.148.10.62
|
||||
45.148.10.67
|
||||
45.148.10.95
|
||||
45.148.10.119
|
||||
45.148.10.120
|
||||
45.148.10.194
|
||||
45.148.10.244
|
||||
45.148.10.247
|
||||
51.79.208.246
|
||||
51.107.190.246
|
||||
51.120.83.160
|
||||
52.184.96.217
|
||||
52.238.192.78
|
||||
54.163.186.39
|
||||
64.226.123.37
|
||||
68.221.130.241
|
||||
72.146.20.230
|
||||
74.248.24.145
|
||||
74.248.33.172
|
||||
74.248.97.169
|
||||
74.249.245.134
|
||||
82.102.18.116
|
||||
85.204.70.100
|
||||
88.151.32.7
|
||||
91.92.41.115
|
||||
91.92.241.196
|
||||
91.192.10.86
|
||||
93.123.109.101
|
||||
93.123.109.167
|
||||
94.154.43.179
|
||||
94.154.43.183
|
||||
94.154.43.184
|
||||
94.154.43.185
|
||||
94.154.43.186
|
||||
94.154.43.188
|
||||
94.154.43.229
|
||||
107.170.9.103
|
||||
107.173.254.55
|
||||
129.212.237.196
|
||||
134.209.162.128
|
||||
135.225.93.215
|
||||
136.108.11.195
|
||||
139.59.118.17
|
||||
146.70.40.68
|
||||
147.182.149.75
|
||||
157.245.63.62
|
||||
158.101.144.198
|
||||
158.158.32.229
|
||||
158.158.105.63
|
||||
162.243.79.174
|
||||
163.7.11.71
|
||||
163.7.13.115
|
||||
165.245.185.158
|
||||
167.99.181.249
|
||||
172.213.144.209
|
||||
172.213.153.79
|
||||
172.213.208.13
|
||||
172.213.225.181
|
||||
172.213.227.73
|
||||
172.213.244.85
|
||||
176.65.132.38
|
||||
185.93.89.147
|
||||
195.178.110.31
|
||||
195.178.110.104
|
||||
195.178.110.135
|
||||
195.178.110.155
|
||||
195.178.110.159
|
||||
195.178.110.199
|
||||
195.178.110.211
|
||||
195.178.110.223
|
||||
207.175.20.232
|
||||
207.175.159.248
|
||||
209.99.189.152
|
||||
209.99.189.190
|
||||
@@ -1,3 +1,3 @@
|
||||
2600:3c15::2000:53ff:fe31:8c0b
|
||||
2602:fa59:10:a3a::1
|
||||
2a04:4e40:e000:0:d09:97ab:43b1:a59a
|
||||
2600:3c15::2000:53ff:fe31:8c0b
|
||||
2602:fa59:10:a3a::1
|
||||
2a04:4e40:e000:0:d09:97ab:43b1:a59a
|
||||
@@ -1,126 +1,126 @@
|
||||
195.178.110.199 # denied=621 total=1258 first=03:02:41.078 last=03:02:42.924
|
||||
45.148.10.67 # denied=621 total=1258 first=20:49:39.003 last=20:49:41.111
|
||||
20.251.48.208 # denied=306 total=612 first=23:50:43.575 last=17:01:41.376
|
||||
20.215.216.94 # denied=257 total=516 first=16:16:39.439 last=15:21:39.387
|
||||
20.215.218.234 # denied=252 total=504 first=02:46:27.628 last=05:35:25.304
|
||||
20.198.120.225 # denied=214 total=428 first=10:07:52.191 last=10:09:25.008
|
||||
172.213.227.73 # denied=191 total=382 first=03:00:13.592 last=01:13:37.755
|
||||
20.197.178.120 # denied=186 total=374 first=14:54:24.411 last=14:54:52.938
|
||||
74.249.245.134 # denied=177 total=354 first=21:27:53.575 last=21:29:06.182
|
||||
20.151.10.161 # denied=162 total=325 first=17:31:38.451 last=17:32:27.663
|
||||
20.205.229.184 # denied=161 total=323 first=12:17:54.322 last=12:18:41.173
|
||||
4.185.41.66 # denied=161 total=323 first=18:18:18.046 last=18:18:24.319
|
||||
52.184.96.217 # denied=161 total=323 first=20:02:55.760 last=20:03:44.824
|
||||
172.213.225.181 # denied=160 total=321 first=13:48:04.161 last=13:48:11.331
|
||||
20.48.236.161 # denied=160 total=321 first=15:11:59.817 last=15:12:31.060
|
||||
158.158.32.229 # denied=158 total=316 first=12:33:51.566 last=12:34:03.712
|
||||
20.63.63.128 # denied=157 total=315 first=16:04:22.373 last=16:04:50.675
|
||||
20.206.67.15 # denied=156 total=313 first=05:56:36.144 last=05:57:20.412
|
||||
20.215.185.25 # denied=150 total=300 first=08:18:05.984 last=08:19:09.190
|
||||
20.203.243.122 # denied=147 total=294 first=03:58:39.580 last=03:58:55.359
|
||||
20.52.171.102 # denied=146 total=292 first=20:01:30.635 last=20:01:36.800
|
||||
20.226.26.5 # denied=143 total=286 first=06:33:33.891 last=06:34:07.483
|
||||
68.221.130.241 # denied=139 total=278 first=08:28:43.979 last=08:28:50.496
|
||||
20.100.172.153 # denied=137 total=275 first=09:10:06.751 last=09:10:17.835
|
||||
51.107.190.246 # denied=137 total=274 first=01:44:18.242 last=01:44:28.832
|
||||
74.248.33.172 # denied=128 total=257 first=23:32:36.049 last=23:32:42.718
|
||||
20.203.179.12 # denied=125 total=250 first=17:33:20.484 last=17:33:29.742
|
||||
20.113.142.140 # denied=115 total=231 first=07:47:47.716 last=07:48:00.044
|
||||
74.248.97.169 # denied=115 total=231 first=13:25:17.217 last=13:25:31.602
|
||||
20.251.112.224 # denied=107 total=215 first=06:52:51.081 last=06:53:05.602
|
||||
158.158.105.63 # denied=104 total=208 first=11:24:12.912 last=23:00:49.043
|
||||
4.223.71.149 # denied=104 total=209 first=00:26:55.320 last=00:27:19.244
|
||||
4.223.73.90 # denied=102 total=204 first=19:50:04.916 last=18:12:09.187
|
||||
135.225.93.215 # denied=101 total=203 first=02:32:24.496 last=02:32:32.326
|
||||
20.9.85.55 # denied=101 total=203 first=15:43:36.450 last=15:44:20.170
|
||||
20.91.208.34 # denied=101 total=203 first=22:07:01.428 last=22:07:20.883
|
||||
52.238.192.78 # denied=101 total=203 first=00:04:31.589 last=00:05:07.114
|
||||
172.213.208.13 # denied=96 total=192 first=13:27:56.743 last=19:14:00.938
|
||||
172.213.244.85 # denied=82 total=165 first=17:01:49.042 last=17:01:52.331
|
||||
20.206.105.145 # denied=78 total=157 first=04:06:08.085 last=04:06:29.772
|
||||
51.120.83.160 # denied=72 total=144 first=15:40:29.699 last=15:40:39.446
|
||||
172.213.153.79 # denied=57 total=114 first=18:40:13.799 last=18:40:20.149
|
||||
20.91.239.158 # denied=57 total=114 first=13:42:20.392 last=13:42:24.986
|
||||
4.232.185.87 # denied=53 total=110 first=21:23:31.012 last=21:23:33.019
|
||||
20.218.73.95 # denied=49 total=98 first=04:39:44.907 last=04:39:46.708
|
||||
20.91.203.45 # denied=47 total=94 first=16:27:01.288 last=16:27:10.455
|
||||
20.197.192.193 # denied=44 total=88 first=13:45:32.377 last=13:45:43.108
|
||||
74.248.24.145 # denied=37 total=74 first=09:21:37.839 last=09:21:43.127
|
||||
172.213.144.209 # denied=35 total=70 first=07:52:16.066 last=07:52:17.778
|
||||
35.198.180.224 # denied=22 total=46 first=14:14:37.617 last=14:14:48.930
|
||||
45.148.10.62 # denied=22 total=98 first=07:53:03.360 last=03:15:12.651
|
||||
45.148.10.244 # denied=18 total=109 first=04:53:37.585 last=09:56:59.103
|
||||
45.148.10.120 # denied=16 total=33 first=14:24:06.542 last=17:06:11.688
|
||||
34.39.210.94 # denied=12 total=24 first=19:31:07.030 last=19:31:07.101
|
||||
195.178.110.31 # denied=11 total=49 first=02:27:56.164 last=02:27:58.425
|
||||
195.178.110.223 # denied=10 total=37 first=01:31:40.464 last=01:56:49.503
|
||||
34.95.239.96 # denied=10 total=20 first=11:25:18.487 last=11:25:18.532
|
||||
107.173.254.55 # denied=9 total=29 first=07:04:56.768 last=07:05:17.755
|
||||
136.108.11.195 # denied=9 total=25 first=08:33:11.182 last=08:33:13.921
|
||||
139.59.118.17 # denied=9 total=180 first=08:21:30.247 last=08:22:03.812
|
||||
146.70.40.68 # denied=9 total=30 first=18:55:47.310 last=18:55:48.145
|
||||
147.182.149.75 # denied=9 total=40 first=21:50:17.837 last=21:50:45.474
|
||||
16.146.99.254 # denied=9 total=279 first=12:11:20.725 last=12:12:09.790
|
||||
163.7.11.71 # denied=9 total=93 first=07:24:55.235 last=07:25:05.144
|
||||
167.99.181.249 # denied=9 total=40 first=21:50:26.091 last=21:51:01.239
|
||||
18.142.90.109 # denied=9 total=279 first=17:06:23.216 last=17:07:15.117
|
||||
18.227.73.7 # denied=9 total=392 first=22:00:31.465 last=22:01:33.982
|
||||
207.175.159.248 # denied=9 total=25 first=03:52:06.643 last=03:52:07.542
|
||||
207.175.20.232 # denied=9 total=25 first=09:43:00.775 last=09:43:03.604
|
||||
209.99.189.190 # denied=9 total=77 first=17:04:48.190 last=09:53:52.093
|
||||
3.79.41.12 # denied=9 total=286 first=04:20:16.234 last=04:20:22.797
|
||||
34.105.30.251 # denied=9 total=29 first=15:55:43.824 last=15:55:49.547
|
||||
34.23.104.90 # denied=9 total=25 first=14:40:59.025 last=14:41:01.713
|
||||
34.242.226.103 # denied=9 total=286 first=06:52:40.299 last=06:52:54.689
|
||||
34.9.173.20 # denied=9 total=245 first=16:55:22.164 last=16:55:30.344
|
||||
45.67.85.190 # denied=9 total=32 first=19:41:44.132 last=19:41:46.806
|
||||
54.163.186.39 # denied=9 total=286 first=01:39:29.740 last=01:40:00.874
|
||||
82.102.18.116 # denied=9 total=30 first=04:49:33.098 last=04:49:34.184
|
||||
85.204.70.100 # denied=9 total=30 first=13:55:11.862 last=13:55:12.567
|
||||
88.151.32.7 # denied=9 total=88 first=18:43:38.911 last=19:04:03.160
|
||||
91.192.10.86 # denied=9 total=31 first=13:38:54.986 last=13:38:56.159
|
||||
93.123.109.101 # denied=9 total=4320 first=00:35:05.539 last=00:40:32.578
|
||||
185.93.89.147 # denied=8 total=3762 first=19:07:14.620 last=08:52:41.657
|
||||
195.178.110.155 # denied=8 total=57 first=09:10:16.072 last=09:10:19.329
|
||||
45.148.10.194 # denied=8 total=58 first=15:46:42.822 last=15:46:45.473
|
||||
45.148.10.247 # denied=8 total=57 first=00:58:56.398 last=00:58:59.599
|
||||
72.146.20.230 # denied=7 total=14 first=03:01:31.244 last=03:01:31.427
|
||||
91.92.241.196 # denied=7 total=15 first=13:55:12.175 last=15:50:21.628
|
||||
209.99.189.152 # denied=6 total=13 first=18:03:04.845 last=18:03:12.906
|
||||
34.140.123.172 # denied=6 total=434 first=21:34:17.485 last=21:35:45.084
|
||||
162.243.79.174 # denied=5 total=11 first=12:20:28.790 last=12:20:40.350
|
||||
51.79.208.246 # denied=5 total=10 first=13:50:27.669 last=13:50:29.418
|
||||
94.154.43.184 # denied=5 total=10 first=11:23:26.214 last=09:31:40.319
|
||||
195.178.110.211 # denied=4 total=8 first=19:35:03.504 last=20:22:13.338
|
||||
45.148.10.119 # denied=3 total=11 first=02:36:55.008 last=07:16:27.585
|
||||
157.245.63.62 # denied=2 total=4 first=08:13:33.142 last=13:04:56.122
|
||||
163.7.13.115 # denied=2 total=5 first=14:06:27.842 last=14:06:29.745
|
||||
45.138.16.114 # denied=2 total=5 first=03:09:59.971 last=03:10:00.217
|
||||
45.148.10.95 # denied=2 total=4 first=21:05:26.356 last=14:40:26.566
|
||||
91.92.41.115 # denied=2 total=8 first=14:44:48.975 last=14:44:54.158
|
||||
94.154.43.179 # denied=2 total=5 first=13:27:23.753 last=04:38:17.921
|
||||
107.170.9.103 # denied=1 total=2 first=00:19:26.062 last=00:19:26.062
|
||||
129.212.237.196 # denied=1 total=2 first=09:23:08.470 last=09:23:08.471
|
||||
134.209.162.128 # denied=1 total=2 first=00:43:12.731 last=00:43:12.731
|
||||
158.101.144.198 # denied=1 total=2 first=14:30:06.125 last=14:30:06.125
|
||||
165.245.185.158 # denied=1 total=2 first=09:20:47.477 last=09:20:47.477
|
||||
176.65.132.38 # denied=1 total=3 first=20:33:22.070 last=05:08:32.533
|
||||
195.178.110.159 # denied=1 total=2 first=20:41:43.691 last=20:41:43.691
|
||||
2.57.122.173 # denied=1 total=2 first=12:10:19.177 last=12:10:19.177
|
||||
23.180.120.147 # denied=1 total=4 first=13:53:30.303 last=13:53:30.473
|
||||
31.58.51.184 # denied=1 total=4 first=15:07:53.176 last=15:07:58.514
|
||||
34.125.42.15 # denied=1 total=2 first=21:39:44.709 last=21:39:44.709
|
||||
34.91.243.226 # denied=1 total=2 first=19:51:57.606 last=19:51:57.606
|
||||
35.231.100.82 # denied=1 total=2 first=15:36:23.715 last=15:36:23.715
|
||||
35.233.191.179 # denied=1 total=2 first=00:16:07.188 last=00:16:07.199
|
||||
35.95.56.230 # denied=1 total=3 first=02:29:40.010 last=02:29:40.562
|
||||
43.98.201.177 # denied=1 total=2 first=01:01:05.988 last=01:01:05.988
|
||||
45.139.104.172 # denied=1 total=2 first=03:14:49.950 last=03:14:49.950
|
||||
64.226.123.37 # denied=1 total=2 first=21:33:32.148 last=21:33:32.148
|
||||
8.229.130.50 # denied=1 total=2 first=19:23:37.001 last=19:23:37.002
|
||||
93.123.109.167 # denied=1 total=2 first=04:39:35.474 last=04:39:35.474
|
||||
94.154.43.183 # denied=1 total=3 first=21:50:39.582 last=00:01:42.127
|
||||
94.154.43.185 # denied=1 total=3 first=01:40:53.903 last=04:02:34.085
|
||||
94.154.43.186 # denied=1 total=3 first=21:07:26.439 last=13:43:18.923
|
||||
94.154.43.188 # denied=1 total=5 first=02:45:01.636 last=11:09:54.264
|
||||
94.154.43.229 # denied=1 total=4 first=14:35:26.801 last=12:53:30.198
|
||||
195.178.110.199 # denied=621 total=1258 first=03:02:41.078 last=03:02:42.924
|
||||
45.148.10.67 # denied=621 total=1258 first=20:49:39.003 last=20:49:41.111
|
||||
20.251.48.208 # denied=306 total=612 first=23:50:43.575 last=17:01:41.376
|
||||
20.215.216.94 # denied=257 total=516 first=16:16:39.439 last=15:21:39.387
|
||||
20.215.218.234 # denied=252 total=504 first=02:46:27.628 last=05:35:25.304
|
||||
20.198.120.225 # denied=214 total=428 first=10:07:52.191 last=10:09:25.008
|
||||
172.213.227.73 # denied=191 total=382 first=03:00:13.592 last=01:13:37.755
|
||||
20.197.178.120 # denied=186 total=374 first=14:54:24.411 last=14:54:52.938
|
||||
74.249.245.134 # denied=177 total=354 first=21:27:53.575 last=21:29:06.182
|
||||
20.151.10.161 # denied=162 total=325 first=17:31:38.451 last=17:32:27.663
|
||||
20.205.229.184 # denied=161 total=323 first=12:17:54.322 last=12:18:41.173
|
||||
4.185.41.66 # denied=161 total=323 first=18:18:18.046 last=18:18:24.319
|
||||
52.184.96.217 # denied=161 total=323 first=20:02:55.760 last=20:03:44.824
|
||||
172.213.225.181 # denied=160 total=321 first=13:48:04.161 last=13:48:11.331
|
||||
20.48.236.161 # denied=160 total=321 first=15:11:59.817 last=15:12:31.060
|
||||
158.158.32.229 # denied=158 total=316 first=12:33:51.566 last=12:34:03.712
|
||||
20.63.63.128 # denied=157 total=315 first=16:04:22.373 last=16:04:50.675
|
||||
20.206.67.15 # denied=156 total=313 first=05:56:36.144 last=05:57:20.412
|
||||
20.215.185.25 # denied=150 total=300 first=08:18:05.984 last=08:19:09.190
|
||||
20.203.243.122 # denied=147 total=294 first=03:58:39.580 last=03:58:55.359
|
||||
20.52.171.102 # denied=146 total=292 first=20:01:30.635 last=20:01:36.800
|
||||
20.226.26.5 # denied=143 total=286 first=06:33:33.891 last=06:34:07.483
|
||||
68.221.130.241 # denied=139 total=278 first=08:28:43.979 last=08:28:50.496
|
||||
20.100.172.153 # denied=137 total=275 first=09:10:06.751 last=09:10:17.835
|
||||
51.107.190.246 # denied=137 total=274 first=01:44:18.242 last=01:44:28.832
|
||||
74.248.33.172 # denied=128 total=257 first=23:32:36.049 last=23:32:42.718
|
||||
20.203.179.12 # denied=125 total=250 first=17:33:20.484 last=17:33:29.742
|
||||
20.113.142.140 # denied=115 total=231 first=07:47:47.716 last=07:48:00.044
|
||||
74.248.97.169 # denied=115 total=231 first=13:25:17.217 last=13:25:31.602
|
||||
20.251.112.224 # denied=107 total=215 first=06:52:51.081 last=06:53:05.602
|
||||
158.158.105.63 # denied=104 total=208 first=11:24:12.912 last=23:00:49.043
|
||||
4.223.71.149 # denied=104 total=209 first=00:26:55.320 last=00:27:19.244
|
||||
4.223.73.90 # denied=102 total=204 first=19:50:04.916 last=18:12:09.187
|
||||
135.225.93.215 # denied=101 total=203 first=02:32:24.496 last=02:32:32.326
|
||||
20.9.85.55 # denied=101 total=203 first=15:43:36.450 last=15:44:20.170
|
||||
20.91.208.34 # denied=101 total=203 first=22:07:01.428 last=22:07:20.883
|
||||
52.238.192.78 # denied=101 total=203 first=00:04:31.589 last=00:05:07.114
|
||||
172.213.208.13 # denied=96 total=192 first=13:27:56.743 last=19:14:00.938
|
||||
172.213.244.85 # denied=82 total=165 first=17:01:49.042 last=17:01:52.331
|
||||
20.206.105.145 # denied=78 total=157 first=04:06:08.085 last=04:06:29.772
|
||||
51.120.83.160 # denied=72 total=144 first=15:40:29.699 last=15:40:39.446
|
||||
172.213.153.79 # denied=57 total=114 first=18:40:13.799 last=18:40:20.149
|
||||
20.91.239.158 # denied=57 total=114 first=13:42:20.392 last=13:42:24.986
|
||||
4.232.185.87 # denied=53 total=110 first=21:23:31.012 last=21:23:33.019
|
||||
20.218.73.95 # denied=49 total=98 first=04:39:44.907 last=04:39:46.708
|
||||
20.91.203.45 # denied=47 total=94 first=16:27:01.288 last=16:27:10.455
|
||||
20.197.192.193 # denied=44 total=88 first=13:45:32.377 last=13:45:43.108
|
||||
74.248.24.145 # denied=37 total=74 first=09:21:37.839 last=09:21:43.127
|
||||
172.213.144.209 # denied=35 total=70 first=07:52:16.066 last=07:52:17.778
|
||||
35.198.180.224 # denied=22 total=46 first=14:14:37.617 last=14:14:48.930
|
||||
45.148.10.62 # denied=22 total=98 first=07:53:03.360 last=03:15:12.651
|
||||
45.148.10.244 # denied=18 total=109 first=04:53:37.585 last=09:56:59.103
|
||||
45.148.10.120 # denied=16 total=33 first=14:24:06.542 last=17:06:11.688
|
||||
34.39.210.94 # denied=12 total=24 first=19:31:07.030 last=19:31:07.101
|
||||
195.178.110.31 # denied=11 total=49 first=02:27:56.164 last=02:27:58.425
|
||||
195.178.110.223 # denied=10 total=37 first=01:31:40.464 last=01:56:49.503
|
||||
34.95.239.96 # denied=10 total=20 first=11:25:18.487 last=11:25:18.532
|
||||
107.173.254.55 # denied=9 total=29 first=07:04:56.768 last=07:05:17.755
|
||||
136.108.11.195 # denied=9 total=25 first=08:33:11.182 last=08:33:13.921
|
||||
139.59.118.17 # denied=9 total=180 first=08:21:30.247 last=08:22:03.812
|
||||
146.70.40.68 # denied=9 total=30 first=18:55:47.310 last=18:55:48.145
|
||||
147.182.149.75 # denied=9 total=40 first=21:50:17.837 last=21:50:45.474
|
||||
16.146.99.254 # denied=9 total=279 first=12:11:20.725 last=12:12:09.790
|
||||
163.7.11.71 # denied=9 total=93 first=07:24:55.235 last=07:25:05.144
|
||||
167.99.181.249 # denied=9 total=40 first=21:50:26.091 last=21:51:01.239
|
||||
18.142.90.109 # denied=9 total=279 first=17:06:23.216 last=17:07:15.117
|
||||
18.227.73.7 # denied=9 total=392 first=22:00:31.465 last=22:01:33.982
|
||||
207.175.159.248 # denied=9 total=25 first=03:52:06.643 last=03:52:07.542
|
||||
207.175.20.232 # denied=9 total=25 first=09:43:00.775 last=09:43:03.604
|
||||
209.99.189.190 # denied=9 total=77 first=17:04:48.190 last=09:53:52.093
|
||||
3.79.41.12 # denied=9 total=286 first=04:20:16.234 last=04:20:22.797
|
||||
34.105.30.251 # denied=9 total=29 first=15:55:43.824 last=15:55:49.547
|
||||
34.23.104.90 # denied=9 total=25 first=14:40:59.025 last=14:41:01.713
|
||||
34.242.226.103 # denied=9 total=286 first=06:52:40.299 last=06:52:54.689
|
||||
34.9.173.20 # denied=9 total=245 first=16:55:22.164 last=16:55:30.344
|
||||
45.67.85.190 # denied=9 total=32 first=19:41:44.132 last=19:41:46.806
|
||||
54.163.186.39 # denied=9 total=286 first=01:39:29.740 last=01:40:00.874
|
||||
82.102.18.116 # denied=9 total=30 first=04:49:33.098 last=04:49:34.184
|
||||
85.204.70.100 # denied=9 total=30 first=13:55:11.862 last=13:55:12.567
|
||||
88.151.32.7 # denied=9 total=88 first=18:43:38.911 last=19:04:03.160
|
||||
91.192.10.86 # denied=9 total=31 first=13:38:54.986 last=13:38:56.159
|
||||
93.123.109.101 # denied=9 total=4320 first=00:35:05.539 last=00:40:32.578
|
||||
185.93.89.147 # denied=8 total=3762 first=19:07:14.620 last=08:52:41.657
|
||||
195.178.110.155 # denied=8 total=57 first=09:10:16.072 last=09:10:19.329
|
||||
45.148.10.194 # denied=8 total=58 first=15:46:42.822 last=15:46:45.473
|
||||
45.148.10.247 # denied=8 total=57 first=00:58:56.398 last=00:58:59.599
|
||||
72.146.20.230 # denied=7 total=14 first=03:01:31.244 last=03:01:31.427
|
||||
91.92.241.196 # denied=7 total=15 first=13:55:12.175 last=15:50:21.628
|
||||
209.99.189.152 # denied=6 total=13 first=18:03:04.845 last=18:03:12.906
|
||||
34.140.123.172 # denied=6 total=434 first=21:34:17.485 last=21:35:45.084
|
||||
162.243.79.174 # denied=5 total=11 first=12:20:28.790 last=12:20:40.350
|
||||
51.79.208.246 # denied=5 total=10 first=13:50:27.669 last=13:50:29.418
|
||||
94.154.43.184 # denied=5 total=10 first=11:23:26.214 last=09:31:40.319
|
||||
195.178.110.211 # denied=4 total=8 first=19:35:03.504 last=20:22:13.338
|
||||
45.148.10.119 # denied=3 total=11 first=02:36:55.008 last=07:16:27.585
|
||||
157.245.63.62 # denied=2 total=4 first=08:13:33.142 last=13:04:56.122
|
||||
163.7.13.115 # denied=2 total=5 first=14:06:27.842 last=14:06:29.745
|
||||
45.138.16.114 # denied=2 total=5 first=03:09:59.971 last=03:10:00.217
|
||||
45.148.10.95 # denied=2 total=4 first=21:05:26.356 last=14:40:26.566
|
||||
91.92.41.115 # denied=2 total=8 first=14:44:48.975 last=14:44:54.158
|
||||
94.154.43.179 # denied=2 total=5 first=13:27:23.753 last=04:38:17.921
|
||||
107.170.9.103 # denied=1 total=2 first=00:19:26.062 last=00:19:26.062
|
||||
129.212.237.196 # denied=1 total=2 first=09:23:08.470 last=09:23:08.471
|
||||
134.209.162.128 # denied=1 total=2 first=00:43:12.731 last=00:43:12.731
|
||||
158.101.144.198 # denied=1 total=2 first=14:30:06.125 last=14:30:06.125
|
||||
165.245.185.158 # denied=1 total=2 first=09:20:47.477 last=09:20:47.477
|
||||
176.65.132.38 # denied=1 total=3 first=20:33:22.070 last=05:08:32.533
|
||||
195.178.110.159 # denied=1 total=2 first=20:41:43.691 last=20:41:43.691
|
||||
2.57.122.173 # denied=1 total=2 first=12:10:19.177 last=12:10:19.177
|
||||
23.180.120.147 # denied=1 total=4 first=13:53:30.303 last=13:53:30.473
|
||||
31.58.51.184 # denied=1 total=4 first=15:07:53.176 last=15:07:58.514
|
||||
34.125.42.15 # denied=1 total=2 first=21:39:44.709 last=21:39:44.709
|
||||
34.91.243.226 # denied=1 total=2 first=19:51:57.606 last=19:51:57.606
|
||||
35.231.100.82 # denied=1 total=2 first=15:36:23.715 last=15:36:23.715
|
||||
35.233.191.179 # denied=1 total=2 first=00:16:07.188 last=00:16:07.199
|
||||
35.95.56.230 # denied=1 total=3 first=02:29:40.010 last=02:29:40.562
|
||||
43.98.201.177 # denied=1 total=2 first=01:01:05.988 last=01:01:05.988
|
||||
45.139.104.172 # denied=1 total=2 first=03:14:49.950 last=03:14:49.950
|
||||
64.226.123.37 # denied=1 total=2 first=21:33:32.148 last=21:33:32.148
|
||||
8.229.130.50 # denied=1 total=2 first=19:23:37.001 last=19:23:37.002
|
||||
93.123.109.167 # denied=1 total=2 first=04:39:35.474 last=04:39:35.474
|
||||
94.154.43.183 # denied=1 total=3 first=21:50:39.582 last=00:01:42.127
|
||||
94.154.43.185 # denied=1 total=3 first=01:40:53.903 last=04:02:34.085
|
||||
94.154.43.186 # denied=1 total=3 first=21:07:26.439 last=13:43:18.923
|
||||
94.154.43.188 # denied=1 total=5 first=02:45:01.636 last=11:09:54.264
|
||||
94.154.43.229 # denied=1 total=4 first=14:35:26.801 last=12:53:30.198
|
||||
@@ -1,3 +1,3 @@
|
||||
2a04:4e40:e000:0:d09:97ab:43b1:a59a # denied=2 total=4 first=14:41:30.905 last=14:41:30.922
|
||||
2600:3c15::2000:53ff:fe31:8c0b # denied=1 total=2 first=12:35:18.643 last=12:35:18.643
|
||||
2602:fa59:10:a3a::1 # denied=1 total=2 first=02:10:02.531 last=02:10:02.532
|
||||
2a04:4e40:e000:0:d09:97ab:43b1:a59a # denied=2 total=4 first=14:41:30.905 last=14:41:30.922
|
||||
2600:3c15::2000:53ff:fe31:8c0b # denied=1 total=2 first=12:35:18.643 last=12:35:18.643
|
||||
2602:fa59:10:a3a::1 # denied=1 total=2 first=02:10:02.531 last=02:10:02.532
|
||||
+2127
-2127
File diff suppressed because it is too large.
Load diff
@@ -1,202 +1,202 @@
|
||||
# copyparty-ids firewall export - generated 2026-08-11T11:44:39
|
||||
|
||||
# Openfactory IPv4 ranges (whitelisted)
|
||||
/ip firewall address-list
|
||||
add list=Openfactory address=5.226.144.0/21
|
||||
|
||||
# Cloudflare IPv4 ranges (whitelisted)
|
||||
/ip firewall address-list
|
||||
add list=Cloudflare address=173.245.48.0/20
|
||||
add list=Cloudflare address=103.21.244.0/22
|
||||
add list=Cloudflare address=103.22.200.0/22
|
||||
add list=Cloudflare address=103.31.4.0/22
|
||||
add list=Cloudflare address=141.101.64.0/18
|
||||
add list=Cloudflare address=108.162.192.0/18
|
||||
add list=Cloudflare address=190.93.240.0/20
|
||||
add list=Cloudflare address=188.114.96.0/20
|
||||
add list=Cloudflare address=197.234.240.0/22
|
||||
add list=Cloudflare address=198.41.128.0/17
|
||||
add list=Cloudflare address=162.158.0.0/15
|
||||
add list=Cloudflare address=104.16.0.0/13
|
||||
add list=Cloudflare address=104.24.0.0/14
|
||||
add list=Cloudflare address=172.64.0.0/13
|
||||
add list=Cloudflare address=131.0.72.0/22
|
||||
|
||||
# Cloudflare IPv6 ranges (whitelisted)
|
||||
/ipv6 firewall address-list
|
||||
add list=Cloudflare address=2400:cb00::/32
|
||||
add list=Cloudflare address=2606:4700::/32
|
||||
add list=Cloudflare address=2803:f800::/32
|
||||
add list=Cloudflare address=2405:b500::/32
|
||||
add list=Cloudflare address=2405:8100::/32
|
||||
add list=Cloudflare address=2a06:98c0::/29
|
||||
add list=Cloudflare address=2c0f:f248::/32
|
||||
|
||||
# PaloAlto IPv4 ranges (whitelisted)
|
||||
/ip firewall address-list
|
||||
add list=PaloAlto address=35.203.210.0/23
|
||||
add list=PaloAlto address=144.86.173.0/24
|
||||
add list=PaloAlto address=147.185.132.0/23
|
||||
add list=PaloAlto address=162.216.149.0/24
|
||||
add list=PaloAlto address=162.216.150.0/24
|
||||
add list=PaloAlto address=172.105.147.0/24
|
||||
add list=PaloAlto address=198.235.24.0/24
|
||||
add list=PaloAlto address=205.210.31.0/24
|
||||
add list=PaloAlto address=216.25.88.0/21
|
||||
|
||||
# PaloAlto IPv6 ranges (whitelisted)
|
||||
/ipv6 firewall address-list
|
||||
add list=PaloAlto address=2604:a940:300:5b6::/64
|
||||
add list=PaloAlto address=2604:a940:301:225::/64
|
||||
add list=PaloAlto address=2604:a940:302:118::/64
|
||||
|
||||
# Blocked IPv4 (128, non-whitelisted)
|
||||
/ip firewall address-list
|
||||
add list=Blocked address=2.57.122.173
|
||||
add list=Blocked address=3.79.41.12
|
||||
add list=Blocked address=4.185.41.66
|
||||
add list=Blocked address=4.223.71.149
|
||||
add list=Blocked address=4.223.73.90
|
||||
add list=Blocked address=4.232.185.87
|
||||
add list=Blocked address=8.229.130.50
|
||||
add list=Blocked address=16.146.99.254
|
||||
add list=Blocked address=18.142.90.109
|
||||
add list=Blocked address=18.227.73.7
|
||||
add list=Blocked address=20.9.85.55
|
||||
add list=Blocked address=20.48.236.161
|
||||
add list=Blocked address=20.52.171.102
|
||||
add list=Blocked address=20.63.63.128
|
||||
add list=Blocked address=20.91.203.45
|
||||
add list=Blocked address=20.91.208.34
|
||||
add list=Blocked address=20.91.239.158
|
||||
add list=Blocked address=20.100.172.153
|
||||
add list=Blocked address=20.113.142.140
|
||||
add list=Blocked address=20.151.10.161
|
||||
add list=Blocked address=20.197.178.120
|
||||
add list=Blocked address=20.197.192.193
|
||||
add list=Blocked address=20.198.120.225
|
||||
add list=Blocked address=20.203.179.12
|
||||
add list=Blocked address=20.203.243.122
|
||||
add list=Blocked address=20.205.229.184
|
||||
add list=Blocked address=20.206.67.15
|
||||
add list=Blocked address=20.206.105.145
|
||||
add list=Blocked address=20.215.185.25
|
||||
add list=Blocked address=20.215.216.94
|
||||
add list=Blocked address=20.215.218.234
|
||||
add list=Blocked address=20.218.73.95
|
||||
add list=Blocked address=20.226.26.5
|
||||
add list=Blocked address=20.251.48.208
|
||||
add list=Blocked address=20.251.112.224
|
||||
add list=Blocked address=23.180.120.147
|
||||
add list=Blocked address=31.58.51.184
|
||||
add list=Blocked address=34.9.173.20
|
||||
add list=Blocked address=34.23.104.90
|
||||
add list=Blocked address=34.39.210.94
|
||||
add list=Blocked address=34.91.243.226
|
||||
add list=Blocked address=34.95.239.96
|
||||
add list=Blocked address=34.105.30.251
|
||||
add list=Blocked address=34.125.42.15
|
||||
add list=Blocked address=34.140.123.172
|
||||
add list=Blocked address=34.242.226.103
|
||||
add list=Blocked address=35.95.56.230
|
||||
add list=Blocked address=35.198.180.224
|
||||
add list=Blocked address=35.231.100.82
|
||||
add list=Blocked address=35.233.191.179
|
||||
add list=Blocked address=43.98.201.177
|
||||
add list=Blocked address=45.67.85.190
|
||||
add list=Blocked address=45.138.16.114
|
||||
add list=Blocked address=45.139.104.172
|
||||
add list=Blocked address=45.148.10.62
|
||||
add list=Blocked address=45.148.10.67
|
||||
add list=Blocked address=45.148.10.95
|
||||
add list=Blocked address=45.148.10.119
|
||||
add list=Blocked address=45.148.10.120
|
||||
add list=Blocked address=45.148.10.194
|
||||
add list=Blocked address=45.148.10.244
|
||||
add list=Blocked address=45.148.10.247
|
||||
add list=Blocked address=51.79.208.246
|
||||
add list=Blocked address=51.107.190.246
|
||||
add list=Blocked address=51.120.83.160
|
||||
add list=Blocked address=52.184.96.217
|
||||
add list=Blocked address=52.238.192.78
|
||||
add list=Blocked address=54.163.186.39
|
||||
add list=Blocked address=64.226.123.37
|
||||
add list=Blocked address=68.221.130.241
|
||||
add list=Blocked address=72.146.20.230
|
||||
add list=Blocked address=74.248.24.145
|
||||
add list=Blocked address=74.248.33.172
|
||||
add list=Blocked address=74.248.97.169
|
||||
add list=Blocked address=74.249.245.134
|
||||
add list=Blocked address=82.102.18.116
|
||||
add list=Blocked address=85.204.70.100
|
||||
add list=Blocked address=88.151.32.7
|
||||
add list=Blocked address=91.92.41.115
|
||||
add list=Blocked address=91.92.241.196
|
||||
add list=Blocked address=91.192.10.86
|
||||
add list=Blocked address=93.123.109.101
|
||||
add list=Blocked address=93.123.109.167
|
||||
add list=Blocked address=94.154.43.179
|
||||
add list=Blocked address=94.154.43.183
|
||||
add list=Blocked address=94.154.43.184
|
||||
add list=Blocked address=94.154.43.185
|
||||
add list=Blocked address=94.154.43.186
|
||||
add list=Blocked address=94.154.43.188
|
||||
add list=Blocked address=94.154.43.229
|
||||
add list=Blocked address=107.170.9.103
|
||||
add list=Blocked address=107.173.254.55
|
||||
add list=Blocked address=129.212.237.196
|
||||
add list=Blocked address=134.209.162.128
|
||||
add list=Blocked address=135.225.93.215
|
||||
add list=Blocked address=136.108.11.195
|
||||
add list=Blocked address=139.59.118.17
|
||||
add list=Blocked address=146.70.40.68
|
||||
add list=Blocked address=147.182.149.75
|
||||
add list=Blocked address=157.245.63.62
|
||||
add list=Blocked address=158.101.144.198
|
||||
add list=Blocked address=158.158.32.229
|
||||
add list=Blocked address=158.158.105.63
|
||||
add list=Blocked address=162.243.79.174
|
||||
add list=Blocked address=163.7.11.71
|
||||
add list=Blocked address=163.7.13.115
|
||||
add list=Blocked address=165.245.185.158
|
||||
add list=Blocked address=167.99.181.249
|
||||
add list=Blocked address=172.213.144.209
|
||||
add list=Blocked address=172.213.153.79
|
||||
add list=Blocked address=172.213.208.13
|
||||
add list=Blocked address=172.213.225.181
|
||||
add list=Blocked address=172.213.227.73
|
||||
add list=Blocked address=172.213.244.85
|
||||
add list=Blocked address=176.65.132.38
|
||||
add list=Blocked address=185.93.89.147
|
||||
add list=Blocked address=195.178.110.31
|
||||
add list=Blocked address=195.178.110.104
|
||||
add list=Blocked address=195.178.110.135
|
||||
add list=Blocked address=195.178.110.155
|
||||
add list=Blocked address=195.178.110.159
|
||||
add list=Blocked address=195.178.110.199
|
||||
add list=Blocked address=195.178.110.211
|
||||
add list=Blocked address=195.178.110.223
|
||||
add list=Blocked address=207.175.20.232
|
||||
add list=Blocked address=207.175.159.248
|
||||
add list=Blocked address=209.99.189.152
|
||||
add list=Blocked address=209.99.189.190
|
||||
|
||||
# Blocked IPv6 (3, non-whitelisted)
|
||||
/ipv6 firewall address-list
|
||||
add list=Blocked address=2600:3c15::2000:53ff:fe31:8c0b
|
||||
add list=Blocked address=2602:fa59:10:a3a::1
|
||||
add list=Blocked address=2a04:4e40:e000:0:d09:97ab:43b1:a59a
|
||||
|
||||
/ip firewall filter
|
||||
add chain=input action=accept src-address-list=Openfactory comment="copyparty-ids openfactory whitelist (v4)"
|
||||
add chain=input action=accept src-address-list=Cloudflare comment="copyparty-ids cloudflare whitelist (v4)"
|
||||
add chain=input action=accept src-address-list=PaloAlto comment="copyparty-ids paloalto whitelist (v4)"
|
||||
add chain=input action=drop src-address-list=Blocked comment="copyparty-ids blocked (v4)"
|
||||
add chain=forward action=drop src-address-list=Blocked comment="copyparty-ids blocked (v4)"
|
||||
|
||||
/ipv6 firewall filter
|
||||
add chain=input action=accept src-address-list=Openfactory comment="copyparty-ids openfactory whitelist (v6)"
|
||||
add chain=input action=accept src-address-list=Cloudflare comment="copyparty-ids cloudflare whitelist (v6)"
|
||||
add chain=input action=accept src-address-list=PaloAlto comment="copyparty-ids paloalto whitelist (v6)"
|
||||
add chain=input action=drop src-address-list=Blocked comment="copyparty-ids blocked (v6)"
|
||||
add chain=forward action=drop src-address-list=Blocked comment="copyparty-ids blocked (v6)"
|
||||
# copyparty-ids firewall export - generated 2026-08-11T11:44:39
|
||||
|
||||
# Openfactory IPv4 ranges (whitelisted)
|
||||
/ip firewall address-list
|
||||
add list=Openfactory address=5.226.144.0/21
|
||||
|
||||
# Cloudflare IPv4 ranges (whitelisted)
|
||||
/ip firewall address-list
|
||||
add list=Cloudflare address=173.245.48.0/20
|
||||
add list=Cloudflare address=103.21.244.0/22
|
||||
add list=Cloudflare address=103.22.200.0/22
|
||||
add list=Cloudflare address=103.31.4.0/22
|
||||
add list=Cloudflare address=141.101.64.0/18
|
||||
add list=Cloudflare address=108.162.192.0/18
|
||||
add list=Cloudflare address=190.93.240.0/20
|
||||
add list=Cloudflare address=188.114.96.0/20
|
||||
add list=Cloudflare address=197.234.240.0/22
|
||||
add list=Cloudflare address=198.41.128.0/17
|
||||
add list=Cloudflare address=162.158.0.0/15
|
||||
add list=Cloudflare address=104.16.0.0/13
|
||||
add list=Cloudflare address=104.24.0.0/14
|
||||
add list=Cloudflare address=172.64.0.0/13
|
||||
add list=Cloudflare address=131.0.72.0/22
|
||||
|
||||
# Cloudflare IPv6 ranges (whitelisted)
|
||||
/ipv6 firewall address-list
|
||||
add list=Cloudflare address=2400:cb00::/32
|
||||
add list=Cloudflare address=2606:4700::/32
|
||||
add list=Cloudflare address=2803:f800::/32
|
||||
add list=Cloudflare address=2405:b500::/32
|
||||
add list=Cloudflare address=2405:8100::/32
|
||||
add list=Cloudflare address=2a06:98c0::/29
|
||||
add list=Cloudflare address=2c0f:f248::/32
|
||||
|
||||
# PaloAlto IPv4 ranges (whitelisted)
|
||||
/ip firewall address-list
|
||||
add list=PaloAlto address=35.203.210.0/23
|
||||
add list=PaloAlto address=144.86.173.0/24
|
||||
add list=PaloAlto address=147.185.132.0/23
|
||||
add list=PaloAlto address=162.216.149.0/24
|
||||
add list=PaloAlto address=162.216.150.0/24
|
||||
add list=PaloAlto address=172.105.147.0/24
|
||||
add list=PaloAlto address=198.235.24.0/24
|
||||
add list=PaloAlto address=205.210.31.0/24
|
||||
add list=PaloAlto address=216.25.88.0/21
|
||||
|
||||
# PaloAlto IPv6 ranges (whitelisted)
|
||||
/ipv6 firewall address-list
|
||||
add list=PaloAlto address=2604:a940:300:5b6::/64
|
||||
add list=PaloAlto address=2604:a940:301:225::/64
|
||||
add list=PaloAlto address=2604:a940:302:118::/64
|
||||
|
||||
# Blocked IPv4 (128, non-whitelisted)
|
||||
/ip firewall address-list
|
||||
add list=Blocked address=2.57.122.173
|
||||
add list=Blocked address=3.79.41.12
|
||||
add list=Blocked address=4.185.41.66
|
||||
add list=Blocked address=4.223.71.149
|
||||
add list=Blocked address=4.223.73.90
|
||||
add list=Blocked address=4.232.185.87
|
||||
add list=Blocked address=8.229.130.50
|
||||
add list=Blocked address=16.146.99.254
|
||||
add list=Blocked address=18.142.90.109
|
||||
add list=Blocked address=18.227.73.7
|
||||
add list=Blocked address=20.9.85.55
|
||||
add list=Blocked address=20.48.236.161
|
||||
add list=Blocked address=20.52.171.102
|
||||
add list=Blocked address=20.63.63.128
|
||||
add list=Blocked address=20.91.203.45
|
||||
add list=Blocked address=20.91.208.34
|
||||
add list=Blocked address=20.91.239.158
|
||||
add list=Blocked address=20.100.172.153
|
||||
add list=Blocked address=20.113.142.140
|
||||
add list=Blocked address=20.151.10.161
|
||||
add list=Blocked address=20.197.178.120
|
||||
add list=Blocked address=20.197.192.193
|
||||
add list=Blocked address=20.198.120.225
|
||||
add list=Blocked address=20.203.179.12
|
||||
add list=Blocked address=20.203.243.122
|
||||
add list=Blocked address=20.205.229.184
|
||||
add list=Blocked address=20.206.67.15
|
||||
add list=Blocked address=20.206.105.145
|
||||
add list=Blocked address=20.215.185.25
|
||||
add list=Blocked address=20.215.216.94
|
||||
add list=Blocked address=20.215.218.234
|
||||
add list=Blocked address=20.218.73.95
|
||||
add list=Blocked address=20.226.26.5
|
||||
add list=Blocked address=20.251.48.208
|
||||
add list=Blocked address=20.251.112.224
|
||||
add list=Blocked address=23.180.120.147
|
||||
add list=Blocked address=31.58.51.184
|
||||
add list=Blocked address=34.9.173.20
|
||||
add list=Blocked address=34.23.104.90
|
||||
add list=Blocked address=34.39.210.94
|
||||
add list=Blocked address=34.91.243.226
|
||||
add list=Blocked address=34.95.239.96
|
||||
add list=Blocked address=34.105.30.251
|
||||
add list=Blocked address=34.125.42.15
|
||||
add list=Blocked address=34.140.123.172
|
||||
add list=Blocked address=34.242.226.103
|
||||
add list=Blocked address=35.95.56.230
|
||||
add list=Blocked address=35.198.180.224
|
||||
add list=Blocked address=35.231.100.82
|
||||
add list=Blocked address=35.233.191.179
|
||||
add list=Blocked address=43.98.201.177
|
||||
add list=Blocked address=45.67.85.190
|
||||
add list=Blocked address=45.138.16.114
|
||||
add list=Blocked address=45.139.104.172
|
||||
add list=Blocked address=45.148.10.62
|
||||
add list=Blocked address=45.148.10.67
|
||||
add list=Blocked address=45.148.10.95
|
||||
add list=Blocked address=45.148.10.119
|
||||
add list=Blocked address=45.148.10.120
|
||||
add list=Blocked address=45.148.10.194
|
||||
add list=Blocked address=45.148.10.244
|
||||
add list=Blocked address=45.148.10.247
|
||||
add list=Blocked address=51.79.208.246
|
||||
add list=Blocked address=51.107.190.246
|
||||
add list=Blocked address=51.120.83.160
|
||||
add list=Blocked address=52.184.96.217
|
||||
add list=Blocked address=52.238.192.78
|
||||
add list=Blocked address=54.163.186.39
|
||||
add list=Blocked address=64.226.123.37
|
||||
add list=Blocked address=68.221.130.241
|
||||
add list=Blocked address=72.146.20.230
|
||||
add list=Blocked address=74.248.24.145
|
||||
add list=Blocked address=74.248.33.172
|
||||
add list=Blocked address=74.248.97.169
|
||||
add list=Blocked address=74.249.245.134
|
||||
add list=Blocked address=82.102.18.116
|
||||
add list=Blocked address=85.204.70.100
|
||||
add list=Blocked address=88.151.32.7
|
||||
add list=Blocked address=91.92.41.115
|
||||
add list=Blocked address=91.92.241.196
|
||||
add list=Blocked address=91.192.10.86
|
||||
add list=Blocked address=93.123.109.101
|
||||
add list=Blocked address=93.123.109.167
|
||||
add list=Blocked address=94.154.43.179
|
||||
add list=Blocked address=94.154.43.183
|
||||
add list=Blocked address=94.154.43.184
|
||||
add list=Blocked address=94.154.43.185
|
||||
add list=Blocked address=94.154.43.186
|
||||
add list=Blocked address=94.154.43.188
|
||||
add list=Blocked address=94.154.43.229
|
||||
add list=Blocked address=107.170.9.103
|
||||
add list=Blocked address=107.173.254.55
|
||||
add list=Blocked address=129.212.237.196
|
||||
add list=Blocked address=134.209.162.128
|
||||
add list=Blocked address=135.225.93.215
|
||||
add list=Blocked address=136.108.11.195
|
||||
add list=Blocked address=139.59.118.17
|
||||
add list=Blocked address=146.70.40.68
|
||||
add list=Blocked address=147.182.149.75
|
||||
add list=Blocked address=157.245.63.62
|
||||
add list=Blocked address=158.101.144.198
|
||||
add list=Blocked address=158.158.32.229
|
||||
add list=Blocked address=158.158.105.63
|
||||
add list=Blocked address=162.243.79.174
|
||||
add list=Blocked address=163.7.11.71
|
||||
add list=Blocked address=163.7.13.115
|
||||
add list=Blocked address=165.245.185.158
|
||||
add list=Blocked address=167.99.181.249
|
||||
add list=Blocked address=172.213.144.209
|
||||
add list=Blocked address=172.213.153.79
|
||||
add list=Blocked address=172.213.208.13
|
||||
add list=Blocked address=172.213.225.181
|
||||
add list=Blocked address=172.213.227.73
|
||||
add list=Blocked address=172.213.244.85
|
||||
add list=Blocked address=176.65.132.38
|
||||
add list=Blocked address=185.93.89.147
|
||||
add list=Blocked address=195.178.110.31
|
||||
add list=Blocked address=195.178.110.104
|
||||
add list=Blocked address=195.178.110.135
|
||||
add list=Blocked address=195.178.110.155
|
||||
add list=Blocked address=195.178.110.159
|
||||
add list=Blocked address=195.178.110.199
|
||||
add list=Blocked address=195.178.110.211
|
||||
add list=Blocked address=195.178.110.223
|
||||
add list=Blocked address=207.175.20.232
|
||||
add list=Blocked address=207.175.159.248
|
||||
add list=Blocked address=209.99.189.152
|
||||
add list=Blocked address=209.99.189.190
|
||||
|
||||
# Blocked IPv6 (3, non-whitelisted)
|
||||
/ipv6 firewall address-list
|
||||
add list=Blocked address=2600:3c15::2000:53ff:fe31:8c0b
|
||||
add list=Blocked address=2602:fa59:10:a3a::1
|
||||
add list=Blocked address=2a04:4e40:e000:0:d09:97ab:43b1:a59a
|
||||
|
||||
/ip firewall filter
|
||||
add chain=input action=accept src-address-list=Openfactory comment="copyparty-ids openfactory whitelist (v4)"
|
||||
add chain=input action=accept src-address-list=Cloudflare comment="copyparty-ids cloudflare whitelist (v4)"
|
||||
add chain=input action=accept src-address-list=PaloAlto comment="copyparty-ids paloalto whitelist (v4)"
|
||||
add chain=input action=drop src-address-list=Blocked comment="copyparty-ids blocked (v4)"
|
||||
add chain=forward action=drop src-address-list=Blocked comment="copyparty-ids blocked (v4)"
|
||||
|
||||
/ipv6 firewall filter
|
||||
add chain=input action=accept src-address-list=Openfactory comment="copyparty-ids openfactory whitelist (v6)"
|
||||
add chain=input action=accept src-address-list=Cloudflare comment="copyparty-ids cloudflare whitelist (v6)"
|
||||
add chain=input action=accept src-address-list=PaloAlto comment="copyparty-ids paloalto whitelist (v6)"
|
||||
add chain=input action=drop src-address-list=Blocked comment="copyparty-ids blocked (v6)"
|
||||
add chain=forward action=drop src-address-list=Blocked comment="copyparty-ids blocked (v6)"
|
||||
+30035
-30035
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -1,384 +1,384 @@
|
||||
[
|
||||
{
|
||||
"address": "::/128",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "::1/128",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "fec0::/10",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "::ffff:0.0.0.0/96",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "::/96",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "100::/64",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "2001:db8::/32",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "2001:10::/28",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "3ffe::/16",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "2a0e:8f04::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2a0e:8f05::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2a0e:8f06::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2a0e:8f07::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340:2080::/48",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2001:67c:2648::/48",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340:2044:200::/56",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340:2044:600::/56",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340:2044:800::/56",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2400:cb00::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"address": "2606:4700::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"address": "2803:f800::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"address": "2405:b500::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"address": "2405:8100::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"address": "2a06:98c0::/29",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"address": "2c0f:f248::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"address": "2604:a940:300:5b6::/64",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "PaloAlto"
|
||||
},
|
||||
{
|
||||
"address": "2604:a940:301:225::/64",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "PaloAlto"
|
||||
},
|
||||
{
|
||||
"address": "2604:a940:302:118::/64",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "PaloAlto"
|
||||
},
|
||||
{
|
||||
"address": "2001:4ca0:108:42::24/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2400:8901::2000:62ff:fe9a:e1c2/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2600:3000::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2600:3c09::2000:5cff:fe99:c802/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2600:3c15::2000:53ff:fe31:8c0b/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2602:fa59:10:a3a::1/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a01:2a8:a0dd:1::1012/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a04:4e40:e000:0:d09:97ab:43b1:a59a/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a04:c300::/29",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a09:bac5:9443:3af::5e:4d/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a09:bac5:9443:3af::5e:88/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a0a:4cc0:2000:8528:c4e8:3ff:febb:3ee9/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2001:ba0:24c:a500::1/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2406:da18:525:0:a23e:e8f6:3ea1:4c2c/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2600:3c15::2000:9cff:fef0:8ad6/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2602:fa59::/40",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340:2008:ec80:64cc:9116:beb2:1931/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340:2008:ec80:be24:11ff:fe3b:4058/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340:2008:ec80:be24:11ff:fe82:2775/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a01:4f8:c014:7f9e::1/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a04:4e40:4400:0:537:cdd2:7250:95db/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a04:4e40:e000::/48",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a05:4140:3::37cd/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a06:a880:5:7fb3::1/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a09:bac1:76c0:460::5e:6a/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a09:bac5::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a13:adc0::2ed:89ff:fe58:19c5/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2400:8901::2000:beff:fea3:5a44/128",
|
||||
"creation-time": "2026-08-05",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340::/32",
|
||||
"creation-time": "2026-08-06",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340:2017:3810::/64",
|
||||
"comment": "hosting",
|
||||
"creation-time": "2026-08-07",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2001:8d8:5ff:5f:82:165:82:154/128",
|
||||
"creation-time": "2026-08-07",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2600:3c15::/32",
|
||||
"creation-time": "2026-08-07",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2001:448a:a071:520:e18f:3d1f:944e:174d/128",
|
||||
"creation-time": "2026-08-08",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
}
|
||||
[
|
||||
{
|
||||
"address": "::/128",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "::1/128",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "fec0::/10",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "::ffff:0.0.0.0/96",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "::/96",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "100::/64",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "2001:db8::/32",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "2001:10::/28",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "3ffe::/16",
|
||||
"comment": "defconf:",
|
||||
"creation-time": "2025-11-21",
|
||||
"dynamic": "no",
|
||||
"list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"address": "2a0e:8f04::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2a0e:8f05::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2a0e:8f06::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2a0e:8f07::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340:2080::/48",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2001:67c:2648::/48",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340:2044:200::/56",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340:2044:600::/56",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340:2044:800::/56",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2400:cb00::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"address": "2606:4700::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"address": "2803:f800::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"address": "2405:b500::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"address": "2405:8100::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"address": "2a06:98c0::/29",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"address": "2c0f:f248::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"address": "2604:a940:300:5b6::/64",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "PaloAlto"
|
||||
},
|
||||
{
|
||||
"address": "2604:a940:301:225::/64",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "PaloAlto"
|
||||
},
|
||||
{
|
||||
"address": "2604:a940:302:118::/64",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "PaloAlto"
|
||||
},
|
||||
{
|
||||
"address": "2001:4ca0:108:42::24/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2400:8901::2000:62ff:fe9a:e1c2/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2600:3000::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2600:3c09::2000:5cff:fe99:c802/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2600:3c15::2000:53ff:fe31:8c0b/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2602:fa59:10:a3a::1/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a01:2a8:a0dd:1::1012/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a04:4e40:e000:0:d09:97ab:43b1:a59a/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a04:c300::/29",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a09:bac5:9443:3af::5e:4d/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a09:bac5:9443:3af::5e:88/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a0a:4cc0:2000:8528:c4e8:3ff:febb:3ee9/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2001:ba0:24c:a500::1/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2406:da18:525:0:a23e:e8f6:3ea1:4c2c/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2600:3c15::2000:9cff:fef0:8ad6/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2602:fa59::/40",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340:2008:ec80:64cc:9116:beb2:1931/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340:2008:ec80:be24:11ff:fe3b:4058/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340:2008:ec80:be24:11ff:fe82:2775/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a01:4f8:c014:7f9e::1/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a04:4e40:4400:0:537:cdd2:7250:95db/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a04:4e40:e000::/48",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a05:4140:3::37cd/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a06:a880:5:7fb3::1/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a09:bac1:76c0:460::5e:6a/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a09:bac5::/32",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a13:adc0::2ed:89ff:fe58:19c5/128",
|
||||
"creation-time": "2026-08-03",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2400:8901::2000:beff:fea3:5a44/128",
|
||||
"creation-time": "2026-08-05",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340::/32",
|
||||
"creation-time": "2026-08-06",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2a00:6340:2017:3810::/64",
|
||||
"comment": "hosting",
|
||||
"creation-time": "2026-08-07",
|
||||
"dynamic": "no",
|
||||
"list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"address": "2001:8d8:5ff:5f:82:165:82:154/128",
|
||||
"creation-time": "2026-08-07",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2600:3c15::/32",
|
||||
"creation-time": "2026-08-07",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
},
|
||||
{
|
||||
"address": "2001:448a:a071:520:e18f:3d1f:944e:174d/128",
|
||||
"creation-time": "2026-08-08",
|
||||
"dynamic": "no",
|
||||
"list": "Blocked"
|
||||
}
|
||||
]
|
||||
@@ -1,137 +1,137 @@
|
||||
[
|
||||
{
|
||||
"action": "passthrough",
|
||||
"chain": "forward",
|
||||
"comment": "special"
|
||||
},
|
||||
{
|
||||
"action": "fasttrack-connection",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"connection-state": "established,related",
|
||||
"hw-offload": "yes",
|
||||
"log": "no",
|
||||
"log-prefix": ""
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"connection-state": "established,related",
|
||||
"log": "no",
|
||||
"log-prefix": ""
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"connection-state": "invalid",
|
||||
"log": "no",
|
||||
"log-prefix": ""
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "Allow",
|
||||
"connection-nat-state": "dstnat"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "allow",
|
||||
"connection-state": "new",
|
||||
"dst-address": "192.168.88.25",
|
||||
"dst-port": "6667",
|
||||
"log": "no",
|
||||
"log-prefix": "",
|
||||
"protocol": "tcp"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"connection-nat-state": "!dstnat",
|
||||
"connection-state": "new",
|
||||
"in-interface-list": "WAN",
|
||||
"log": "no",
|
||||
"log-prefix": ""
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "allow",
|
||||
"log": "no",
|
||||
"log-prefix": "",
|
||||
"protocol": "icmp"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "accept",
|
||||
"connection-state": "established",
|
||||
"log": "no",
|
||||
"log-prefix": ""
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "allow",
|
||||
"dst-port": "500",
|
||||
"protocol": "udp"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "input",
|
||||
"comment": "Block",
|
||||
"dst-port": "80,443",
|
||||
"in-interface-list": "WAN",
|
||||
"protocol": "tcp"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "Allow",
|
||||
"dst-port": "80,443",
|
||||
"in-interface-list": "LAN",
|
||||
"protocol": "tcp",
|
||||
"src-address": "192.168.88.0/24"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "ids",
|
||||
"src-address-list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "ids",
|
||||
"src-address-list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "ids",
|
||||
"src-address-list": "PaloAlto"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "input",
|
||||
"comment": "ids",
|
||||
"src-address-list": "Blocked"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "ids",
|
||||
"src-address-list": "Blocked"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "input",
|
||||
"comment": "drop",
|
||||
"in-interface": "pppoe-out1",
|
||||
"log": "no",
|
||||
"log-prefix": ""
|
||||
}
|
||||
[
|
||||
{
|
||||
"action": "passthrough",
|
||||
"chain": "forward",
|
||||
"comment": "special"
|
||||
},
|
||||
{
|
||||
"action": "fasttrack-connection",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"connection-state": "established,related",
|
||||
"hw-offload": "yes",
|
||||
"log": "no",
|
||||
"log-prefix": ""
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"connection-state": "established,related",
|
||||
"log": "no",
|
||||
"log-prefix": ""
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"connection-state": "invalid",
|
||||
"log": "no",
|
||||
"log-prefix": ""
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "Allow",
|
||||
"connection-nat-state": "dstnat"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "allow",
|
||||
"connection-state": "new",
|
||||
"dst-address": "192.168.88.25",
|
||||
"dst-port": "6667",
|
||||
"log": "no",
|
||||
"log-prefix": "",
|
||||
"protocol": "tcp"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"connection-nat-state": "!dstnat",
|
||||
"connection-state": "new",
|
||||
"in-interface-list": "WAN",
|
||||
"log": "no",
|
||||
"log-prefix": ""
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "allow",
|
||||
"log": "no",
|
||||
"log-prefix": "",
|
||||
"protocol": "icmp"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "accept",
|
||||
"connection-state": "established",
|
||||
"log": "no",
|
||||
"log-prefix": ""
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "allow",
|
||||
"dst-port": "500",
|
||||
"protocol": "udp"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "input",
|
||||
"comment": "Block",
|
||||
"dst-port": "80,443",
|
||||
"in-interface-list": "WAN",
|
||||
"protocol": "tcp"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "Allow",
|
||||
"dst-port": "80,443",
|
||||
"in-interface-list": "LAN",
|
||||
"protocol": "tcp",
|
||||
"src-address": "192.168.88.0/24"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "ids",
|
||||
"src-address-list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "ids",
|
||||
"src-address-list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "ids",
|
||||
"src-address-list": "PaloAlto"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "input",
|
||||
"comment": "ids",
|
||||
"src-address-list": "Blocked"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "ids",
|
||||
"src-address-list": "Blocked"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "input",
|
||||
"comment": "drop",
|
||||
"in-interface": "pppoe-out1",
|
||||
"log": "no",
|
||||
"log-prefix": ""
|
||||
}
|
||||
]
|
||||
@@ -1,186 +1,186 @@
|
||||
[
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"connection-state": "established,related,untracked"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"connection-state": "invalid"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"protocol": "icmpv6"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"port": "33434-33534",
|
||||
"protocol": "udp"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"dst-port": "546",
|
||||
"protocol": "udp",
|
||||
"src-address": "fe80::/10"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"dst-port": "500,4500",
|
||||
"protocol": "udp"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"protocol": "ipsec-ah"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"protocol": "ipsec-esp"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"ipsec-policy": "in,ipsec"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"in-interface-list": "!LAN"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"connection-state": "established,related,untracked"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"connection-state": "invalid"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"src-address-list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"dst-address-list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"hop-limit": "equal:1",
|
||||
"protocol": "icmpv6"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "ids",
|
||||
"log": "no",
|
||||
"log-prefix": "",
|
||||
"src-address-list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "ids",
|
||||
"src-address-list": "Blocked"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"protocol": "icmpv6"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"log": "no",
|
||||
"log-prefix": "",
|
||||
"protocol": "icmpv6"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"protocol": "139"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"dst-port": "500,4500",
|
||||
"protocol": "udp"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"protocol": "ipsec-ah"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"protocol": "ipsec-esp"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"ipsec-policy": "in,ipsec"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"in-interface-list": "!LAN"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "ids",
|
||||
"src-address-list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "ids",
|
||||
"src-address-list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "ids",
|
||||
"src-address-list": "PaloAlto"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "input",
|
||||
"comment": "ids",
|
||||
"src-address-list": "Blocked"
|
||||
}
|
||||
[
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"connection-state": "established,related,untracked"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"connection-state": "invalid"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"protocol": "icmpv6"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"port": "33434-33534",
|
||||
"protocol": "udp"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"dst-port": "546",
|
||||
"protocol": "udp",
|
||||
"src-address": "fe80::/10"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"dst-port": "500,4500",
|
||||
"protocol": "udp"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"protocol": "ipsec-ah"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"protocol": "ipsec-esp"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"ipsec-policy": "in,ipsec"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"in-interface-list": "!LAN"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"connection-state": "established,related,untracked"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"connection-state": "invalid"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"src-address-list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"dst-address-list": "bad_ipv6"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"hop-limit": "equal:1",
|
||||
"protocol": "icmpv6"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "ids",
|
||||
"log": "no",
|
||||
"log-prefix": "",
|
||||
"src-address-list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "ids",
|
||||
"src-address-list": "Blocked"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"protocol": "icmpv6"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "defconf:",
|
||||
"log": "no",
|
||||
"log-prefix": "",
|
||||
"protocol": "icmpv6"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"protocol": "139"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"dst-port": "500,4500",
|
||||
"protocol": "udp"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"protocol": "ipsec-ah"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"protocol": "ipsec-esp"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"ipsec-policy": "in,ipsec"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "forward",
|
||||
"comment": "defconf:",
|
||||
"in-interface-list": "!LAN"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "ids",
|
||||
"src-address-list": "Openfactory"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "ids",
|
||||
"src-address-list": "Cloudflare"
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"chain": "input",
|
||||
"comment": "ids",
|
||||
"src-address-list": "PaloAlto"
|
||||
},
|
||||
{
|
||||
"action": "drop",
|
||||
"chain": "input",
|
||||
"comment": "ids",
|
||||
"src-address-list": "Blocked"
|
||||
}
|
||||
]
|
||||
+1148
-1148
File diff suppressed because it is too large.
Load diff
+1147
-1147
File diff suppressed because it is too large.
Load diff
+1259
-1259
File diff suppressed because it is too large.
Load diff
+1148
-1148
File diff suppressed because it is too large.
Load diff
+1259
-1259
File diff suppressed because it is too large.
Load diff
+1186
-1186
File diff suppressed because it is too large.
Load diff
+1287
-1287
File diff suppressed because it is too large.
Load diff
+1303
-1303
File diff suppressed because it is too large.
Load diff
+1050
-1050
File diff suppressed because it is too large.
Load diff
+1050
-1050
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -1,41 +1,41 @@
|
||||
2001:ba0:24c:a500::1
|
||||
2001:4ca0:108:42::24
|
||||
2400:8901::2000:62ff:fe9a:e1c2
|
||||
2406:da18:525:0:a23e:e8f6:3ea1:4c2c
|
||||
2600:3000:1305:4212::81
|
||||
2600:3000:1305:4212::82
|
||||
2600:3000:1305:4212::83
|
||||
2600:3000:1305:4212::84
|
||||
2600:3000:1305:4212::85
|
||||
2600:3000:2710:200::81
|
||||
2600:3000:2710:200::82
|
||||
2600:3000:2710:200::83
|
||||
2600:3000:2710:200::84
|
||||
2600:3000:2710:200::85
|
||||
2600:3000:2710:200::86
|
||||
2600:3c09::2000:5cff:fe99:c802
|
||||
2600:3c15::2000:53ff:fe31:8c0b
|
||||
2600:3c15::2000:9cff:fef0:8ad6
|
||||
2602:fa59:10:4c9::1
|
||||
2602:fa59:10:a3a::1
|
||||
2602:fa59:10:e70::1
|
||||
2a00:6340:2008:ec80:64cc:9116:beb2:1931
|
||||
2a00:6340:2008:ec80:be24:11ff:fe3b:4058
|
||||
2a00:6340:2008:ec80:be24:11ff:fe82:2775
|
||||
2a01:2a8:a0dd:1::1012
|
||||
2a01:4f8:c014:7f9e::1
|
||||
2a04:4e40:e000:0:33c:a689:be95:5a4
|
||||
2a04:4e40:e000:0:566:f8d7:adbe:f536
|
||||
2a04:4e40:e000:0:954:9789:20b1:d5fc
|
||||
2a04:4e40:e000:0:bfc:4b0:174b:d52d
|
||||
2a04:c300::3ce
|
||||
2a04:c300:400::58
|
||||
2a04:c300:400::5d
|
||||
2a04:c300:400::99
|
||||
2a05:4140:3::37cd
|
||||
2a09:bac1:76c0:460::5e:6a
|
||||
2a09:bac5:55fb:18c8::278:a7
|
||||
2a09:bac5:9443:3af::5e:4d
|
||||
2a09:bac5:9443:3af::5e:88
|
||||
2a0a:4cc0:2000:8528:c4e8:3ff:febb:3ee9
|
||||
2a13:adc0::2ed:89ff:fe58:19c5
|
||||
2001:ba0:24c:a500::1
|
||||
2001:4ca0:108:42::24
|
||||
2400:8901::2000:62ff:fe9a:e1c2
|
||||
2406:da18:525:0:a23e:e8f6:3ea1:4c2c
|
||||
2600:3000:1305:4212::81
|
||||
2600:3000:1305:4212::82
|
||||
2600:3000:1305:4212::83
|
||||
2600:3000:1305:4212::84
|
||||
2600:3000:1305:4212::85
|
||||
2600:3000:2710:200::81
|
||||
2600:3000:2710:200::82
|
||||
2600:3000:2710:200::83
|
||||
2600:3000:2710:200::84
|
||||
2600:3000:2710:200::85
|
||||
2600:3000:2710:200::86
|
||||
2600:3c09::2000:5cff:fe99:c802
|
||||
2600:3c15::2000:53ff:fe31:8c0b
|
||||
2600:3c15::2000:9cff:fef0:8ad6
|
||||
2602:fa59:10:4c9::1
|
||||
2602:fa59:10:a3a::1
|
||||
2602:fa59:10:e70::1
|
||||
2a00:6340:2008:ec80:64cc:9116:beb2:1931
|
||||
2a00:6340:2008:ec80:be24:11ff:fe3b:4058
|
||||
2a00:6340:2008:ec80:be24:11ff:fe82:2775
|
||||
2a01:2a8:a0dd:1::1012
|
||||
2a01:4f8:c014:7f9e::1
|
||||
2a04:4e40:e000:0:33c:a689:be95:5a4
|
||||
2a04:4e40:e000:0:566:f8d7:adbe:f536
|
||||
2a04:4e40:e000:0:954:9789:20b1:d5fc
|
||||
2a04:4e40:e000:0:bfc:4b0:174b:d52d
|
||||
2a04:c300::3ce
|
||||
2a04:c300:400::58
|
||||
2a04:c300:400::5d
|
||||
2a04:c300:400::99
|
||||
2a05:4140:3::37cd
|
||||
2a09:bac1:76c0:460::5e:6a
|
||||
2a09:bac5:55fb:18c8::278:a7
|
||||
2a09:bac5:9443:3af::5e:4d
|
||||
2a09:bac5:9443:3af::5e:88
|
||||
2a0a:4cc0:2000:8528:c4e8:3ff:febb:3ee9
|
||||
2a13:adc0::2ed:89ff:fe58:19c5
|
||||
+16090
-16090
File diff suppressed because it is too large.
Load diff
@@ -1,23 +1,23 @@
|
||||
host,count
|
||||
pbs.allucanget.biz,43743
|
||||
s.allucanget.biz,42014
|
||||
coolify.allucanget.biz,41829
|
||||
wagnerloibner.com,37046
|
||||
git.allucanget.biz,25376
|
||||
openmicodyssey.com,25325
|
||||
copyparty.allucanget.biz,18117
|
||||
openwebui.allucanget.biz,14539
|
||||
contact.allucanget.biz,10770
|
||||
ai.allucanget.biz,9799
|
||||
contact.wagnerloibner.com,9592
|
||||
admin.openmicodyssey.com,8974
|
||||
www.openmicodyssey.com,8386
|
||||
api.openmicodyssey.com,4598
|
||||
tcv.allucanget.biz,2557
|
||||
cam.openmicodyssey.com,2468
|
||||
linearvoid.tv,1951
|
||||
lounge.allucanget.biz,1745
|
||||
code.allucanget.biz,788
|
||||
www.wagnerloibner.com,326
|
||||
m.allucanget.biz,242
|
||||
postiz.allucanget.biz,78
|
||||
host,count
|
||||
pbs.allucanget.biz,43743
|
||||
s.allucanget.biz,42014
|
||||
coolify.allucanget.biz,41829
|
||||
wagnerloibner.com,37046
|
||||
git.allucanget.biz,25376
|
||||
openmicodyssey.com,25325
|
||||
copyparty.allucanget.biz,18117
|
||||
openwebui.allucanget.biz,14539
|
||||
contact.allucanget.biz,10770
|
||||
ai.allucanget.biz,9799
|
||||
contact.wagnerloibner.com,9592
|
||||
admin.openmicodyssey.com,8974
|
||||
www.openmicodyssey.com,8386
|
||||
api.openmicodyssey.com,4598
|
||||
tcv.allucanget.biz,2557
|
||||
cam.openmicodyssey.com,2468
|
||||
linearvoid.tv,1951
|
||||
lounge.allucanget.biz,1745
|
||||
code.allucanget.biz,788
|
||||
www.wagnerloibner.com,326
|
||||
m.allucanget.biz,242
|
||||
postiz.allucanget.biz,78
|
||||
|
+311264
-311264
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
+310264
-310264
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -1,26 +1,26 @@
|
||||
2a01:2a8:a0dd:1::1012 # errors=9517 total=9517 ratio=1.0 first=09/Aug/2026:19:01:21 +0200 last=18/Jul/2026:23:59:49 +0200
|
||||
2a0a:4cc0:2000:8528:c4e8:3ff:febb:3ee9 # errors=150 total=150 ratio=1.0 first=27/Jul/2026:14:49:23 +0200 last=27/Jul/2026:14:49:53 +0200
|
||||
2a00:6340:2008:ec80:be24:11ff:fe3b:4058 # errors=105 total=120 ratio=0.875 first=31/Jul/2026:18:53:29 +0200 last=17/Jul/2026:17:28:19 +0200
|
||||
2a06:98c0:3600::103 # errors=63 total=74 ratio=0.851 first=29/Jul/2026:05:34:01 +0200 last=27/Jul/2026:18:39:05 +0200
|
||||
2600:3000:1305:4212::83 # errors=44 total=78 ratio=0.564 first=10/Aug/2026:04:04:22 +0200 last=02/Aug/2026:08:41:15 +0200
|
||||
2a09:bac5:9443:3af::5e:4d # errors=40 total=40 ratio=1.0 first=25/Jul/2026:05:55:27 +0200 last=25/Jul/2026:05:55:39 +0200
|
||||
2600:3000:2710:200::85 # errors=37 total=68 ratio=0.544 first=10/Aug/2026:17:56:13 +0200 last=29/Jul/2026:02:00:14 +0200
|
||||
2600:3000:2710:200::86 # errors=29 total=49 ratio=0.592 first=10/Aug/2026:17:56:04 +0200 last=17/Jul/2026:17:26:06 +0200
|
||||
2600:3000:1305:4212::85 # errors=28 total=48 ratio=0.583 first=10/Aug/2026:02:00:13 +0200 last=10/Aug/2026:21:57:52 +0200
|
||||
2600:3000:2710:200::82 # errors=28 total=51 ratio=0.549 first=10/Aug/2026:04:01:19 +0200 last=17/Jul/2026:17:14:39 +0200
|
||||
2600:3000:2710:200::83 # errors=28 total=48 ratio=0.583 first=02/Aug/2026:08:43:47 +0200 last=17/Jul/2026:17:27:06 +0200
|
||||
2600:3000:1305:4212::81 # errors=24 total=46 ratio=0.522 first=02/Aug/2026:08:41:14 +0200 last=30/Jul/2026:02:00:11 +0200
|
||||
2600:3000:2710:200::81 # errors=23 total=38 ratio=0.605 first=25/Jul/2026:02:00:09 +0200 last=15/Jul/2026:18:29:14 +0200
|
||||
2600:3000:2710:200::84 # errors=23 total=44 ratio=0.523 first=10/Aug/2026:10:30:53 +0200 last=17/Jul/2026:17:22:50 +0200
|
||||
2600:3000:1305:4212::82 # errors=19 total=31 ratio=0.613 first=10/Aug/2026:10:30:34 +0200 last=02/Aug/2026:08:43:51 +0200
|
||||
2600:3000:1305:4212::84 # errors=19 total=35 ratio=0.543 first=29/Jul/2026:16:26:16 +0200 last=10/Aug/2026:19:53:10 +0200
|
||||
2a04:c300:400::99 # errors=15 total=15 ratio=1.0 first=25/Jul/2026:16:45:35 +0200 last=25/Jul/2026:16:45:40 +0200
|
||||
2a00:6340:2008:ec80:be24:11ff:fe82:2775 # errors=14 total=16 ratio=0.875 first=31/Jul/2026:19:10:46 +0200 last=31/Jul/2026:19:11:42 +0200
|
||||
2400:8901::2000:62ff:fe9a:e1c2 # errors=9 total=9 ratio=1.0 first=18/Jul/2026:21:57:41 +0200 last=18/Jul/2026:21:57:44 +0200
|
||||
2a09:bac5:9443:3af::5e:88 # errors=8 total=8 ratio=1.0 first=16/Jul/2026:10:53:36 +0200 last=16/Jul/2026:10:53:36 +0200
|
||||
2001:4ca0:108:42::24 # errors=7 total=8 ratio=0.875 first=09/Aug/2026:19:50:32 +0200 last=19/Jul/2026:09:41:27 +0200
|
||||
2a04:c300:400::58 # errors=7 total=8 ratio=0.875 first=20/Jul/2026:23:55:45 +0200 last=29/Jul/2026:17:55:40 +0200
|
||||
2a04:c300:400::5d # errors=7 total=13 ratio=0.538 first=23/Jul/2026:15:28:34 +0200 last=23/Jul/2026:15:28:38 +0200
|
||||
2600:3c09::2000:5cff:fe99:c802 # errors=5 total=5 ratio=1.0 first=28/Jul/2026:22:51:11 +0200 last=28/Jul/2026:22:51:14 +0200
|
||||
2600:3c15::2000:53ff:fe31:8c0b # errors=5 total=8 ratio=0.625 first=23/Jul/2026:14:35:18 +0200 last=23/Jul/2026:14:34:55 +0200
|
||||
2602:fa59:10:a3a::1 # errors=5 total=7 ratio=0.714 first=28/Jul/2026:04:10:02 +0200 last=28/Jul/2026:05:36:59 +0200
|
||||
2a01:2a8:a0dd:1::1012 # errors=9517 total=9517 ratio=1.0 first=09/Aug/2026:19:01:21 +0200 last=18/Jul/2026:23:59:49 +0200
|
||||
2a0a:4cc0:2000:8528:c4e8:3ff:febb:3ee9 # errors=150 total=150 ratio=1.0 first=27/Jul/2026:14:49:23 +0200 last=27/Jul/2026:14:49:53 +0200
|
||||
2a00:6340:2008:ec80:be24:11ff:fe3b:4058 # errors=105 total=120 ratio=0.875 first=31/Jul/2026:18:53:29 +0200 last=17/Jul/2026:17:28:19 +0200
|
||||
2a06:98c0:3600::103 # errors=63 total=74 ratio=0.851 first=29/Jul/2026:05:34:01 +0200 last=27/Jul/2026:18:39:05 +0200
|
||||
2600:3000:1305:4212::83 # errors=44 total=78 ratio=0.564 first=10/Aug/2026:04:04:22 +0200 last=02/Aug/2026:08:41:15 +0200
|
||||
2a09:bac5:9443:3af::5e:4d # errors=40 total=40 ratio=1.0 first=25/Jul/2026:05:55:27 +0200 last=25/Jul/2026:05:55:39 +0200
|
||||
2600:3000:2710:200::85 # errors=37 total=68 ratio=0.544 first=10/Aug/2026:17:56:13 +0200 last=29/Jul/2026:02:00:14 +0200
|
||||
2600:3000:2710:200::86 # errors=29 total=49 ratio=0.592 first=10/Aug/2026:17:56:04 +0200 last=17/Jul/2026:17:26:06 +0200
|
||||
2600:3000:1305:4212::85 # errors=28 total=48 ratio=0.583 first=10/Aug/2026:02:00:13 +0200 last=10/Aug/2026:21:57:52 +0200
|
||||
2600:3000:2710:200::82 # errors=28 total=51 ratio=0.549 first=10/Aug/2026:04:01:19 +0200 last=17/Jul/2026:17:14:39 +0200
|
||||
2600:3000:2710:200::83 # errors=28 total=48 ratio=0.583 first=02/Aug/2026:08:43:47 +0200 last=17/Jul/2026:17:27:06 +0200
|
||||
2600:3000:1305:4212::81 # errors=24 total=46 ratio=0.522 first=02/Aug/2026:08:41:14 +0200 last=30/Jul/2026:02:00:11 +0200
|
||||
2600:3000:2710:200::81 # errors=23 total=38 ratio=0.605 first=25/Jul/2026:02:00:09 +0200 last=15/Jul/2026:18:29:14 +0200
|
||||
2600:3000:2710:200::84 # errors=23 total=44 ratio=0.523 first=10/Aug/2026:10:30:53 +0200 last=17/Jul/2026:17:22:50 +0200
|
||||
2600:3000:1305:4212::82 # errors=19 total=31 ratio=0.613 first=10/Aug/2026:10:30:34 +0200 last=02/Aug/2026:08:43:51 +0200
|
||||
2600:3000:1305:4212::84 # errors=19 total=35 ratio=0.543 first=29/Jul/2026:16:26:16 +0200 last=10/Aug/2026:19:53:10 +0200
|
||||
2a04:c300:400::99 # errors=15 total=15 ratio=1.0 first=25/Jul/2026:16:45:35 +0200 last=25/Jul/2026:16:45:40 +0200
|
||||
2a00:6340:2008:ec80:be24:11ff:fe82:2775 # errors=14 total=16 ratio=0.875 first=31/Jul/2026:19:10:46 +0200 last=31/Jul/2026:19:11:42 +0200
|
||||
2400:8901::2000:62ff:fe9a:e1c2 # errors=9 total=9 ratio=1.0 first=18/Jul/2026:21:57:41 +0200 last=18/Jul/2026:21:57:44 +0200
|
||||
2a09:bac5:9443:3af::5e:88 # errors=8 total=8 ratio=1.0 first=16/Jul/2026:10:53:36 +0200 last=16/Jul/2026:10:53:36 +0200
|
||||
2001:4ca0:108:42::24 # errors=7 total=8 ratio=0.875 first=09/Aug/2026:19:50:32 +0200 last=19/Jul/2026:09:41:27 +0200
|
||||
2a04:c300:400::58 # errors=7 total=8 ratio=0.875 first=20/Jul/2026:23:55:45 +0200 last=29/Jul/2026:17:55:40 +0200
|
||||
2a04:c300:400::5d # errors=7 total=13 ratio=0.538 first=23/Jul/2026:15:28:34 +0200 last=23/Jul/2026:15:28:38 +0200
|
||||
2600:3c09::2000:5cff:fe99:c802 # errors=5 total=5 ratio=1.0 first=28/Jul/2026:22:51:11 +0200 last=28/Jul/2026:22:51:14 +0200
|
||||
2600:3c15::2000:53ff:fe31:8c0b # errors=5 total=8 ratio=0.625 first=23/Jul/2026:14:35:18 +0200 last=23/Jul/2026:14:34:55 +0200
|
||||
2602:fa59:10:a3a::1 # errors=5 total=7 ratio=0.714 first=28/Jul/2026:04:10:02 +0200 last=28/Jul/2026:05:36:59 +0200
|
||||
+1522
-1522
File diff suppressed because it is too large.
Load diff
+322
-322
@@ -1,322 +1,322 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Consolidated intrusion detection log scanner.
|
||||
|
||||
Runs both copyparty and Nginx Proxy Manager (NPM) log analyzers,
|
||||
and outputs a single consolidated MikroTik RouterOS blocklist.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import os
|
||||
from dataclasses import dataclass, field
|
||||
|
||||
from ..utils.blocklist_history import (
|
||||
committed_lines,
|
||||
cumulative_blocklist,
|
||||
current_file_lines,
|
||||
write_blocklist_report,
|
||||
)
|
||||
from ..utils.constants import (
|
||||
COPYPARTY_LOG_PATH,
|
||||
COPYPARTY_REPORT_DIR,
|
||||
DEFAULT_ERROR_RATIO,
|
||||
DEFAULT_MIN_DENIED,
|
||||
DEFAULT_MIN_ERRORS,
|
||||
DEFAULT_TOP,
|
||||
NPM_LOG_PATH,
|
||||
NPM_REPORT_DIR,
|
||||
REPORT_DIR,
|
||||
REPORT_RETENTION_DAYS,
|
||||
REPORT_RETENTION_MAX_FILES,
|
||||
SUBNET_THRESHOLD,
|
||||
)
|
||||
from ..firewall import MikrotikFirewall, write_blocklist_files
|
||||
from ..utils.retention import prune_report_dirs
|
||||
from ..copyparty import CopypartyAnalyzer
|
||||
from ..npm import NpmAnalyzer
|
||||
from ..utils.ip_utils import is_whitelisted
|
||||
from ..mikrotik import split_cidr_versions
|
||||
from ..utils.whois import consolidate_by_subnet
|
||||
|
||||
|
||||
@dataclass
|
||||
class ScanParams:
|
||||
"""Configuration for a consolidated scan.
|
||||
|
||||
Shared by the CLI entry point and the web interface so both run the
|
||||
exact same pipeline.
|
||||
"""
|
||||
|
||||
copyparty_log_path: str = COPYPARTY_LOG_PATH
|
||||
copyparty_report_dir: str = COPYPARTY_REPORT_DIR
|
||||
min_denied: int = DEFAULT_MIN_DENIED
|
||||
npm_log_path: str = NPM_LOG_PATH
|
||||
npm_report_dir: str = NPM_REPORT_DIR
|
||||
min_errors: int = DEFAULT_MIN_ERRORS
|
||||
error_ratio: float = DEFAULT_ERROR_RATIO
|
||||
report_dir: str = REPORT_DIR
|
||||
top: int = DEFAULT_TOP
|
||||
quiet: bool = False
|
||||
full: bool = False
|
||||
update_firewall: bool = False
|
||||
dry_run: bool = False
|
||||
|
||||
|
||||
@dataclass
|
||||
class ScanResult:
|
||||
"""Structured outcome of a consolidated scan."""
|
||||
|
||||
ok: bool
|
||||
cp_exists: bool = False
|
||||
npm_exists: bool = False
|
||||
cp_candidates: int = 0
|
||||
npm_candidates: int = 0
|
||||
blocked_ips: int = 0
|
||||
blocked_targets: int = 0
|
||||
blocked_ipv4: list[str] = field(default_factory=list)
|
||||
blocked_ipv6: list[str] = field(default_factory=list)
|
||||
blocklist_v4_path: str | None = None
|
||||
blocklist_v6_path: str | None = None
|
||||
firewall_connected: bool = False
|
||||
firewall_changes: dict | None = None
|
||||
blocklist_report_path: str | None = None
|
||||
errors: list[str] = field(default_factory=list)
|
||||
|
||||
|
||||
def run_scan(params: ScanParams) -> ScanResult:
|
||||
"""Run the full consolidated scan pipeline and return structured results.
|
||||
|
||||
Steps: connect to MikroTik (optional) -> snapshot state -> run copyparty
|
||||
+ NPM analyzers -> consolidate candidates -> write blocklists -> compare
|
||||
and apply firewall changes (optional).
|
||||
"""
|
||||
errors: list[str] = []
|
||||
|
||||
# --- Step 1-3: connect to MikroTik RouterOS and capture current state ---
|
||||
# If the router is unreachable we fall back to scan-only mode: still
|
||||
# generate reports and blocklists, but skip the firewall sync.
|
||||
firewall: MikrotikFirewall | None = None
|
||||
if params.update_firewall:
|
||||
firewall = MikrotikFirewall()
|
||||
try:
|
||||
firewall.connect()
|
||||
# Read current firewall rules + address lists and snapshot them to
|
||||
# reports/mikrotik/data/ and the git-diffable data/mikrotik/.
|
||||
firewall.save_state_report(params.report_dir)
|
||||
except Exception as e:
|
||||
message = f"could not read MikroTik router ({firewall.router_ip}): {e}"
|
||||
errors.append(message)
|
||||
print(f"\nWARNING: {message}")
|
||||
firewall.disconnect()
|
||||
firewall = None
|
||||
|
||||
# --- Step 4: run copyparty + NPM analyzers -> blocklist candidates ------
|
||||
cp_analyzer = CopypartyAnalyzer(
|
||||
log_path=params.copyparty_log_path,
|
||||
report_dir=params.copyparty_report_dir,
|
||||
top=params.top,
|
||||
quiet=params.quiet,
|
||||
full=params.full,
|
||||
min_denied=params.min_denied,
|
||||
)
|
||||
|
||||
npm_analyzer = NpmAnalyzer(
|
||||
log_path=params.npm_log_path,
|
||||
report_dir=params.npm_report_dir,
|
||||
top=params.top,
|
||||
quiet=params.quiet,
|
||||
full=params.full,
|
||||
min_errors=params.min_errors,
|
||||
error_ratio=params.error_ratio,
|
||||
)
|
||||
|
||||
print("=== Running copyparty scan ===")
|
||||
cp_exists = True
|
||||
try:
|
||||
cp_analyzer.run()
|
||||
except Exception as e:
|
||||
errors.append(f"copyparty scan failed: {e}")
|
||||
print(f"Error running copyparty scan: {e}")
|
||||
cp_exists = False
|
||||
|
||||
print("\n=== Running NPM scan ===")
|
||||
npm_exists = True
|
||||
try:
|
||||
npm_analyzer.run()
|
||||
except Exception as e:
|
||||
errors.append(f"NPM scan failed: {e}")
|
||||
print(f"Error running NPM scan: {e}")
|
||||
npm_exists = False
|
||||
|
||||
if not cp_exists and not npm_exists:
|
||||
message = "Both scans failed. Unable to generate consolidated blocklist."
|
||||
errors.append(message)
|
||||
print(f"\n{message}")
|
||||
if firewall is not None:
|
||||
firewall.disconnect()
|
||||
return ScanResult(ok=False, errors=errors)
|
||||
|
||||
# Consolidate block candidates
|
||||
consolidated_candidates: set[str] = set()
|
||||
if cp_exists:
|
||||
consolidated_candidates.update(cp_analyzer.block_candidates())
|
||||
if npm_exists:
|
||||
consolidated_candidates.update(npm_analyzer.block_candidates())
|
||||
|
||||
# Exclude whitelisted IPs
|
||||
final_blocked_ips = {
|
||||
ip for ip in consolidated_candidates if not is_whitelisted(ip)}
|
||||
|
||||
# Group into subnets via WHOIS if multiple malicious IPs in same subnet
|
||||
print("\nGrouping blocked IPs into subnets using WHOIS...")
|
||||
final_blocked_targets = consolidate_by_subnet(
|
||||
final_blocked_ips, threshold=SUBNET_THRESHOLD)
|
||||
blocked_ipv4, blocked_ipv6 = split_cidr_versions(final_blocked_targets)
|
||||
|
||||
cp_candidates = len(cp_analyzer.block_candidates()) if cp_exists else 0
|
||||
npm_candidates = len(npm_analyzer.block_candidates()) if npm_exists else 0
|
||||
|
||||
print("\n=== Consolidated Summary ===")
|
||||
print(f"copyparty block candidates: {cp_candidates}")
|
||||
print(f"NPM block candidates: {npm_candidates}")
|
||||
print(f"Total unified blocked IPs: {len(final_blocked_ips)}")
|
||||
print(f"Total target blocks/subnets: {len(final_blocked_targets)}")
|
||||
|
||||
# --- Step 6: write consolidated blocklists to reports/app/data ----------
|
||||
# Capture the previous blocklist state BEFORE the files are overwritten so
|
||||
# the change report can compute the complete-set delta.
|
||||
app_data_dir = os.path.join(params.report_dir, "app", "data")
|
||||
blocklist_v4_path = os.path.join(app_data_dir, "blocklist_ipv4.txt")
|
||||
blocklist_v6_path = os.path.join(app_data_dir, "blocklist_ipv6.txt")
|
||||
prev_v4 = current_file_lines(blocklist_v4_path)
|
||||
prev_v6 = current_file_lines(blocklist_v6_path)
|
||||
history_v4 = committed_lines(blocklist_v4_path)
|
||||
history_v6 = committed_lines(blocklist_v6_path)
|
||||
|
||||
write_blocklist_files(blocked_ipv4, blocked_ipv6, params.report_dir)
|
||||
print(f"blocklist files:\n {blocklist_v4_path}\n {blocklist_v6_path}")
|
||||
|
||||
# --- Steps 5+7: compare current state with candidates and apply ---------
|
||||
firewall_changes: dict | None = None
|
||||
blocklist_report_path: str | None = None
|
||||
if firewall is not None:
|
||||
try:
|
||||
firewall_changes = firewall.sync_blocklist(
|
||||
blocked_ipv4, blocked_ipv6, dry_run=params.dry_run,
|
||||
report_dir=params.report_dir)
|
||||
finally:
|
||||
firewall.disconnect()
|
||||
action = "Would" if params.dry_run else ""
|
||||
print(f"{action} add {len(firewall_changes['added_ipv4'])} IPv4 and "
|
||||
f"{len(firewall_changes['added_ipv6'])} IPv6 addresses; "
|
||||
f"remove {len(firewall_changes['removed_ipv4'])} IPv4 and "
|
||||
f"{len(firewall_changes['removed_ipv6'])} IPv6 addresses.")
|
||||
|
||||
# Timestamped change report — only when the router was reachable.
|
||||
complete_v4, complete_v6 = cumulative_blocklist(
|
||||
blocklist_v4_path, blocklist_v6_path,
|
||||
blocked_ipv4, blocked_ipv6)
|
||||
blocklist_report_path = write_blocklist_report(
|
||||
params.report_dir,
|
||||
history_v4=history_v4, history_v6=history_v6,
|
||||
prev_v4=prev_v4, prev_v6=prev_v6,
|
||||
complete_v4=complete_v4, complete_v6=complete_v6,
|
||||
firewall_changes=firewall_changes,
|
||||
dry_run=params.dry_run,
|
||||
errors=errors)
|
||||
print(f"blocklist report: {blocklist_report_path}")
|
||||
|
||||
# --- Step 8: prune old reports (retention) ------------------------------
|
||||
# Each report subdirectory keeps at most REPORT_RETENTION_MAX_FILES files,
|
||||
# all newer than REPORT_RETENTION_DAYS days. The blocklist files in
|
||||
# ``app/data`` are always protected. ``--dry-run`` only previews.
|
||||
pruned = prune_report_dirs(
|
||||
params.report_dir, params.copyparty_report_dir, params.npm_report_dir,
|
||||
dry_run=params.dry_run)
|
||||
total_pruned = sum(len(paths) for paths in pruned.values())
|
||||
action = "Would prune" if params.dry_run else "Pruned"
|
||||
print(f"{action} {total_pruned} report file(s) "
|
||||
f"(keep {REPORT_RETENTION_DAYS}d / "
|
||||
f"max {REPORT_RETENTION_MAX_FILES} per dir)")
|
||||
|
||||
return ScanResult(
|
||||
ok=True,
|
||||
cp_exists=cp_exists,
|
||||
npm_exists=npm_exists,
|
||||
cp_candidates=cp_candidates,
|
||||
npm_candidates=npm_candidates,
|
||||
blocked_ips=len(final_blocked_ips),
|
||||
blocked_targets=len(final_blocked_targets),
|
||||
blocked_ipv4=blocked_ipv4,
|
||||
blocked_ipv6=blocked_ipv6,
|
||||
blocklist_v4_path=blocklist_v4_path,
|
||||
blocklist_v6_path=blocklist_v6_path,
|
||||
firewall_connected=firewall is not None,
|
||||
firewall_changes=firewall_changes,
|
||||
blocklist_report_path=blocklist_report_path,
|
||||
errors=errors,
|
||||
)
|
||||
|
||||
|
||||
def _build_parser() -> argparse.ArgumentParser:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Consolidated IDS Scanner: run copyparty + NPM analyzers and generate unified blocklist."
|
||||
)
|
||||
|
||||
# copyparty arguments
|
||||
parser.add_argument("--copyparty-log-path", default=COPYPARTY_LOG_PATH,
|
||||
help=f"copyparty log directory (default: {COPYPARTY_LOG_PATH})")
|
||||
parser.add_argument("--copyparty-report-dir", default=COPYPARTY_REPORT_DIR,
|
||||
help=f"copyparty report directory (default: {COPYPARTY_REPORT_DIR})")
|
||||
parser.add_argument("--min-denied", type=int, default=DEFAULT_MIN_DENIED,
|
||||
help=f"minimum copyparty denied hits before flagging (default: {DEFAULT_MIN_DENIED})")
|
||||
|
||||
# NPM arguments
|
||||
parser.add_argument("--npm-log-path", default=NPM_LOG_PATH,
|
||||
help=f"NPM log directory (default: {NPM_LOG_PATH})")
|
||||
parser.add_argument("--npm-report-dir", default=NPM_REPORT_DIR,
|
||||
help=f"NPM report directory (default: {NPM_REPORT_DIR})")
|
||||
parser.add_argument("--min-errors", type=int, default=DEFAULT_MIN_ERRORS,
|
||||
help=f"minimum NPM error responses to flag (default: {DEFAULT_MIN_ERRORS})")
|
||||
parser.add_argument("--error-ratio", type=float, default=DEFAULT_ERROR_RATIO,
|
||||
help=f"minimum NPM error ratio to flag (default: {DEFAULT_ERROR_RATIO})")
|
||||
|
||||
# Shared arguments
|
||||
parser.add_argument("--report-dir", default=REPORT_DIR,
|
||||
help=f"consolidated reports directory (default: {REPORT_DIR})")
|
||||
parser.add_argument("--top", type=int, default=DEFAULT_TOP,
|
||||
help=f"rows in the top-IP tables (default: {DEFAULT_TOP})")
|
||||
parser.add_argument("--quiet", action="store_true",
|
||||
help="write files, suppress console reports")
|
||||
parser.add_argument("--full", action="store_true",
|
||||
help="rescan all log files from the start (ignore incremental state)")
|
||||
parser.add_argument("--update-firewall", action="store_true",
|
||||
help="synchronize the MikroTik Blocked list after scanning")
|
||||
parser.add_argument("--dry-run", action="store_true",
|
||||
help="preview firewall changes without applying them")
|
||||
return parser
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> None:
|
||||
args = _build_parser().parse_args(argv)
|
||||
params = ScanParams(
|
||||
copyparty_log_path=args.copyparty_log_path,
|
||||
copyparty_report_dir=args.copyparty_report_dir,
|
||||
min_denied=args.min_denied,
|
||||
npm_log_path=args.npm_log_path,
|
||||
npm_report_dir=args.npm_report_dir,
|
||||
min_errors=args.min_errors,
|
||||
error_ratio=args.error_ratio,
|
||||
report_dir=args.report_dir,
|
||||
top=args.top,
|
||||
quiet=args.quiet,
|
||||
full=args.full,
|
||||
update_firewall=args.update_firewall,
|
||||
dry_run=args.dry_run,
|
||||
)
|
||||
run_scan(params)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
#!/usr/bin/env python3
|
||||
"""Consolidated intrusion detection log scanner.
|
||||
|
||||
Runs both copyparty and Nginx Proxy Manager (NPM) log analyzers,
|
||||
and outputs a single consolidated MikroTik RouterOS blocklist.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import os
|
||||
from dataclasses import dataclass, field
|
||||
|
||||
from ..utils.blocklist_history import (
|
||||
committed_lines,
|
||||
cumulative_blocklist,
|
||||
current_file_lines,
|
||||
write_blocklist_report,
|
||||
)
|
||||
from ..utils.constants import (
|
||||
COPYPARTY_LOG_PATH,
|
||||
COPYPARTY_REPORT_DIR,
|
||||
DEFAULT_ERROR_RATIO,
|
||||
DEFAULT_MIN_DENIED,
|
||||
DEFAULT_MIN_ERRORS,
|
||||
DEFAULT_TOP,
|
||||
NPM_LOG_PATH,
|
||||
NPM_REPORT_DIR,
|
||||
REPORT_DIR,
|
||||
REPORT_RETENTION_DAYS,
|
||||
REPORT_RETENTION_MAX_FILES,
|
||||
SUBNET_THRESHOLD,
|
||||
)
|
||||
from ..firewall import MikrotikFirewall, write_blocklist_files
|
||||
from ..utils.retention import prune_report_dirs
|
||||
from ..copyparty import CopypartyAnalyzer
|
||||
from ..npm import NpmAnalyzer
|
||||
from ..utils.ip_utils import is_whitelisted
|
||||
from ..mikrotik import split_cidr_versions
|
||||
from ..utils.whois import consolidate_by_subnet
|
||||
|
||||
|
||||
@dataclass
|
||||
class ScanParams:
|
||||
"""Configuration for a consolidated scan.
|
||||
|
||||
Shared by the CLI entry point and the web interface so both run the
|
||||
exact same pipeline.
|
||||
"""
|
||||
|
||||
copyparty_log_path: str = COPYPARTY_LOG_PATH
|
||||
copyparty_report_dir: str = COPYPARTY_REPORT_DIR
|
||||
min_denied: int = DEFAULT_MIN_DENIED
|
||||
npm_log_path: str = NPM_LOG_PATH
|
||||
npm_report_dir: str = NPM_REPORT_DIR
|
||||
min_errors: int = DEFAULT_MIN_ERRORS
|
||||
error_ratio: float = DEFAULT_ERROR_RATIO
|
||||
report_dir: str = REPORT_DIR
|
||||
top: int = DEFAULT_TOP
|
||||
quiet: bool = False
|
||||
full: bool = False
|
||||
update_firewall: bool = False
|
||||
dry_run: bool = False
|
||||
|
||||
|
||||
@dataclass
|
||||
class ScanResult:
|
||||
"""Structured outcome of a consolidated scan."""
|
||||
|
||||
ok: bool
|
||||
cp_exists: bool = False
|
||||
npm_exists: bool = False
|
||||
cp_candidates: int = 0
|
||||
npm_candidates: int = 0
|
||||
blocked_ips: int = 0
|
||||
blocked_targets: int = 0
|
||||
blocked_ipv4: list[str] = field(default_factory=list)
|
||||
blocked_ipv6: list[str] = field(default_factory=list)
|
||||
blocklist_v4_path: str | None = None
|
||||
blocklist_v6_path: str | None = None
|
||||
firewall_connected: bool = False
|
||||
firewall_changes: dict | None = None
|
||||
blocklist_report_path: str | None = None
|
||||
errors: list[str] = field(default_factory=list)
|
||||
|
||||
|
||||
def run_scan(params: ScanParams) -> ScanResult:
|
||||
"""Run the full consolidated scan pipeline and return structured results.
|
||||
|
||||
Steps: connect to MikroTik (optional) -> snapshot state -> run copyparty
|
||||
+ NPM analyzers -> consolidate candidates -> write blocklists -> compare
|
||||
and apply firewall changes (optional).
|
||||
"""
|
||||
errors: list[str] = []
|
||||
|
||||
# --- Step 1-3: connect to MikroTik RouterOS and capture current state ---
|
||||
# If the router is unreachable we fall back to scan-only mode: still
|
||||
# generate reports and blocklists, but skip the firewall sync.
|
||||
firewall: MikrotikFirewall | None = None
|
||||
if params.update_firewall:
|
||||
firewall = MikrotikFirewall()
|
||||
try:
|
||||
firewall.connect()
|
||||
# Read current firewall rules + address lists and snapshot them to
|
||||
# reports/mikrotik/data/ and the git-diffable data/mikrotik/.
|
||||
firewall.save_state_report(params.report_dir)
|
||||
except Exception as e:
|
||||
message = f"could not read MikroTik router ({firewall.router_ip}): {e}"
|
||||
errors.append(message)
|
||||
print(f"\nWARNING: {message}")
|
||||
firewall.disconnect()
|
||||
firewall = None
|
||||
|
||||
# --- Step 4: run copyparty + NPM analyzers -> blocklist candidates ------
|
||||
cp_analyzer = CopypartyAnalyzer(
|
||||
log_path=params.copyparty_log_path,
|
||||
report_dir=params.copyparty_report_dir,
|
||||
top=params.top,
|
||||
quiet=params.quiet,
|
||||
full=params.full,
|
||||
min_denied=params.min_denied,
|
||||
)
|
||||
|
||||
npm_analyzer = NpmAnalyzer(
|
||||
log_path=params.npm_log_path,
|
||||
report_dir=params.npm_report_dir,
|
||||
top=params.top,
|
||||
quiet=params.quiet,
|
||||
full=params.full,
|
||||
min_errors=params.min_errors,
|
||||
error_ratio=params.error_ratio,
|
||||
)
|
||||
|
||||
print("=== Running copyparty scan ===")
|
||||
cp_exists = True
|
||||
try:
|
||||
cp_analyzer.run()
|
||||
except Exception as e:
|
||||
errors.append(f"copyparty scan failed: {e}")
|
||||
print(f"Error running copyparty scan: {e}")
|
||||
cp_exists = False
|
||||
|
||||
print("\n=== Running NPM scan ===")
|
||||
npm_exists = True
|
||||
try:
|
||||
npm_analyzer.run()
|
||||
except Exception as e:
|
||||
errors.append(f"NPM scan failed: {e}")
|
||||
print(f"Error running NPM scan: {e}")
|
||||
npm_exists = False
|
||||
|
||||
if not cp_exists and not npm_exists:
|
||||
message = "Both scans failed. Unable to generate consolidated blocklist."
|
||||
errors.append(message)
|
||||
print(f"\n{message}")
|
||||
if firewall is not None:
|
||||
firewall.disconnect()
|
||||
return ScanResult(ok=False, errors=errors)
|
||||
|
||||
# Consolidate block candidates
|
||||
consolidated_candidates: set[str] = set()
|
||||
if cp_exists:
|
||||
consolidated_candidates.update(cp_analyzer.block_candidates())
|
||||
if npm_exists:
|
||||
consolidated_candidates.update(npm_analyzer.block_candidates())
|
||||
|
||||
# Exclude whitelisted IPs
|
||||
final_blocked_ips = {
|
||||
ip for ip in consolidated_candidates if not is_whitelisted(ip)}
|
||||
|
||||
# Group into subnets via WHOIS if multiple malicious IPs in same subnet
|
||||
print("\nGrouping blocked IPs into subnets using WHOIS...")
|
||||
final_blocked_targets = consolidate_by_subnet(
|
||||
final_blocked_ips, threshold=SUBNET_THRESHOLD)
|
||||
blocked_ipv4, blocked_ipv6 = split_cidr_versions(final_blocked_targets)
|
||||
|
||||
cp_candidates = len(cp_analyzer.block_candidates()) if cp_exists else 0
|
||||
npm_candidates = len(npm_analyzer.block_candidates()) if npm_exists else 0
|
||||
|
||||
print("\n=== Consolidated Summary ===")
|
||||
print(f"copyparty block candidates: {cp_candidates}")
|
||||
print(f"NPM block candidates: {npm_candidates}")
|
||||
print(f"Total unified blocked IPs: {len(final_blocked_ips)}")
|
||||
print(f"Total target blocks/subnets: {len(final_blocked_targets)}")
|
||||
|
||||
# --- Step 6: write consolidated blocklists to reports/app/data ----------
|
||||
# Capture the previous blocklist state BEFORE the files are overwritten so
|
||||
# the change report can compute the complete-set delta.
|
||||
app_data_dir = os.path.join(params.report_dir, "app", "data")
|
||||
blocklist_v4_path = os.path.join(app_data_dir, "blocklist_ipv4.txt")
|
||||
blocklist_v6_path = os.path.join(app_data_dir, "blocklist_ipv6.txt")
|
||||
prev_v4 = current_file_lines(blocklist_v4_path)
|
||||
prev_v6 = current_file_lines(blocklist_v6_path)
|
||||
history_v4 = committed_lines(blocklist_v4_path)
|
||||
history_v6 = committed_lines(blocklist_v6_path)
|
||||
|
||||
write_blocklist_files(blocked_ipv4, blocked_ipv6, params.report_dir)
|
||||
print(f"blocklist files:\n {blocklist_v4_path}\n {blocklist_v6_path}")
|
||||
|
||||
# --- Steps 5+7: compare current state with candidates and apply ---------
|
||||
firewall_changes: dict | None = None
|
||||
blocklist_report_path: str | None = None
|
||||
if firewall is not None:
|
||||
try:
|
||||
firewall_changes = firewall.sync_blocklist(
|
||||
blocked_ipv4, blocked_ipv6, dry_run=params.dry_run,
|
||||
report_dir=params.report_dir)
|
||||
finally:
|
||||
firewall.disconnect()
|
||||
action = "Would" if params.dry_run else ""
|
||||
print(f"{action} add {len(firewall_changes['added_ipv4'])} IPv4 and "
|
||||
f"{len(firewall_changes['added_ipv6'])} IPv6 addresses; "
|
||||
f"remove {len(firewall_changes['removed_ipv4'])} IPv4 and "
|
||||
f"{len(firewall_changes['removed_ipv6'])} IPv6 addresses.")
|
||||
|
||||
# Timestamped change report — only when the router was reachable.
|
||||
complete_v4, complete_v6 = cumulative_blocklist(
|
||||
blocklist_v4_path, blocklist_v6_path,
|
||||
blocked_ipv4, blocked_ipv6)
|
||||
blocklist_report_path = write_blocklist_report(
|
||||
params.report_dir,
|
||||
history_v4=history_v4, history_v6=history_v6,
|
||||
prev_v4=prev_v4, prev_v6=prev_v6,
|
||||
complete_v4=complete_v4, complete_v6=complete_v6,
|
||||
firewall_changes=firewall_changes,
|
||||
dry_run=params.dry_run,
|
||||
errors=errors)
|
||||
print(f"blocklist report: {blocklist_report_path}")
|
||||
|
||||
# --- Step 8: prune old reports (retention) ------------------------------
|
||||
# Each report subdirectory keeps at most REPORT_RETENTION_MAX_FILES files,
|
||||
# all newer than REPORT_RETENTION_DAYS days. The blocklist files in
|
||||
# ``app/data`` are always protected. ``--dry-run`` only previews.
|
||||
pruned = prune_report_dirs(
|
||||
params.report_dir, params.copyparty_report_dir, params.npm_report_dir,
|
||||
dry_run=params.dry_run)
|
||||
total_pruned = sum(len(paths) for paths in pruned.values())
|
||||
action = "Would prune" if params.dry_run else "Pruned"
|
||||
print(f"{action} {total_pruned} report file(s) "
|
||||
f"(keep {REPORT_RETENTION_DAYS}d / "
|
||||
f"max {REPORT_RETENTION_MAX_FILES} per dir)")
|
||||
|
||||
return ScanResult(
|
||||
ok=True,
|
||||
cp_exists=cp_exists,
|
||||
npm_exists=npm_exists,
|
||||
cp_candidates=cp_candidates,
|
||||
npm_candidates=npm_candidates,
|
||||
blocked_ips=len(final_blocked_ips),
|
||||
blocked_targets=len(final_blocked_targets),
|
||||
blocked_ipv4=blocked_ipv4,
|
||||
blocked_ipv6=blocked_ipv6,
|
||||
blocklist_v4_path=blocklist_v4_path,
|
||||
blocklist_v6_path=blocklist_v6_path,
|
||||
firewall_connected=firewall is not None,
|
||||
firewall_changes=firewall_changes,
|
||||
blocklist_report_path=blocklist_report_path,
|
||||
errors=errors,
|
||||
)
|
||||
|
||||
|
||||
def _build_parser() -> argparse.ArgumentParser:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Consolidated IDS Scanner: run copyparty + NPM analyzers and generate unified blocklist."
|
||||
)
|
||||
|
||||
# copyparty arguments
|
||||
parser.add_argument("--copyparty-log-path", default=COPYPARTY_LOG_PATH,
|
||||
help=f"copyparty log directory (default: {COPYPARTY_LOG_PATH})")
|
||||
parser.add_argument("--copyparty-report-dir", default=COPYPARTY_REPORT_DIR,
|
||||
help=f"copyparty report directory (default: {COPYPARTY_REPORT_DIR})")
|
||||
parser.add_argument("--min-denied", type=int, default=DEFAULT_MIN_DENIED,
|
||||
help=f"minimum copyparty denied hits before flagging (default: {DEFAULT_MIN_DENIED})")
|
||||
|
||||
# NPM arguments
|
||||
parser.add_argument("--npm-log-path", default=NPM_LOG_PATH,
|
||||
help=f"NPM log directory (default: {NPM_LOG_PATH})")
|
||||
parser.add_argument("--npm-report-dir", default=NPM_REPORT_DIR,
|
||||
help=f"NPM report directory (default: {NPM_REPORT_DIR})")
|
||||
parser.add_argument("--min-errors", type=int, default=DEFAULT_MIN_ERRORS,
|
||||
help=f"minimum NPM error responses to flag (default: {DEFAULT_MIN_ERRORS})")
|
||||
parser.add_argument("--error-ratio", type=float, default=DEFAULT_ERROR_RATIO,
|
||||
help=f"minimum NPM error ratio to flag (default: {DEFAULT_ERROR_RATIO})")
|
||||
|
||||
# Shared arguments
|
||||
parser.add_argument("--report-dir", default=REPORT_DIR,
|
||||
help=f"consolidated reports directory (default: {REPORT_DIR})")
|
||||
parser.add_argument("--top", type=int, default=DEFAULT_TOP,
|
||||
help=f"rows in the top-IP tables (default: {DEFAULT_TOP})")
|
||||
parser.add_argument("--quiet", action="store_true",
|
||||
help="write files, suppress console reports")
|
||||
parser.add_argument("--full", action="store_true",
|
||||
help="rescan all log files from the start (ignore incremental state)")
|
||||
parser.add_argument("--update-firewall", action="store_true",
|
||||
help="synchronize the MikroTik Blocked list after scanning")
|
||||
parser.add_argument("--dry-run", action="store_true",
|
||||
help="preview firewall changes without applying them")
|
||||
return parser
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> None:
|
||||
args = _build_parser().parse_args(argv)
|
||||
params = ScanParams(
|
||||
copyparty_log_path=args.copyparty_log_path,
|
||||
copyparty_report_dir=args.copyparty_report_dir,
|
||||
min_denied=args.min_denied,
|
||||
npm_log_path=args.npm_log_path,
|
||||
npm_report_dir=args.npm_report_dir,
|
||||
min_errors=args.min_errors,
|
||||
error_ratio=args.error_ratio,
|
||||
report_dir=args.report_dir,
|
||||
top=args.top,
|
||||
quiet=args.quiet,
|
||||
full=args.full,
|
||||
update_firewall=args.update_firewall,
|
||||
dry_run=args.dry_run,
|
||||
)
|
||||
run_scan(params)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
+33
-33
@@ -1,33 +1,33 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Persistent state for incremental log scanning.
|
||||
|
||||
Tracks the last processed byte offset per absolute log file path so a scan
|
||||
only reads new entries instead of re-reading the whole file. The state file
|
||||
is written atomically (temp file + rename) to avoid corruption.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
|
||||
from ..utils.constants import SCAN_STATE_PATH
|
||||
|
||||
|
||||
def load_state() -> dict[str, int]:
|
||||
"""Return ``{absolute log path: byte offset}`` from the scan-state file."""
|
||||
try:
|
||||
with open(SCAN_STATE_PATH, "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
return {k: int(v) for k, v in data.items()}
|
||||
except (OSError, ValueError, TypeError):
|
||||
return {}
|
||||
|
||||
|
||||
def save_state(state: dict[str, int]) -> None:
|
||||
"""Write the scan-state file atomically (temp file + rename)."""
|
||||
os.makedirs(os.path.dirname(SCAN_STATE_PATH), exist_ok=True)
|
||||
tmp = SCAN_STATE_PATH + ".tmp"
|
||||
with open(tmp, "w", encoding="utf-8") as f:
|
||||
json.dump(state, f, indent=2, sort_keys=True)
|
||||
os.replace(tmp, SCAN_STATE_PATH)
|
||||
#!/usr/bin/env python3
|
||||
"""Persistent state for incremental log scanning.
|
||||
|
||||
Tracks the last processed byte offset per absolute log file path so a scan
|
||||
only reads new entries instead of re-reading the whole file. The state file
|
||||
is written atomically (temp file + rename) to avoid corruption.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
|
||||
from ..utils.constants import SCAN_STATE_PATH
|
||||
|
||||
|
||||
def load_state() -> dict[str, int]:
|
||||
"""Return ``{absolute log path: byte offset}`` from the scan-state file."""
|
||||
try:
|
||||
with open(SCAN_STATE_PATH, "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
return {k: int(v) for k, v in data.items()}
|
||||
except (OSError, ValueError, TypeError):
|
||||
return {}
|
||||
|
||||
|
||||
def save_state(state: dict[str, int]) -> None:
|
||||
"""Write the scan-state file atomically (temp file + rename)."""
|
||||
os.makedirs(os.path.dirname(SCAN_STATE_PATH), exist_ok=True)
|
||||
tmp = SCAN_STATE_PATH + ".tmp"
|
||||
with open(tmp, "w", encoding="utf-8") as f:
|
||||
json.dump(state, f, indent=2, sort_keys=True)
|
||||
os.replace(tmp, SCAN_STATE_PATH)
|
||||
+83
-83
@@ -1,83 +1,83 @@
|
||||
// Shared helpers for the Intrusion Detection web UI.
|
||||
|
||||
async function api(path, options = {}) {
|
||||
const opts = { headers: {}, ...options };
|
||||
if (opts.body && typeof opts.body !== "string") {
|
||||
opts.headers["Content-Type"] = "application/json";
|
||||
opts.body = JSON.stringify(opts.body);
|
||||
}
|
||||
const res = await fetch(path, opts);
|
||||
let data = null;
|
||||
try {
|
||||
data = await res.json();
|
||||
} catch (e) {
|
||||
/* non-JSON */
|
||||
}
|
||||
if (!res.ok) {
|
||||
const msg = (data && (data.error || data.message)) || `HTTP ${res.status}`;
|
||||
throw new Error(msg);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
function escapeHtml(s) {
|
||||
return String(s ?? "").replace(
|
||||
/[&<>"']/g,
|
||||
(c) =>
|
||||
({
|
||||
"&": "&",
|
||||
"<": "<",
|
||||
">": ">",
|
||||
'"': """,
|
||||
"'": "'",
|
||||
})[c],
|
||||
);
|
||||
}
|
||||
|
||||
function toast(message, type = "info") {
|
||||
const box = document.getElementById("toasts");
|
||||
if (!box) return;
|
||||
const node = document.createElement("div");
|
||||
node.className = `toast toast-${type}`;
|
||||
node.textContent = message;
|
||||
box.appendChild(node);
|
||||
setTimeout(() => node.remove(), 4000);
|
||||
}
|
||||
|
||||
function fmtTime(s) {
|
||||
if (!s) return "—";
|
||||
const d = new Date(s);
|
||||
return isNaN(d) ? s : d.toLocaleString();
|
||||
}
|
||||
|
||||
function badge(state) {
|
||||
const node = document.createElement("span");
|
||||
node.className = `badge ${state}`;
|
||||
node.textContent = state;
|
||||
return node;
|
||||
}
|
||||
|
||||
function el(tag, attrs = {}, ...children) {
|
||||
const node = document.createElement(tag);
|
||||
// Allow el("tr", child1, child2, ...): if the 2nd argument is a node or an
|
||||
// array, treat it as the first child instead of an attributes object.
|
||||
if (attrs && (attrs.nodeType === 1 || Array.isArray(attrs))) {
|
||||
children.unshift(attrs);
|
||||
attrs = {};
|
||||
}
|
||||
for (const [k, v] of Object.entries(attrs || {})) {
|
||||
if (k === "class") node.className = v;
|
||||
else if (k === "text") node.textContent = v;
|
||||
else if (k === "html") node.innerHTML = v;
|
||||
else if (k.startsWith("on")) node.addEventListener(k.slice(2), v);
|
||||
else node.setAttribute(k, v);
|
||||
}
|
||||
for (const c of children) {
|
||||
node.append(c == null ? "" : c);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
async function startScan(kind, params) {
|
||||
return api(`/api/scan/${kind}`, { method: "POST", body: params });
|
||||
}
|
||||
// Shared helpers for the Intrusion Detection web UI.
|
||||
|
||||
async function api(path, options = {}) {
|
||||
const opts = { headers: {}, ...options };
|
||||
if (opts.body && typeof opts.body !== "string") {
|
||||
opts.headers["Content-Type"] = "application/json";
|
||||
opts.body = JSON.stringify(opts.body);
|
||||
}
|
||||
const res = await fetch(path, opts);
|
||||
let data = null;
|
||||
try {
|
||||
data = await res.json();
|
||||
} catch (e) {
|
||||
/* non-JSON */
|
||||
}
|
||||
if (!res.ok) {
|
||||
const msg = (data && (data.error || data.message)) || `HTTP ${res.status}`;
|
||||
throw new Error(msg);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
function escapeHtml(s) {
|
||||
return String(s ?? "").replace(
|
||||
/[&<>"']/g,
|
||||
(c) =>
|
||||
({
|
||||
"&": "&",
|
||||
"<": "<",
|
||||
">": ">",
|
||||
'"': """,
|
||||
"'": "'",
|
||||
})[c],
|
||||
);
|
||||
}
|
||||
|
||||
function toast(message, type = "info") {
|
||||
const box = document.getElementById("toasts");
|
||||
if (!box) return;
|
||||
const node = document.createElement("div");
|
||||
node.className = `toast toast-${type}`;
|
||||
node.textContent = message;
|
||||
box.appendChild(node);
|
||||
setTimeout(() => node.remove(), 4000);
|
||||
}
|
||||
|
||||
function fmtTime(s) {
|
||||
if (!s) return "—";
|
||||
const d = new Date(s);
|
||||
return isNaN(d) ? s : d.toLocaleString();
|
||||
}
|
||||
|
||||
function badge(state) {
|
||||
const node = document.createElement("span");
|
||||
node.className = `badge ${state}`;
|
||||
node.textContent = state;
|
||||
return node;
|
||||
}
|
||||
|
||||
function el(tag, attrs = {}, ...children) {
|
||||
const node = document.createElement(tag);
|
||||
// Allow el("tr", child1, child2, ...): if the 2nd argument is a node or an
|
||||
// array, treat it as the first child instead of an attributes object.
|
||||
if (attrs && (attrs.nodeType === 1 || Array.isArray(attrs))) {
|
||||
children.unshift(attrs);
|
||||
attrs = {};
|
||||
}
|
||||
for (const [k, v] of Object.entries(attrs || {})) {
|
||||
if (k === "class") node.className = v;
|
||||
else if (k === "text") node.textContent = v;
|
||||
else if (k === "html") node.innerHTML = v;
|
||||
else if (k.startsWith("on")) node.addEventListener(k.slice(2), v);
|
||||
else node.setAttribute(k, v);
|
||||
}
|
||||
for (const c of children) {
|
||||
node.append(c == null ? "" : c);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
async function startScan(kind, params) {
|
||||
return api(`/api/scan/${kind}`, { method: "POST", body: params });
|
||||
}
|
||||
+499
-499
@@ -1,499 +1,499 @@
|
||||
:root {
|
||||
--bg: #0f172a;
|
||||
--surface: #1e293b;
|
||||
--surface-2: #263449;
|
||||
--border: #334155;
|
||||
--text: #e2e8f0;
|
||||
--muted: #94a3b8;
|
||||
--accent: #22d3ee;
|
||||
--ok: #34d399;
|
||||
--warn: #fbbf24;
|
||||
--danger: #f87171;
|
||||
--mono: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family:
|
||||
system-ui,
|
||||
-apple-system,
|
||||
"Segoe UI",
|
||||
Roboto,
|
||||
sans-serif;
|
||||
background: var(--bg);
|
||||
color: var(--text);
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.topbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1.5rem;
|
||||
padding: 0.75rem 1.5rem;
|
||||
background: var(--surface);
|
||||
border-bottom: 1px solid var(--border);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.brand {
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.02em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.topbar nav {
|
||||
display: flex;
|
||||
gap: 0.25rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.topbar nav a {
|
||||
color: var(--muted);
|
||||
text-decoration: none;
|
||||
padding: 0.4rem 0.75rem;
|
||||
border-radius: 8px;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.topbar nav a:hover {
|
||||
color: var(--text);
|
||||
background: var(--surface-2);
|
||||
}
|
||||
.topbar nav a.active {
|
||||
color: var(--accent);
|
||||
background: var(--surface-2);
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1100px;
|
||||
margin: 0 auto;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.4rem;
|
||||
margin: 0 0 0.25rem;
|
||||
}
|
||||
h2 {
|
||||
font-size: 1.05rem;
|
||||
margin: 0;
|
||||
}
|
||||
.muted {
|
||||
color: var(--muted);
|
||||
}
|
||||
.mono {
|
||||
font-family: var(--mono);
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.panel {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 12px;
|
||||
padding: 1rem 1.25rem;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
.panel-head {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.cards {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||||
gap: 1rem;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 12px;
|
||||
padding: 1rem 1.25rem;
|
||||
}
|
||||
|
||||
.card-label {
|
||||
font-size: 0.78rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
color: var(--muted);
|
||||
}
|
||||
.card-value {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 700;
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
.card-value.ok {
|
||||
color: var(--ok);
|
||||
}
|
||||
.card-value.warn {
|
||||
color: var(--warn);
|
||||
}
|
||||
.card-value.danger {
|
||||
color: var(--danger);
|
||||
}
|
||||
.card-value.muted {
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 0.88rem;
|
||||
}
|
||||
|
||||
.table th {
|
||||
text-align: left;
|
||||
color: var(--muted);
|
||||
font-weight: 600;
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding: 0.5rem 0.6rem;
|
||||
font-size: 0.78rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
|
||||
.table td {
|
||||
padding: 0.5rem 0.6rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.table tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
.table .num {
|
||||
text-align: right;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.badge {
|
||||
display: inline-block;
|
||||
padding: 0.1rem 0.5rem;
|
||||
border-radius: 999px;
|
||||
font-size: 0.72rem;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.03em;
|
||||
background: var(--surface-2);
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.badge.ok,
|
||||
.badge.done {
|
||||
background: rgba(52, 211, 153, 0.15);
|
||||
color: var(--ok);
|
||||
}
|
||||
.badge.warn,
|
||||
.badge.running,
|
||||
.badge.queued {
|
||||
background: rgba(251, 191, 36, 0.15);
|
||||
color: var(--warn);
|
||||
}
|
||||
.badge.danger,
|
||||
.badge.error {
|
||||
background: rgba(248, 113, 113, 0.15);
|
||||
color: var(--danger);
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.4rem;
|
||||
border: 1px solid var(--border);
|
||||
background: var(--surface-2);
|
||||
color: var(--text);
|
||||
padding: 0.45rem 0.9rem;
|
||||
border-radius: 8px;
|
||||
font-size: 0.88rem;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
border-color: var(--accent);
|
||||
}
|
||||
.btn.primary {
|
||||
background: var(--accent);
|
||||
border-color: var(--accent);
|
||||
color: #062a35;
|
||||
font-weight: 600;
|
||||
}
|
||||
.btn.primary:hover {
|
||||
filter: brightness(1.08);
|
||||
}
|
||||
.btn.danger {
|
||||
border-color: rgba(248, 113, 113, 0.5);
|
||||
color: var(--danger);
|
||||
}
|
||||
.btn.danger:hover {
|
||||
background: rgba(248, 113, 113, 0.12);
|
||||
}
|
||||
.btn.ghost {
|
||||
background: transparent;
|
||||
}
|
||||
.btn:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.panel-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
margin-top: 1rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.form-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
label {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.3rem;
|
||||
font-size: 0.82rem;
|
||||
color: var(--muted);
|
||||
}
|
||||
label.check {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
font-size: 0.88rem;
|
||||
color: var(--text);
|
||||
margin-top: 1.4rem;
|
||||
}
|
||||
|
||||
input,
|
||||
select {
|
||||
background: var(--bg);
|
||||
border: 1px solid var(--border);
|
||||
color: var(--text);
|
||||
border-radius: 8px;
|
||||
padding: 0.45rem 0.6rem;
|
||||
font-size: 0.88rem;
|
||||
}
|
||||
|
||||
input:focus,
|
||||
select:focus {
|
||||
outline: none;
|
||||
border-color: var(--accent);
|
||||
}
|
||||
|
||||
.job-status {
|
||||
margin-top: 1rem;
|
||||
font-family: var(--mono);
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
#toasts {
|
||||
position: fixed;
|
||||
bottom: 1rem;
|
||||
right: 1rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.toast {
|
||||
padding: 0.6rem 1rem;
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--border);
|
||||
background: var(--surface);
|
||||
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4);
|
||||
font-size: 0.88rem;
|
||||
max-width: 360px;
|
||||
}
|
||||
|
||||
.toast-error {
|
||||
border-color: var(--danger);
|
||||
color: var(--danger);
|
||||
}
|
||||
.toast-ok {
|
||||
border-color: var(--ok);
|
||||
color: var(--ok);
|
||||
}
|
||||
.toast-warn {
|
||||
border-color: var(--warn);
|
||||
color: var(--warn);
|
||||
}
|
||||
|
||||
pre.content {
|
||||
background: var(--bg);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
padding: 1rem;
|
||||
overflow: auto;
|
||||
max-height: 480px;
|
||||
font-family: var(--mono);
|
||||
font-size: 0.8rem;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.25rem;
|
||||
max-height: 300px;
|
||||
overflow: auto;
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.list a {
|
||||
color: var(--accent);
|
||||
text-decoration: none;
|
||||
font-family: var(--mono);
|
||||
font-size: 0.85rem;
|
||||
padding: 0.2rem 0.4rem;
|
||||
border-radius: 6px;
|
||||
}
|
||||
.list a:hover {
|
||||
background: var(--surface-2);
|
||||
}
|
||||
|
||||
/* Blocklist display */
|
||||
|
||||
.table tbody[id="v4"] td {
|
||||
padding: 0;
|
||||
}
|
||||
.table tbody[id="v4"] td .btn {
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
|
||||
/* IPv4 graph page */
|
||||
|
||||
.graph-controls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1.25rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.legend {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
font-size: 0.82rem;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.sw {
|
||||
display: inline-block;
|
||||
width: 0.8rem;
|
||||
height: 0.8rem;
|
||||
border-radius: 3px;
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
.sw.red {
|
||||
background: #e53935;
|
||||
}
|
||||
.sw.green {
|
||||
background: #43a047;
|
||||
}
|
||||
.sw.plain {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.graph-wrap {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
max-width: 920px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
#graph-canvas {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
aspect-ratio: 1 / 1;
|
||||
background: #fff;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
image-rendering: pixelated;
|
||||
cursor: crosshair;
|
||||
}
|
||||
|
||||
.graph-overlay {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.g-line {
|
||||
position: absolute;
|
||||
background: rgba(148, 163, 184, 0.55);
|
||||
}
|
||||
.g-v {
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 1px;
|
||||
}
|
||||
.g-h {
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
.g-label {
|
||||
position: absolute;
|
||||
transform: translate(6px, 4px);
|
||||
font-size: 0.55rem;
|
||||
line-height: 1;
|
||||
color: #475569;
|
||||
white-space: nowrap;
|
||||
user-select: none;
|
||||
text-shadow: 0 0 2px #fff, 0 0 2px #fff;
|
||||
}
|
||||
|
||||
.graph-tooltip {
|
||||
position: absolute;
|
||||
z-index: 5;
|
||||
background: var(--surface-2);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
padding: 0.5rem 0.65rem;
|
||||
pointer-events: none;
|
||||
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.45);
|
||||
max-width: 260px;
|
||||
}
|
||||
.graph-tooltip.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tt-head {
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.2rem;
|
||||
}
|
||||
.tt-status {
|
||||
font-size: 0.75rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.04em;
|
||||
font-weight: 600;
|
||||
}
|
||||
.tt-status.blocked {
|
||||
color: #e53935;
|
||||
}
|
||||
.tt-status.whitelisted {
|
||||
color: #43a047;
|
||||
}
|
||||
.tt-status.unlisted {
|
||||
color: var(--muted);
|
||||
}
|
||||
.tt-list {
|
||||
margin-top: 0.35rem;
|
||||
font-size: 0.72rem;
|
||||
white-space: pre-line;
|
||||
color: var(--text);
|
||||
}
|
||||
:root {
|
||||
--bg: #0f172a;
|
||||
--surface: #1e293b;
|
||||
--surface-2: #263449;
|
||||
--border: #334155;
|
||||
--text: #e2e8f0;
|
||||
--muted: #94a3b8;
|
||||
--accent: #22d3ee;
|
||||
--ok: #34d399;
|
||||
--warn: #fbbf24;
|
||||
--danger: #f87171;
|
||||
--mono: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family:
|
||||
system-ui,
|
||||
-apple-system,
|
||||
"Segoe UI",
|
||||
Roboto,
|
||||
sans-serif;
|
||||
background: var(--bg);
|
||||
color: var(--text);
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.topbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1.5rem;
|
||||
padding: 0.75rem 1.5rem;
|
||||
background: var(--surface);
|
||||
border-bottom: 1px solid var(--border);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.brand {
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.02em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.topbar nav {
|
||||
display: flex;
|
||||
gap: 0.25rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.topbar nav a {
|
||||
color: var(--muted);
|
||||
text-decoration: none;
|
||||
padding: 0.4rem 0.75rem;
|
||||
border-radius: 8px;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.topbar nav a:hover {
|
||||
color: var(--text);
|
||||
background: var(--surface-2);
|
||||
}
|
||||
.topbar nav a.active {
|
||||
color: var(--accent);
|
||||
background: var(--surface-2);
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1100px;
|
||||
margin: 0 auto;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.4rem;
|
||||
margin: 0 0 0.25rem;
|
||||
}
|
||||
h2 {
|
||||
font-size: 1.05rem;
|
||||
margin: 0;
|
||||
}
|
||||
.muted {
|
||||
color: var(--muted);
|
||||
}
|
||||
.mono {
|
||||
font-family: var(--mono);
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.panel {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 12px;
|
||||
padding: 1rem 1.25rem;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
.panel-head {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.cards {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||||
gap: 1rem;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 12px;
|
||||
padding: 1rem 1.25rem;
|
||||
}
|
||||
|
||||
.card-label {
|
||||
font-size: 0.78rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
color: var(--muted);
|
||||
}
|
||||
.card-value {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 700;
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
.card-value.ok {
|
||||
color: var(--ok);
|
||||
}
|
||||
.card-value.warn {
|
||||
color: var(--warn);
|
||||
}
|
||||
.card-value.danger {
|
||||
color: var(--danger);
|
||||
}
|
||||
.card-value.muted {
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 0.88rem;
|
||||
}
|
||||
|
||||
.table th {
|
||||
text-align: left;
|
||||
color: var(--muted);
|
||||
font-weight: 600;
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding: 0.5rem 0.6rem;
|
||||
font-size: 0.78rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
|
||||
.table td {
|
||||
padding: 0.5rem 0.6rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.table tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
.table .num {
|
||||
text-align: right;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.badge {
|
||||
display: inline-block;
|
||||
padding: 0.1rem 0.5rem;
|
||||
border-radius: 999px;
|
||||
font-size: 0.72rem;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.03em;
|
||||
background: var(--surface-2);
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.badge.ok,
|
||||
.badge.done {
|
||||
background: rgba(52, 211, 153, 0.15);
|
||||
color: var(--ok);
|
||||
}
|
||||
.badge.warn,
|
||||
.badge.running,
|
||||
.badge.queued {
|
||||
background: rgba(251, 191, 36, 0.15);
|
||||
color: var(--warn);
|
||||
}
|
||||
.badge.danger,
|
||||
.badge.error {
|
||||
background: rgba(248, 113, 113, 0.15);
|
||||
color: var(--danger);
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.4rem;
|
||||
border: 1px solid var(--border);
|
||||
background: var(--surface-2);
|
||||
color: var(--text);
|
||||
padding: 0.45rem 0.9rem;
|
||||
border-radius: 8px;
|
||||
font-size: 0.88rem;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
border-color: var(--accent);
|
||||
}
|
||||
.btn.primary {
|
||||
background: var(--accent);
|
||||
border-color: var(--accent);
|
||||
color: #062a35;
|
||||
font-weight: 600;
|
||||
}
|
||||
.btn.primary:hover {
|
||||
filter: brightness(1.08);
|
||||
}
|
||||
.btn.danger {
|
||||
border-color: rgba(248, 113, 113, 0.5);
|
||||
color: var(--danger);
|
||||
}
|
||||
.btn.danger:hover {
|
||||
background: rgba(248, 113, 113, 0.12);
|
||||
}
|
||||
.btn.ghost {
|
||||
background: transparent;
|
||||
}
|
||||
.btn:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.panel-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
margin-top: 1rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.form-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
label {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.3rem;
|
||||
font-size: 0.82rem;
|
||||
color: var(--muted);
|
||||
}
|
||||
label.check {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
font-size: 0.88rem;
|
||||
color: var(--text);
|
||||
margin-top: 1.4rem;
|
||||
}
|
||||
|
||||
input,
|
||||
select {
|
||||
background: var(--bg);
|
||||
border: 1px solid var(--border);
|
||||
color: var(--text);
|
||||
border-radius: 8px;
|
||||
padding: 0.45rem 0.6rem;
|
||||
font-size: 0.88rem;
|
||||
}
|
||||
|
||||
input:focus,
|
||||
select:focus {
|
||||
outline: none;
|
||||
border-color: var(--accent);
|
||||
}
|
||||
|
||||
.job-status {
|
||||
margin-top: 1rem;
|
||||
font-family: var(--mono);
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
#toasts {
|
||||
position: fixed;
|
||||
bottom: 1rem;
|
||||
right: 1rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.toast {
|
||||
padding: 0.6rem 1rem;
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--border);
|
||||
background: var(--surface);
|
||||
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4);
|
||||
font-size: 0.88rem;
|
||||
max-width: 360px;
|
||||
}
|
||||
|
||||
.toast-error {
|
||||
border-color: var(--danger);
|
||||
color: var(--danger);
|
||||
}
|
||||
.toast-ok {
|
||||
border-color: var(--ok);
|
||||
color: var(--ok);
|
||||
}
|
||||
.toast-warn {
|
||||
border-color: var(--warn);
|
||||
color: var(--warn);
|
||||
}
|
||||
|
||||
pre.content {
|
||||
background: var(--bg);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
padding: 1rem;
|
||||
overflow: auto;
|
||||
max-height: 480px;
|
||||
font-family: var(--mono);
|
||||
font-size: 0.8rem;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.25rem;
|
||||
max-height: 300px;
|
||||
overflow: auto;
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.list a {
|
||||
color: var(--accent);
|
||||
text-decoration: none;
|
||||
font-family: var(--mono);
|
||||
font-size: 0.85rem;
|
||||
padding: 0.2rem 0.4rem;
|
||||
border-radius: 6px;
|
||||
}
|
||||
.list a:hover {
|
||||
background: var(--surface-2);
|
||||
}
|
||||
|
||||
/* Blocklist display */
|
||||
|
||||
.table tbody[id="v4"] td {
|
||||
padding: 0;
|
||||
}
|
||||
.table tbody[id="v4"] td .btn {
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
|
||||
/* IPv4 graph page */
|
||||
|
||||
.graph-controls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1.25rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.legend {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
font-size: 0.82rem;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.sw {
|
||||
display: inline-block;
|
||||
width: 0.8rem;
|
||||
height: 0.8rem;
|
||||
border-radius: 3px;
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
.sw.red {
|
||||
background: #e53935;
|
||||
}
|
||||
.sw.green {
|
||||
background: #43a047;
|
||||
}
|
||||
.sw.plain {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.graph-wrap {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
max-width: 920px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
#graph-canvas {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
aspect-ratio: 1 / 1;
|
||||
background: #fff;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
image-rendering: pixelated;
|
||||
cursor: crosshair;
|
||||
}
|
||||
|
||||
.graph-overlay {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.g-line {
|
||||
position: absolute;
|
||||
background: rgba(148, 163, 184, 0.55);
|
||||
}
|
||||
.g-v {
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 1px;
|
||||
}
|
||||
.g-h {
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
.g-label {
|
||||
position: absolute;
|
||||
transform: translate(6px, 4px);
|
||||
font-size: 0.55rem;
|
||||
line-height: 1;
|
||||
color: #475569;
|
||||
white-space: nowrap;
|
||||
user-select: none;
|
||||
text-shadow: 0 0 2px #fff, 0 0 2px #fff;
|
||||
}
|
||||
|
||||
.graph-tooltip {
|
||||
position: absolute;
|
||||
z-index: 5;
|
||||
background: var(--surface-2);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
padding: 0.5rem 0.65rem;
|
||||
pointer-events: none;
|
||||
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.45);
|
||||
max-width: 260px;
|
||||
}
|
||||
.graph-tooltip.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tt-head {
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.2rem;
|
||||
}
|
||||
.tt-status {
|
||||
font-size: 0.75rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.04em;
|
||||
font-weight: 600;
|
||||
}
|
||||
.tt-status.blocked {
|
||||
color: #e53935;
|
||||
}
|
||||
.tt-status.whitelisted {
|
||||
color: #43a047;
|
||||
}
|
||||
.tt-status.unlisted {
|
||||
color: var(--muted);
|
||||
}
|
||||
.tt-list {
|
||||
margin-top: 0.35rem;
|
||||
font-size: 0.72rem;
|
||||
white-space: pre-line;
|
||||
color: var(--text);
|
||||
}
|
||||
+50
-50
@@ -1,50 +1,50 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>{% block title %}Intrusion Detection{% endblock %}</title>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="{{ url_for('static', filename='style.css') }}"
|
||||
/>
|
||||
</head>
|
||||
<body>
|
||||
<header class="topbar">
|
||||
<div class="brand">🛡 Intrusion Detection</div>
|
||||
<nav>
|
||||
<a href="/" class="{{ 'active' if request.path == '/' }}">Dashboard</a>
|
||||
<a href="/scan" class="{{ 'active' if request.path == '/scan' }}"
|
||||
>Scan</a
|
||||
>
|
||||
<a href="/reports" class="{{ 'active' if request.path == '/reports' }}"
|
||||
>Reports</a
|
||||
>
|
||||
<a
|
||||
href="/blocklist"
|
||||
class="{{ 'active' if request.path == '/blocklist' }}"
|
||||
>Blocklist</a
|
||||
>
|
||||
<a
|
||||
href="/firewall"
|
||||
class="{{ 'active' if request.path == '/firewall' }}"
|
||||
>Firewall</a
|
||||
>
|
||||
<a
|
||||
href="/whitelist"
|
||||
class="{{ 'active' if request.path == '/whitelist' }}"
|
||||
>Whitelist</a
|
||||
>
|
||||
<a
|
||||
href="/graph"
|
||||
class="{{ 'active' if request.path == '/graph' }}"
|
||||
>Graph</a
|
||||
>
|
||||
</nav>
|
||||
</header>
|
||||
<main class="container">{% block content %}{% endblock %}</main>
|
||||
<div id="toasts"></div>
|
||||
<script src="{{ url_for('static', filename='app.js') }}"></script>
|
||||
{% block scripts %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>{% block title %}Intrusion Detection{% endblock %}</title>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="{{ url_for('static', filename='style.css') }}"
|
||||
/>
|
||||
</head>
|
||||
<body>
|
||||
<header class="topbar">
|
||||
<div class="brand">🛡 Intrusion Detection</div>
|
||||
<nav>
|
||||
<a href="/" class="{{ 'active' if request.path == '/' }}">Dashboard</a>
|
||||
<a href="/scan" class="{{ 'active' if request.path == '/scan' }}"
|
||||
>Scan</a
|
||||
>
|
||||
<a href="/reports" class="{{ 'active' if request.path == '/reports' }}"
|
||||
>Reports</a
|
||||
>
|
||||
<a
|
||||
href="/blocklist"
|
||||
class="{{ 'active' if request.path == '/blocklist' }}"
|
||||
>Blocklist</a
|
||||
>
|
||||
<a
|
||||
href="/firewall"
|
||||
class="{{ 'active' if request.path == '/firewall' }}"
|
||||
>Firewall</a
|
||||
>
|
||||
<a
|
||||
href="/whitelist"
|
||||
class="{{ 'active' if request.path == '/whitelist' }}"
|
||||
>Whitelist</a
|
||||
>
|
||||
<a
|
||||
href="/graph"
|
||||
class="{{ 'active' if request.path == '/graph' }}"
|
||||
>Graph</a
|
||||
>
|
||||
</nav>
|
||||
</header>
|
||||
<main class="container">{% block content %}{% endblock %}</main>
|
||||
<div id="toasts"></div>
|
||||
<script src="{{ url_for('static', filename='app.js') }}"></script>
|
||||
{% block scripts %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
+134
-134
@@ -1,134 +1,134 @@
|
||||
{% extends "base.html" %} {% block title %}Blocklist — Intrusion Detection{%
|
||||
endblock %} {% block content %}
|
||||
<h1>Blocklist</h1>
|
||||
<p class="muted">
|
||||
Current consolidated blocklist (from the latest scan). Adding/removing touches
|
||||
the MikroTik router.
|
||||
</p>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-head"><h2>Add / remove entry</h2></div>
|
||||
<div class="panel-actions" style="margin-top: 0">
|
||||
<input
|
||||
id="ip"
|
||||
placeholder="IP or CIDR, e.g. 1.2.3.4 or 1.2.0.0/16"
|
||||
style="min-width: 260px"
|
||||
/>
|
||||
<button class="btn primary" id="add-btn">Add to Blocked</button>
|
||||
<button class="btn danger" id="remove-btn">Remove from Blocked</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-head">
|
||||
<h2>IPv4 <span id="v4-count"></span></h2>
|
||||
</div>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Address</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="v4"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-head">
|
||||
<h2>IPv6 <span id="v6-count"></span></h2>
|
||||
</div>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Address</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="v6"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endblock %} {% block scripts %}
|
||||
<script>
|
||||
async function loadBlocklist() {
|
||||
try {
|
||||
const data = await api("/api/blocklist");
|
||||
render("v4", data.ipv4 || [], "v4-count");
|
||||
render("v6", data.ipv6 || [], "v6-count");
|
||||
} catch (e) {
|
||||
toast(e.message, "error");
|
||||
}
|
||||
}
|
||||
|
||||
function render(tbodyId, entries, countId) {
|
||||
const body = document.getElementById(tbodyId);
|
||||
body.innerHTML = "";
|
||||
document.getElementById(countId).textContent = `(${entries.length})`;
|
||||
if (!entries.length) {
|
||||
body.innerHTML =
|
||||
'<tr><td colspan="2" class="muted">No entries.</td></tr>';
|
||||
return;
|
||||
}
|
||||
for (const ip of entries) {
|
||||
body.append(
|
||||
el(
|
||||
"tr",
|
||||
el("td", { class: "mono", text: ip }),
|
||||
el(
|
||||
"td",
|
||||
{ style: "text-align:right" },
|
||||
el("button", {
|
||||
class: "btn danger",
|
||||
text: "Remove",
|
||||
onclick: () => remove(ip),
|
||||
}),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async function act(action) {
|
||||
const ip = document.getElementById("ip").value.trim();
|
||||
if (!ip) {
|
||||
toast("Enter an IP or CIDR", "warn");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const data = await api(`/api/blocklist/${action}`, {
|
||||
method: "POST",
|
||||
body: { ip },
|
||||
});
|
||||
toast(
|
||||
`Removed ${ip}`.replace(
|
||||
"Removed",
|
||||
action === "add" ? "Added" : "Removed",
|
||||
),
|
||||
"ok",
|
||||
);
|
||||
document.getElementById("ip").value = "";
|
||||
loadBlocklist();
|
||||
} catch (e) {
|
||||
toast(e.message, "error");
|
||||
}
|
||||
}
|
||||
|
||||
async function remove(ip) {
|
||||
try {
|
||||
await api("/api/blocklist/remove", { method: "POST", body: { ip } });
|
||||
toast(`Removed ${ip}`, "ok");
|
||||
loadBlocklist();
|
||||
} catch (e) {
|
||||
toast(e.message, "error");
|
||||
}
|
||||
}
|
||||
|
||||
document
|
||||
.getElementById("add-btn")
|
||||
.addEventListener("click", () => act("add"));
|
||||
document
|
||||
.getElementById("remove-btn")
|
||||
.addEventListener("click", () => act("remove"));
|
||||
loadBlocklist();
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% extends "base.html" %} {% block title %}Blocklist — Intrusion Detection{%
|
||||
endblock %} {% block content %}
|
||||
<h1>Blocklist</h1>
|
||||
<p class="muted">
|
||||
Current consolidated blocklist (from the latest scan). Adding/removing touches
|
||||
the MikroTik router.
|
||||
</p>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-head"><h2>Add / remove entry</h2></div>
|
||||
<div class="panel-actions" style="margin-top: 0">
|
||||
<input
|
||||
id="ip"
|
||||
placeholder="IP or CIDR, e.g. 1.2.3.4 or 1.2.0.0/16"
|
||||
style="min-width: 260px"
|
||||
/>
|
||||
<button class="btn primary" id="add-btn">Add to Blocked</button>
|
||||
<button class="btn danger" id="remove-btn">Remove from Blocked</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-head">
|
||||
<h2>IPv4 <span id="v4-count"></span></h2>
|
||||
</div>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Address</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="v4"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-head">
|
||||
<h2>IPv6 <span id="v6-count"></span></h2>
|
||||
</div>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Address</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="v6"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endblock %} {% block scripts %}
|
||||
<script>
|
||||
async function loadBlocklist() {
|
||||
try {
|
||||
const data = await api("/api/blocklist");
|
||||
render("v4", data.ipv4 || [], "v4-count");
|
||||
render("v6", data.ipv6 || [], "v6-count");
|
||||
} catch (e) {
|
||||
toast(e.message, "error");
|
||||
}
|
||||
}
|
||||
|
||||
function render(tbodyId, entries, countId) {
|
||||
const body = document.getElementById(tbodyId);
|
||||
body.innerHTML = "";
|
||||
document.getElementById(countId).textContent = `(${entries.length})`;
|
||||
if (!entries.length) {
|
||||
body.innerHTML =
|
||||
'<tr><td colspan="2" class="muted">No entries.</td></tr>';
|
||||
return;
|
||||
}
|
||||
for (const ip of entries) {
|
||||
body.append(
|
||||
el(
|
||||
"tr",
|
||||
el("td", { class: "mono", text: ip }),
|
||||
el(
|
||||
"td",
|
||||
{ style: "text-align:right" },
|
||||
el("button", {
|
||||
class: "btn danger",
|
||||
text: "Remove",
|
||||
onclick: () => remove(ip),
|
||||
}),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async function act(action) {
|
||||
const ip = document.getElementById("ip").value.trim();
|
||||
if (!ip) {
|
||||
toast("Enter an IP or CIDR", "warn");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const data = await api(`/api/blocklist/${action}`, {
|
||||
method: "POST",
|
||||
body: { ip },
|
||||
});
|
||||
toast(
|
||||
`Removed ${ip}`.replace(
|
||||
"Removed",
|
||||
action === "add" ? "Added" : "Removed",
|
||||
),
|
||||
"ok",
|
||||
);
|
||||
document.getElementById("ip").value = "";
|
||||
loadBlocklist();
|
||||
} catch (e) {
|
||||
toast(e.message, "error");
|
||||
}
|
||||
}
|
||||
|
||||
async function remove(ip) {
|
||||
try {
|
||||
await api("/api/blocklist/remove", { method: "POST", body: { ip } });
|
||||
toast(`Removed ${ip}`, "ok");
|
||||
loadBlocklist();
|
||||
} catch (e) {
|
||||
toast(e.message, "error");
|
||||
}
|
||||
}
|
||||
|
||||
document
|
||||
.getElementById("add-btn")
|
||||
.addEventListener("click", () => act("add"));
|
||||
document
|
||||
.getElementById("remove-btn")
|
||||
.addEventListener("click", () => act("remove"));
|
||||
loadBlocklist();
|
||||
</script>
|
||||
{% endblock %}
|
||||
+102
-102
@@ -1,102 +1,102 @@
|
||||
{% extends "base.html" %} {% block title %}Dashboard — Intrusion Detection{%
|
||||
endblock %} {% block content %}
|
||||
<h1>Dashboard</h1>
|
||||
<p class="muted">
|
||||
Localhost-only control panel for the intrusion detection scanner.
|
||||
</p>
|
||||
|
||||
<div class="cards" id="status-cards"></div>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-head">
|
||||
<h2>Latest scans</h2>
|
||||
<a class="btn ghost" href="/scan">Run a scan →</a>
|
||||
</div>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Job</th>
|
||||
<th>Kind</th>
|
||||
<th>State</th>
|
||||
<th>Started</th>
|
||||
<th>Finished</th>
|
||||
<th class="num">Blocked</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="latest-scans"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endblock %} {% block scripts %}
|
||||
<script>
|
||||
async function loadDashboard() {
|
||||
try {
|
||||
const s = await api("/api/status");
|
||||
renderCards(s);
|
||||
renderScans(s.latest_scans || []);
|
||||
} catch (e) {
|
||||
toast(e.message, "error");
|
||||
}
|
||||
}
|
||||
|
||||
function renderCards(s) {
|
||||
const cards = [
|
||||
{
|
||||
label: "Scan running",
|
||||
value: s.scan_running ? "Yes" : "No",
|
||||
tone: s.scan_running ? "warn" : "ok",
|
||||
},
|
||||
{ label: "Blocklist IPv4", value: s.blocklist_ipv4_count ?? "—" },
|
||||
{ label: "Blocklist IPv6", value: s.blocklist_ipv6_count ?? "—" },
|
||||
{
|
||||
label: "Firewall snapshot",
|
||||
value:
|
||||
s.firewall_snapshot && s.firewall_snapshot.exists
|
||||
? "Present"
|
||||
: "None",
|
||||
tone:
|
||||
s.firewall_snapshot && s.firewall_snapshot.exists ? "ok" : "muted",
|
||||
},
|
||||
];
|
||||
const box = document.getElementById("status-cards");
|
||||
box.innerHTML = "";
|
||||
for (const c of cards) {
|
||||
box.append(
|
||||
el(
|
||||
"div",
|
||||
{ class: "card" },
|
||||
el("div", { class: "card-label", text: c.label }),
|
||||
el("div", { class: `card-value ${c.tone || ""}`, text: c.value }),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function renderScans(scans) {
|
||||
const body = document.getElementById("latest-scans");
|
||||
body.innerHTML = "";
|
||||
if (!scans.length) {
|
||||
body.innerHTML =
|
||||
'<tr><td colspan="6" class="muted">No scans yet — run one from the Scan page.</td></tr>';
|
||||
return;
|
||||
}
|
||||
for (const j of scans) {
|
||||
const r = j.result || {};
|
||||
body.append(
|
||||
el(
|
||||
"tr",
|
||||
el("td", { class: "mono", text: j.job_id }),
|
||||
el("td", { text: j.kind }),
|
||||
el("td", {}, badge(j.state)),
|
||||
el("td", { text: fmtTime(j.started) }),
|
||||
el("td", { text: fmtTime(j.finished) }),
|
||||
el("td", { class: "num", text: r.blocked_targets ?? "—" }),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
loadDashboard();
|
||||
// Keep the latest-scans table fresh without hammering /api/scan/status.
|
||||
setInterval(loadDashboard, 15000);
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% extends "base.html" %} {% block title %}Dashboard — Intrusion Detection{%
|
||||
endblock %} {% block content %}
|
||||
<h1>Dashboard</h1>
|
||||
<p class="muted">
|
||||
Localhost-only control panel for the intrusion detection scanner.
|
||||
</p>
|
||||
|
||||
<div class="cards" id="status-cards"></div>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-head">
|
||||
<h2>Latest scans</h2>
|
||||
<a class="btn ghost" href="/scan">Run a scan →</a>
|
||||
</div>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Job</th>
|
||||
<th>Kind</th>
|
||||
<th>State</th>
|
||||
<th>Started</th>
|
||||
<th>Finished</th>
|
||||
<th class="num">Blocked</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="latest-scans"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endblock %} {% block scripts %}
|
||||
<script>
|
||||
async function loadDashboard() {
|
||||
try {
|
||||
const s = await api("/api/status");
|
||||
renderCards(s);
|
||||
renderScans(s.latest_scans || []);
|
||||
} catch (e) {
|
||||
toast(e.message, "error");
|
||||
}
|
||||
}
|
||||
|
||||
function renderCards(s) {
|
||||
const cards = [
|
||||
{
|
||||
label: "Scan running",
|
||||
value: s.scan_running ? "Yes" : "No",
|
||||
tone: s.scan_running ? "warn" : "ok",
|
||||
},
|
||||
{ label: "Blocklist IPv4", value: s.blocklist_ipv4_count ?? "—" },
|
||||
{ label: "Blocklist IPv6", value: s.blocklist_ipv6_count ?? "—" },
|
||||
{
|
||||
label: "Firewall snapshot",
|
||||
value:
|
||||
s.firewall_snapshot && s.firewall_snapshot.exists
|
||||
? "Present"
|
||||
: "None",
|
||||
tone:
|
||||
s.firewall_snapshot && s.firewall_snapshot.exists ? "ok" : "muted",
|
||||
},
|
||||
];
|
||||
const box = document.getElementById("status-cards");
|
||||
box.innerHTML = "";
|
||||
for (const c of cards) {
|
||||
box.append(
|
||||
el(
|
||||
"div",
|
||||
{ class: "card" },
|
||||
el("div", { class: "card-label", text: c.label }),
|
||||
el("div", { class: `card-value ${c.tone || ""}`, text: c.value }),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function renderScans(scans) {
|
||||
const body = document.getElementById("latest-scans");
|
||||
body.innerHTML = "";
|
||||
if (!scans.length) {
|
||||
body.innerHTML =
|
||||
'<tr><td colspan="6" class="muted">No scans yet — run one from the Scan page.</td></tr>';
|
||||
return;
|
||||
}
|
||||
for (const j of scans) {
|
||||
const r = j.result || {};
|
||||
body.append(
|
||||
el(
|
||||
"tr",
|
||||
el("td", { class: "mono", text: j.job_id }),
|
||||
el("td", { text: j.kind }),
|
||||
el("td", {}, badge(j.state)),
|
||||
el("td", { text: fmtTime(j.started) }),
|
||||
el("td", { text: fmtTime(j.finished) }),
|
||||
el("td", { class: "num", text: r.blocked_targets ?? "—" }),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
loadDashboard();
|
||||
// Keep the latest-scans table fresh without hammering /api/scan/status.
|
||||
setInterval(loadDashboard, 15000);
|
||||
</script>
|
||||
{% endblock %}
|
||||
+176
-176
@@ -1,176 +1,176 @@
|
||||
{% extends "base.html" %} {% block title %}Firewall — Intrusion Detection{%
|
||||
endblock %} {% block content %}
|
||||
<h1>Firewall</h1>
|
||||
<p class="muted">
|
||||
Current MikroTik state (from the latest <code>data/mikrotik</code> snapshot).
|
||||
Sync previews or applies the blocklist diff.
|
||||
</p>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-actions" style="margin-top: 0">
|
||||
<button class="btn" id="preview-btn">Preview sync (dry-run)</button>
|
||||
<button class="btn danger" id="apply-btn">Apply sync</button>
|
||||
<span class="muted" id="fw-result"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-head"><h2>Address lists</h2></div>
|
||||
<div id="address-lists"></div>
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-head"><h2>Firewall rules</h2></div>
|
||||
<div id="firewall-rules"></div>
|
||||
</div>
|
||||
{% endblock %} {% block scripts %}
|
||||
<script>
|
||||
async function loadState() {
|
||||
try {
|
||||
const s = await api("/api/firewall/state");
|
||||
renderAddressLists(s.address_lists || {});
|
||||
renderRules("firewall-rules", s.firewall_rules || {});
|
||||
} catch (e) {
|
||||
toast(e.message, "error");
|
||||
}
|
||||
}
|
||||
|
||||
function renderAddressLists(addr) {
|
||||
const box = document.getElementById("address-lists");
|
||||
box.innerHTML = "";
|
||||
const byList = {};
|
||||
for (const version of ["ipv4", "ipv6"]) {
|
||||
for (const e of addr[version] || []) {
|
||||
const name = e.list || "?";
|
||||
(byList[name] = byList[name] || { ipv4: [], ipv6: [] })[version].push(
|
||||
e.address,
|
||||
);
|
||||
}
|
||||
}
|
||||
const names = Object.keys(byList);
|
||||
if (!names.length) {
|
||||
box.innerHTML =
|
||||
'<p class="muted">No address-list snapshot available. Run <code>app.py --update-firewall</code> first.</p>';
|
||||
return;
|
||||
}
|
||||
for (const name of names) {
|
||||
const rows = [];
|
||||
for (const version of ["ipv4", "ipv6"]) {
|
||||
const entries = (byList[name][version] || []).sort();
|
||||
rows.push(
|
||||
el(
|
||||
"tr",
|
||||
el("td", { text: version }),
|
||||
el("td", { class: "mono", text: entries.join(", ") || "—" }),
|
||||
),
|
||||
);
|
||||
}
|
||||
box.append(
|
||||
el(
|
||||
"div",
|
||||
{ style: "margin-bottom:1rem" },
|
||||
el("div", {
|
||||
style: "font-weight:600;margin-bottom:.4rem",
|
||||
text: name,
|
||||
}),
|
||||
el(
|
||||
"table",
|
||||
{ class: "table" },
|
||||
el(
|
||||
"thead",
|
||||
{},
|
||||
el(
|
||||
"tr",
|
||||
{},
|
||||
el("th", { text: "Version" }),
|
||||
el("th", { text: "Addresses" }),
|
||||
),
|
||||
),
|
||||
el("tbody", {}, ...rows),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function renderRules(boxId, rules) {
|
||||
const box = document.getElementById(boxId);
|
||||
box.innerHTML = "";
|
||||
for (const version of ["ipv4", "ipv6"]) {
|
||||
const list = rules[version] || [];
|
||||
const rows = list.map((r) =>
|
||||
el(
|
||||
"tr",
|
||||
el("td", {
|
||||
class: "mono",
|
||||
text: r.address ? r.address : r["src-address-list"] || "",
|
||||
}),
|
||||
el("td", { text: r.chain || "—" }),
|
||||
el("td", { text: r.action || "—" }),
|
||||
el("td", { text: r.comment || "" }),
|
||||
),
|
||||
);
|
||||
box.append(
|
||||
el(
|
||||
"div",
|
||||
{ style: "margin-bottom:1rem" },
|
||||
el("div", {
|
||||
style: "font-weight:600;margin-bottom:.4rem",
|
||||
text: `IPv${version} (${list.length})`,
|
||||
}),
|
||||
rows.length
|
||||
? el(
|
||||
"table",
|
||||
{ class: "table" },
|
||||
el(
|
||||
"thead",
|
||||
{},
|
||||
el(
|
||||
"tr",
|
||||
{},
|
||||
el("th", { text: "Address / List" }),
|
||||
el("th", { text: "Chain" }),
|
||||
el("th", { text: "Action" }),
|
||||
el("th", { text: "Comment" }),
|
||||
),
|
||||
),
|
||||
el("tbody", {}, ...rows),
|
||||
)
|
||||
: el("p", { class: "muted", text: "No rules in snapshot." }),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async function sync(dryRun) {
|
||||
const out = document.getElementById("fw-result");
|
||||
out.textContent = "Working…";
|
||||
try {
|
||||
const changes = await api(`/api/firewall/${dryRun ? "sync" : "apply"}`, {
|
||||
method: "POST",
|
||||
body: {},
|
||||
});
|
||||
const verb = dryRun ? "Would" : "";
|
||||
out.textContent =
|
||||
`${verb} add ${(changes.added_ipv4 || []).length} IPv4 + ${(changes.added_ipv6 || []).length} IPv6; ` +
|
||||
`remove ${(changes.removed_ipv4 || []).length} IPv4 + ${(changes.removed_ipv6 || []).length} IPv6.`;
|
||||
toast(
|
||||
(dryRun ? "Preview" : "Applied") + " firewall sync",
|
||||
dryRun ? "warn" : "ok",
|
||||
);
|
||||
if (!dryRun) loadState();
|
||||
} catch (e) {
|
||||
out.textContent = "";
|
||||
toast(e.message, "error");
|
||||
}
|
||||
}
|
||||
|
||||
document
|
||||
.getElementById("preview-btn")
|
||||
.addEventListener("click", () => sync(true));
|
||||
document
|
||||
.getElementById("apply-btn")
|
||||
.addEventListener("click", () => sync(false));
|
||||
loadState();
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% extends "base.html" %} {% block title %}Firewall — Intrusion Detection{%
|
||||
endblock %} {% block content %}
|
||||
<h1>Firewall</h1>
|
||||
<p class="muted">
|
||||
Current MikroTik state (from the latest <code>data/mikrotik</code> snapshot).
|
||||
Sync previews or applies the blocklist diff.
|
||||
</p>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-actions" style="margin-top: 0">
|
||||
<button class="btn" id="preview-btn">Preview sync (dry-run)</button>
|
||||
<button class="btn danger" id="apply-btn">Apply sync</button>
|
||||
<span class="muted" id="fw-result"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-head"><h2>Address lists</h2></div>
|
||||
<div id="address-lists"></div>
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-head"><h2>Firewall rules</h2></div>
|
||||
<div id="firewall-rules"></div>
|
||||
</div>
|
||||
{% endblock %} {% block scripts %}
|
||||
<script>
|
||||
async function loadState() {
|
||||
try {
|
||||
const s = await api("/api/firewall/state");
|
||||
renderAddressLists(s.address_lists || {});
|
||||
renderRules("firewall-rules", s.firewall_rules || {});
|
||||
} catch (e) {
|
||||
toast(e.message, "error");
|
||||
}
|
||||
}
|
||||
|
||||
function renderAddressLists(addr) {
|
||||
const box = document.getElementById("address-lists");
|
||||
box.innerHTML = "";
|
||||
const byList = {};
|
||||
for (const version of ["ipv4", "ipv6"]) {
|
||||
for (const e of addr[version] || []) {
|
||||
const name = e.list || "?";
|
||||
(byList[name] = byList[name] || { ipv4: [], ipv6: [] })[version].push(
|
||||
e.address,
|
||||
);
|
||||
}
|
||||
}
|
||||
const names = Object.keys(byList);
|
||||
if (!names.length) {
|
||||
box.innerHTML =
|
||||
'<p class="muted">No address-list snapshot available. Run <code>app.py --update-firewall</code> first.</p>';
|
||||
return;
|
||||
}
|
||||
for (const name of names) {
|
||||
const rows = [];
|
||||
for (const version of ["ipv4", "ipv6"]) {
|
||||
const entries = (byList[name][version] || []).sort();
|
||||
rows.push(
|
||||
el(
|
||||
"tr",
|
||||
el("td", { text: version }),
|
||||
el("td", { class: "mono", text: entries.join(", ") || "—" }),
|
||||
),
|
||||
);
|
||||
}
|
||||
box.append(
|
||||
el(
|
||||
"div",
|
||||
{ style: "margin-bottom:1rem" },
|
||||
el("div", {
|
||||
style: "font-weight:600;margin-bottom:.4rem",
|
||||
text: name,
|
||||
}),
|
||||
el(
|
||||
"table",
|
||||
{ class: "table" },
|
||||
el(
|
||||
"thead",
|
||||
{},
|
||||
el(
|
||||
"tr",
|
||||
{},
|
||||
el("th", { text: "Version" }),
|
||||
el("th", { text: "Addresses" }),
|
||||
),
|
||||
),
|
||||
el("tbody", {}, ...rows),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function renderRules(boxId, rules) {
|
||||
const box = document.getElementById(boxId);
|
||||
box.innerHTML = "";
|
||||
for (const version of ["ipv4", "ipv6"]) {
|
||||
const list = rules[version] || [];
|
||||
const rows = list.map((r) =>
|
||||
el(
|
||||
"tr",
|
||||
el("td", {
|
||||
class: "mono",
|
||||
text: r.address ? r.address : r["src-address-list"] || "",
|
||||
}),
|
||||
el("td", { text: r.chain || "—" }),
|
||||
el("td", { text: r.action || "—" }),
|
||||
el("td", { text: r.comment || "" }),
|
||||
),
|
||||
);
|
||||
box.append(
|
||||
el(
|
||||
"div",
|
||||
{ style: "margin-bottom:1rem" },
|
||||
el("div", {
|
||||
style: "font-weight:600;margin-bottom:.4rem",
|
||||
text: `IPv${version} (${list.length})`,
|
||||
}),
|
||||
rows.length
|
||||
? el(
|
||||
"table",
|
||||
{ class: "table" },
|
||||
el(
|
||||
"thead",
|
||||
{},
|
||||
el(
|
||||
"tr",
|
||||
{},
|
||||
el("th", { text: "Address / List" }),
|
||||
el("th", { text: "Chain" }),
|
||||
el("th", { text: "Action" }),
|
||||
el("th", { text: "Comment" }),
|
||||
),
|
||||
),
|
||||
el("tbody", {}, ...rows),
|
||||
)
|
||||
: el("p", { class: "muted", text: "No rules in snapshot." }),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async function sync(dryRun) {
|
||||
const out = document.getElementById("fw-result");
|
||||
out.textContent = "Working…";
|
||||
try {
|
||||
const changes = await api(`/api/firewall/${dryRun ? "sync" : "apply"}`, {
|
||||
method: "POST",
|
||||
body: {},
|
||||
});
|
||||
const verb = dryRun ? "Would" : "";
|
||||
out.textContent =
|
||||
`${verb} add ${(changes.added_ipv4 || []).length} IPv4 + ${(changes.added_ipv6 || []).length} IPv6; ` +
|
||||
`remove ${(changes.removed_ipv4 || []).length} IPv4 + ${(changes.removed_ipv6 || []).length} IPv6.`;
|
||||
toast(
|
||||
(dryRun ? "Preview" : "Applied") + " firewall sync",
|
||||
dryRun ? "warn" : "ok",
|
||||
);
|
||||
if (!dryRun) loadState();
|
||||
} catch (e) {
|
||||
out.textContent = "";
|
||||
toast(e.message, "error");
|
||||
}
|
||||
}
|
||||
|
||||
document
|
||||
.getElementById("preview-btn")
|
||||
.addEventListener("click", () => sync(true));
|
||||
document
|
||||
.getElementById("apply-btn")
|
||||
.addEventListener("click", () => sync(false));
|
||||
loadState();
|
||||
</script>
|
||||
{% endblock %}
|
||||
+227
-227
@@ -1,227 +1,227 @@
|
||||
{% extends "base.html" %} {% block title %}Graph — Intrusion Detection{%
|
||||
endblock %} {% block content %}
|
||||
<h1>IPv4 address space map</h1>
|
||||
<p class="muted">
|
||||
One pixel per /24 network, arranged as 16×16 tiles of /8 (first octet).
|
||||
Blocked targets are red, whitelisted ranges are green.
|
||||
</p>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-head">
|
||||
<div class="graph-controls">
|
||||
<label class="check" style="margin-top: 0">
|
||||
<input type="checkbox" id="show-whitelisted" checked />
|
||||
Show whitelisted
|
||||
</label>
|
||||
<span class="legend">
|
||||
<span class="sw red"></span> Blocked
|
||||
<span class="sw green"></span> Whitelisted
|
||||
<span class="sw plain"></span> Unlisted
|
||||
</span>
|
||||
</div>
|
||||
<button class="btn ghost" id="graph-refresh">↻ Refresh</button>
|
||||
</div>
|
||||
<div class="graph-wrap" id="graph-wrap">
|
||||
<canvas id="graph-canvas" width="4096" height="4096"></canvas>
|
||||
<div class="graph-overlay" id="graph-overlay"></div>
|
||||
<div class="graph-tooltip hidden" id="graph-tooltip"></div>
|
||||
</div>
|
||||
<p class="muted mono" id="graph-stats">Loading…</p>
|
||||
</div>
|
||||
{% endblock %} {% block scripts %}
|
||||
<script>
|
||||
// Layout mirrors plot.py: 16x16 grid of /8 tiles, each 256x256 px (one pixel
|
||||
// per /24). Blocked ranges override whitelisted ranges.
|
||||
const TILE = 16;
|
||||
const SIZE = 256;
|
||||
const TOTAL = TILE * SIZE; // 4096
|
||||
|
||||
const V_UNLISTED = 0;
|
||||
const V_WHITELISTED = 1;
|
||||
const V_BLOCKED = 2;
|
||||
const COLOR_WHITELISTED = "#43a047";
|
||||
const COLOR_BLOCKED = "#e53935";
|
||||
|
||||
const canvas = document.getElementById("graph-canvas");
|
||||
const ctx = canvas.getContext("2d");
|
||||
const overlay = document.getElementById("graph-overlay");
|
||||
const tooltip = document.getElementById("graph-tooltip");
|
||||
const stats = document.getElementById("graph-stats");
|
||||
|
||||
// /24 index (0..2^24-1) -> value (whitelisted/blocked)
|
||||
const marked = new Map();
|
||||
|
||||
function parseCIDR(s) {
|
||||
const m = String(s)
|
||||
.trim()
|
||||
.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})(?:\/(\d{1,2}))?$/);
|
||||
if (!m) return null;
|
||||
const o = [m[1], m[2], m[3], m[4]].map(Number);
|
||||
if (o.some((n) => n > 255)) return null;
|
||||
const prefix = m[5] === undefined ? 32 : Number(m[5]);
|
||||
if (prefix < 0 || prefix > 32) return null;
|
||||
const ip = ((o[0] << 24) | (o[1] << 16) | (o[2] << 8) | o[3]) >>> 0;
|
||||
const mask = prefix === 0 ? 0 : (0xffffffff << (32 - prefix)) >>> 0;
|
||||
const network = (ip & mask) >>> 0;
|
||||
const broadcast = (ip | (~mask >>> 0)) >>> 0;
|
||||
return {
|
||||
first24: network >>> 8,
|
||||
last24: broadcast >>> 8,
|
||||
label: `${o[0]}.${o[1]}.${o[2]}.${o[3]}/${prefix}`,
|
||||
};
|
||||
}
|
||||
|
||||
function idxToPos(idx) {
|
||||
const a = (idx >>> 16) & 0xff;
|
||||
const b = (idx >>> 8) & 0xff;
|
||||
const c = idx & 0xff;
|
||||
return {
|
||||
x: (a % TILE) * SIZE + b,
|
||||
y: Math.floor(a / TILE) * SIZE + c,
|
||||
};
|
||||
}
|
||||
|
||||
function markRange(range, value) {
|
||||
for (let idx = range.first24; idx <= range.last24; idx++) {
|
||||
const prev = marked.get(idx);
|
||||
if (prev === undefined || value > prev) marked.set(idx, value);
|
||||
}
|
||||
}
|
||||
|
||||
function drawOverlay() {
|
||||
overlay.innerHTML = "";
|
||||
// /8 tile borders
|
||||
for (let i = 0; i <= TILE; i++) {
|
||||
const pct = (i / TILE) * 100;
|
||||
const v = el("div", { class: "g-line g-v", style: `left:${pct}%` });
|
||||
const h = el("div", { class: "g-line g-h", style: `top:${pct}%` });
|
||||
overlay.append(v, h);
|
||||
}
|
||||
// first-octet labels, one per /8 tile
|
||||
for (let a = 0; a < 256; a++) {
|
||||
const col = a % TILE;
|
||||
const row = Math.floor(a / TILE);
|
||||
overlay.append(
|
||||
el("div", {
|
||||
class: "g-label",
|
||||
style: `left:${(col / TILE) * 100}%;top:${(row / TILE) * 100}%`,
|
||||
text: `${a}.0.0.0/8`,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function render() {
|
||||
const showWl = document.getElementById("show-whitelisted").checked;
|
||||
ctx.fillStyle = "#ffffff";
|
||||
ctx.fillRect(0, 0, TOTAL, TOTAL);
|
||||
for (const [idx, value] of marked) {
|
||||
if (!showWl && value === V_WHITELISTED) continue;
|
||||
const p = idxToPos(idx);
|
||||
ctx.fillStyle = value === V_BLOCKED ? COLOR_BLOCKED : COLOR_WHITELISTED;
|
||||
ctx.fillRect(p.x, p.y, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// --- hover tooltip ------------------------------------------------------
|
||||
|
||||
function matchesIn(ranges, idx) {
|
||||
const out = [];
|
||||
for (const r of ranges) {
|
||||
if (idx >= r.first24 && idx <= r.last24) out.push(r.label);
|
||||
if (out.length >= 12) break;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function showTooltip(e, x, y) {
|
||||
const tileCol = Math.floor(x / SIZE);
|
||||
const tileRow = Math.floor(y / SIZE);
|
||||
const a = tileRow * TILE + tileCol;
|
||||
const b = x % SIZE;
|
||||
const c = y % SIZE;
|
||||
const idx = (a << 16) | (b << 8) | c;
|
||||
const value = marked.get(idx) ?? V_UNLISTED;
|
||||
const status =
|
||||
value === V_BLOCKED
|
||||
? "blocked"
|
||||
: value === V_WHITELISTED
|
||||
? "whitelisted"
|
||||
: "unlisted";
|
||||
const entries = matchesIn(blockedRanges, idx).concat(
|
||||
matchesIn(whitelistedRanges, idx),
|
||||
);
|
||||
tooltip.innerHTML = "";
|
||||
tooltip.append(
|
||||
el("div", { class: "tt-head mono", text: `${a}.${b}.${c}.0/24` }),
|
||||
el("div", { class: `tt-status ${status}`, text: status }),
|
||||
);
|
||||
if (entries.length) {
|
||||
tooltip.append(
|
||||
el("div", { class: "tt-list mono", text: entries.join("\n") }),
|
||||
);
|
||||
} else {
|
||||
tooltip.append(
|
||||
el("div", { class: "tt-list muted", text: "no matching entry" }),
|
||||
);
|
||||
}
|
||||
tooltip.classList.remove("hidden");
|
||||
const rect = canvas.getBoundingClientRect();
|
||||
let left = e.clientX - rect.left + 14;
|
||||
let top = e.clientY - rect.top + 14;
|
||||
if (left + tooltip.offsetWidth > rect.width)
|
||||
left = e.clientX - rect.left - tooltip.offsetWidth - 14;
|
||||
if (top + tooltip.offsetHeight > rect.height)
|
||||
top = e.clientY - rect.top - tooltip.offsetHeight - 14;
|
||||
tooltip.style.left = `${Math.max(0, left)}px`;
|
||||
tooltip.style.top = `${Math.max(0, top)}px`;
|
||||
}
|
||||
|
||||
canvas.addEventListener("mousemove", (e) => {
|
||||
const rect = canvas.getBoundingClientRect();
|
||||
const lx = ((e.clientX - rect.left) * TOTAL) / rect.width;
|
||||
const ly = ((e.clientY - rect.top) * TOTAL) / rect.height;
|
||||
const x = Math.floor(lx);
|
||||
const y = Math.floor(ly);
|
||||
if (x < 0 || x >= TOTAL || y < 0 || y >= TOTAL) {
|
||||
tooltip.classList.add("hidden");
|
||||
return;
|
||||
}
|
||||
showTooltip(e, x, y);
|
||||
});
|
||||
|
||||
canvas.addEventListener("mouseleave", () => {
|
||||
tooltip.classList.add("hidden");
|
||||
});
|
||||
|
||||
// --- load ---------------------------------------------------------------
|
||||
|
||||
let blockedRanges = [];
|
||||
let whitelistedRanges = [];
|
||||
|
||||
async function loadGraph() {
|
||||
try {
|
||||
const d = await api("/api/graph/ipv4");
|
||||
blockedRanges = (d.blocked || []).map(parseCIDR).filter(Boolean);
|
||||
whitelistedRanges = (d.whitelisted || []).map(parseCIDR).filter(Boolean);
|
||||
marked.clear();
|
||||
for (const r of whitelistedRanges) markRange(r, V_WHITELISTED);
|
||||
for (const r of blockedRanges) markRange(r, V_BLOCKED);
|
||||
render();
|
||||
drawOverlay();
|
||||
const c = d.counts || {};
|
||||
stats.textContent = `blocked targets: ${c.blocked ?? blockedRanges.length} · whitelisted ranges: ${c.whitelisted ?? whitelistedRanges.length} · marked /24 pixels: ${marked.size}`;
|
||||
} catch (err) {
|
||||
stats.textContent = `failed to load graph data: ${err.message}`;
|
||||
toast(err.message, "error");
|
||||
}
|
||||
}
|
||||
|
||||
document
|
||||
.getElementById("show-whitelisted")
|
||||
.addEventListener("change", render);
|
||||
document.getElementById("graph-refresh").addEventListener("click", loadGraph);
|
||||
|
||||
loadGraph();
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% extends "base.html" %} {% block title %}Graph — Intrusion Detection{%
|
||||
endblock %} {% block content %}
|
||||
<h1>IPv4 address space map</h1>
|
||||
<p class="muted">
|
||||
One pixel per /24 network, arranged as 16×16 tiles of /8 (first octet).
|
||||
Blocked targets are red, whitelisted ranges are green.
|
||||
</p>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-head">
|
||||
<div class="graph-controls">
|
||||
<label class="check" style="margin-top: 0">
|
||||
<input type="checkbox" id="show-whitelisted" checked />
|
||||
Show whitelisted
|
||||
</label>
|
||||
<span class="legend">
|
||||
<span class="sw red"></span> Blocked
|
||||
<span class="sw green"></span> Whitelisted
|
||||
<span class="sw plain"></span> Unlisted
|
||||
</span>
|
||||
</div>
|
||||
<button class="btn ghost" id="graph-refresh">↻ Refresh</button>
|
||||
</div>
|
||||
<div class="graph-wrap" id="graph-wrap">
|
||||
<canvas id="graph-canvas" width="4096" height="4096"></canvas>
|
||||
<div class="graph-overlay" id="graph-overlay"></div>
|
||||
<div class="graph-tooltip hidden" id="graph-tooltip"></div>
|
||||
</div>
|
||||
<p class="muted mono" id="graph-stats">Loading…</p>
|
||||
</div>
|
||||
{% endblock %} {% block scripts %}
|
||||
<script>
|
||||
// Layout mirrors plot.py: 16x16 grid of /8 tiles, each 256x256 px (one pixel
|
||||
// per /24). Blocked ranges override whitelisted ranges.
|
||||
const TILE = 16;
|
||||
const SIZE = 256;
|
||||
const TOTAL = TILE * SIZE; // 4096
|
||||
|
||||
const V_UNLISTED = 0;
|
||||
const V_WHITELISTED = 1;
|
||||
const V_BLOCKED = 2;
|
||||
const COLOR_WHITELISTED = "#43a047";
|
||||
const COLOR_BLOCKED = "#e53935";
|
||||
|
||||
const canvas = document.getElementById("graph-canvas");
|
||||
const ctx = canvas.getContext("2d");
|
||||
const overlay = document.getElementById("graph-overlay");
|
||||
const tooltip = document.getElementById("graph-tooltip");
|
||||
const stats = document.getElementById("graph-stats");
|
||||
|
||||
// /24 index (0..2^24-1) -> value (whitelisted/blocked)
|
||||
const marked = new Map();
|
||||
|
||||
function parseCIDR(s) {
|
||||
const m = String(s)
|
||||
.trim()
|
||||
.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})(?:\/(\d{1,2}))?$/);
|
||||
if (!m) return null;
|
||||
const o = [m[1], m[2], m[3], m[4]].map(Number);
|
||||
if (o.some((n) => n > 255)) return null;
|
||||
const prefix = m[5] === undefined ? 32 : Number(m[5]);
|
||||
if (prefix < 0 || prefix > 32) return null;
|
||||
const ip = ((o[0] << 24) | (o[1] << 16) | (o[2] << 8) | o[3]) >>> 0;
|
||||
const mask = prefix === 0 ? 0 : (0xffffffff << (32 - prefix)) >>> 0;
|
||||
const network = (ip & mask) >>> 0;
|
||||
const broadcast = (ip | (~mask >>> 0)) >>> 0;
|
||||
return {
|
||||
first24: network >>> 8,
|
||||
last24: broadcast >>> 8,
|
||||
label: `${o[0]}.${o[1]}.${o[2]}.${o[3]}/${prefix}`,
|
||||
};
|
||||
}
|
||||
|
||||
function idxToPos(idx) {
|
||||
const a = (idx >>> 16) & 0xff;
|
||||
const b = (idx >>> 8) & 0xff;
|
||||
const c = idx & 0xff;
|
||||
return {
|
||||
x: (a % TILE) * SIZE + b,
|
||||
y: Math.floor(a / TILE) * SIZE + c,
|
||||
};
|
||||
}
|
||||
|
||||
function markRange(range, value) {
|
||||
for (let idx = range.first24; idx <= range.last24; idx++) {
|
||||
const prev = marked.get(idx);
|
||||
if (prev === undefined || value > prev) marked.set(idx, value);
|
||||
}
|
||||
}
|
||||
|
||||
function drawOverlay() {
|
||||
overlay.innerHTML = "";
|
||||
// /8 tile borders
|
||||
for (let i = 0; i <= TILE; i++) {
|
||||
const pct = (i / TILE) * 100;
|
||||
const v = el("div", { class: "g-line g-v", style: `left:${pct}%` });
|
||||
const h = el("div", { class: "g-line g-h", style: `top:${pct}%` });
|
||||
overlay.append(v, h);
|
||||
}
|
||||
// first-octet labels, one per /8 tile
|
||||
for (let a = 0; a < 256; a++) {
|
||||
const col = a % TILE;
|
||||
const row = Math.floor(a / TILE);
|
||||
overlay.append(
|
||||
el("div", {
|
||||
class: "g-label",
|
||||
style: `left:${(col / TILE) * 100}%;top:${(row / TILE) * 100}%`,
|
||||
text: `${a}.0.0.0/8`,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function render() {
|
||||
const showWl = document.getElementById("show-whitelisted").checked;
|
||||
ctx.fillStyle = "#ffffff";
|
||||
ctx.fillRect(0, 0, TOTAL, TOTAL);
|
||||
for (const [idx, value] of marked) {
|
||||
if (!showWl && value === V_WHITELISTED) continue;
|
||||
const p = idxToPos(idx);
|
||||
ctx.fillStyle = value === V_BLOCKED ? COLOR_BLOCKED : COLOR_WHITELISTED;
|
||||
ctx.fillRect(p.x, p.y, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// --- hover tooltip ------------------------------------------------------
|
||||
|
||||
function matchesIn(ranges, idx) {
|
||||
const out = [];
|
||||
for (const r of ranges) {
|
||||
if (idx >= r.first24 && idx <= r.last24) out.push(r.label);
|
||||
if (out.length >= 12) break;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function showTooltip(e, x, y) {
|
||||
const tileCol = Math.floor(x / SIZE);
|
||||
const tileRow = Math.floor(y / SIZE);
|
||||
const a = tileRow * TILE + tileCol;
|
||||
const b = x % SIZE;
|
||||
const c = y % SIZE;
|
||||
const idx = (a << 16) | (b << 8) | c;
|
||||
const value = marked.get(idx) ?? V_UNLISTED;
|
||||
const status =
|
||||
value === V_BLOCKED
|
||||
? "blocked"
|
||||
: value === V_WHITELISTED
|
||||
? "whitelisted"
|
||||
: "unlisted";
|
||||
const entries = matchesIn(blockedRanges, idx).concat(
|
||||
matchesIn(whitelistedRanges, idx),
|
||||
);
|
||||
tooltip.innerHTML = "";
|
||||
tooltip.append(
|
||||
el("div", { class: "tt-head mono", text: `${a}.${b}.${c}.0/24` }),
|
||||
el("div", { class: `tt-status ${status}`, text: status }),
|
||||
);
|
||||
if (entries.length) {
|
||||
tooltip.append(
|
||||
el("div", { class: "tt-list mono", text: entries.join("\n") }),
|
||||
);
|
||||
} else {
|
||||
tooltip.append(
|
||||
el("div", { class: "tt-list muted", text: "no matching entry" }),
|
||||
);
|
||||
}
|
||||
tooltip.classList.remove("hidden");
|
||||
const rect = canvas.getBoundingClientRect();
|
||||
let left = e.clientX - rect.left + 14;
|
||||
let top = e.clientY - rect.top + 14;
|
||||
if (left + tooltip.offsetWidth > rect.width)
|
||||
left = e.clientX - rect.left - tooltip.offsetWidth - 14;
|
||||
if (top + tooltip.offsetHeight > rect.height)
|
||||
top = e.clientY - rect.top - tooltip.offsetHeight - 14;
|
||||
tooltip.style.left = `${Math.max(0, left)}px`;
|
||||
tooltip.style.top = `${Math.max(0, top)}px`;
|
||||
}
|
||||
|
||||
canvas.addEventListener("mousemove", (e) => {
|
||||
const rect = canvas.getBoundingClientRect();
|
||||
const lx = ((e.clientX - rect.left) * TOTAL) / rect.width;
|
||||
const ly = ((e.clientY - rect.top) * TOTAL) / rect.height;
|
||||
const x = Math.floor(lx);
|
||||
const y = Math.floor(ly);
|
||||
if (x < 0 || x >= TOTAL || y < 0 || y >= TOTAL) {
|
||||
tooltip.classList.add("hidden");
|
||||
return;
|
||||
}
|
||||
showTooltip(e, x, y);
|
||||
});
|
||||
|
||||
canvas.addEventListener("mouseleave", () => {
|
||||
tooltip.classList.add("hidden");
|
||||
});
|
||||
|
||||
// --- load ---------------------------------------------------------------
|
||||
|
||||
let blockedRanges = [];
|
||||
let whitelistedRanges = [];
|
||||
|
||||
async function loadGraph() {
|
||||
try {
|
||||
const d = await api("/api/graph/ipv4");
|
||||
blockedRanges = (d.blocked || []).map(parseCIDR).filter(Boolean);
|
||||
whitelistedRanges = (d.whitelisted || []).map(parseCIDR).filter(Boolean);
|
||||
marked.clear();
|
||||
for (const r of whitelistedRanges) markRange(r, V_WHITELISTED);
|
||||
for (const r of blockedRanges) markRange(r, V_BLOCKED);
|
||||
render();
|
||||
drawOverlay();
|
||||
const c = d.counts || {};
|
||||
stats.textContent = `blocked targets: ${c.blocked ?? blockedRanges.length} · whitelisted ranges: ${c.whitelisted ?? whitelistedRanges.length} · marked /24 pixels: ${marked.size}`;
|
||||
} catch (err) {
|
||||
stats.textContent = `failed to load graph data: ${err.message}`;
|
||||
toast(err.message, "error");
|
||||
}
|
||||
}
|
||||
|
||||
document
|
||||
.getElementById("show-whitelisted")
|
||||
.addEventListener("change", render);
|
||||
document.getElementById("graph-refresh").addEventListener("click", loadGraph);
|
||||
|
||||
loadGraph();
|
||||
</script>
|
||||
{% endblock %}
|
||||
+76
-76
@@ -1,76 +1,76 @@
|
||||
{% extends "base.html" %} {% block title %}Reports — Intrusion Detection{%
|
||||
endblock %} {% block content %}
|
||||
<h1>Reports</h1>
|
||||
<p class="muted">Browse the timestamped reports written by each scanner.</p>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-actions" style="margin-top: 0">
|
||||
<label style="flex-direction: row; align-items: center; gap: 0.5rem"
|
||||
>Source
|
||||
<select id="source">
|
||||
<option value="copyparty">copyparty</option>
|
||||
<option value="npm">npm</option>
|
||||
<option value="app">app</option>
|
||||
<option value="mikrotik">mikrotik</option>
|
||||
</select>
|
||||
</label>
|
||||
<button class="btn" id="refresh-btn">Refresh</button>
|
||||
</div>
|
||||
<div class="list" id="files"></div>
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-head"><h2 id="content-title">Report content</h2></div>
|
||||
<pre class="content" id="content">
|
||||
Select a report on the left to view it.</pre
|
||||
>
|
||||
</div>
|
||||
{% endblock %} {% block scripts %}
|
||||
<script>
|
||||
async function loadFiles() {
|
||||
const source = document.getElementById("source").value;
|
||||
const list = document.getElementById("files");
|
||||
list.innerHTML = '<div class="muted">Loading…</div>';
|
||||
try {
|
||||
const data = await api(`/api/reports/${source}`);
|
||||
list.innerHTML = "";
|
||||
const files = data.files || [];
|
||||
if (!files.length) {
|
||||
list.innerHTML = '<div class="muted">No reports in this source.</div>';
|
||||
return;
|
||||
}
|
||||
for (const name of files) {
|
||||
list.append(
|
||||
el("a", {
|
||||
href: "#",
|
||||
text: name,
|
||||
onclick: (ev) => {
|
||||
ev.preventDefault();
|
||||
openReport(name);
|
||||
},
|
||||
}),
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
list.innerHTML = `<div class="muted">${escapeHtml(e.message)}</div>`;
|
||||
}
|
||||
}
|
||||
|
||||
async function openReport(name) {
|
||||
const source = document.getElementById("source").value;
|
||||
document.getElementById("content-title").textContent = name;
|
||||
const pre = document.getElementById("content");
|
||||
pre.textContent = "Loading…";
|
||||
try {
|
||||
const data = await api(`/api/reports/${source}/${name}`);
|
||||
pre.textContent = data.content;
|
||||
} catch (e) {
|
||||
pre.textContent = `Error: ${e.message}`;
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById("refresh-btn").addEventListener("click", loadFiles);
|
||||
document.getElementById("source").addEventListener("change", loadFiles);
|
||||
loadFiles();
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% extends "base.html" %} {% block title %}Reports — Intrusion Detection{%
|
||||
endblock %} {% block content %}
|
||||
<h1>Reports</h1>
|
||||
<p class="muted">Browse the timestamped reports written by each scanner.</p>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-actions" style="margin-top: 0">
|
||||
<label style="flex-direction: row; align-items: center; gap: 0.5rem"
|
||||
>Source
|
||||
<select id="source">
|
||||
<option value="copyparty">copyparty</option>
|
||||
<option value="npm">npm</option>
|
||||
<option value="app">app</option>
|
||||
<option value="mikrotik">mikrotik</option>
|
||||
</select>
|
||||
</label>
|
||||
<button class="btn" id="refresh-btn">Refresh</button>
|
||||
</div>
|
||||
<div class="list" id="files"></div>
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-head"><h2 id="content-title">Report content</h2></div>
|
||||
<pre class="content" id="content">
|
||||
Select a report on the left to view it.</pre
|
||||
>
|
||||
</div>
|
||||
{% endblock %} {% block scripts %}
|
||||
<script>
|
||||
async function loadFiles() {
|
||||
const source = document.getElementById("source").value;
|
||||
const list = document.getElementById("files");
|
||||
list.innerHTML = '<div class="muted">Loading…</div>';
|
||||
try {
|
||||
const data = await api(`/api/reports/${source}`);
|
||||
list.innerHTML = "";
|
||||
const files = data.files || [];
|
||||
if (!files.length) {
|
||||
list.innerHTML = '<div class="muted">No reports in this source.</div>';
|
||||
return;
|
||||
}
|
||||
for (const name of files) {
|
||||
list.append(
|
||||
el("a", {
|
||||
href: "#",
|
||||
text: name,
|
||||
onclick: (ev) => {
|
||||
ev.preventDefault();
|
||||
openReport(name);
|
||||
},
|
||||
}),
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
list.innerHTML = `<div class="muted">${escapeHtml(e.message)}</div>`;
|
||||
}
|
||||
}
|
||||
|
||||
async function openReport(name) {
|
||||
const source = document.getElementById("source").value;
|
||||
document.getElementById("content-title").textContent = name;
|
||||
const pre = document.getElementById("content");
|
||||
pre.textContent = "Loading…";
|
||||
try {
|
||||
const data = await api(`/api/reports/${source}/${name}`);
|
||||
pre.textContent = data.content;
|
||||
} catch (e) {
|
||||
pre.textContent = `Error: ${e.message}`;
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById("refresh-btn").addEventListener("click", loadFiles);
|
||||
document.getElementById("source").addEventListener("change", loadFiles);
|
||||
loadFiles();
|
||||
</script>
|
||||
{% endblock %}
|
||||
+185
-185
@@ -1,185 +1,185 @@
|
||||
{% extends "base.html" %} {% block title %}Scan — Intrusion Detection{% endblock
|
||||
%} {% block content %}
|
||||
<h1>Run a scan</h1>
|
||||
<p class="muted">
|
||||
Scans run in the background; only one at a time. You can leave this page and
|
||||
come back.
|
||||
</p>
|
||||
|
||||
<div class="panel">
|
||||
<form id="scan-form" class="form-grid">
|
||||
<label
|
||||
>Type
|
||||
<select id="kind">
|
||||
<option value="consolidated">Consolidated (copyparty + npm)</option>
|
||||
<option value="copyparty">copyparty only</option>
|
||||
<option value="npm">npm only</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>Top IPs <input id="top" type="number" value="30" min="1" /></label>
|
||||
<label
|
||||
>Min denied (copyparty)
|
||||
<input id="min_denied" type="number" value="1" min="0"
|
||||
/></label>
|
||||
<label
|
||||
>Min errors (npm) <input id="min_errors" type="number" value="5" min="0"
|
||||
/></label>
|
||||
<label
|
||||
>Error ratio (npm)
|
||||
<input
|
||||
id="error_ratio"
|
||||
type="number"
|
||||
step="0.05"
|
||||
value="0.5"
|
||||
min="0"
|
||||
max="1"
|
||||
/></label>
|
||||
<label class="check"
|
||||
><input id="update_firewall" type="checkbox" /> Update firewall after
|
||||
scan</label
|
||||
>
|
||||
<label class="check"
|
||||
><input id="dry_run" type="checkbox" /> Dry-run (preview, no
|
||||
changes)</label
|
||||
>
|
||||
<label class="check"
|
||||
><input id="full" type="checkbox" /> Full scan (ignore incremental
|
||||
state)</label
|
||||
>
|
||||
</form>
|
||||
<div class="panel-actions">
|
||||
<button class="btn primary" id="run-btn">Run scan</button>
|
||||
<span class="muted" id="busy-hint"></span>
|
||||
</div>
|
||||
<div id="job-status" class="job-status"></div>
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-head"><h2>Recent jobs</h2></div>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Job</th>
|
||||
<th>Kind</th>
|
||||
<th>State</th>
|
||||
<th>Started</th>
|
||||
<th>Finished</th>
|
||||
<th class="num">Blocked</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="jobs"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endblock %} {% block scripts %}
|
||||
<script>
|
||||
let pollTimer = null;
|
||||
|
||||
const form = document.getElementById("scan-form");
|
||||
const runBtn = document.getElementById("run-btn");
|
||||
const hint = document.getElementById("busy-hint");
|
||||
|
||||
async function runScan() {
|
||||
const kind = document.getElementById("kind").value;
|
||||
const params = {
|
||||
top: parseInt(document.getElementById("top").value, 10) || 30,
|
||||
min_denied:
|
||||
parseInt(document.getElementById("min_denied").value, 10) || 1,
|
||||
min_errors:
|
||||
parseInt(document.getElementById("min_errors").value, 10) || 5,
|
||||
error_ratio:
|
||||
parseFloat(document.getElementById("error_ratio").value) || 0.5,
|
||||
update_firewall: document.getElementById("update_firewall").checked,
|
||||
dry_run: document.getElementById("dry_run").checked,
|
||||
full: document.getElementById("full").checked,
|
||||
quiet: true,
|
||||
};
|
||||
runBtn.disabled = true;
|
||||
try {
|
||||
const job = await startScan(kind, params);
|
||||
setStatus(`Job ${job.job_id} started (${job.state}).`, "ok");
|
||||
poll(job.job_id);
|
||||
} catch (e) {
|
||||
setStatus(e.message, "error");
|
||||
runBtn.disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
function setStatus(msg, type) {
|
||||
const box = document.getElementById("job-status");
|
||||
box.textContent = msg;
|
||||
box.style.color =
|
||||
type === "error"
|
||||
? "var(--danger)"
|
||||
: type === "ok"
|
||||
? "var(--ok)"
|
||||
: "inherit";
|
||||
}
|
||||
|
||||
async function poll(jobId) {
|
||||
clearTimeout(pollTimer);
|
||||
let job;
|
||||
try {
|
||||
job = await api(`/api/scan/${jobId}`);
|
||||
} catch (e) {
|
||||
setStatus(e.message, "error");
|
||||
runBtn.disabled = false;
|
||||
return;
|
||||
}
|
||||
const r = job.result || {};
|
||||
setStatus(
|
||||
`[${job.state}] ${job.kind} — started ${fmtTime(job.started)}` +
|
||||
(job.finished ? `, finished ${fmtTime(job.finished)}` : "") +
|
||||
(r.blocked_targets != null
|
||||
? `, blocked targets: ${r.blocked_targets}`
|
||||
: "") +
|
||||
(job.error ? `, error: ${job.error}` : ""),
|
||||
job.state === "error" ? "error" : job.state === "done" ? "ok" : "",
|
||||
);
|
||||
if (job.state === "running" || job.state === "queued") {
|
||||
pollTimer = setTimeout(() => poll(jobId), 2000);
|
||||
} else {
|
||||
runBtn.disabled = false;
|
||||
refreshJobs();
|
||||
const running = (await api("/api/scan/status")).running;
|
||||
hint.textContent = running ? "" : "";
|
||||
}
|
||||
}
|
||||
|
||||
async function refreshJobs() {
|
||||
try {
|
||||
const s = await api("/api/scan/status");
|
||||
hint.textContent = s.running ? "A scan is currently running…" : "";
|
||||
const body = document.getElementById("jobs");
|
||||
body.innerHTML = "";
|
||||
const jobs = s.latest_scans || [];
|
||||
if (!jobs.length) {
|
||||
body.innerHTML =
|
||||
'<tr><td colspan="6" class="muted">No jobs yet.</td></tr>';
|
||||
return;
|
||||
}
|
||||
for (const j of jobs) {
|
||||
const r = j.result || {};
|
||||
body.append(
|
||||
el(
|
||||
"tr",
|
||||
el("td", { class: "mono", text: j.job_id }),
|
||||
el("td", { text: j.kind }),
|
||||
el("td", {}, badge(j.state)),
|
||||
el("td", { text: fmtTime(j.started) }),
|
||||
el("td", { text: fmtTime(j.finished) }),
|
||||
el("td", { class: "num", text: r.blocked_targets ?? "—" }),
|
||||
),
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
toast(e.message, "error");
|
||||
}
|
||||
}
|
||||
|
||||
runBtn.addEventListener("click", runScan);
|
||||
refreshJobs();
|
||||
// /api/scan/status is only polled every 15 s; the active job's own
|
||||
// 2 s poll keeps live progress without hammering the status endpoint.
|
||||
setInterval(refreshJobs, 15000);
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% extends "base.html" %} {% block title %}Scan — Intrusion Detection{% endblock
|
||||
%} {% block content %}
|
||||
<h1>Run a scan</h1>
|
||||
<p class="muted">
|
||||
Scans run in the background; only one at a time. You can leave this page and
|
||||
come back.
|
||||
</p>
|
||||
|
||||
<div class="panel">
|
||||
<form id="scan-form" class="form-grid">
|
||||
<label
|
||||
>Type
|
||||
<select id="kind">
|
||||
<option value="consolidated">Consolidated (copyparty + npm)</option>
|
||||
<option value="copyparty">copyparty only</option>
|
||||
<option value="npm">npm only</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>Top IPs <input id="top" type="number" value="30" min="1" /></label>
|
||||
<label
|
||||
>Min denied (copyparty)
|
||||
<input id="min_denied" type="number" value="1" min="0"
|
||||
/></label>
|
||||
<label
|
||||
>Min errors (npm) <input id="min_errors" type="number" value="5" min="0"
|
||||
/></label>
|
||||
<label
|
||||
>Error ratio (npm)
|
||||
<input
|
||||
id="error_ratio"
|
||||
type="number"
|
||||
step="0.05"
|
||||
value="0.5"
|
||||
min="0"
|
||||
max="1"
|
||||
/></label>
|
||||
<label class="check"
|
||||
><input id="update_firewall" type="checkbox" /> Update firewall after
|
||||
scan</label
|
||||
>
|
||||
<label class="check"
|
||||
><input id="dry_run" type="checkbox" /> Dry-run (preview, no
|
||||
changes)</label
|
||||
>
|
||||
<label class="check"
|
||||
><input id="full" type="checkbox" /> Full scan (ignore incremental
|
||||
state)</label
|
||||
>
|
||||
</form>
|
||||
<div class="panel-actions">
|
||||
<button class="btn primary" id="run-btn">Run scan</button>
|
||||
<span class="muted" id="busy-hint"></span>
|
||||
</div>
|
||||
<div id="job-status" class="job-status"></div>
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-head"><h2>Recent jobs</h2></div>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Job</th>
|
||||
<th>Kind</th>
|
||||
<th>State</th>
|
||||
<th>Started</th>
|
||||
<th>Finished</th>
|
||||
<th class="num">Blocked</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="jobs"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endblock %} {% block scripts %}
|
||||
<script>
|
||||
let pollTimer = null;
|
||||
|
||||
const form = document.getElementById("scan-form");
|
||||
const runBtn = document.getElementById("run-btn");
|
||||
const hint = document.getElementById("busy-hint");
|
||||
|
||||
async function runScan() {
|
||||
const kind = document.getElementById("kind").value;
|
||||
const params = {
|
||||
top: parseInt(document.getElementById("top").value, 10) || 30,
|
||||
min_denied:
|
||||
parseInt(document.getElementById("min_denied").value, 10) || 1,
|
||||
min_errors:
|
||||
parseInt(document.getElementById("min_errors").value, 10) || 5,
|
||||
error_ratio:
|
||||
parseFloat(document.getElementById("error_ratio").value) || 0.5,
|
||||
update_firewall: document.getElementById("update_firewall").checked,
|
||||
dry_run: document.getElementById("dry_run").checked,
|
||||
full: document.getElementById("full").checked,
|
||||
quiet: true,
|
||||
};
|
||||
runBtn.disabled = true;
|
||||
try {
|
||||
const job = await startScan(kind, params);
|
||||
setStatus(`Job ${job.job_id} started (${job.state}).`, "ok");
|
||||
poll(job.job_id);
|
||||
} catch (e) {
|
||||
setStatus(e.message, "error");
|
||||
runBtn.disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
function setStatus(msg, type) {
|
||||
const box = document.getElementById("job-status");
|
||||
box.textContent = msg;
|
||||
box.style.color =
|
||||
type === "error"
|
||||
? "var(--danger)"
|
||||
: type === "ok"
|
||||
? "var(--ok)"
|
||||
: "inherit";
|
||||
}
|
||||
|
||||
async function poll(jobId) {
|
||||
clearTimeout(pollTimer);
|
||||
let job;
|
||||
try {
|
||||
job = await api(`/api/scan/${jobId}`);
|
||||
} catch (e) {
|
||||
setStatus(e.message, "error");
|
||||
runBtn.disabled = false;
|
||||
return;
|
||||
}
|
||||
const r = job.result || {};
|
||||
setStatus(
|
||||
`[${job.state}] ${job.kind} — started ${fmtTime(job.started)}` +
|
||||
(job.finished ? `, finished ${fmtTime(job.finished)}` : "") +
|
||||
(r.blocked_targets != null
|
||||
? `, blocked targets: ${r.blocked_targets}`
|
||||
: "") +
|
||||
(job.error ? `, error: ${job.error}` : ""),
|
||||
job.state === "error" ? "error" : job.state === "done" ? "ok" : "",
|
||||
);
|
||||
if (job.state === "running" || job.state === "queued") {
|
||||
pollTimer = setTimeout(() => poll(jobId), 2000);
|
||||
} else {
|
||||
runBtn.disabled = false;
|
||||
refreshJobs();
|
||||
const running = (await api("/api/scan/status")).running;
|
||||
hint.textContent = running ? "" : "";
|
||||
}
|
||||
}
|
||||
|
||||
async function refreshJobs() {
|
||||
try {
|
||||
const s = await api("/api/scan/status");
|
||||
hint.textContent = s.running ? "A scan is currently running…" : "";
|
||||
const body = document.getElementById("jobs");
|
||||
body.innerHTML = "";
|
||||
const jobs = s.latest_scans || [];
|
||||
if (!jobs.length) {
|
||||
body.innerHTML =
|
||||
'<tr><td colspan="6" class="muted">No jobs yet.</td></tr>';
|
||||
return;
|
||||
}
|
||||
for (const j of jobs) {
|
||||
const r = j.result || {};
|
||||
body.append(
|
||||
el(
|
||||
"tr",
|
||||
el("td", { class: "mono", text: j.job_id }),
|
||||
el("td", { text: j.kind }),
|
||||
el("td", {}, badge(j.state)),
|
||||
el("td", { text: fmtTime(j.started) }),
|
||||
el("td", { text: fmtTime(j.finished) }),
|
||||
el("td", { class: "num", text: r.blocked_targets ?? "—" }),
|
||||
),
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
toast(e.message, "error");
|
||||
}
|
||||
}
|
||||
|
||||
runBtn.addEventListener("click", runScan);
|
||||
refreshJobs();
|
||||
// /api/scan/status is only polled every 15 s; the active job's own
|
||||
// 2 s poll keeps live progress without hammering the status endpoint.
|
||||
setInterval(refreshJobs, 15000);
|
||||
</script>
|
||||
{% endblock %}
|
||||
+110
-110
@@ -1,110 +1,110 @@
|
||||
{% extends "base.html" %} {% block title %}Whitelist — Intrusion Detection{%
|
||||
endblock %} {% block content %}
|
||||
<h1>Whitelist</h1>
|
||||
<p class="muted">
|
||||
Provider whitelists (from the router snapshot). Never add a whole cloud
|
||||
provider to the blocklist.
|
||||
</p>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-head"><h2>Add / remove CIDR</h2></div>
|
||||
<div class="panel-actions" style="margin-top: 0">
|
||||
<select id="wl-name">
|
||||
{% for name in whitelist_names %}
|
||||
<option value="{{ name }}">{{ name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<input
|
||||
id="wl-address"
|
||||
placeholder="CIDR, e.g. 1.2.3.0/24"
|
||||
style="min-width: 220px"
|
||||
/>
|
||||
<button class="btn primary" id="wl-add-btn">Add</button>
|
||||
<button class="btn danger" id="wl-remove-btn">Remove</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="whitelists"></div>
|
||||
{% endblock %} {% block scripts %}
|
||||
<script>
|
||||
async function loadWhitelists() {
|
||||
try {
|
||||
const data = await api("/api/whitelist");
|
||||
const box = document.getElementById("whitelists");
|
||||
box.innerHTML = "";
|
||||
for (const name of data.names || []) {
|
||||
const w = data.whitelists[name] || {};
|
||||
const rows = [];
|
||||
for (const version of ["ipv4", "ipv6"]) {
|
||||
const entries = (w[version] || []).sort();
|
||||
rows.push(
|
||||
el(
|
||||
"tr",
|
||||
el("td", { text: version }),
|
||||
el("td", { class: "mono", text: entries.join(", ") || "—" }),
|
||||
),
|
||||
);
|
||||
}
|
||||
box.append(
|
||||
el(
|
||||
"div",
|
||||
{ class: "panel" },
|
||||
el(
|
||||
"div",
|
||||
{ class: "panel-head" },
|
||||
el("h2", {
|
||||
text: `${name} (${(w.ipv4 || []).length + (w.ipv6 || []).length})`,
|
||||
}),
|
||||
),
|
||||
el(
|
||||
"table",
|
||||
{ class: "table" },
|
||||
el(
|
||||
"thead",
|
||||
{},
|
||||
el(
|
||||
"tr",
|
||||
{},
|
||||
el("th", { text: "Version" }),
|
||||
el("th", { text: "Addresses" }),
|
||||
),
|
||||
),
|
||||
el("tbody", {}, ...rows),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
toast(e.message, "error");
|
||||
}
|
||||
}
|
||||
|
||||
async function act(action) {
|
||||
const name = document.getElementById("wl-name").value;
|
||||
const address = document.getElementById("wl-address").value.trim();
|
||||
if (!address) {
|
||||
toast("Enter a CIDR", "warn");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await api("/api/whitelist/update", {
|
||||
method: "POST",
|
||||
body: { name, address, action },
|
||||
});
|
||||
toast(`${action} ${address} on ${name}`, "ok");
|
||||
document.getElementById("wl-address").value = "";
|
||||
loadWhitelists();
|
||||
} catch (e) {
|
||||
toast(e.message, "error");
|
||||
}
|
||||
}
|
||||
|
||||
document
|
||||
.getElementById("wl-add-btn")
|
||||
.addEventListener("click", () => act("add"));
|
||||
document
|
||||
.getElementById("wl-remove-btn")
|
||||
.addEventListener("click", () => act("remove"));
|
||||
loadWhitelists();
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% extends "base.html" %} {% block title %}Whitelist — Intrusion Detection{%
|
||||
endblock %} {% block content %}
|
||||
<h1>Whitelist</h1>
|
||||
<p class="muted">
|
||||
Provider whitelists (from the router snapshot). Never add a whole cloud
|
||||
provider to the blocklist.
|
||||
</p>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-head"><h2>Add / remove CIDR</h2></div>
|
||||
<div class="panel-actions" style="margin-top: 0">
|
||||
<select id="wl-name">
|
||||
{% for name in whitelist_names %}
|
||||
<option value="{{ name }}">{{ name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<input
|
||||
id="wl-address"
|
||||
placeholder="CIDR, e.g. 1.2.3.0/24"
|
||||
style="min-width: 220px"
|
||||
/>
|
||||
<button class="btn primary" id="wl-add-btn">Add</button>
|
||||
<button class="btn danger" id="wl-remove-btn">Remove</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="whitelists"></div>
|
||||
{% endblock %} {% block scripts %}
|
||||
<script>
|
||||
async function loadWhitelists() {
|
||||
try {
|
||||
const data = await api("/api/whitelist");
|
||||
const box = document.getElementById("whitelists");
|
||||
box.innerHTML = "";
|
||||
for (const name of data.names || []) {
|
||||
const w = data.whitelists[name] || {};
|
||||
const rows = [];
|
||||
for (const version of ["ipv4", "ipv6"]) {
|
||||
const entries = (w[version] || []).sort();
|
||||
rows.push(
|
||||
el(
|
||||
"tr",
|
||||
el("td", { text: version }),
|
||||
el("td", { class: "mono", text: entries.join(", ") || "—" }),
|
||||
),
|
||||
);
|
||||
}
|
||||
box.append(
|
||||
el(
|
||||
"div",
|
||||
{ class: "panel" },
|
||||
el(
|
||||
"div",
|
||||
{ class: "panel-head" },
|
||||
el("h2", {
|
||||
text: `${name} (${(w.ipv4 || []).length + (w.ipv6 || []).length})`,
|
||||
}),
|
||||
),
|
||||
el(
|
||||
"table",
|
||||
{ class: "table" },
|
||||
el(
|
||||
"thead",
|
||||
{},
|
||||
el(
|
||||
"tr",
|
||||
{},
|
||||
el("th", { text: "Version" }),
|
||||
el("th", { text: "Addresses" }),
|
||||
),
|
||||
),
|
||||
el("tbody", {}, ...rows),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
toast(e.message, "error");
|
||||
}
|
||||
}
|
||||
|
||||
async function act(action) {
|
||||
const name = document.getElementById("wl-name").value;
|
||||
const address = document.getElementById("wl-address").value.trim();
|
||||
if (!address) {
|
||||
toast("Enter a CIDR", "warn");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await api("/api/whitelist/update", {
|
||||
method: "POST",
|
||||
body: { name, address, action },
|
||||
});
|
||||
toast(`${action} ${address} on ${name}`, "ok");
|
||||
document.getElementById("wl-address").value = "";
|
||||
loadWhitelists();
|
||||
} catch (e) {
|
||||
toast(e.message, "error");
|
||||
}
|
||||
}
|
||||
|
||||
document
|
||||
.getElementById("wl-add-btn")
|
||||
.addEventListener("click", () => act("add"));
|
||||
document
|
||||
.getElementById("wl-remove-btn")
|
||||
.addEventListener("click", () => act("remove"));
|
||||
loadWhitelists();
|
||||
</script>
|
||||
{% endblock %}
|
||||
+13
-13
@@ -1,13 +1,13 @@
|
||||
# Intrusion Detection System — shared utilities
|
||||
#
|
||||
# Modules:
|
||||
# constants.py central configuration, paths, env vars
|
||||
# files.py filesystem & I/O helpers
|
||||
# ip_utils.py IP address parsing, validation, whitelist lookup
|
||||
# models.py data models (Request, IPStats) + aggregate()
|
||||
# reporting.py text rendering, table formatting
|
||||
# utils.py shared CLI arg parser
|
||||
# whitelists.py whitelist CIDR download, caching, validation
|
||||
# whois.py WHOIS subnet queries, IP consolidation
|
||||
# blocklist_history.py git-backed cumulative blocklist reconstruction
|
||||
# retention.py report file retention & pruning
|
||||
# Intrusion Detection System — shared utilities
|
||||
#
|
||||
# Modules:
|
||||
# constants.py central configuration, paths, env vars
|
||||
# files.py filesystem & I/O helpers
|
||||
# ip_utils.py IP address parsing, validation, whitelist lookup
|
||||
# models.py data models (Request, IPStats) + aggregate()
|
||||
# reporting.py text rendering, table formatting
|
||||
# utils.py shared CLI arg parser
|
||||
# whitelists.py whitelist CIDR download, caching, validation
|
||||
# whois.py WHOIS subnet queries, IP consolidation
|
||||
# blocklist_history.py git-backed cumulative blocklist reconstruction
|
||||
# retention.py report file retention & pruning
|
||||
+186
-186
@@ -1,186 +1,186 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Git-backed cumulative blocklist history.
|
||||
|
||||
The consolidated blocklist lives in git-tracked files
|
||||
(``reports/app/data/blocklist_ipv4.txt`` / ``blocklist_ipv6.txt``). To make the
|
||||
MikroTik blocklist grow-only, the "complete set of all blocked IPs" is
|
||||
reconstructed from **every git revision** of those files (the union of all
|
||||
lines ever present), plus the current working files and the latest scan
|
||||
targets.
|
||||
|
||||
This keeps IPs blocked even after they leave the NPM ~30-day log window, and
|
||||
only ever removes router entries that were never blocked by the system.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import ipaddress
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
from datetime import datetime
|
||||
from typing import Any, Iterable
|
||||
|
||||
from .files import write_json
|
||||
from .reporting import timestamp_name
|
||||
|
||||
#: A ``+ 1.2.3.4/32`` added line in a git patch; ``+++ b/...`` is the file
|
||||
#: header and is excluded by the negative lookahead.
|
||||
_ADDED_LINE_RE = re.compile(r"^\+(?!\+)(.*)$")
|
||||
|
||||
|
||||
def _run_git(*args: str) -> subprocess.CompletedProcess[str] | None:
|
||||
"""Run a git command, returning None on any failure (never raises)."""
|
||||
try:
|
||||
return subprocess.run(
|
||||
["git", *args], capture_output=True, text=True, check=False)
|
||||
except (OSError, subprocess.SubprocessError):
|
||||
return None
|
||||
|
||||
|
||||
def _valid_line(line: str) -> str | None:
|
||||
"""Normalize a blocklist line to a canonical CIDR string, or None."""
|
||||
line = line.strip()
|
||||
if not line:
|
||||
return None
|
||||
try:
|
||||
return str(ipaddress.ip_network(line, strict=False))
|
||||
except ValueError:
|
||||
return None
|
||||
|
||||
|
||||
def committed_lines(path: str) -> set[str]:
|
||||
"""Return the union of all lines ever present in ``path`` across git.
|
||||
|
||||
Uses a single ``git log --all -p -- <path>`` and collects the ``+`` added
|
||||
lines (excluding the ``+++`` file header). A line present in any revision
|
||||
appears as an added line in some commit's diff, so the union equals "all
|
||||
lines ever present".
|
||||
|
||||
Returns an empty set when git is unavailable, the path is untracked, or the
|
||||
repository has no history — callers then fall back to the working file.
|
||||
"""
|
||||
proc = _run_git("log", "--all", "-p", "--", path)
|
||||
if proc is None or proc.returncode != 0:
|
||||
return set()
|
||||
lines: set[str] = set()
|
||||
for raw in proc.stdout.splitlines():
|
||||
m = _ADDED_LINE_RE.match(raw)
|
||||
if not m:
|
||||
continue
|
||||
clean = _valid_line(m.group(1))
|
||||
if clean is not None:
|
||||
lines.add(clean)
|
||||
return lines
|
||||
|
||||
|
||||
def current_file_lines(path: str) -> set[str]:
|
||||
"""Return the validated lines currently in ``path`` (missing file -> {})."""
|
||||
try:
|
||||
with open(path, "r", encoding="utf-8") as f:
|
||||
return {clean for clean in (_valid_line(x) for x in f)
|
||||
if clean is not None}
|
||||
except OSError:
|
||||
return set()
|
||||
|
||||
|
||||
def cumulative_blocklist(v4_path: str, v6_path: str,
|
||||
desired_v4: Iterable[str],
|
||||
desired_v6: Iterable[str],
|
||||
) -> tuple[set[str], set[str]]:
|
||||
"""Complete set of all blocked targets (history | working file | desired).
|
||||
|
||||
Returns ``(complete_v4, complete_v6)`` of canonical CIDR strings.
|
||||
"""
|
||||
complete_v4 = (
|
||||
committed_lines(v4_path)
|
||||
| current_file_lines(v4_path)
|
||||
| {c for c in (_valid_line(x) for x in desired_v4) if c is not None})
|
||||
complete_v6 = (
|
||||
committed_lines(v6_path)
|
||||
| current_file_lines(v6_path)
|
||||
| {c for c in (_valid_line(x) for x in desired_v6) if c is not None})
|
||||
return complete_v4, complete_v6
|
||||
|
||||
|
||||
def compute_changes(current_v4: set[str], current_v6: set[str],
|
||||
complete_v4: set[str], complete_v6: set[str],
|
||||
whitelisted_v4: set[str], whitelisted_v6: set[str],
|
||||
) -> dict[str, Any]:
|
||||
"""Compute the add/remove diff for a cumulative (grow-only) blocklist.
|
||||
|
||||
Entries are added when present in the complete set but not yet on the
|
||||
router and not whitelisted. Entries are removed only when they sit on the
|
||||
router but are absent from the complete set — i.e. they were never blocked
|
||||
by the system (manual/rogue entries). Callers may attach extra keys (e.g.
|
||||
``dry_run``).
|
||||
"""
|
||||
return {
|
||||
"added_ipv4": sorted(complete_v4 - current_v4 - whitelisted_v4),
|
||||
"added_ipv6": sorted(complete_v6 - current_v6 - whitelisted_v6),
|
||||
"removed_ipv4": sorted(current_v4 - complete_v4),
|
||||
"removed_ipv6": sorted(current_v6 - complete_v6),
|
||||
}
|
||||
|
||||
|
||||
def blocklist_delta(history_v4: set[str], history_v6: set[str],
|
||||
prev_v4: set[str], prev_v6: set[str],
|
||||
complete_v4: set[str], complete_v6: set[str],
|
||||
) -> dict[str, list[str]]:
|
||||
"""Complete-set delta between the previous and current blocklist state.
|
||||
|
||||
``added`` are entries newly part of the blocklist (this run's targets not
|
||||
blocked before); ``removed`` are entries no longer part of it — normally
|
||||
empty in the cumulative model.
|
||||
"""
|
||||
before_v4 = history_v4 | prev_v4
|
||||
before_v6 = history_v6 | prev_v6
|
||||
return {
|
||||
"added_ipv4": sorted(complete_v4 - before_v4),
|
||||
"added_ipv6": sorted(complete_v6 - before_v6),
|
||||
"removed_ipv4": sorted(before_v4 - complete_v4),
|
||||
"removed_ipv6": sorted(before_v6 - complete_v6),
|
||||
}
|
||||
|
||||
|
||||
def write_blocklist_report(report_dir: str,
|
||||
*,
|
||||
history_v4: set[str], history_v6: set[str],
|
||||
prev_v4: set[str], prev_v6: set[str],
|
||||
complete_v4: set[str], complete_v6: set[str],
|
||||
firewall_changes: dict | None = None,
|
||||
dry_run: bool = False,
|
||||
errors: Iterable[str] = (),
|
||||
) -> str:
|
||||
"""Write the timestamped blocklist report to ``<report_dir>/app/``.
|
||||
|
||||
Records the complete-set delta (added/removed) plus the full cumulative
|
||||
blocked list (git history | working files | scan targets), and — when
|
||||
supplied — the router sync changes. Returns the written file path.
|
||||
"""
|
||||
delta = blocklist_delta(
|
||||
history_v4, history_v6, prev_v4, prev_v6, complete_v4, complete_v6)
|
||||
payload = {
|
||||
"generated_at": datetime.now().astimezone().isoformat(
|
||||
timespec="seconds"),
|
||||
"report_dir": report_dir,
|
||||
"dry_run": dry_run,
|
||||
"summary": {
|
||||
"added": len(delta["added_ipv4"]) + len(delta["added_ipv6"]),
|
||||
"removed": len(delta["removed_ipv4"]) + len(delta["removed_ipv6"]),
|
||||
"total_blocked": len(complete_v4) + len(complete_v6),
|
||||
},
|
||||
"added_ipv4": delta["added_ipv4"],
|
||||
"added_ipv6": delta["added_ipv6"],
|
||||
"removed_ipv4": delta["removed_ipv4"],
|
||||
"removed_ipv6": delta["removed_ipv6"],
|
||||
"blocked_ipv4": sorted(complete_v4),
|
||||
"blocked_ipv6": sorted(complete_v6),
|
||||
"firewall_changes": firewall_changes,
|
||||
"errors": list(errors),
|
||||
}
|
||||
app_dir = os.path.join(report_dir, "app")
|
||||
os.makedirs(app_dir, exist_ok=True)
|
||||
path = os.path.join(app_dir, f"{timestamp_name()}.json")
|
||||
write_json(path, payload)
|
||||
return path
|
||||
#!/usr/bin/env python3
|
||||
"""Git-backed cumulative blocklist history.
|
||||
|
||||
The consolidated blocklist lives in git-tracked files
|
||||
(``reports/app/data/blocklist_ipv4.txt`` / ``blocklist_ipv6.txt``). To make the
|
||||
MikroTik blocklist grow-only, the "complete set of all blocked IPs" is
|
||||
reconstructed from **every git revision** of those files (the union of all
|
||||
lines ever present), plus the current working files and the latest scan
|
||||
targets.
|
||||
|
||||
This keeps IPs blocked even after they leave the NPM ~30-day log window, and
|
||||
only ever removes router entries that were never blocked by the system.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import ipaddress
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
from datetime import datetime
|
||||
from typing import Any, Iterable
|
||||
|
||||
from .files import write_json
|
||||
from .reporting import timestamp_name
|
||||
|
||||
#: A ``+ 1.2.3.4/32`` added line in a git patch; ``+++ b/...`` is the file
|
||||
#: header and is excluded by the negative lookahead.
|
||||
_ADDED_LINE_RE = re.compile(r"^\+(?!\+)(.*)$")
|
||||
|
||||
|
||||
def _run_git(*args: str) -> subprocess.CompletedProcess[str] | None:
|
||||
"""Run a git command, returning None on any failure (never raises)."""
|
||||
try:
|
||||
return subprocess.run(
|
||||
["git", *args], capture_output=True, text=True, check=False)
|
||||
except (OSError, subprocess.SubprocessError):
|
||||
return None
|
||||
|
||||
|
||||
def _valid_line(line: str) -> str | None:
|
||||
"""Normalize a blocklist line to a canonical CIDR string, or None."""
|
||||
line = line.strip()
|
||||
if not line:
|
||||
return None
|
||||
try:
|
||||
return str(ipaddress.ip_network(line, strict=False))
|
||||
except ValueError:
|
||||
return None
|
||||
|
||||
|
||||
def committed_lines(path: str) -> set[str]:
|
||||
"""Return the union of all lines ever present in ``path`` across git.
|
||||
|
||||
Uses a single ``git log --all -p -- <path>`` and collects the ``+`` added
|
||||
lines (excluding the ``+++`` file header). A line present in any revision
|
||||
appears as an added line in some commit's diff, so the union equals "all
|
||||
lines ever present".
|
||||
|
||||
Returns an empty set when git is unavailable, the path is untracked, or the
|
||||
repository has no history — callers then fall back to the working file.
|
||||
"""
|
||||
proc = _run_git("log", "--all", "-p", "--", path)
|
||||
if proc is None or proc.returncode != 0:
|
||||
return set()
|
||||
lines: set[str] = set()
|
||||
for raw in proc.stdout.splitlines():
|
||||
m = _ADDED_LINE_RE.match(raw)
|
||||
if not m:
|
||||
continue
|
||||
clean = _valid_line(m.group(1))
|
||||
if clean is not None:
|
||||
lines.add(clean)
|
||||
return lines
|
||||
|
||||
|
||||
def current_file_lines(path: str) -> set[str]:
|
||||
"""Return the validated lines currently in ``path`` (missing file -> {})."""
|
||||
try:
|
||||
with open(path, "r", encoding="utf-8") as f:
|
||||
return {clean for clean in (_valid_line(x) for x in f)
|
||||
if clean is not None}
|
||||
except OSError:
|
||||
return set()
|
||||
|
||||
|
||||
def cumulative_blocklist(v4_path: str, v6_path: str,
|
||||
desired_v4: Iterable[str],
|
||||
desired_v6: Iterable[str],
|
||||
) -> tuple[set[str], set[str]]:
|
||||
"""Complete set of all blocked targets (history | working file | desired).
|
||||
|
||||
Returns ``(complete_v4, complete_v6)`` of canonical CIDR strings.
|
||||
"""
|
||||
complete_v4 = (
|
||||
committed_lines(v4_path)
|
||||
| current_file_lines(v4_path)
|
||||
| {c for c in (_valid_line(x) for x in desired_v4) if c is not None})
|
||||
complete_v6 = (
|
||||
committed_lines(v6_path)
|
||||
| current_file_lines(v6_path)
|
||||
| {c for c in (_valid_line(x) for x in desired_v6) if c is not None})
|
||||
return complete_v4, complete_v6
|
||||
|
||||
|
||||
def compute_changes(current_v4: set[str], current_v6: set[str],
|
||||
complete_v4: set[str], complete_v6: set[str],
|
||||
whitelisted_v4: set[str], whitelisted_v6: set[str],
|
||||
) -> dict[str, Any]:
|
||||
"""Compute the add/remove diff for a cumulative (grow-only) blocklist.
|
||||
|
||||
Entries are added when present in the complete set but not yet on the
|
||||
router and not whitelisted. Entries are removed only when they sit on the
|
||||
router but are absent from the complete set — i.e. they were never blocked
|
||||
by the system (manual/rogue entries). Callers may attach extra keys (e.g.
|
||||
``dry_run``).
|
||||
"""
|
||||
return {
|
||||
"added_ipv4": sorted(complete_v4 - current_v4 - whitelisted_v4),
|
||||
"added_ipv6": sorted(complete_v6 - current_v6 - whitelisted_v6),
|
||||
"removed_ipv4": sorted(current_v4 - complete_v4),
|
||||
"removed_ipv6": sorted(current_v6 - complete_v6),
|
||||
}
|
||||
|
||||
|
||||
def blocklist_delta(history_v4: set[str], history_v6: set[str],
|
||||
prev_v4: set[str], prev_v6: set[str],
|
||||
complete_v4: set[str], complete_v6: set[str],
|
||||
) -> dict[str, list[str]]:
|
||||
"""Complete-set delta between the previous and current blocklist state.
|
||||
|
||||
``added`` are entries newly part of the blocklist (this run's targets not
|
||||
blocked before); ``removed`` are entries no longer part of it — normally
|
||||
empty in the cumulative model.
|
||||
"""
|
||||
before_v4 = history_v4 | prev_v4
|
||||
before_v6 = history_v6 | prev_v6
|
||||
return {
|
||||
"added_ipv4": sorted(complete_v4 - before_v4),
|
||||
"added_ipv6": sorted(complete_v6 - before_v6),
|
||||
"removed_ipv4": sorted(before_v4 - complete_v4),
|
||||
"removed_ipv6": sorted(before_v6 - complete_v6),
|
||||
}
|
||||
|
||||
|
||||
def write_blocklist_report(report_dir: str,
|
||||
*,
|
||||
history_v4: set[str], history_v6: set[str],
|
||||
prev_v4: set[str], prev_v6: set[str],
|
||||
complete_v4: set[str], complete_v6: set[str],
|
||||
firewall_changes: dict | None = None,
|
||||
dry_run: bool = False,
|
||||
errors: Iterable[str] = (),
|
||||
) -> str:
|
||||
"""Write the timestamped blocklist report to ``<report_dir>/app/``.
|
||||
|
||||
Records the complete-set delta (added/removed) plus the full cumulative
|
||||
blocked list (git history | working files | scan targets), and — when
|
||||
supplied — the router sync changes. Returns the written file path.
|
||||
"""
|
||||
delta = blocklist_delta(
|
||||
history_v4, history_v6, prev_v4, prev_v6, complete_v4, complete_v6)
|
||||
payload = {
|
||||
"generated_at": datetime.now().astimezone().isoformat(
|
||||
timespec="seconds"),
|
||||
"report_dir": report_dir,
|
||||
"dry_run": dry_run,
|
||||
"summary": {
|
||||
"added": len(delta["added_ipv4"]) + len(delta["added_ipv6"]),
|
||||
"removed": len(delta["removed_ipv4"]) + len(delta["removed_ipv6"]),
|
||||
"total_blocked": len(complete_v4) + len(complete_v6),
|
||||
},
|
||||
"added_ipv4": delta["added_ipv4"],
|
||||
"added_ipv6": delta["added_ipv6"],
|
||||
"removed_ipv4": delta["removed_ipv4"],
|
||||
"removed_ipv6": delta["removed_ipv6"],
|
||||
"blocked_ipv4": sorted(complete_v4),
|
||||
"blocked_ipv6": sorted(complete_v6),
|
||||
"firewall_changes": firewall_changes,
|
||||
"errors": list(errors),
|
||||
}
|
||||
app_dir = os.path.join(report_dir, "app")
|
||||
os.makedirs(app_dir, exist_ok=True)
|
||||
path = os.path.join(app_dir, f"{timestamp_name()}.json")
|
||||
write_json(path, payload)
|
||||
return path
|
||||
Loaded 100 of 113 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user