RoamSwitch Server Edition-Bedienungsanleitung
Offizielle Installations-, Bereitstellungs- und Betriebsreferenz für Cloud VPS (AWS, GCP, Azure, Linode, DigitalOcean), Bare-Metal-Rechenzentren und Container-Hosts.
1. Übersicht und Anforderungen
RoamSwitch Server Edition ist eine headless (keine GUI-Abhängigkeiten) autonome Verteidigungs- und Integritätsüberwachungssuite, die für Linux-Server entwickelt wurde, die dem öffentlichen Internet ausgesetzt sind.
Im Gegensatz zur Client-Edition, die Profile basierend auf dem Wi-Fi-Status dynamisch wechselt, erzwingt die Server-Edition Inbound Default Drop, Critical Path File Integrity Monitoring (FIM), präventive Kernel-LPE-Abwehr (Frag Gap), eBPF-Laufzeit-Bedrohungserkennung, SSH-Sperrschutz und automatisierte Mehrkanal-Notfallwarnungen (Telegram/LINE/Webhook).
cve_kernel_map_updates_enabled, standardmäßig an). Abgerufen werden die Kernel-CVE-Daten, die Web-Regeln und, auf Ubuntu-Servern, die Ubuntu-Paket-CVE-Daten für den CVE-Abgleich der OS-Pakete. roamswitch-updater empfängt per HTTPS-GET von lafine.net Daten mit Ed25519-Signatur (das signierte Manifest wird täglich geprüft, die CVE-Daten selbst etwa alle 30 Tage, die Web-Regeln nur bei einer neueren Manifest-Version), ohne Query-String und Cookies, mit einem festen User-Agent: RoamSwitch-Updater als einzigem Header, der die Software nennt, und sendet nichts über diesen Host. Er lässt sich mit roamswitch server config set cve_kernel_map_updates_enabled false (oder dem Einrichtungsassistenten bzw. der Server-TUI) abschalten, und das Audit läuft dann weiter mit der eingebauten Baseline; der CVE-Abgleich der OS-Pakete auf einem Ubuntu-Server meldet dann jedoch „keine lokalen CVE-Daten“. Jeder weitere Datenverkehr, der den Host verlässt, beschränkt sich auf Folgendes, das der Betreiber ausdrücklich aktiviert hat: Benachrichtigungen (Telegram / LINE / Webhook), die Überprüfung von npm-Signaturen (npm_audit_signatures_enabled, nur wenn der Befehl ausgeführt wird) und die Ereignisweiterleitung (forward_enabled, standardmäßig aus; §16). Die Ereignisweiterleitung geht nur an Ziele, die Sie selbst benennen (ein SIEM, syslog, ein Webhook); TLS-syslog wird über das System-openssl gesendet und der strukturierte Webhook über einen curl-Subprozess. Darüber hinaus verbinden sich das Sensor-Pairing (sensor_pairing_enabled, standardmäßig aus) und die LLM-Anbindung des mitgelieferten separaten Werkzeugs accessscope (standardmäßig aus; in der Befehlszeile nur, wenn --llm angegeben wird) nur dann nach außen, wenn der Betreiber sie aktiviert. Die Liste der Ausnahmen steht im Abschnitt Zero Telemetry des Sicherheits-Whitepapers zur Server Edition.Systemanforderungen
- Unterstützte Distributionen: Ubuntu 22.04 / 24.04 LTS, Debian 12+, AlmaLinux / Rocky Linux / RHEL 9+, Fedora 39+, openSUSE Leap 15.5+, Raspberry Pi OS (64-Bit)
- Architectures:
x86_64(amd64) oderaarch64(arm64) - Kernel: Linux 5.10+ (
nftables,cgroups v2, eBPF BTF empfohlen) - Footprint: 20–30 MB residenter Speicher, <0,1 % CPU bei Leerlauf/normaler Arbeitslast
2. Installationsverfahren
Die Verwendung der offiziell signierten Repositorys gewährleistet eine automatische Abhängigkeitsauflösung und nahtlose Aktualisierungen über Ihren Standard-Systempaketmanager.
2.1 APT (Ubuntu/Debian/Raspberry Pi OS)
# 1. Repository-Signaturschlüssel registrieren
curl -fsSL https://lafine.net/apt/roamswitch-archive-keyring.asc \
| sudo gpg --dearmor -o /usr/share/keyrings/roamswitch-archive-keyring.gpg
# 2. Repository hinzufügen
echo "deb [arch=amd64,arm64 signed-by=/usr/share/keyrings/roamswitch-archive-keyring.gpg] https://lafine.net/apt stable main" \
| sudo tee /etc/apt/sources.list.d/roamswitch.list
# 3. Installieren
sudo apt update && sudo apt install roamswitch-server
2.2 DNF/RPM (Fedora/RHEL/AlmaLinux/Rocky Linux)
# 1. GPG-Schlüssel importieren
sudo rpm --import https://lafine.net/rpm/RPM-GPG-KEY-roamswitch
# 2. Repository-Konfigurationsdatei hinzufügen
sudo curl -fsSL -o /etc/yum.repos.d/roamswitch.repo https://lafine.net/rpm/fedora/roamswitch.repo
# 3. Installieren
sudo dnf install roamswitch-server
2.3 openSUSE (zypper)
sudo rpm --import https://lafine.net/rpm/RPM-GPG-KEY-roamswitch
sudo zypper addrepo https://lafine.net/rpm/opensuse/roamswitch.repo
sudo zypper refresh && sudo zypper install roamswitch-server
roamswitch) und die Server Edition (roamswitch-server) deklarieren gegenseitige Paketkonflikte. Wählen Sie in Headless-Serverumgebungen immer roamswitch-server aus.3. Ersteinrichtung und Serviceüberprüfung
3.1 Servicestatus
Nach der Installation startet roamswitch-server.service sofort und wird beim Systemstart aktiviert.
sudo systemctl status roamswitch-server.service
3.2 Interaktiver Setup-Assistent
Starten Sie mit dem folgenden Befehl den interaktiven Einrichtungsassistenten, um Ports, Wartungs-Quell-IPs, Benachrichtigungskanäle und die Eindämmungsaktion interaktiv zu konfigurieren (Enter übernimmt jeweils den Standardwert).
sudo roamswitch server setup
- Ports: Geben Sie die SSH-Wartungsports (Standard
22) und die öffentlichen Dienstports (Standard80,443) jeweils durch Kommas getrennt ein. - Wartungs-Quell-IPs: IPs oder CIDRs eines SSH-Bastion-Hosts bzw. der Überwachung (z. B.
203.0.113.50/32). Der Assistent verlangt eine Angabe und nimmt keine leere Eingabe an. Um SSH von jeder Quelle zuzulassen, geben SieANYWHEREein (dann bleibt der SSH-Verwaltungszugang auch während der Isolation für die ganze Welt offen). - Benachrichtigungskanäle: Aktivieren Sie jeweils Telegram-Bot, LINE Messaging API und/oder einen generischen Webhook (Slack / Discord / Teams).
- Reaktion auf ein kritisches eBPF-Ereignis: Wählen Sie
isolate(Host isolieren),freeze(Prozess einfrieren) oderalert_only(nur benachrichtigen). Nach dem Speichern werden Sie aufgefordert, eine Testbenachrichtigung zu senden und den Dienst neu zu starten. - Automatische Updates der CVE-Daten (Standard
y): Wählen Sie, ob die vom Container-Isolations-Audit verwendete Kernel-CVE-Datenbank, die Web-Regeln und, auf Ubuntu-Servern, die Ubuntu-Paket-CVE-Daten für den CVE-Abgleich der OS-Pakete anonym von lafine.net abgerufen werden sollen (das signierte Manifest wird täglich geprüft, die CVE-Daten selbst etwa alle 30 Tage und die Web-Regeln nur bei einer neueren Manifest-Version; nur HTTPS-GET, kein Query-String, keine Cookies, als einziger Header, der die Software nennt, ein festerUser-Agent: RoamSwitch-Updater, Ed25519-Signatur wird geprüft). Über diesen Host wird nichts gesendet. Es ist die einzige standardmäßig aktive externe Kommunikation der Server Edition; mitnwird sie abgeschaltet (das Audit läuft weiterhin gegen die eingebettete Baseline, der CVE-Abgleich der OS-Pakete auf einem Ubuntu-Server meldet dann aber „keine lokalen CVE-Daten“). Ist sie in einer bestehendenserver.confbereits deaktiviert, bleibt auch die Standardantwortn. - File-Scan-Guard-Einstellungen: legen Sie fest, ob die Virenprüfung für Mail-Relays, freigegebene Ordner und Upload-Ziele (§13) aktiviert werden soll, und legen Sie die Zielverzeichnisse fest. Optional, standardmäßig deaktiviert.
- Resource-Guard-Einstellungen: aktivieren Sie die Ressourcenerschöpfungs-Erkennung, die anhaltendes RSS-Wachstum (Speicherlecks/DoS) oder Absturzschleifen in netzwerkexponierten Diensten erkennt.
- Übersicht der dauerhaft aktiven Kernschutzfunktionen: zeigt die Kernabwehrmechanismen an, die unabhängig vom Assistenten stets aktiv sind — eingehendes Default-Drop, FIM, eBPF-Integration usw. (keine Eingabe erforderlich).
- Einstellungen für die Übergabe an einen Untersuchungsagenten (investigation): legen Sie fest, ob die Erstuntersuchung — bei kritischen eBPF-Ereignissen oder bei Erkennung von Manipulationen an Critical-Path-FIM/Abhängigkeits-Lockfiles, sofern jeweils nur eine Benachrichtigung ausgelöst wurde — automatisch an eine externe KI-Agenten-CLI (Claude Code / agy / Codex CLI / OpenCode oder einen benutzerdefinierten Befehl) delegiert werden soll (§10.1). Standardmäßig deaktiviert.
-100 beginnt (z. B. -1001234567890). Den korrekten Wert finden Sie im Feld "chat":{"id":...} der Antwort von curl -s "https://api.telegram.org/bot<token>/getUpdates".3.3 34-Punkte-Server-Sicherheitsaudit
sudo roamswitch status --server
Führt eine sofortige 34-Prüfung der Firewall-Regeln, der Frag Gap-Abschwächung, der Yama LSM-Einschränkungen, Berechtigungen und der Docker-Port-Offenlegung durch und ergibt eine Sicherheitsbewertung und -note von 0–100 (S bis C).
Jeder Prüfpunkt wird nun zusätzlich für Compliance-Berichte mit einer NIST-CSF-2.0-Funktion/-Kategorie (immer vorhanden, wenn zutreffend) und, nur bei einer belastbaren Zuordnung, einer CIS-Controls-v8-Kontrollnummer versehen.
4. Firewall- und Portregeln
Die Konfigurationsdatei /etc/roamswitch/server.conf unterliegt aus Gründen des Schutzes vertraulicher Informationen zwingend den Berechtigungen 0600 (nur root kann lesen/schreiben). Das Format ist flaches key=value; Abschnittsüberschriften wie [network] werden ignoriert.
# --- Firewall ---
ssh_ports=22 # SSH-Verwaltungsport (bleibt auch bei Notfall-Isolation erhalten)
allowed_ports=80,443 # Öffentliche Dienstports
whitelist_ips=203.0.113.10/32 # Wartungs-Quell-IP / CIDR (leer = alle erlaubt, früher admin_source_ips)
protect_docker_ports=true # DOCKER-USER-Schutz (verhindert, dass Container die Firewall umgehen)
preserve_ssh_on_isolation=true # SSH-Verwaltungspfad auch bei Notfall-Isolation erhalten (false = vollständige Sperre)
# --- eBPF-Laufzeitschutz ---
action_on_critical=isolate # isolate | freeze (SIGSTOP+Netzwerksperre) | alert_only
ebpf_socket_path=/run/roamswitch/events.sock
# --- Egress-/C2-Blockierung & DNS-Sinkhole ---
egress_ip_blocklist_enabled=true # Standard true. Das mitgelieferte Seed enthält nur die drei von JPCERT/CC veröffentlichten Angriffsserver; sonst wird nichts blockiert, bis ein Feed installiert ist
metadata_watch_enabled=true # Standard true. Meldet, wenn ein Nicht-root-Programm/Container Cloud-Metadaten kontaktiert (nur Protokoll, keine Blockierung; erkennt SSRF)
metadata_watch_allow_users= # Konten, die den Metadatendienst legitim nutzen (Namen oder numerische IDs, kommagetrennt; root ist immer ausgenommen)
dns_sinkhole_enabled=false # Standard false (um internes DNS/Split-Horizon-Setups nicht zu stören)
dns_sinkhole_provider=quad9 # quad9 | cloudflare | adguard | cleanbrowsing
# --- Container-Isolations-CVE-Daten (standardmäßig aktiv) ---
cve_kernel_map_updates_enabled=true # Standard true. Die einzige standardmäßig aktive externe Kommunikation (signierte Kernel-CVE-Daten, Web-Regeln und, auf Ubuntu-Servern, Ubuntu-Paket-CVE-Daten; Manifest täglich, CVE-Daten etwa alle 30 Tage; anonym, nur Empfang, signaturgeprüft). Mit false wird sie abgeschaltet
# --- Benachrichtigungen ---
telegram_enabled=false
telegram_bot_token=
telegram_chat_id=
line_enabled=false
webhook_enabled=false
webhook_url=
webhook_block_private_addresses=false # opt-in SSRF guard
webhook_allow_addresses=
# --- System ---
language=ja
fim_check_interval_secs=300 # Früher scan_interval genannt
isolation_hard_cap_secs=3600 # Sekunden, bevor eine Isolation mit hoher Konfidenz in den DEGRADED-Modus übergeht (0 = halten, bis sie aufgehoben wird)
Wenn Sie die Konfiguration direkt bearbeitet haben, starten Sie den Dienst neu, damit die Änderungen wirksam werden (roamswitch-server unterstützt kein Reload):
sudo roamswitch server restart
4.1 Richtlinien nach Schweregrad (guard.yaml, optional)
Wenn action_on_critical allein nicht granular genug ist, erstellen Sie /etc/roamswitch/guard.yaml (eine Vorlage liegt unter /etc/roamswitch/guard.yaml.example bei). Ist die Datei nicht vorhanden, wird automatisch eine gleichwertige Richtlinie aus dem action_on_critical-Wert von server.conf synthetisiert, sodass bestehende Installationen unverändert funktionieren.
policies:
on_warning:
action: log_and_notify
on_critical:
server_action: isolate_process
kill_process: true
fallback_to_host_isolation_after_retries: 3 # Eskaliert automatisch zur Host-Isolation, wenn derselbe Prozess erneut auftritt
on_emergency:
action: isolate_host_all
kill_process: true
server_safeguards:
maintenance_ssh_ports: [22]
safety_timer_secs: 300 # Sekunden, bis eine Isolation mit geringer Konfidenz automatisch aufgehoben wird (0 deaktiviert). Gilt nicht für Isolationen mit hoher Konfidenz (siehe unten)
Automatische Aufhebung einer Isolation (nach Konfidenz): Eine Aufhebung allein nach einem festen Timer lässt einen geduldigen Angreifer einfach abwarten, daher wird der Auslöser jeder Isolation nach Konfidenz klassifiziert. (1) Geringe Konfidenz (eBPF Error / Warning und darunter, generische Portanomalien): wird nach einem kurzen Timer vollständig wiederhergestellt (safety_timer_secs, standardmäßig 300 s). (2) Hohe Konfidenz (Manipulation von Canaries, ransomwareartiges Massen-Umschreiben, eBPF Critical / Emergency / Alert, wiederholte Eskalation derselben Regel): wird nie stillschweigend wiederhergestellt. Nach dem kurzen Timer wird die Ursache weiter geprüft, und die Isolation wird nur dann mit einer Benachrichtigung aufgehoben, wenn die Ursache verifiziert beseitigt ist. Lässt sich das nicht bestätigen, hat niemand quittiert und ist die harte Obergrenze erreicht (isolation_hard_cap_secs in server.conf, standardmäßig 3600 s, 0 = keine Obergrenze), geht sie in den DEGRADED-Modus über. (3) Der DEGRADED-Modus blockiert weiterhin neuen Datenverkehr außer den Verwaltungspfaden (den SSH-Wartungsports und den Whitelist-IPs) und öffnet sich nie per Timer. Er wird nur durch eine verifiziert erfolgreiche erneute Prüfung, eine ausdrückliche Quittierung (eine Quittierung im DEGRADED-Modus bedeutet Aufhebung) oder sudo roamswitch emergency-restore aufgehoben. Bei jeder Isolation werden bestehende Verbindungen außer den Verwaltungspfaden (ein C2-Kanal oder eine Reverse Shell, die der Angreifer bereits geöffnet hat) gekappt. Jeder Übergang wird in der Vorfalls-Zeitachse festgehalten und in 10 Sprachen benachrichtigt.
sudo roamswitch server ack
roamswitch server ack quittiert eine FULL-Isolation und hält sie dabei strikt aufrecht (der Betreiber hat die Verantwortung übernommen, daher kein Übergang in DEGRADED und keine automatische Aufhebung) und hebt eine DEGRADED-Isolation auf.
4.2 Egress-/C2-Blockierung und DNS-Sinkhole
Mit egress_ip_blocklist_enabled=true (Standard) werden ausgehende Verbindungen zu bekannten bösartigen IPs per nftables blockiert. Als Feed dient /var/lib/roamswitch/threatfeed/malicious_ips.txt (vom Update-Mechanismus verwaltet), sofern vorhanden, sonst das mit dem Paket gelieferte Seed (/usr/share/roamswitch/threatfeed/); es wird eines von beiden verwendet, sie werden nicht zusammengeführt. Das Seed enthält nur die drei Angriffsserver-Adressen, die JPCERT/CC in seinem Bericht vom 15.10.2026 zu Angriffen auf Webdienste und APIs veröffentlicht hat (210.149.87.120, 118.26.36.16, 69.10.51.162). Adressen gemieteter Server können neu vergeben werden; funktioniert ein legitimes Ziel nicht mehr, prüfen Sie die entsprechende Zeile in dieser Datei.
Wird dns_sinkhole_enabled=true gesetzt, erzwingt dies die Auflösung über einen filternden DNS-Resolver (Quad9 / Cloudflare / AdGuard / CleanBrowsing) und blockiert die Auflösung bekannt bösartiger Domains. Der Standardwert ist false, da dies internes DNS oder Split-Horizon-Setups beeinträchtigen kann.
Ist metadata_watch_enabled an (Standard), schreibt die nftables-Tabelle inet roamswitch_metadata_watch nur dann eine Kernel-Logzeile, wenn ein Nicht-root-Programm oder ein Container neu eine Verbindung zu einer Cloud-Metadaten-Adresse (169.254.169.254, 169.254.170.2, 100.100.100.200, fd00:ec2::254) aufbaut; der Server-Daemon meldet das einmal täglich je Konto (bei Containern je Quelladresse). Es wird nur protokolliert und gemeldet, nie blockiert. Übergibt ein Angreifer der Anwendung eine URL auf seinem eigenen Server, die per 302 auf eine interne Adresse weiterleitet, steht im Zugriffsprotokoll nur die externe URL; nur dieser ausgehende Verkehr zeigt den zweiten Schritt. Eine Anwendung, die ihre Cloud-Rolle legitim nutzt, wird ebenfalls gemeldet; tragen Sie ihr Konto in metadata_watch_allow_users ein, um sie auszunehmen (ein Container kann nicht ausgenommen werden).
4.3 Eingangsportscan-Erkennung
Erkennt Quell-IPs, die in kurzer Zeit viele verschiedene Ports kontaktiert haben, durch Abgleich von nftables-Log-Regeln mit journald (standardmäßig aktiviert). Scan-Quellen mit hoher Konfidenz können für eine festgelegte Dauer automatisch blockiert werden. Bei gemeinsamer Nutzung mit RoamSwitch Sensor (eine andere Funktion als §10.1 — Voll-Port-Prüfungs-Probes eines gepaarten Sensors werden zur Fehlalarmvermeidung ausgeschlossen) wird die eigene IP des Sensors automatisch ausgeschlossen.
# --- Eingangsportscan-Erkennung (standardmäßig aktiviert) ---
port_scan_detect_enabled=true # false zum Deaktivieren
port_scan_detect_min_distinct_ports=15 # Wird als Scan gewertet, wenn Verbindungen mindestens so viele verschiedene Ports erreichen
port_scan_detect_window_secs=300 # Aggregationsfenster für die Erkennung (Sekunden)
port_scan_block_enabled=true # Blockiert die erkannte Scan-Quell-IP automatisch
port_scan_block_duration_secs=600 # Dauer der automatischen Blockierung (Sekunden)
Den Erkennungsverlauf können Sie mit dem Befehl roamswitch port-scan einsehen.
4.4 DNS-Tunneling-Erkennung
Prüft ausschließlich den vom Host selbst ausgehenden DNS-Verkehr (UDP/TCP-Port 53) über einen dedizierten NFQUEUE-Consumer. Eine Anfrage gilt als verdächtig geformt, wenn die Label-Länge 40 Byte UND die Shannon-Entropie 3,8 überschreitet, oder wenn der Abfragetyp TXT/NULL ist; ein Alarm wird ausgelöst, sobald innerhalb der letzten 60 Sekunden 10 oder mehr solcher Anfragen auftreten (eine Abklingzeit von 300 Sekunden verhindert wiederholte Alarme unter denselben Bedingungen). Ziel ist die Erkennung der Abfragemuster, die für DNS-Tunneling-/Exfiltrationswerkzeuge wie iodine und dnscat2 typisch sind. Die zugrunde liegende nftables-Regel trägt dasselbe bypass-Flag wie die anderen DNS-bezogenen Schutzfunktionen dieses Daemons, sodass die DNS-Namensauflösung niemals beeinträchtigt wird, selbst wenn dieser Schutz gestoppt ist oder nicht reagiert. Diese Funktion dient ausschließlich der Benachrichtigung — sie blockiert niemals automatisch. Wie bei jeder anderen Einstellung wird eine Änderung von dns_tunnel_detect_enabled erst nach einem Dienst-Neustart wirksam.
# --- DNS-Tunneling-Erkennung (standardmäßig aktiviert) ---
dns_tunnel_detect_enabled=true # false zum Deaktivieren
4.5 SSH-Brute-Force-Schutz
Der Schutz liest fehlgeschlagene sshd-Anmeldungen in dem Moment, in dem sie ins Log geschrieben werden, und zählt sie je Quelladresse (standardmäßig aktiv). Bei einer Quelle, die die eingestellte Zahl an Fehlversuchen erreicht (Standard: 6 innerhalb von 600 Sekunden), verwirft die nftables-Tabelle inet roamswitch_sshguard ausschließlich neue Verbindungen zu den SSH-Ports. Die erste Sperre dauert 1 Stunde, vervierfacht sich bei jedem erneuten Auftreten derselben Quelle und ist auf 7 Tage begrenzt. Zugleich mit der Sperre werden auch die Verbindungen getrennt, die diese Quelle bereits zu SSH offen hatte (die conntrack-Einträge werden gelöscht und eine Regel verwirft die Pakete der Antwortrichtung). Gesperrt wird nur eine Quelle ohne authentifizierte Sitzung, ohne protokollierte Anmeldung per öffentlichem Schlüssel und ohne Ausnahme; das wird unmittelbar vor dem Trennen noch einmal geprüft. Eine authentifizierte Sitzung und eine ausgenommene Quelle werden daher nie getrennt. Es wird nichts nach außen gesendet; lokal laufen nur journalctl, nft, loginctl und ähnliche Befehle.
Das Log wird mit journalctl -f mitgelesen. journald hält fest, welcher Prozess eine Zeile geschrieben hat; Zeilen, die nicht von sshd stammen, werden ignoriert. Ohne journald folgt der Schutz /var/log/auth.log oder /var/log/secure; in diesen Dateien kann aber jeder lokale Benutzer, der syslog verwenden darf, Zeilen fälschen und so eine unbeteiligte Quelle sperren lassen. Wo journald vorhanden ist, belassen Sie ssh_guard_log_source beim Standard auto. Gezählt werden fehlgeschlagene Passwörter, unbekannte Benutzer, Verbindungsabbrüche vor der Authentifizierung nach genanntem Benutzernamen, überschrittene Versuchszahlen und PAM-Authentifizierungsfehler. Fehlgeschlagene öffentliche Schlüssel (Failed publickey) werden nicht gezählt, weil ein legitimer Client mit mehreren Schlüsseln sie bei jeder Anmeldung erzeugt. Die Quelladresse wird vom Zeilenende gelesen (from <IP> port <N>). Ein Angreifer kann beliebigen Text als Benutzernamen verwenden, doch eine dort eingetragene gefälschte Quelladresse führt nicht dazu, dass eine unbeteiligte Quelle gesperrt wird. IPv6 wird je /64 gezählt und auch je /64 gesperrt (liegt in diesem /64 eine Adresse, die erreichbar bleiben muss, etwa das Gateway, wird nur die einzelne Quelladresse gesperrt).
Nie gesperrt werden das Gateway, DNS-Resolver, der Server selbst, Loopback, whitelist_ips, ssh_guard_allow, die Quelle einer offenen, bereits authentifizierten SSH-Sitzung, jede Adresse, die sich in den letzten 30 Tagen (ssh_guard_trust_key_days) per öffentlichem Schlüssel angemeldet hat (eine erfolgreiche Passwortanmeldung zählt nicht), und ein gekoppelter Sensor. Häufen sich bei einer dieser Quellen Fehlversuche, wird nur protokolliert. Private Adressen sind nicht ausgenommen, denn auch ein kompromittiertes Gerät im eigenen Netz kann Ausgangspunkt eines Brute-Force-Angriffs sein. Eine Quelle, die lediglich vor der Authentifizierung eine Verbindung offen hält, ist ebenfalls nicht ausgenommen.
Wenn fail2ban (mit aktivem sshd-Jail) oder CrowdSec (mit laufendem Firewall-Bouncer) sshd bereits schützt, überlässt der Schutz das Sperren den beiden, damit dieselbe Adresse nicht doppelt gesperrt wird, und erkennt und meldet nur (ssh_guard_yield_to_fail2ban, standardmäßig true). Auch bei ssh_guard_block_enabled=false wird nur erkannt und gemeldet. Gemeldet wird bei einer Sperre (im reinen Erkennungsmodus beim Erreichen der Schwelle) und wenn eine Anmeldung von einer Quelle gelingt, die zuvor Fehlversuche angehäuft hatte (kritisch: Ein Brute-Force-Angriff könnte erfolgreich gewesen sein; die Sitzung wird nicht getrennt). Nicht jeder einzelne Fehlversuch wird gemeldet, und Quellen über 10 pro Stunde werden in einer Meldung zusammengefasst.
Die Sperrliste zeigt roamswitch server bans (mit --json; die Liste kann nur root lesen, also mit sudo), aufgehoben wird mit sudo roamswitch server unban <IP | IPv6-/64 | --all>; dabei wird auch der Fehlerzähler dieser Quelle gelöscht. Sperren werden nach einem Neustart des Servers mit ihrer Restzeit wiederhergestellt. roamswitch emergency-restore hebt SSH-Sperren nicht auf (dass das Netzwerk wiederhergestellt wird, ist kein Grund, jemanden wieder hereinzulassen, der Passwörter geraten hat); das Wiederherstellungsmenü (roamswitch recover) und die Deinstallation entfernen die ganze Tabelle. Das MCP-Tool get_ssh_guard_incidents ist schreibgeschützt, ein Tool zum Aufheben von Sperren gibt es nicht. In der Server-TUI zeigt der Abschnitt „SSH-Brute-Force“ im Vorfallsbildschirm die Sperren an und hebt sie auf (bei Start als root; §17).
roamswitch server bans
sudo roamswitch server unban 203.0.113.9
sudo roamswitch server unban --all
Es gibt 10 Einstellungen, alle beginnen mit ssh_guard_ (§18.1). Geändert wird zum Beispiel mit sudo roamswitch server config set ssh_guard_max_failures 10, übernommen mit sudo roamswitch server restart. Mit ssh_guard_enabled=false wird der Schutz ganz abgeschaltet, mit ssh_guard_block_enabled=false erkennt und meldet er nur noch. Der Punkt „SSH-Brute-Force-Schutz“ der 34 Diagnosepunkte wird auch bestanden, solange dieser Schutz läuft und sperrt.
Grenzen: Versuche, die nur mit öffentlichen Schlüsseln scheitern, werden nicht gezählt. Ein auf viele Quelladressen verteilter Brute-Force-Angriff wird je Quelle gezählt und daher erst gestoppt, wenn eine einzelne Quelle die Schwelle erreicht. Die grundlegende Abhilfe ist, die Passwortauthentifizierung zu deaktivieren und nur öffentliche Schlüssel zuzulassen.
5. Ausfallsichere SSH-Sperrverhinderung
Eine versehentliche Sperrung aufgrund einer Fehlkonfiguration der Firewall ist eine untragbare Betriebskatastrophe. RoamSwitch Server Edition umfasst mehrstufige Schutzmaßnahmen:
- ESTABLISHED / RELATED Unconditional Pass: Aktive Sitzungen werden während des Neuladens der Regel nie gelöscht.
- SSH bleibt bei Air-Gap-Isolation erhalten: Selbst wenn eine Anomalie eine Notfall-Isolation auslöst, hält
preserve_ssh_on_isolation = trueneuen und bestehenden Datenverkehr nur auf den Verwaltungspfaden aufrecht – den SSH-Wartungsports und den Quell-IPs der Administratoren (whitelist_ips) –, sodass Sie untersuchen und wiederherstellen können, ohne vor Ort zu sein. Jede andere bestehende Verbindung (C2, Datenabfluss oder eine Reverse Shell, die der Angreifer bereits geöffnet hat) wird gekappt. Ist keine Administrationsquelle angegeben (whitelist_ipsund die erlaubten Adressen in guard.yaml sind leer), nehmen die SSH-Wartungsports auch während der Isolation neue Verbindungen von jeder Quelle an; der Server gibt beim Start eine Warnung aus. Mitpreserve_ssh_on_isolation=falsekappt die Isolation auch SSH. Die Server-Edition bis 1.10.4 hatte einen Fehler. Der Isolationsregelsatz verwarf die SSH-Antworten, sodass das SSH des Betreibers während der Isolation nicht funktionierte. In 1.10.5 wurde er behoben. - Atomic nftables Loading with Rollback: Regelsyntaxfehler lösen sofort ein Rollback ohne Ausfallzeit auf den vorherigen verifizierten Regelsatz aus.
6. Containerschutz (Docker / Podman)
Das Standardverhalten von Docker erstellt benutzerdefinierte iptables-Regeln, die Standard-Host-Firewalls umgehen und Container-Ports (z. B. -p 8080:8080) direkt dem Internet zugänglich machen.
Mit protect_docker_ports=true (dem Standard) passt sich RoamSwitch an das Firewall-Backend von Docker an, sodass Datenverkehr zu Containern von außen ebenfalls unerreichbar ist, sofern er nicht einen in ssh_ports oder allowed_ports aufgeführten Port betrifft. Beim Backend iptables / iptables-nft fügt es oben in der Kette DOCKER-USER eine Prüfregel ein (für IPv4, und bei aktiviertem Docker-IPv6 zusätzlich über ip6tables). Beim nativen nftables-Backend von Docker (Docker 29 und neuer, wo DOCKER-USER nicht existiert) legt es im Forward-Hook vor den Ketten von Docker eine eigene Tabelle inet roamswitch_docker_guard an (eine inet-Tabelle deckt IPv4 und IPv6 ab). Die Entscheidung nutzt den ursprünglichen Zielport vor dem DNAT (ctorigdstport) und gilt nur für Datenverkehr, der an der externen Schnittstelle eintrifft; Container-Egress und Datenverkehr zwischen Containern bleiben unberührt. Es verhindert die versehentliche Exponierung von beispielsweise einem Entwicklungs-Datenbankcontainer.
Der Schutz ist idempotent und heilt sich jede Minute selbst: Startet dockerd nach RoamSwitch, überschreibt ein Docker-Neustart oder -Reload die Regeln, oder nach einem manuellen nft flush oder dem Verlust der nftables-Tabelle, wird er erneut angewendet, während ein bereits aktueller Schutz unangetastet bleibt.
Ein Echtzeitschutz, der docker events beobachtet, erkennt außerdem Container, die mit --privileged oder mit eingehängtem /var/run/docker.sock gestartet wurden (Risiko eines Container-Ausbruchs), unmittelbar nach dem Start und benachrichtigt Sie. Zusätzlich prüft der Container-Exec-Guard (container_exec_guard_enabled, standardmäßig an) in Containern ausgeführte Binärdateien mit YARA (eine Umgehung, die die Datei nach der Ausführung löscht, wird dennoch geprüft, da der Inhalt aus dem bereits geöffneten Dateideskriptor gelesen wird). Der Schutz markiert außerdem bereits laufende Container beim Start und folgt neuen Containern automatisch. Beide arbeiten nur benachrichtigend und blockieren nie automatisch. Beide funktionieren auch mit Docker 29 (seit 1.11.1). Schlägt das Abonnement der Ereignisse weiter fehl, wird der Abstand zwischen den Verbindungsversuchen von 5 Sekunden bis auf höchstens 5 Minuten verlängert.
7. Integritätsüberwachung kritischer Pfaddateien (FIM)
Mehr als 150 kritische Dateien – kritische Binärdateien wie /bin/login, /usr/bin/sudo und /usr/sbin/sshd, Authentifizierungskonfigurationen wie /etc/shadow und /etc/sudoers sowie systemd-Units – werden per SHA-256 überwacht.
Der Umfang ist nicht auf einzelne Dateien beschränkt. In kritischen Verzeichnissen (/etc/pam.d, /etc/sudoers.d, /etc/ssh/sshd_config.d, /etc/cron.*, /etc/systemd/system, /etc/ld.so.conf.d, /etc/profile.d und /root/.ssh (außer known_hosts)) wird auch das Auftauchen einer neuen Datei erkannt, und abgedeckt sind zudem die authorized_keys jedes Kontos, das sich anmelden kann, /etc/ld.so.preload (sie existiert normalerweise nicht; ihr Auftauchen ist ein Anzeichen eines lokalen Rootkits) sowie die eigenen Binärdateien von RoamSwitch. Temporäre Units, die snapd erzeugt (snap-*.mount und so weiter), sind ausgenommen. Die Erkennung neuer Dateien funktioniert nur gegen eine Baseline, die diesen Umfang einschließt; führen Sie daher nach einem Upgrade einmal sudo roamswitch fim update aus. Dateien, die fim verify ohne root nicht lesen kann, werden als „übersprungen, nicht lesbar“ gemeldet, nicht als Manipulation.
7.1 Manuelle Hash-Verifizierung
sudo roamswitch fim verify
7.2 Ereignisgesteuerte Erkennung (sofort)
Überwachte Dateien werden einzeln über fanotify (FAN_CLASS_NOTIF, Ereignisse bei abgeschlossenem Schreibvorgang) beobachtet, sodass eine Manipulation sofort erneut gehasht und erkannt wird, statt auf den nächsten periodischen Scan zu warten. Der periodische Scan (Standard fim_check_interval_secs=300 Sekunden) bleibt als Rückfallebene für eventuell verpasste Ereignisse bestehen. Auch Änderungen, die eine neue Datei unter demselben Namen ablegen (install, sed -i und Ähnliches), werden erkannt; die Benachrichtigung nennt den ändernden Prozess und dessen SSH-Anmeldung (§7.5).
7.3 Automatische Baseline-Synchronisierung bei Betriebssystem-Updates
Unter Debian/Ubuntu konfiguriert die Paketinstallation automatisch den DPkg::Post-Invoke-Hook unter /etc/apt/apt.conf.d/99roamswitch-fim. Unter Fedora/RHEL/Rocky/AlmaLinux/openSUSE übernimmt eine systemd.path-Einheit (roamswitch-fim-update.path), die /var/lib/rpm überwacht, dieselbe Rolle.
Unter Debian/Ubuntu hängt /etc/apt/apt.conf.d/99roamswitch-fim einen DPkg::Post-Invoke-Hook an. Legitime Paketaktualisierungen über sudo apt upgrade aktualisieren automatisch die FIM-Baseline und verhindern so falsch-positive Warnungen.
sudo roamswitch fim update
Wenn der Daemon zum ersten Mal startet und die Baseline anlegt und dabei ein Paketmanager (apt/dpkg, dnf/rpm, zypper oder pacman) arbeitet, wartet er bis zu 120 Sekunden auf dessen Ende, bevor er die Baseline anlegt. Auch bei der Installation im selben apt install wie Apache o. Ä. landen die temporären Dateien, an denen dpkg gerade arbeitet (etwa *.dpkg-new), nicht mehr in der Baseline und erscheinen bei der nächsten Prüfung nicht als Manipulation (ab 1.11.18). Ist der Paketmanager nach 120 Sekunden noch aktiv, wird eine Warnung protokolliert und die Baseline trotzdem angelegt.
7.4 Honeytokens (Credential-Köder)
Beim Start nutzt der Daemon seine Root-Rechte, um unter /root idempotent drei Köder-Anmeldedateien abzulegen: .aws/credentials, .ssh/id_rsa und .docker/config.json (zusammen Honeytokens genannt). Eine an diesen Pfaden bereits vorhandene echte Datei wird niemals überschrieben. Ein im Hintergrund laufender Watcher-Prozess erkennt per inotify jeden Lesezugriff auf diese Dateien und wertet ihn als Aufklärungsaktivität nach einer Kompromittierung (MITRE ATT&CK T1552: Unsecured Credentials), woraufhin sofort eine Benachrichtigung der Stufe Critical gesendet und ein Eintrag in der Incident-Timeline vorgenommen wird. Die Funktion ist standardmäßig an und lässt sich mit den Schlüsseln honeytokens_enabled (false stoppt Anlegen und Überwachen; bereits angelegte Köder bleiben) und honeytokens_home (Ort der Köder; Standard /root) ändern. Die Pakete bis 1.10.4 enthielten das für diese Funktion nötige roamswitch-honeytokens nicht, sodass sie bei Installationen aus den Paketen nicht lief. Seit 1.10.5 ist es enthalten, und das Problem, dass die systemd-Sandbox in der Server-Edition Schreibzugriffe auf /root blockierte, wurde in 1.10.10 behoben. Seit 1.11.1 wird jeder docker-Befehl, den RoamSwitch selbst ausführt, mit einem leeren, privaten Verzeichnis (als root /run/roamswitch/docker-config) als DOCKER_CONFIG gestartet und löst daher den Köder .docker/config.json nicht aus (zuvor konnten die Überwachung des Daemons und roamswitch status --server den Köder lesen und eine Fehlerkennung auslösen). Ein Lesezugriff durch ein anderes Programm wird weiterhin wie bisher erkannt.
Wird ein echter Zugriff auf ein Honeytoken erkannt, platziert RoamSwitch in Erwartung einer weiteren Erkundung durch den Angreifer bis zu zwei zusätzliche, thematisch verwandte Köder pro Auslöser (z. B. wird nach Zugriff auf .aws/credentials auch .aws/config abgelegt, nach Zugriff auf .ssh/id_rsa auch .ssh/config, nach Zugriff auf .docker/config.json auch .kube/config), insgesamt höchstens sechs über alle Auslöser hinweg. Wenn während einer Vorfalluntersuchung solche unbekannten Dateien unter /root zunehmen, ist das erwartetes Verhalten.
7.5 Einbruchsweg (wer die Änderung vorgenommen hat und über welche SSH-Anmeldung)
Die Benachrichtigungen über eine geänderte Datei (Critical-Path-FIM und Lockfile-FIM) enthalten jetzt den Prozess, der die Änderung vorgenommen hat (Konto, ausführbare Datei, Befehl), und die SSH-Anmeldung, zu der dieser Prozess gehört (Quell-IP und Port, Anmeldezeit, Authentifizierungsmethode und Fingerabdruck des öffentlichen Schlüssels). Das ist standardmäßig aktiv (fim_intrusion_context_enabled). Im Moment des Lesens eines Ereignisses legt der Daemon einen Schnappschuss von /proc/<pid> des schreibenden Prozesses an (ausführbare Datei, Benutzer, loginuid, sessionid, cgroup, Elternkette), denn ein Prozess wie tee oder sed ist eine Millisekunde später verschwunden. Ein bereits beendeter Prozess wird aus dem Ausführungsrekorder ergänzt (sofern aktiviert). Die Zuordnung zu einer Anmeldung nutzt zuerst die Sitzungstabelle des SSH-Schutzes und sonst die Accepted-Zeilen von logind und journald. Sie funktioniert auch bei deaktiviertem SSH-Schutz. Es wird nichts nach außen gesendet.
Vertraut wird nur dem, was der Kernel meldet: die ausführbare Datei aus /proc/<pid>/exe (nicht argv[0]), die Anmeldung aus loginuid (wird bei der Anmeldung einmal gesetzt und über sudo und su hinweg vererbt) und dem session-N.scope der cgroup, der Rest aus der Elternkette. Werte, die ein Prozess selbst ändern kann, etwa comm, die Befehlszeile und die Umgebung, werden nur angezeigt und nie für eine Entscheidung herangezogen; ein Prozess, der sich nur sshd nennt, gilt nicht als SSH-Anmeldung. Eine Benachrichtigung hält drei Antworten auseinander: gefunden (Quelle, Zeit, Methode, Schlüssel); „Es wurde keine SSH-Anmeldung gefunden“ (die Prüfung ergab einen systemd-Dienst, einen Container, eine lokale Anmeldesitzung oder einen Prozess ohne Anmeldesitzung); und „Der Anmeldeweg konnte nicht ermittelt werden“ (der Prozess war schon beendet und steht nicht im Ausführungsrekorder, logind hat nicht geantwortet, die Änderung stammt aus dem periodischen Scan und der Prozess ist unbekannt, und so weiter). Was nicht geprüft werden konnte, wird nie als „keine Anmeldung“ gemeldet. Die Benachrichtigung geht auch dann hinaus, wenn die Abfrage scheitert.
/etc/ssh/sshd_config: modified
Prozess: root (angemeldet als admin) / /usr/bin/tee / Befehl: tee /etc/ssh/sshd_config (pid 4121)
SSH-Anmeldung: die Sitzung, die admin um 2026-10-17 03:12:08 von 203.0.113.25:51544 aus geöffnet hat (Authentifizierung: publickey, Schlüssel SHA256:AbCdEf0123456789)
/etc/sudoers: modified
Der Anmeldeweg konnte nicht ermittelt werden (die Änderung wurde von der periodischen Prüfung gefunden, der ändernde Prozess ist unbekannt)
Auch Änderungen, die eine neue Datei unter demselben Namen ablegen, werden jetzt erkannt: install, sed -i sowie cp mit anschließendem mv im selben Verzeichnis. Eine Markierung je Datei hängt am Inode, weshalb diese Art von Änderung früher kein Ereignis auslöste. Jetzt werden auch die Verzeichnisse markiert, die überwachte Dateien enthalten, und wird im selben Verzeichnis eine Datei mit anderem Namen geschlossen, schlägt der Daemon den Namen wenige Millisekunden später erneut nach. Grenze: Eine in einem anderen Verzeichnis geschriebene und per mv hineinverschobene Datei findet erst der periodische Scan (fim_check_interval_secs). Dann ist der schreibende Prozess nicht bekannt, und die Benachrichtigung sagt das auch.
Neben der Benachrichtigung wird der Befund in der Vorfallszeitleiste (Typ fim) und in /var/lib/roamswitch/fim_intrusions.json (nur root, die letzten 100) festgehalten. Das MCP-Tool verify_fim liefert ihn in einem zusätzlichen Feld, recentIntrusionContext (nur bei Ausführung als root). Das Urteil darüber, ob eine Datei manipuliert wurde, ändert sich nicht. Grenzen: Bei deaktiviertem Ausführungsrekorder und einem nur einen Augenblick lebenden schreibenden Prozess ist die ausführbare Datei nicht bekannt; stattdessen werden die ausführbare Datei und die Befehlszeile des Elternprozesses angezeigt. Die Benachrichtigungen der Persistenzüberwachung (persistence_watch) enthalten keine Prozessangaben und erhalten daher keinen Einbruchsweg. Der Weg zeigt den ändernden Prozess und dessen Anmeldung, nicht mehr: der Zugang selbst (die ausgenutzte Schwachstelle oder die Art, wie ein Schlüssel gestohlen wurde) wird nicht gezeigt. Zum Abschalten fim_intrusion_context_enabled=false setzen.
8. eBPF Runtime Guard und Falco-Integration
Bindet sich in Kernel-Space-eBPF-Ereignisse (Falco/Tetragon) ein, um Frag Gap Kernel-Privilegieneskalation, Container-Escapes und nicht autorisierte Reverse-Shells zu erkennen.
8.1 Anti-Bloat-Architektur
Um das „syslog-Aufblähen“ und den Speicherdruck zu vermeiden, unter dem herkömmliche Sicherheitswerkzeuge leiden, verbindet sich RoamSwitch direkt über den UNIX-Domain-Socket /run/roamswitch/events.sock mit Falco. Der Socket wird nur für root zugänglich angelegt (0600), sodass nur als root laufendes Falco darauf schreiben kann (es ist keine zusätzliche Berechtigungseinrichtung nötig).
- Das gebündelte
/etc/falco/config.d/99-roamswitch-optimized.yamlstreamt Ereignisse ohne Festplatten-E/A direkt in den Daemon. Die Ausgabe von Falco wird in dieser Konfiguration mitsocatan den Socket übergeben; deshalb installieren die deb- und rpm-Pakete der Server Editionsocatals empfohlenes Paket (Recommends). Wer Falco nicht nutzt, braucht es nicht. /etc/logrotate.d/roamswitch-falcogewährleistet eine saubere tägliche Rotation für alle Fallback-Dateiausgaben.
8.2 Autonome Eindämmung
Beim Erkennen eines kritischen Angriffs gibt RoamSwitch sofort SIGSTOP aus, um die PID des störenden Prozesses einzufrieren, und wendet die nftables Air-Gap-Isolation an.
8.3 Automatische forensische Beweissicherung (Forensic Evidence Capture)
Ein Beweisbündel wird automatisch erstellt, sobald der eBPF-Runtime-Guard eine prozessbezogene Eindämmungsmaßnahme ausführt (Einfrieren per SIGSTOP plus Netzwerksperre). Nach der Standardrichtlinie in §4.1 folgen Ereignisse der Stufe Critical diesem Pfad; Ereignisse der Stufe Emergency, die den gesamten Host isolieren, erzeugen derzeit kein solches Bündel. Ein Bündel enthält eine nach bestem Bemühen begrenzte, rund 30-sekündige Paketaufzeichnung auf der Standard-Routing-Schnittstelle (wird stillschweigend übersprungen und entsprechend vermerkt, falls tshark nicht installiert ist) sowie, falls die betroffene PID bekannt ist, einen /proc/<pid>-Snapshot: status, cmdline, maps, environ (Werte, deren Name KEY/TOKEN/SECRET/PASSWORD enthält, werden durch [REDACTED] ersetzt), eine Liste der Linkziele offener Dateideskriptoren sowie die Kette der Vorgängerprozesse bis PID 1. Eine manifest.json mit dem SHA-256-Hash jeder erfassten Datei liegt bei und ermöglicht eine spätere Manipulationsprüfung.
Bündel werden unter /var/lib/roamswitch/incident-evidence/<Zeitstempel>-<ID>/ gespeichert. Sie werden niemals automatisch bereinigt. Um Speicherplatz freizugeben, entfernen Sie Bündel, die älter als die Aufbewahrungsfrist (standardmäßig 30 Tage) sind, gezielt mit:
sudo roamswitch-incident-capture prune [--keep-days N]
Sie können außerdem jederzeit manuell einen Snapshot erfassen, ohne auf eine Eindämmungsmaßnahme zu warten:
sudo roamswitch-incident-capture snapshot [--pid PID] [--reason TEXT] [--json]
8.4 Messung der Isolationsgeschwindigkeit und Heartbeat des Alarmwegs
Wie genau und wie schnell die eBPF-Isolation ist, hängt von den Regeln des Sensors (Falco oder Tetragon) ab. Tatsächlich enthalten die Standardregeln von Falco 0.45.0 (29 Stück) keine, die eine Reverse Shell auf dem Host erkennt: Die Regeln für Reverse Shells gelten nur für Container, und einige davon verwirft die Bedingung priority: warning von RoamSwitch. RoamSwitch setzt gute Regeln nicht voraus, sondern gleicht das auf drei Wegen aus: Es misst, wie lange die Isolation dauert, prüft regelmäßig, ob der Alarmweg lebt, und erkennt Reverse Shells auch selbst.
Messung der Isolationsverzögerung: Zu jedem eBPF-Vorfall hält der Daemon fest, wie viel Zeit von der Erkennung durch Falco bis zum Lesen des Alarms vergeht (detect_to_receive_ms), vom Lesen bis zum Abschluss der Reaktion (receive_to_action_ms, gemessen nach der Rückkehr des Isolationsaufrufs; beim Host-Air-Gap bis zum Laden des Regelsatzes) und die Summe (detect_to_action_ms). Die Werte erscheinen als zusätzliche Felder in ebpf_incidents.json und im MCP-Tool get_ebpf_incidents. Die Benachrichtigung über einen isolierten Prozess enthält eine Zeile „von der Erkennung bis zur Reaktion: N ms“. Gemessen auf einer Ubuntu-24.04-VM (Falco 0.45.0, modern eBPF): 1 bis 2 ms von der Erkennung bis zum Empfang, 41 bis 62 ms vom Empfang bis zu Prozessisolation plus SIGKILL (42 bis 64 ms insgesamt) und 109 ms insgesamt für das Host-Air-Gap (innerhalb des Ziels von 150 ms). Die Zahlen gehören zu dieser VM. Tetragon setzt den Zeitstempel beim Empfang, daher gibt es dort kein detect_to_receive_ms.
Heartbeat (ebpf_heartbeat_interval_secs; standardmäßig 600 Sekunden, 0 schaltet ihn ab, sonst 60 bis 86400): Das Paket bringt eine eigene Falco-Regel von RoamSwitch mit, 96-roamswitch-heartbeat.yaml. In jedem Intervall öffnet der Daemon einen Wegwerfpfad, den nur root nutzen kann (ein Zufallsname unter /run/roamswitch/heartbeat/), und misst, wie lange der Alarm dieser Regel braucht, um über die Ausgabe von Falco zurückzukommen. Ein Hin und Zurück zeigt zugleich, dass die Regel geladen ist, dass Falco läuft und dass der Ausgabeweg lebt. Nur wenn zwei Prüfungen in Folge nicht zurückkommen (die zweite eine Minute nach der ersten), warnt er („Die Regeln sind nicht geladen oder die Ausgabe kommt nicht an“), höchstens einmal in 24 Stunden. Eine Heartbeat-Zeile wird verworfen, ohne Isolation, Benachrichtigung, Allowlist oder Vorfallsprotokoll zu erreichen. Es wird nichts nach außen gesendet. Gemessen wurden 2 bis 6 ms für den Hin- und Rückweg; nach dem Entfernen der Regel kam die Warnung nach etwa 164 Sekunden, nach der Wiederherstellung war der Zustand nach etwa 75 Sekunden wieder normal.
Der Zustand liegt in /var/lib/roamswitch/ebpf_heartbeat.json und wird vom Feld heartbeat des MCP-Tools get_ebpf_incidents und von der Diagnose K-04 (eBPF-Laufzeit-Agent; die Zahl der Diagnosepunkte bleibt 34) gelesen. Auch wenn Falco läuft, fällt K-04 durch, wenn der Heartbeat nicht zurückkommt. Grenzen: Geprüft wird ein Hin und Zurück einer einzigen Regel (der Systemaufrufe der Familie open); dass eine andere Regel für sich kaputt ist, erkennt das nicht. Was zwischen zwei Prüfungen (standardmäßig 10 Minuten) kaputtgeht, fällt erst bei der nächsten auf. Für Tetragon wird es nicht durchgeführt. Auf einem Host, auf dem Falco nicht läuft oder die Regeldatei fehlt, wird nichts geprüft und vor nichts gewarnt (das übernimmt die bestehende Meldung „Schutz gestoppt“). Falco schreibt je Prüfung eine Warnzeile ins Syslog (standardmäßig 144 Zeilen am Tag).
8.5 Reverse-Shell-Erkennung (eigene von RoamSwitch)
Ohne sich auf die Regeln von Falco zu stützen, liest RoamSwitch selbst alle 2 Sekunden /proc und sucht nach einer Shell oder einem Interpreter (sh, bash, python, perl, ruby, php, node und ähnliche), deren Standardein- und -ausgabe an einer einzigen TCP-Verbindung hängen, die dieser Host zu einer externen Adresse aufgebaut hat. Erfasst werden bash -i >& /dev/tcp/…, python, perl, nc -e und socat exec:. Gemeldet wird nur, was zweimal hintereinander gesehen wird, einmal je Prozess. Standardmäßig zählen nur öffentliche externe Adressen; private Adressen (RFC 1918, CGNAT, Link-Local) zählen nur mit reverse_shell_watch_include_private=true, weil ssh-ProxyCommand, Container und lokale Entwicklung sie häufig und legitim machen. Loopback wird nie überwacht. Vom Host angenommene Verbindungen (durch inetd oder socat TCP-LISTEN) sind ebenfalls nicht erfasst. Gemessen auf einer Ubuntu-24.04-VM, wurden bash /dev/tcp, python, perl, nc -e und socat exec: jeweils etwa 2,4 Sekunden nach dem Verbindungsaufbau erkannt. ssh, ssh mit ProxyCommand, git über ssh und ein nc-Client werden nicht erkannt.
Ein Treffer läuft als Critical-eBPF-Ereignis mit dem Namen RoamSwitch Reverse Shell über denselben Weg wie ein Falco-Alarm (Allowlist, Benachrichtigungs-Abkühlzeit, die Aktionen je Schweregrad aus guard.yaml, Vorfallsprotokoll). Standardmäßig wird der Prozess isoliert und beendet (kill). Eine Reverse Shell, die root gehört, lässt sich nicht pro Prozess isolieren und geht daher, wie jedes Critical-Ereignis, bis zum Air-Gap des gesamten Hosts weiter. Wer fürchtet, dass ein legitimes Programm fälschlich erfasst wird, hat zwei Auswege: reverse_shell_watch_notify_only=true (eine Warnung nur mit Benachrichtigung; nichts wird isoliert oder beendet; standardmäßig false) und einen Allowlist-Eintrag, sudo roamswitch server allowlist add "RoamSwitch Reverse Shell" <Prozessname>. Die drei Einstellungsschlüssel sind reverse_shell_watch_enabled (standardmäßig true), reverse_shell_watch_include_private (false) und reverse_shell_watch_notify_only (false).
Grenzen: Es wird nach Namen (Prozessname und Name der ausführbaren Datei) eingegrenzt; ein selbstgebautes Programm unter einem anderen Namen als dem einer Shell oder eines Interpreters, das Standardein- und -ausgabe an einen Socket bindet, wird daher nicht gefunden. Verbindungen über Loopback (etwa die Rückführung von ssh -R) und Verbindungen unter 2 Sekunden werden nicht gesehen, ebenso wenig Prozesse, die im Prozessraum des Hosts nicht sichtbar sind. Diese Erkennung gibt es nur in der Server Edition; der Mac und der Linux-Client haben sie nicht.
9. Notfallwarnungen (Telegram / LINE / Webhook)
Sendet sofortige Warnungen an externe Benachrichtigungskanäle, wenn Portanomalien, FIM-Manipulationen oder eBPF-Eindämmungsereignisse auftreten:
[notifications]
language = ja
# Telegram: Bot-Token und Chat-ID
telegram_bot_token = "123456789:ABCdefGHIjklMNOpqrSTUvwxYZ"
telegram_chat_id = "-1001234567890"
# LINE: Messaging-API-Kanalzugriffstoken und Benutzer-ID
line_channel_access_token = "YOUR_LINE_ACCESS_TOKEN"
line_user_id = "U1234567890abcdef1234567890abcdef"
# Generischer Webhook (Slack, Discord, Teams, eigene Monitoring-Plattform)
webhook_url = "https://hooks.slack.com/services/T00/B00/XXXXX"
Auch ohne konfigurierte externe Kanäle wird jeder gesendete Alarm zusätzlich lokal für die letzten 7 Tage aufbewahrt. Prüfen Sie ihn mit roamswitch notifications.
Interne Webhook-Ziele ablehnen (Opt-in): Mit webhook_block_private_addresses=true (Standard false = unverändert) wird ein Benachrichtigungs-Webhook abgelehnt, wenn sein Ziel — bei einem Hostnamen schon eine einzige aufgelöste Adresse — Loopback, privat (10/8, 172.16/12, 192.168/16), Link-Local (169.254/16, einschließlich des Cloud-Metadaten-Endpunkts 169.254.169.254), ULA (fc00::/7) oder CGNAT (100.64/10) ist. Der Grund erscheint im Log und im Fehler von roamswitch notify-test. Andere Schreibweisen wie 2130706433 oder 0x7f.1 sowie IPv4-mapped IPv6 werden ebenfalls erkannt; die geprüften Adressen werden an curl gebunden, sodass DNS-Rebinding das Ziel nicht austauschen kann. Legitime interne Ziele wie ein hauseigenes SIEM erlauben Sie mit webhook_allow_addresses=10.20.0.0/16,fd00::/8 (kommagetrennte CIDRs). Webhooks der Ereignisweiterleitung haben dasselbe Paar: forward_webhook_block_private_addresses und forward_webhook_allow_addresses. Auch bei false wird eine Warnung geloggt, wenn das Ziel eine Cloud-Metadaten-Adresse ist (der Versand wird nicht gestoppt). Ist eine HTTP-Proxy-Umgebungsvariable gesetzt, erfolgen Auflösung und Verbindung am Proxy und liegen außerhalb dieser Prüfung.
10. KI-Agent / MCP-Integration (Modellkontextprotokoll)
Die RoamSwitch Server Edition enthält roamswitch-mcp und ermöglicht es KI-Agenten (Claude, Gemini, Cursor), den Zustand und die Lage der Infrastruktur zu überwachen.
Konfigurationsbeispiel („claude_desktop_config.json“)
{
"mcpServers": {
"roamswitch": {
"command": "/usr/bin/roamswitch-mcp",
"args": []
}
}
}
10.1 Übergabe an einen Untersuchungsagenten (investigation — Delegation der automatisierten Erstuntersuchung an einen KI-Agenten)
Während roamswitch-mcp aus §10 Abfragen des KI-Clients eines Menschen bedient, ist die investigation-Übergabe ein separater Mechanismus, bei dem der Daemon selbst, ausgelöst durch ein Erkennungsereignis, autonom eine externe KI-Agenten-CLI startet. Zielereignisse sind kritische eBPF-Ereignisse, die als reine Benachrichtigung eingestuft wurden (keine automatische Isolierung oder Prozesseinfrierung ausgelöst haben), sowie Manipulationserkennungen bei Critical-Path-FIM und Abhängigkeits-Lockfiles. Bei Aktivierung erstellt der Daemon zunächst einen lokalen, heuristikbasierten Erst-Triage-Bericht (Wahrscheinlichkeit eines Fehlalarms, Begründung, vorgeschlagene nächste Schritte) und startet dann die konfigurierte KI-Agenten-CLI als Subprozess mit diesem Bericht, um weitere Untersuchung und Zusammenfassung zu delegieren. Standardmäßig deaktiviert.
# An /etc/roamswitch/guard.yaml anhängen (eine von server.conf getrennte Datei)
investigation:
enabled: true
command: "claude" # "claude" | "agy" | "codex" | "opencode" | ein beliebiger benutzerdefinierter Befehl
args: ["-p"] # Der Prompt wird automatisch als letztes Argument angehängt
timeout_secs: 180
Dieselben Einstellungen können auch über den interaktiven Assistenten von sudo roamswitch server setup (§3.2, letzter Schritt) konfiguriert werden. Wählen Sie aus Voreinstellungen für Claude Code (claude -p), agy (agy -p --dangerously-skip-permissions), Codex CLI (codex exec), OpenCode (opencode run) oder einen benutzerdefinierten Befehl. Bei einer erneuten Ausführung wird die passende Voreinstellung anhand der gespeicherten Konfiguration automatisch ausgewählt.
run_as-Benutzer speichert der Assistent (CLI und TUI) nicht, und der Daemon startet sie nicht. Ein Werkzeug, das in einem Modus ohne Berechtigungsabfrage gestartet wird, etwa mit --dangerously-skip-permissions, erhöht das Risiko, dass böswillige Eingaben den Agenten zu unbeabsichtigten Aktionen bewegen. Der Assistent zeigt diesen Hinweis, wenn agy gewählt wird. Wo es nicht vertrauenswürdige Log-Eingabewege gibt, wird eine Werkzeugkonfiguration ohne Überspringen der Berechtigungsabfrage empfohlen.Die investigation-Übergabe wird niemals aufgerufen, während das Netzwerk getrennt ist (z. B. während eines aktiven Air-Gap oder eines Zustands, der isolate_host_all entspricht).
11. CLI-Befehls-Spickzettel
| Befehl | Privilegien | Beschreibung |
|---|---|---|
sudo roamswitch status --server |
root | Zeigt die 34-Punkte-Sicherheitsbewertung und den Status des Servers (--json gibt denselben Bericht als JSON aus) |
sudo roamswitch ports |
root | Überwachen Sie offene Überwachungsports und gebundene Prozesse |
sudo roamswitch fim verify |
root | Überprüfen Sie die SHA-256-Integrität kritischer Pfadsystemdateien |
roamswitch notifications |
Benutzer | Zeigt den Benachrichtigungsverlauf der letzten Woche (jeder gesendete Alarm); --json und --export FILE werden unterstützt |
sudo roamswitch server setup |
root | Starten Sie den interaktiven Erstkonfigurationsassistenten |
sudo roamswitch fim update |
root | Aktualisieren Sie die FIM SHA-256-Basisdatenbank |
sudo roamswitch server config set <key> <value> |
root | Ändert und speichert einen einzelnen Konfigurationsschlüssel (Liste siehe §18) |
sudo roamswitch emergency-restore |
Wurzel | Hebt die gesamte eBPF-/Firewall-Isolation auf und stellt die ursprüngliche Baseline wieder her |
roamswitch port-scan |
Benutzer | Zeigt den Erkennungsverlauf der Eingangsportscan-Erkennung (§4.3) (Quell-IP, ob automatisch blockiert und Blockierdauer) |
roamswitch sensor [key|list|pair|unpair|request-audit|results] |
Benutzer/root | Gegenseitiges Vertrauen mit einem RoamSwitch Sensor über Pairing-Codes. pair --addr <IP> --code <code> --fingerprint <SHA-256> koppelt (der Fingerprint ist der auf dem Sensor-Bildschirm angezeigte Wert), repin aktualisiert den Pin, nachdem der Sensor sein Zertifikat neu erzeugt hat, und request-audit fordert ein aktives Schwachstellenaudit an (das Ergebnis rufen Sie mit results ab). Erfordert sensor_pairing_enabled: true (standardmäßig aus). Details finden Sie im Sensor-Betriebshandbuch |
roamswitch server tui |
Benutzer/root | Startet die TUI, die jede Funktion abdeckt (für gewöhnliche Benutzer schreibgeschützt, als root volle Kontrolle; §17) |
sudo roamswitch server ack |
root | Quittiert die aktuelle Notfall-Isolation (hält eine FULL-Isolation strikt aufrecht, hebt eine DEGRADED-Isolation auf; §4.1) |
roamswitch server ebpf |
Benutzer | Zeigt den aktuellen Eindämmungsstatus des eBPF-Laufzeit-Guards und den Verlauf erkannter Vorfälle |
roamswitch server bans [--json] |
Benutzer/root | Zeigt den SSH-Brute-Force-Schutz (§4.5): seinen Zustand und die aktuell gesperrten Quellen mit Restzeit. --json ist verfügbar. Die Sperrliste kann nur root lesen |
sudo roamswitch server unban <IP | IPv6 /64 | --all> |
root | Hebt eine Sperre des SSH-Schutzes auf und löscht den Fehlerzähler dieser Quelle (IPv6 als /64 angeben; --all hebt alle Sperren auf) |
sudo roamswitch server allowlist [list|add <rule> <process> [--exe <path>]|remove <rule> <process>] |
root | Verwaltet die dauerhafte Allowlist für Fehlalarme. Mit --exe wird der Eintrag an den tatsächlichen Pfad der Programmdatei gebunden, sodass ein umbenannter Prozess ihn nicht nutzen kann (ein Eintrag nur nach Namen lässt sich fälschen, und es wird eine Warnung ausgegeben) |
roamswitch frozen [list|resume <PID>|resume all] |
Benutzer/root | Listet die Prozesse auf, die die Guards in SIGSTOP halten, und gibt einen frei, der ein Fehlalarm war (SIGCONT); resume all gibt alle frei |
sudo roamswitch events search|tree|export|verify|status |
root | Durchsucht den Exec-Recorder (--since 2h --pid --exe --user --parent --text --json), gibt einen Prozessbaum aus, exportiert, prüft die Hash-Kette und zeigt den Status (§15) |
sudo roamswitch forward status|test|queue |
root | Zeigt den Status der Ereignisweiterleitung, sendet ein Testereignis und listet die Wiederholungswarteschlange auf (§16) |
roamswitch timeline / notifications [--json] [--export FILE] |
Benutzer | Zeigt die vereinheitlichte Vorfalls-Zeitachse (experimentell) oder den Benachrichtigungsverlauf; --json gibt ein JSON-Array aus und --export FILE schreibt JSON Lines |
roamswitch audit-agent-setup [--json] |
Benutzer | Schreibgeschützte Prüfung der Anweisungsdateien, Skills und OpenClaw-Einstellungen für KI-Agenten auf riskante Inhalte (nur Home-Ordner, kein Netzwerk; --json gibt JSON aus). Auch im Server TUI unter „Tools“ verfügbar |
12. Fehlerbehebung und FAQ
Q1. Wird RoamSwitch meine SSH-Sitzung unerwartet trennen?
Nein. Im Normalbetrieb erlaubt RoamSwitch bedingungslos die Verbindungszustände established/related und ssh_ports (standardmäßig 22). Selbst wenn ein schwerer Angriff eine Air-Gap-Notfall-Isolation auslöst, hält preserve_ssh_on_isolation=true (der Standard) Verwaltungssitzungen auf den SSH-Wartungsports und Administrator-IPs aufrecht (jede andere bestehende Verbindung wird gekappt). Die Server-Edition bis 1.10.4 hatte einen Fehler. Der Isolationsregelsatz verwarf die SSH-Antworten, sodass das SSH des Betreibers während der Isolation nicht funktionierte. In 1.10.5 wurde er behoben.
Q2. Wie erhalte ich wieder Zugriff, wenn ich versehentlich ausgesperrt wurde?
Melden Sie sich über die Web-Verwaltungskonsole Ihres Cloud-Anbieters (VNC / serielle Konsole) an und führen Sie sudo roamswitch emergency-restore aus, um die Notisolation aufzuheben, oder sudo systemctl stop roamswitch-server, um den Dienst zu stoppen.
Q3. Wie mache ich Ports für neu hinzugefügte Webdienste (z. B. Nginx) verfügbar?
Führen Sie sudo roamswitch server config set allowed_ports 80,443,3000 aus (oder bearbeiten Sie /etc/roamswitch/server.conf direkt) und starten Sie anschließend sudo roamswitch server restart.
13. File Scan Guard (Schutz von Mail-Relays, Freigabeordnern und Upload-Endpunkten)
Eine optionale Funktion, die nur relevant ist, wenn dieser Host ein Verzeichnis besitzt, in dem Dateien für andere gespeichert werden – ein Mail-Relay, eine Samba/NFS-Freigabe, ein Datei-Upload-Endpunkt. Die integrierte YARA-Engine scannt clamav_scan_dirs stets ohne externe Abhängigkeit; mit clamav_enabled=true wird ClamAV als Zweitmeinung hinzugefügt. Bestätigte Bedrohungen werden automatisch nach /var/lib/roamswitch/quarantine verschoben, und der Betreiber wird benachrichtigt.
# --- File Scan Guard (ClamAV, Opt-in) ---
# Die integrierte YARA-Engine scannt clamav_scan_dirs stets bedingungslos.
clamav_enabled=false # true aktiviert die zusätzliche Prüfung über clamdscan
clamav_scan_dirs= # Absolute Pfade zum Scannen (kommagetrennt)
clamav_scan_interval_secs=86400 # Scan-Intervall (Sekunden, mindestens 3600)
clamav_freshclam_interval_secs=7200 # Automatisches Update-Intervall der Signaturdatenbank (Sekunden, mindestens 1800)
Auch über den interaktiven Assistenten sudo roamswitch server setup konfigurierbar; Konfiguration und Quarantänestatus lassen sich über das MCP-Tool get_file_scan_guard_status prüfen.
14. Log Audit (Erkennung und Benachrichtigung bei Protokollmuster-Anomalien)
Ein periodischer journalctl-Scan wandelt Protokollmeldungen in Vorlagen um, um neue Muster (bisher nicht gesehene Protokollformen) und Häufigkeitsanomalien (eine statistische Spitze, Z-Score > 3,0) zu erkennen. Da kein zusätzlicher Daemon oder externe Abhängigkeit nötig ist, handelt es sich um einen leichtgewichtigen Mechanismus, der standardmäßig aktiviert ist. Erkennungen werden über dieselben Benachrichtigungskanäle wie File Scan Guard und FIM gesendet (Telegram / LINE / Webhook). Etwaige API-Schlüssel oder Token, die in einer Protokollzeile auftauchen könnten, werden automatisch maskiert, bevor sie in die Benachrichtigung aufgenommen werden.
# --- Log Audit (standardmäßig aktiviert) ---
log_audit_enabled=true # false zum Deaktivieren
log_audit_interval_secs=1800 # Scan-Intervall in Sekunden (Minimum 300)
Kann auch über den interaktiven Assistenten sudo roamswitch server setup konfiguriert werden; die neuesten Erkennungsergebnisse lassen sich über den CLI-Befehl roamswitch audit-logs oder das MCP-Tool audit_security_logs abrufen.
AccessScope, ein Diagnosewerkzeug für Zugriffsprotokolle (eigenes Werkzeug): Das deb / rpm der Server Edition enthält den Befehl accessscope eines eigenen Werkzeugs, das Zugriffsprotokolle von Webservern und SSH diagnostiziert (die Fenster-App ist nicht enthalten). Es arbeitet nur lesend, und seine Analyse nutzt weder ein LLM noch das Netzwerk. Die Analyse durch ein LLM ist optional und standardmäßig aus (wenn aktiviert, läuft sie auch als root, doch das LLM läuft dann mit Root-Rechten; ein unprivilegierter Benutzer wird empfohlen). accessscope scan --auto diagnostiziert die Protokolle dieses Hosts, accessscope discover listet auf, wo die Protokolle liegen. Einzelheiten auf der AccessScope-Seite. Die deb / rpm der Server Edition enthalten außerdem die Befehle personalsoc und pathscope zweier weiterer eigenständiger Werkzeuge, PersonalSOC (prüft Protokolle und Schutzstatus dieses Hosts) und PathScope (analysiert Pfade zur Rechteausweitung); die Fenster-Apps sind nicht enthalten. Die Befehle selbst kommunizieren nicht über das Netzwerk. Die LLM-Analyse von PersonalSOC läuft nur, wenn Sie --llm angeben.
15. Exec-Recorder und Korrelationsregeln (lokal, nur benachrichtigend)
Prozessausführungen (exec) werden über den Netlink-Proc-Connector aufgezeichnet: Programmdatei, Argumente, Eltern-Abstammung, UID, cwd, Container-ID und SHA-256. Die Funktion ist standardmäßig aktiv, und die Aufzeichnungen liegen im nur für root zugänglichen Verzeichnis /var/lib/roamswitch/exec_log auf diesem Host als segmentierte, per Hash verkettete JSON Lines (0600, standardmäßig 200 MB / 14 Tage) und werden nirgendwohin gesendet. Das Protokoll ist manipulations-erkennbar (events verify), nicht manipulationssicher. Lässt sich der Proc-Connector nicht öffnen, fällt es auf einen /proc-Scan mit niedriger Rate zurück. Die Aufzeichnung läuft in eigenen Threads, getrennt von der fanotify-Permission-Event-Schleife, und hält ihre eigene CPU-Nutzung innerhalb eines Budgets (standardmäßig 3 %).
Lokal suchen und exportieren (das Protokoll ist nur für root zugänglich, daher ist normalerweise sudo erforderlich).
sudo roamswitch events status
sudo roamswitch events search --since 2h --exe curl
sudo roamswitch events tree 4242
sudo roamswitch events export --since 1d > exec-events.jsonl
sudo roamswitch events verify
Korrelationsregeln EXR-001 bis EXR-007 (nur benachrichtigend, jeweils mit einer MITRE-ATT&CK-Technik-ID): EXR-001 eine von einem Webdienst gestartete Shell / EXR-002 Ausführung aus /tmp, einer gelöschten Datei oder memfd / EXR-003 Ausführung unmittelbar nach einem Download / EXR-004 ein Interpreter-Einzeiler mit base64 oder eval / EXR-005 Erlangen von uid 0 ohne setuid / EXR-006 Ausführung einer Binärdatei, die gerade von cron oder systemd abgelegt wurde / EXR-007 Ausführung nach einer Änderung von ld.so.preload. Jede Regel hat einen bewusst ruhigen Standard und isoliert nie von selbst. Einzelne Regeln schalten Sie mit exec_rules_disabled stumm (zum Beispiel EXR-003,EXR-004), und die von EXR-001 überwachten Benutzer passen Sie mit exec_rule_service_users an.
Nur wenn Sie exec_rules_isolation_optin (Standard false) ausdrücklich auf true setzen, werden Regeln mit hohem Schweregrad als Auslöser einer Isolation mit hoher Konfidenz behandelt (§4.1). Standardmäßig benachrichtigen die Regeln nur. Die Aufzeichnungen lassen sich auch über die schreibgeschützten MCP-Tools search_exec_events und get_process_tree lesen.
16. Ereignisweiterleitung (SIEM / syslog / Webhook, Opt-in)
Erkennungsereignisse lassen sich an Ziele weiterleiten, die Sie in Ihrer eigenen Organisation festlegen. Die Funktion ist standardmäßig aus: Es wird nichts gesendet, bis Sie forward_enabled=true setzen und mindestens ein Ziel konfigurieren, und es ist kein Ziel des Herstellers eingebaut. Weitergeleitet werden die Vorfalls-Zeitachse, der Benachrichtigungsverlauf, der eBPF-Guard, Zustandsübergänge der Isolation sowie Alarme von FIM, Canary und Exec-Regeln; das rohe Exec-Protokoll selbst wird nicht weitergeleitet. Es gibt drei Arten von Zielen.
- syslog (
forward_syslog_url:udp://host:514/tcp://host:port/tls://host:port): RFC 5424 oder CEF (forward_syslog_format). Das TCP-/TLS-Framing istoctet(RFC 6587, der Standard) oderlf. Mitforward_tls_ca_filekönnen Sie für die TLS-Prüfung eine CA benennen, und die Verbindung wird an das System-openssl s_clientdelegiert. - JSON-Lines-Datei (
forward_file_path): ein Ereignis pro Zeile, rotiert nachforward_file_max_mb(standardmäßig 50) undforward_file_keep(standardmäßig 5). - Strukturierter Webhook (
forward_webhook_url): ein JSON-POST, signiert mit HMAC-SHA256 über ein gemeinsames Geheimnis (forward_webhook_secretoderforward_webhook_secret_file, das auf eine0600-Datei verweist), übertragen im HeaderX-RoamSwitch-Signature. Die Zustellung erfolgt über einencurl-Subprozess, und das Geheimnis wird nie auf die Kommandozeile gelegt.
Ereignisse, die nicht zugestellt werden konnten (TCP / TLS / Webhook), kommen in eine Wiederholungswarteschlange auf der Festplatte (0600, begrenzt durch forward_queue_max_mb, standardmäßig 20, und forward_queue_max_age_hours, standardmäßig 72) und werden mit exponentiellem Backoff erneut versucht, auch nach einem Neustart. forward_min_severity (Standard low) legt den niedrigsten Schweregrad fest, der gesendet wird. Die Zustellung läuft in einem eigenen Thread, sodass kein zeitkritischer Pfad blockiert wird, und bei einem Überlauf der Warteschlange werden die ältesten Einträge zuerst verworfen.
Prüfen Sie den Status, testen Sie die Konnektivität und untersuchen Sie die Wiederholungswarteschlange mit den folgenden Befehlen (starten Sie den Dienst nach dem Ändern der Einstellungen neu).
# /etc/roamswitch/server.conf
forward_enabled=true
forward_syslog_url=tls://siem.example.org:6514
forward_syslog_format=rfc5424
forward_tls_ca_file=/etc/ssl/certs/corp-ca.pem
forward_min_severity=medium
sudo roamswitch server restart
sudo roamswitch forward status
sudo roamswitch forward test
sudo roamswitch forward queue
17. Server-TUI (ein Terminal-UI für jede Funktion)
roamswitch-server-tui (wird auch von roamswitch server tui gestartet) ist eine TUI, die jede Funktion der Server Edition – verteilt auf die CLI-Verben und die beiden Konfigurationsdateien (server.conf und guard.yaml) – allein per Tastatur über SSH erreicht (sie funktioniert bei 80x24, in 10 Sprachen). Die Entwicklungstests schlagen fehl, sobald ein CLI-Verb oder Konfigurationsschlüssel kein Gegenstück in der TUI erhält.
- Berechtigungsmodus: Als gewöhnlicher Benutzer gestartet, ist sie schreibgeschützt (Änderungen und privilegierte Aktionen sind deaktiviert, und stattdessen wird der nötige Befehl
sudo roamswitch …angezeigt). Als root gestartet, kann sie handeln; folgenreiche Operationen zeigen zuvor, was sie tun werden, und die gefährlichsten verlangen die Eingabe vonyes. Sie startet nie den Daemon und öffnet keinen eigenen Netzwerk-Socket. - Bildschirme (mit den Zifferntasten wechseln):
1Dashboard (Zustand, Isolationsstatus) /2Schutz (eBPF-Isolation, Canary, FIM, Docker, Egress und DNS, Exec-Recorder, Regeln und Ereignissuche, Feeds, XDP-Gate) /3Vorfälle (alle Vorfallstypen einschließlich SSH-Brute-Force-Sperrliste und Aufhebung, Zeitachse, Benachrichtigungsverlauf, eingefrorene Prozesse, Quarantäne-Tresor, Allowlist) /4Benachrichtigungen und Weiterleitung /5Sensor /6Konfiguration /7Dienst /8Werkzeuge /9Protokoll-Audit /0Info und Hilfe.?zeigt die Tasten des aktuellen Bildschirms,Lwechselt zwischen den 10 Sprachen,rlädt neu undqbeendet (bei ungespeicherten Konfigurationsänderungen mit vorheriger Rückfrage). - Konfigurationseditor: Aus einem Schema erzeugt, bearbeitet er alle 146 Schlüssel von
server.confundguard.yaml(§18) mit Validierung von Typ, Bereich und zulässigen Werten. Vor dem Speichern prüfen Sie einen Diff (mit maskierten Geheimnissen), und das Speichern legt ein Backup mit Zeitstempel an und schreibt atomar. Schlüssel, die einen Neustart erfordern, und Schlüssel, bei denen ein falscher Wert Sie aussperren oder den Schutz schwächen kann, sind markiert. Auch die Einrichtung des Untersuchungs-Agents (§10.1) lässt sich nach Auswahl einer Voreinstellung und einer Vorschau schreiben.
Starten Sie sie mit:
sudo roamswitch-server-tui # full control
roamswitch-server-tui # read-only
roamswitch server tui # same as roamswitch-server-tui
18. Referenz der Konfigurationsschlüssel (server.conf / guard.yaml)
roamswitch-server unterstützt kein Neuladen der Konfiguration: Jeder Schlüssel erfordert einen Neustart des Dienstes, damit er wirksam wird (sudo roamswitch server restart). Ändern Sie Schlüssel in server.conf mit roamswitch server config set <key> <value> oder dem Editor in §17; guard.yaml ändern Sie mit dem Editor oder per Hand.
18.1 server.conf (109 Schlüssel)
| Schlüssel | Typ / Werte | Standard | Neustart |
|---|---|---|---|
language | system | ja | en | zh-hans | zh-hant | ko | de | fr | es | it | pt | ja | Ja |
ssh_ports | port list | 22 | Ja |
allowed_ports | port list | 80,443 | Ja |
whitelist_ips | list | — | Ja |
preserve_ssh_on_isolation | bool | true | Ja |
telegram_enabled | bool | false | Ja |
telegram_bot_token | string | — | Ja |
telegram_chat_id | string | — | Ja |
line_enabled | bool | false | Ja |
line_channel_access_token | string | — | Ja |
line_user_id | string | — | Ja |
webhook_enabled | bool | false | Ja |
webhook_url | URL | — | Ja |
webhook_block_private_addresses | bool | false | Ja |
webhook_allow_addresses | CIDR list | — | Ja |
action_on_critical | isolate | freeze | alert_only | isolate | Ja |
ebpf_socket_path | abs path | /run/roamswitch/events.sock | Ja |
ebpf_heartbeat_interval_secs | 0 (off) | int 60–86400 | 600 | Ja |
isolation_hard_cap_secs | int ≥ 0 | 3600 | Ja |
fim_check_interval_secs | int ≥ 10 | 300 | Ja |
fim_intrusion_context_enabled | bool | true | Ja |
protect_docker_ports | bool | true | Ja |
dns_sinkhole_enabled | bool | false | Ja |
dns_sinkhole_provider | quad9 | cloudflare | adguard | cleanbrowsing | quad9 | Ja |
egress_ip_blocklist_enabled | bool | true | Ja |
metadata_watch_enabled | bool | true | Ja |
metadata_watch_allow_users | list | — | Ja |
cve_kernel_map_updates_enabled | bool | true | Ja |
clamav_enabled | bool | false | Ja |
clamav_scan_dirs | abs path list | — | Ja |
clamav_scan_interval_secs | int ≥ 3600 | 86400 | Ja |
clamav_freshclam_interval_secs | int ≥ 1800 | 7200 | Ja |
lockfile_watch_dirs | abs path list | — | Ja |
npm_audit_signatures_enabled | bool | false | Ja |
log_audit_enabled | bool | true | Ja |
log_audit_interval_secs | int ≥ 300 | 1800 | Ja |
resource_guard_enabled | bool | true | Ja |
resource_guard_rss_sample_interval_secs | int ≥ 10 | 60 | Ja |
resource_guard_rss_window_secs | int ≥ 300 | 1800 | Ja |
resource_guard_rss_min_samples | int ≥ 3 | 10 | Ja |
resource_guard_rss_min_growth_pct | int ≥ 10 | 50 | Ja |
resource_guard_rss_recovery_drop_pct | int ≥ 1 | 10 | Ja |
resource_guard_rss_min_kb | int ≥ 0 | 20000 | Ja |
resource_guard_crash_loop_window_secs | int ≥ 60 | 300 | Ja |
resource_guard_crash_loop_min_restarts | int ≥ 2 | 3 | Ja |
resource_guard_correlation_window_secs | int ≥ 60 | 600 | Ja |
resource_guard_zombie_min_count | int ≥ 0 | 20 | Ja |
resource_guard_load_min_normalized | float ≥ 0.0 | 0.5 | Ja |
resource_guard_load_enabled | bool | true | Ja |
resource_guard_cpu_enabled | bool | true | Ja |
resource_guard_cpu_sample_interval_secs | int ≥ 0 | 60 | Ja |
resource_guard_cpu_window_secs | int ≥ 0 | 600 | Ja |
resource_guard_cpu_min_samples | int ≥ 0 | 8 | Ja |
resource_guard_cpu_pct_threshold | float 0.0–1000.0 | 80.0 | Ja |
container_exec_guard_enabled | bool | true | Ja |
port_scan_detect_enabled | bool | true | Ja |
port_scan_detect_min_distinct_ports | int ≥ 0 | 15 | Ja |
port_scan_detect_window_secs | int ≥ 0 | 300 | Ja |
port_scan_block_enabled | bool | true | Ja |
port_scan_block_duration_secs | int ≥ 0 | 600 | Ja |
ssh_guard_enabled | bool | true | Ja |
ssh_guard_block_enabled | bool | true | Ja |
ssh_guard_max_failures | int 2–1000 | 6 | Ja |
ssh_guard_window_secs | int 10–86400 | 600 | Ja |
ssh_guard_ban_secs | int 60–2592000 | 3600 | Ja |
ssh_guard_ban_max_secs | int 60–31536000 | 604800 | Ja |
ssh_guard_allow | IP/CIDR list | — | Ja |
ssh_guard_log_source | auto | journal | abs path | auto | Ja |
ssh_guard_yield_to_fail2ban | bool | true | Ja |
ssh_guard_trust_key_days | int 0–3650 | 30 | Ja |
dns_tunnel_detect_enabled | bool | true | Ja |
reverse_shell_watch_enabled | bool | true | Ja |
reverse_shell_watch_include_private | bool | false | Ja |
reverse_shell_watch_notify_only | bool | false | Ja |
sensor_pairing_enabled | bool | false | Ja |
sensor_colocated | bool | false | Ja |
forward_enabled | bool | false | Ja |
forward_syslog_url | URL | — | Ja |
forward_syslog_format | rfc5424 | cef | rfc5424 | Ja |
forward_syslog_framing | octet | lf | octet | Ja |
forward_tls_ca_file | abs path | — | Ja |
forward_file_path | abs path | — | Ja |
forward_file_max_mb | int 1–10000 | 50 | Ja |
forward_file_keep | int 1–100 | 5 | Ja |
forward_webhook_url | URL | — | Ja |
forward_webhook_secret | string | — | Ja |
forward_webhook_secret_file | abs path | — | Ja |
forward_webhook_block_private_addresses | bool | false | Ja |
forward_webhook_allow_addresses | CIDR list | — | Ja |
forward_min_severity | info | low | medium | high | critical | low | Ja |
forward_queue_max_mb | int 1–10000 | 20 | Ja |
forward_queue_max_age_hours | int 1–8760 | 72 | Ja |
exec_recorder_enabled | bool | true | Ja |
exec_recorder_retention_mb | int 1–100000 | 200 | Ja |
exec_recorder_retention_days | int 1–3650 | 14 | Ja |
exec_recorder_hash_chain | bool | true | Ja |
exec_recorder_hash_exe | bool | true | Ja |
exec_recorder_cpu_budget_pct | int 1–50 | 3 | Ja |
exec_rules_enabled | bool | true | Ja |
exec_rules_disabled | string | — | Ja |
exec_rule_service_users | string | — | Ja |
exec_rule_window_secs | int 5–3600 | 120 | Ja |
exec_rules_isolation_optin | bool | false | Ja |
honeytokens_enabled | bool | true | Ja |
honeytokens_home | abs path | /root | Ja |
harden_userns_enabled | bool | true | Ja |
dns_tunnel_entropy_allowlist | list | — | Ja |
fleet_forwarding_allowed_hosts | list | — | Ja |
fleet_forwarding_allow_plaintext | bool | false | Ja |
18.2 guard.yaml (37 Schlüssel)
| Schlüssel | Typ / Werte | Standard | Neustart |
|---|---|---|---|
sensor.type | falco | tetragon | falco | Ja |
sensor.transport | string | unix_socket | Ja |
sensor.socket_path | abs path | /run/roamswitch/events.sock | Ja |
sensor.reconnect_interval_ms | int 100–3600000 | 1000 | Ja |
policies.on_warning.action | log_and_notify | isolate_process | isolate_host_all | log_and_notify | Ja |
policies.on_warning.server_action | log_and_notify | isolate_process | isolate_host_all | — | Ja |
policies.on_warning.kill_process | bool | false | Ja |
policies.on_warning.freeze_process | bool | false | Ja |
policies.on_warning.fallback_to_host_isolation_after_retries | int 0–1000 | — | Ja |
policies.on_error.action | log_and_notify | isolate_process | isolate_host_all | isolate_process | Ja |
policies.on_error.server_action | log_and_notify | isolate_process | isolate_host_all | — | Ja |
policies.on_error.kill_process | bool | false | Ja |
policies.on_error.freeze_process | bool | false | Ja |
policies.on_error.fallback_to_host_isolation_after_retries | int 0–1000 | — | Ja |
policies.on_critical.action | log_and_notify | isolate_process | isolate_host_all | isolate_process | Ja |
policies.on_critical.server_action | log_and_notify | isolate_process | isolate_host_all | — | Ja |
policies.on_critical.kill_process | bool | true | Ja |
policies.on_critical.freeze_process | bool | false | Ja |
policies.on_critical.fallback_to_host_isolation_after_retries | int 0–1000 | 3 | Ja |
policies.on_emergency.action | log_and_notify | isolate_process | isolate_host_all | isolate_host_all | Ja |
policies.on_emergency.server_action | log_and_notify | isolate_process | isolate_host_all | — | Ja |
policies.on_emergency.kill_process | bool | true | Ja |
policies.on_emergency.freeze_process | bool | false | Ja |
policies.on_emergency.fallback_to_host_isolation_after_retries | int 0–1000 | — | Ja |
server_safeguards.allow_established_connections | bool | true | Ja |
server_safeguards.maintenance_ssh_ports | port list | 22 | Ja |
server_safeguards.whitelist_cidrs | list | — | Ja |
server_safeguards.whitelist_dns_servers | list | — | Ja |
server_safeguards.safety_timer_secs | int ≥ 0 | 300 | Ja |
adaptive_security.enabled | bool | true | Ja |
adaptive_security.untrusted_network_actions.elevate_falco_profile | string | — | Ja |
adaptive_security.untrusted_network_actions.auto_enable_userns_restriction | bool | false | Ja |
investigation.enabled | bool | false | Ja |
investigation.command | abs path | — | Ja |
investigation.args | list | — | Ja |
investigation.run_as | string | — | Ja |
investigation.timeout_secs | int 1–86400 | 180 | Ja |
19. Erkennung von Web-Shells und eingeschleustem Code (Web Rules)
Diese Funktion erkennt PHP-, JavaScript-, JSP- und ASP-Web-Shells sowie eingeschleusten Code auf Ihrem Webserver, in Bildern versteckten PHP-Code und .htaccess-Missbrauch (ab Linux 1.11.23). Es ist keine Einrichtung nötig: Sie findet die Dokumentenwurzeln in der Apache-, nginx- und Caddy-Konfiguration und prüft eine Datei unmittelbar nach dem Schreiben und Schließen (mit rein benachrichtigendem fanotify, das nie einen anderen Prozess blockieren kann). Ein periodischer Scan alle 6 Stunden deckt verworfene Ereignisse und bereits vorhandene Dateien ab. ClamAV ist nicht nötig.
Das Verhalten wird in /etc/roamswitch/web_rules.conf festgelegt (Eigentümer root, Modus 0644; eine Datei, die andere beschreiben können, wird ignoriert). Änderungen werden mit sudo roamswitch server restart wirksam. Eine Vorlage gibt roamswitch web-rules example conf aus.
| Schlüssel | Bedeutung (Standard) |
|---|---|
quarantine | Automatische Quarantäne-Stufe. off isoliert nie, critical nur critical, high critical und high (Standard: critical). Ein High-Treffer bei der Stufe critical löst nur Benachrichtigung und Hook aus; die Datei bleibt unangetastet. |
account_action | Ob die Login-Shell des Besitzers einer erkannten Datei gesperrt wird. off / revoke_shell (Standard: off). Es zählen nur isolierte Treffer mit critical oder high. root, UIDs unter account_min_uid, angemeldete Benutzer und der Benutzer des Daemons werden nie angefasst. Die frühere Shell wird gespeichert und sudo roamswitch web-rules unlock-account <Benutzer> stellt sie wieder her. |
account_min_uid | account_min_uid: die niedrigste UID, auf die die Kontomaßnahme wirken darf (Standard 1000; nicht unter 100 einstellbar). |
scan_dirs, auto_docroots, watch, scan_interval_secs | scan_dirs (absolute Pfade, durch Kommas getrennt), auto_docroots (Standard true; false beendet die automatische Erkennung aus der Webserver-Konfiguration), watch (Standard true; false schaltet die Schreibüberwachung ab und lässt nur den periodischen Scan) und scan_interval_secs (Standard 21600, mindestens 3600). |
# /etc/roamswitch/web_rules.conf
quarantine=critical
account_action=off
account_min_uid=1000
#scan_dirs=/srv/sites/a,/srv/sites/b
auto_docroots=true
watch=true
scan_interval_secs=21600
Bei einem Fund kommt eine Benachrichtigung (Telegram, LINE, Webhook), die die Regel nennt und angibt, ob die Datei isoliert oder belassen wurde. Zum reinen Ansehen ohne Verschieben nutzen Sie sudo roamswitch web-scan <Ordner> (nur Ansicht; --quarantine zum Isolieren) oder den Tools-Bildschirm der Server-TUI. Eigene Regeln liegen in /etc/roamswitch/rules.d/*.json. Um nach einem Fund ein eigenes Skript aufzurufen, legen Sie es unter /etc/roamswitch/hooks/post-detection ab (der Treffer kommt als JSON über die Standardeingabe; ausgeführt wird nur eine root gehörende, nicht beschreibbare Datei in einem sicheren Verzeichnis; keine Shell, Abbruch nach 30 Sekunden). Regelaktualisierungen laufen über das tägliche, rein empfangende Update. Ist cve_kernel_map_updates_enabled aus, gibt es keinerlei Netzwerkkontakt, und die eingebauten Regeln gelten.