FreeBSD/pfSense kein Port-Scan — Python-Agent (pfsense_agent.py) hat keinen vm.port_scan-Handler #34

Closed
opened 2026-06-01 22:13:31 +00:00 by chinux · 1 comment
Owner

Symptom

FreeBSD/pfSense-VMs liefern keinen Port-Scan über den Agent.

Root Cause

pfSense/FreeBSD fährt den Python-Agent VM-Guest-Agent/pfsense_agent.py (registriert über /vm-pfsense-agent). Dessen Command-Handler (Z. 390-401) kennt nur vm.update, vm.update_preview, vm.self_updatekein vm.port_scan (und kein sockstat). theProx sendet bei #16 vm.port_scan → fällt in den else-Zweig → „Unbekannte Action: vm.port_scan" → kein Scan.

(Der Rust-VM-Guest-Agent hätte es: gemeinsame main.rs-vm.port_scan-Arm + collect/freebsd.rs::collect_ports via sockstat. Aber pfSense nutzt den Python-Agent.)

Fix (pfsense_agent.py)

vm.port_scan-Handler ergänzen, der sockstat -l parst und exakt die #16-/freebsd.rs-Shape liefert.

Collector (1:1 zu collect/freebsd.rs::collect_ports):

def collect_ports():
    out = run("sockstat -l -4 -6")  # best effort
    ports = []
    for line in out.splitlines()[1:]:          # Header überspringen
        cols = line.split()
        if len(cols) < 6:
            continue
        proto_raw = cols[4]
        if   proto_raw.startswith("tcp"): protocol = "tcp"
        elif proto_raw.startswith("udp"): protocol = "udp"
        else: continue
        local = cols[5]
        idx = local.rfind(":")
        if idx < 0: continue
        addr_raw, port_raw = local[:idx], local[idx+1:]
        try: port = int(port_raw)
        except ValueError: continue
        address  = "0.0.0.0" if addr_raw == "*" else addr_raw
        process  = cols[1]
        exposure = "local" if address in ("127.0.0.1", "::1") else "public"
        ports.append({"protocol": protocol, "port": port, "address": address,
                      "process": process, "exposure": exposure, "state": "open"})
    ports.sort(key=lambda p: (p["protocol"], p["port"]))
    return ports

Handler (im Command-Loop, vor dem else):

elif action == "vm.port_scan":
    ports = collect_ports()
    safe_send({"type": "command_result", "id": cmd_id, "status": "ok",
               "data": {"scanner": "sockstat", "ports": ports}})

Backend-Ingest unverändert (#16) — gleiche {scanner, ports}-Shape.

Akzeptanz

  • pfSense/FreeBSD-VM beantwortet vm.port_scan mit lauschenden TCP+UDP-Ports inkl. Prozess/Exposure.
  • Port-UI zeigt FreeBSD-Ports identisch zu Linux.
  • (v4/v6-Duplikate aus -4 -6 werden durch den Backend-Dedup aus #35 zentral kollabiert.)

Bezug

Schließt die FreeBSD-Lücke von #16; Shape identisch zu #16/#27.

Branch

feat/pfsense-agent-portscan

## Symptom FreeBSD/pfSense-VMs liefern keinen Port-Scan über den Agent. ## Root Cause pfSense/FreeBSD fährt den **Python-Agent** `VM-Guest-Agent/pfsense_agent.py` (registriert über `/vm-pfsense-agent`). Dessen Command-Handler (Z. 390-401) kennt nur `vm.update`, `vm.update_preview`, `vm.self_update` — **kein `vm.port_scan`** (und kein `sockstat`). theProx sendet bei #16 `vm.port_scan` → fällt in den `else`-Zweig → „Unbekannte Action: vm.port_scan" → kein Scan. (Der Rust-VM-Guest-Agent hätte es: gemeinsame `main.rs`-`vm.port_scan`-Arm + `collect/freebsd.rs::collect_ports` via `sockstat`. Aber pfSense nutzt den Python-Agent.) ## Fix (`pfsense_agent.py`) `vm.port_scan`-Handler ergänzen, der `sockstat -l` parst und **exakt** die #16-/`freebsd.rs`-Shape liefert. Collector (1:1 zu `collect/freebsd.rs::collect_ports`): ```python def collect_ports(): out = run("sockstat -l -4 -6") # best effort ports = [] for line in out.splitlines()[1:]: # Header überspringen cols = line.split() if len(cols) < 6: continue proto_raw = cols[4] if proto_raw.startswith("tcp"): protocol = "tcp" elif proto_raw.startswith("udp"): protocol = "udp" else: continue local = cols[5] idx = local.rfind(":") if idx < 0: continue addr_raw, port_raw = local[:idx], local[idx+1:] try: port = int(port_raw) except ValueError: continue address = "0.0.0.0" if addr_raw == "*" else addr_raw process = cols[1] exposure = "local" if address in ("127.0.0.1", "::1") else "public" ports.append({"protocol": protocol, "port": port, "address": address, "process": process, "exposure": exposure, "state": "open"}) ports.sort(key=lambda p: (p["protocol"], p["port"])) return ports ``` Handler (im Command-Loop, vor dem `else`): ```python elif action == "vm.port_scan": ports = collect_ports() safe_send({"type": "command_result", "id": cmd_id, "status": "ok", "data": {"scanner": "sockstat", "ports": ports}}) ``` Backend-Ingest unverändert (#16) — gleiche `{scanner, ports}`-Shape. ## Akzeptanz - pfSense/FreeBSD-VM beantwortet `vm.port_scan` mit lauschenden TCP+UDP-Ports inkl. Prozess/Exposure. - Port-UI zeigt FreeBSD-Ports identisch zu Linux. - (v4/v6-Duplikate aus `-4 -6` werden durch den Backend-Dedup aus #35 zentral kollabiert.) ## Bezug Schließt die FreeBSD-Lücke von #16; Shape identisch zu #16/#27. ## Branch `feat/pfsense-agent-portscan`
chinux changed title from FreeBSD hat kein Port Scan über Agent to FreeBSD/pfSense kein Port-Scan — Python-Agent (pfsense_agent.py) hat keinen vm.port_scan-Handler 2026-06-01 22:26:43 +00:00
Author
Owner

Second Claude succeed

Verifiziert: VM-Guest-Agent/pfsense_agent.py:427 elif action == "vm.port_scan" → liefert {scanner: "sockstat", ports} aus sockstat -l -4 -6 (:249). FreeBSD-Pfad in collect/freebsd.rs.

**Second Claude succeed** ✅ Verifiziert: `VM-Guest-Agent/pfsense_agent.py:427` `elif action == "vm.port_scan"` → liefert `{scanner: "sockstat", ports}` aus `sockstat -l -4 -6` (:249). FreeBSD-Pfad in `collect/freebsd.rs`.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
chinux/theProx#34
No description provided.