Produkt
Shelltrap für CyberPanel
Ein Webshell-Scanner ist nur so gut wie die beiden Dinge, die niemand auf eine Feature-Liste schreibt: was er tut, wenn er sich nicht sicher ist, und was er tut, wenn er kaputt ist. Hier steht beides.
Was er beobachtet
Shelltrap beobachtet die Docroots der Accounts auf Ihrem CyberPanel-Host — standardmäßig /home —
und reagiert auf Dateiereignisse, während sie passieren. Die Eventmaske umfasst bewusst mehr als
„eine Datei wurde geschrieben":
CLOSE_WRITE— ein Schreibvorgang ist abgeschlossen, der übliche Moment zum ScannenMOVED_TO/MOVED_FROM— ein Umbenennen in einen beobachteten Pfad hinein oder herausCREATE/DELETE— Auftauchen und VerschwindenATTRIB— Attributänderungen, damit ein spätereschmod, ein setuid-Bit oder ein Eigentümerwechsel ein eigenes Ereignis ist und nicht etwas, das der Scanner am nächsten Sonntag erfährt
Heiße Nicht-Kundenpfade werden absichtlich als ignoriert markiert: ein Datenbank-Datenverzeichnis, Logbäume und Panel-Caches. Ein Filesystem-Mark auf dem Root-Dateisystem liefert sonst jeden Open des Hosts — das ist ein Performance-Problem, kein Sicherheitsgewinn.
Ein Überlauf der Warteschlange wird nicht verschluckt. FAN_Q_OVERFLOW wird gezählt, alarmiert und
mit einem zeitlich begrenzten Rekonsiliationsscan beantwortet. Dieselbe Rekonsiliation läuft nach
Reboot, Absturz, Upgrade und nach jedem neuen Mount unterhalb eines Kundenroots. „Nicht gescannt"
und „Scanner gestört" sind eigene Zustände und werden nie als clean angezeigt.
Vier Schritte zwischen Schreibvorgang und Verdikt
Die Trennung in diesem Bild ist das gesamte Sicherheitsargument. Ein Scanner ist ein Programm, das vom Angreifer gewählte Dateien öffnet und durch Archiv-, Bild-, Dokument- und Executable-Parser schickt. Das ist der gefährlichste Code im System, also läuft er nicht als root:
Der Root-Broker (shelltrapd) ist ein statisch gelinktes Go-Binary ohne cgo. Er hält die
fanotify-Gruppen, normalisiert Ereignisse, öffnet Dateien sicher (openat2 mit
RESOLVE_NO_SYMLINKS, auf älteren Kerneln ein komponentenweiser openat-Walk mit O_NOFOLLOW),
erfasst minimale Metadaten, übergibt Scan-Jobs an Worker, führt Quarantäne-Transaktionen aus und
bedient die lokale API. Er enthält kein YARA, keinen ClamAV-Code und kein Archiv-, Office- oder
ELF-Parsing. Er akzeptiert keinen freien Pfad aus Panel oder UI, nur opake Objekt-IDs. Einzige
Ausnahme ist der Root-CLI-Aufruf scan <pfad>, über SO_PEERCRED als uid 0 verifiziert.
Der Scanner-Worker ist ein eigener Prozess unter einem eigenen Systembenutzer, in eigenem
Mount- und PID-Namespace, mit seccomp, rlimits und cgroup-Grenzen, definiertem Timeout,
Crash-Retry — und ohne Netz. Er bekommt vom Broker einen nur lesbaren Deskriptor über
SCM_RIGHTS; er löst selbst nie einen Pfad auf.
Die Engines
Im Worker, in dieser Reihenfolge:
- Typerkennung über Magic Bytes. Sie steuert nur die Priorität. Größenfilter, Medien, Backups
und Caches werden nie stillschweigend als sauber gewertet — sie werden als
unscannedgemeldet und in einen begrenzten Tiefenscan oder einen geplanten Spezialscan gegeben. Bild-Header vor PHP,.phar,.phtml,.user.iniund verschachtelte Archive laufen immer durch die volle Pipeline. - ClamAV über den clamd-Socket, nur im Full-Profil.
- YARA 4.5, mit Regeln, die je Feed-Generation gegen genau diese Engine-Version vorkompiliert sind.
- Hash-Sets — SHA-256-Mengen plus eine Known-Good-Allowlist für WordPress-Core und verbreitete Plugins und Themes, Laravel und Joomla. Die Allowlist darf einen Pfad-Kontexttreffer nicht blind überstimmen: Ein Known-Good-Hash in einem Upload-Verzeichnis bleibt ein Fund.
- Heuristik, mit erklärbarem Scoring je Signal: PHP-Obfuskationsmerkmale (
eval,base64_decode,gzinflate,str_rot13, chr-Ketten, lange Hexstrings, variable Funktionsaufrufe, Entropie), PHP in Upload-Verzeichnissen,.htaccess- und.user.ini-Tricks (AddHandler,AddType,auto_prepend_file), Symlinks aus dem Home-Verzeichnis hinaus, world-writable und setuid-Dateien. Ein Treffer braucht mehrere unabhängige Signale. Entropie oder eine einzelne lange Zeile ergeben für sich genommen nie einsuspicious— diese Lehre hat uns eine Handvoll Fehlalarme auf normalen JPEGs und auf Wordfences eigenem Transient-Cache gekostet, und sie ist behoben.
Grenzen je Mandant und global gelten für Dateigröße, Scanzeit, Archiv-Rekursion, Dateizahl,
Kompressionsverhältnis, expandierte Bytes und Temp-Speicher. Eine Überschreitung tötet den
Worker-Prozess und vermerkt das Objekt als unscanned mit Grund — ein begrenztes Scheitern statt
eines unbegrenzten.
Lieber die Begründung sehen als darüber lesen? Der Webshell Signal Explorer geht sechs reale Formen durch, einschließlich des Fehlalarms, der nicht passieren darf.
Fünf Verdikte
| Verdikt | Bedeutung | Standardaktion |
|---|---|---|
clean | von jeder Engine des Profils gescannt, nichts gefunden | keine |
suspicious | mehrere unabhängige Signale, unterhalb der Aktionsschwelle | melden |
malicious | Signatur- oder Hashtreffer oder Heuristik-Score über der Schwelle | Quarantäne bei Signatur- und Hashtreffern |
unscanned | eine Grenze wurde erreicht, der Grund ist protokolliert | melden, planmäßig erneut versuchen |
degraded | der Scanner selbst war beeinträchtigt | melden, alarmieren |
Der Cache-Schlüssel enthält Mount-ID, Inode, hochauflösende mtime und ctime, Größe, Content-Hash
sowie Regelmengen-, Engine- und Policy-Generation. Ein Signaturupdate invalidiert alte
clean-Verdikte automatisch. Pfadabhängige Policy-Verdikte (etwa „PHP in uploads") liegen in einem
getrennten Cache, weil derselbe Inode über einen Hardlink oder ein Rename den Kontext wechseln
kann.
Reaktion, und warum Quarantäne eine Transaktion ist
Restore überschreibt nie ein vorhandenes Ziel und stellt Eigentümer, Modus, Zeiten, ACLs, erweiterte
Attribute und den SELinux-Kontext wieder her. Eine chmod 000-Aktion gibt es nicht: eine Datei an
Ort und Stelle kaputtzumachen ist keine Eindämmung, sondern ein Support-Ticket. EXDEV —
Quarantäne und Original auf verschiedenen Dateisystemen — ist der Normalfall und kein Fehler.
Benachrichtigung heißt: Admin-Mail sofort bei malicious, Digest bei suspicious, optional
Kundenmail über den CyberPanel-Kontakt und Webhooks, die auf eine Ziel-Allowlist beschränkt sind.
Ignore-Regeln umfassen Pfad-Globs je Site, Signatur-IDs, Hash-Allowlists und Benutzer.
Eine Ignore-Regel unterdrückt die Aktion, nie den Scan und nie die Aufzeichnung des Fundes.
Das Upload-Gate
Eine einzige PHP-Datei, über auto_prepend_file in einer globalen lsphp-ini je PHP-Version geladen,
tut gar nichts, solange $_FILES leer ist. Ist es das nicht, reicht sie die Temp-Deskriptoren über
einen lokalen Socket an den Broker und wartet höchstens upload.timeout_ms (Standard 2000 ms,
gedeckelt bei 60000 ms). Eine malicious-Antwort bedeutet HTTP 403 und eine gelöschte Temp-Datei.
Fail-open ist bei einem Gate-Fehler der Standard, fail-closed ist je Domain verfügbar.
Das ist der Mechanismus, der auf OpenLiteSpeed und LiteSpeed Enterprise ohne ModSecurity identisch
funktioniert, und das ist der ehrliche Grund für diese Wahl. Wir nennen auch seine Grenze:
auto_prepend_file lässt sich per .user.ini innerhalb der Site überschreiben. Genau dieses Muster
ist selbst ein Heuristiktreffer, und der Echtzeit-Watcher bleibt als Catch-all hinter dem Gate.
FTP-Uploads werden über pure-uploadscript eingereiht und direkt nach dem Upload gescannt; dieser
Post-Upload-Charakter wird ausgewiesen statt weggeredet.
Mehr dazu: wie das Upload-Gate funktioniert .
Plattformstufen
shelltrapd --check liefert JSON mit tier, diagnostic.tier und je Mount einem reason und
error. Ist ein Backend ausdrücklich konfiguriert, spiegelt das oberste tier diese Wahl wider —
für eine echte Fähigkeitsaussage lesen Sie deshalb immer auch diagnostic.tier.
Debian hat bei CyberPanel selbst nur Third-Party-Support, also sagen wir es nicht zu. Globale inotify-Sysctls werden nie hinter Ihrem Rücken angehoben: Der Installer zählt Watches und fragt.
Full- und Lite-Profil
Das Profil wird nach einer Messung gewählt, nicht aus einer Versionstabelle. Full verlangt einen
laufenden oder installierbaren clamd, einen Socket, der vom Benutzer shelltrap-scan tatsächlich
erreichbar ist, und mindestens 1,5 GiB MemAvailable, die nach der gemessenen Reload-Spitze übrig
bleiben. Sonst wählt die Installation Lite, setzt scanner.enable_clamd = false und sagt das.
Lite hat sichtbar geringere Abdeckung: Die Support-Zusage für die Software ist dieselbe, die
Erkennungszusage nicht.
Ein später gestarteter clamd stuft Sie nicht stillschweigend auf Full hoch. Das ist Absicht: Ein Profilwechsel ist eine Sicherheitsentscheidung und bekommt eine Messung, keine Vermutung.
Signatur-Feeds
Fremdregeln werden nie direkt von einem fremden Mirror aktiviert. Jede Regel trägt ihre Provenienz —
Quelle, Commit, Lizenz, Autor, ob sie verändert wurde — und der Build lässt nur Regeln unter
DRL-1.1, BSD-3-Clause, Apache-2.0 und MIT zu (plus GPL-2.0-only für ClamAV-Datenbanken).
Wo eine Upstream-Lizenz uns verpflichtet, Autor, URI und Lizenzhinweis sichtbar zu halten, wandert
diese Attribution bis in die Fundanzeige und die Benachrichtigungsmail.
Die ClamAV-Datenbanken daily, main und bytecode holt freshclam je Server; gebündelt werden
sie nicht.
Das CyberPanel-Plugin
Das Plugin ist eine Bedienoberfläche, kein zweiter Scanner. Broker und Worker laufen weiter, wenn das Panel steht, aktualisiert wird oder kaputt ist.
- Seiten: Dashboard und Health, Funde mit Filtern, Paging, Detail und Signalen, Quarantäne mit Restore (Purge nur Admin), Policies je Domain mit sichtbarer Vererbung global → Account → Domain, Ignore-Listen, Feed-Generationen, Audit (nur Admin), Jobs sowie eine Hilfe- und Statusseite.
- Rollen: Administratoren sehen alles; Reseller und Kunden sehen ihre eigenen Sites, können in
ihrem Bereich ein Restore anfordern und dürfen nur die Policy-Schlüssel ändern, die ein
Administrator freigegeben hat.
upload.on_errorundheuristics.actionbleiben für beide Rollen gesperrt, und der Broker setzt diese Grenze unabhängig von der UI durch. - Integrität: Der CyberPanel-Installer patcht Core-Dateien zeilenweise, deshalb legt das Plugin atomare Snapshots an, bevor es etwas anfasst, prüft sie per Prüfsumme und rollt zurück, wenn Installation oder Reparatur scheitern. Nach einem Panel-Upgrade ist der Reparaturpfad idempotent und läuft erneut.
Einzelheiten: die Plugin-Dokumentation .
Lizenzierung
Eine Lizenz je Server. Die Aktivierung bindet die Lizenz an einen Server-Fingerabdruck aus
/etc/machine-id; deactivate gibt den Platz wieder frei. Der Daemon prüft einen Ed25519-signierten
Token offline — der Lizenzdienst muss nicht erreichbar sein, damit der Scanner arbeitet — und ein
systemd-Timer erneuert ihn täglich mit einer Stunde Jitter.
Ohne gültige Lizenz stürzt der Daemon nicht ab und läuft nicht in eine Schleife: Der Watcher zählt
weiter Ereignisse, der Scheduler plant nichts, das Upload-Gate antwortet allow mit dem Grund
unlicensed, und Health meldet unlicensed mit präziser Ursache. Feeds antworten 401. Das ist die
kommerzielle Grenze, und sie ist so gebaut, dass sie sichtbar scheitert statt gefährlich.
Mehr: Lizenzierung und Aktivierung .
Was Shelltrap nicht ist
Ehrlichkeit ist billiger als eine Rückerstattung:
- Er ist keine WAF und keine Firewall. Er sieht Dateien an, keine Requests.
- Er verhindert keine Ausführung auf Kernel-Ebene. Ein Open vorab zu blockieren ist ein 1.x-Prototyp und wird heute bewusst nicht zugesagt. Was es heute gibt, ist ein synchrones Gate auf dem Web-Upload-Weg und schnelle asynchrone Erkennung überall sonst.
- Er behauptet nicht, alles zu finden. Kein Scanner tut das. Er behauptet, ehrlich zu sagen, was er gescannt hat, was er nicht scannen konnte und warum er so entschieden hat.
- Er kann sich nicht gegen einen Angreifer wehren, der schon root auf der Maschine hat. Nichts, was auf dieser Maschine läuft, kann das.
Kommen Sie von CXS?
Die Migrationsseite ordnet Begriffe, Quarantäne und Konfiguration zu, und der Rechner ermittelt, wie viele Lizenzen eine Flotte braucht.
CXS-Migration
Ein praktischer Migrationsweg vom ConfigServer eXploit Scanner zu Shelltrap auf CyberPanel: Zuordnung der Funktionen, eine Umstellungs-Checkliste, die im Report-only beginnt, und ein Lizenzrechner.