Files
links/routermon/tasks.py
T
junvandCopilot 430ca18b41 routermon: add WAN incoming traffic monitoring
- Add WanEvent model (src_ip, protocol, dst_port, src_port, geo fields)
  with migration 0003_wanevent

- Extend parser to handle kernel:/iptables WAN_IN: syslog lines
  - Generalise _RE_SYSLOG to accept 'kernel' process name (no pid)
  - Parse KEY=value tokens from iptables log (robust vs monolithic regex)
  - Reject private source IPs silently

- Receiver: bulk-create WanEvent rows in _flush(); replace per-flush
  geo threads with a single bounded geo-enrichment worker (_geo_queue,
  max 500) to safely handle high-volume port scans

- Tasks: batch-delete WanEvent rows (<=3 day retention cap); batch-delete
  DnsQuery rows to avoid long SQLite locks

- Views: WanLivePartialView (filterable HTMX table), WanChartDataView
  (timeline JSON); dashboard context adds wan_total_24h,
  top_attacked_ports_json, top_wan_sources

- Templates:
  - _live_wan.html: live event table with color-coded protocol,
    clickable IP/port filters, well-known port labels
  - dashboard.html: WAN section with 24h counter, timeline chart,
    top attacked ports bar chart, top source IPs table, live event stream
  - settings.html: Step 5 guide for /jffs/scripts/firewall-start with
    rate-limited iptables LOG rules (INPUT + FORWARD chains, 60/min limit)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-16 15:34:39 +10:00

48 lines
1.8 KiB
Python

"""APScheduler periodic tasks for routermon."""
import logging
logger = logging.getLogger(__name__)
_BATCH = 500 # rows per delete batch to avoid long locks
def cleanup_old_queries():
"""Delete DnsQuery and WanEvent rows older than retention_days. Run periodically."""
try:
from datetime import timedelta
from django.utils import timezone
from .models import RouterMonSettings, DnsQuery, WanEvent
settings = RouterMonSettings.get()
if settings.retention_days <= 0:
return
cutoff = timezone.now() - timedelta(days=settings.retention_days)
# Batch-delete DnsQuery rows
total_dns = 0
while True:
ids = list(DnsQuery.objects.filter(timestamp__lt=cutoff).values_list('pk', flat=True)[:_BATCH])
if not ids:
break
deleted, _ = DnsQuery.objects.filter(pk__in=ids).delete()
total_dns += deleted
# WAN events accumulate fast under port scans — use shorter retention (3 days max)
wan_retention = min(settings.retention_days, 3)
wan_cutoff = timezone.now() - timedelta(days=wan_retention)
total_wan = 0
while True:
ids = list(WanEvent.objects.filter(timestamp__lt=wan_cutoff).values_list('pk', flat=True)[:_BATCH])
if not ids:
break
deleted, _ = WanEvent.objects.filter(pk__in=ids).delete()
total_wan += deleted
if total_dns:
logger.info('routermon: pruned %d old DNS query records (>%d days)', total_dns, settings.retention_days)
if total_wan:
logger.info('routermon: pruned %d old WAN event records (>%d days)', total_wan, wan_retention)
except Exception as exc:
logger.error('routermon: cleanup_old_queries error: %s', exc, exc_info=True)