shelltrap.com
en de

Dokumentation

Installation und Erstinbetriebnahme

Der Installer prüft, was der Host tatsächlich leisten kann, statt einer Kernel-Version zu vertrauen. Lesen Sie den Abschnitt zu den Profilen und den Abschnitt zum Report-only-Betrieb, bevor Sie irgendetwas ausführen.

Voraussetzungen

  • Root-Zugriff oder ein Paket-Dienstkonto mit vollen Installationsrechten. Der Broker shelltrapd läuft als root; der Worker läuft als shelltrap-scan, einem Systembenutzer ohne Login-Shell und ohne Home-Verzeichnis.
  • Ein von CyberPanel unterstütztes Betriebssystem: Ubuntu 20.04, 22.04 oder 24.04; AlmaLinux, RockyLinux oder RHEL 8, 9 oder 10; CloudLinux 8; CentOS 9. Debian wird von CyberPanel nur über Dritte unterstützt und ist nicht zugesichert.
  • Ein Linux-Dateisystem unterhalb der konfigurierten Kundenverzeichnisse (standardmäßig /home), ausreichend Arbeitsspeicher und ein Kernel, auf dem der Installer die fanotify- und File-Handle-Capabilities tatsächlich prüfen kann.
  • Für das Full-Profil: mindestens 1,5 GiB MemAvailable, die nach der gemessenen Reload-Reserve verbleiben; diese umfasst den beobachteten clamd-Speicherbedarf zuzüglich eines festen Sicherheitszuschlags. Diese Messung darf nicht durch eine globale sysctl-Änderung ersetzt werden.
  • Für ClamAV im Full-Profil: ein laufender oder installierbarer clamd und ein Unix-Socket, der für den Benutzer shelltrap-scan erreichbar ist, standardmäßig /run/clamav/clamd.ctl. Ein nur für root lesbarer Socket genügt nicht. Fehlt der Dienst oder der Zugriff des Workers, wird der Zustand degraded und niemals clean.
  • Für den PHP-Upload-Adapter: eine unterstützte lsphp/LSWS-Installation. Der Adapter benötigt lediglich den lokalen Socket /run/shelltrap/upload.sock.
  • Werkzeuge: sha256sum, GnuPG und entweder curl oder wget für den Host-Installer; für das CyberPanel-Paket zusätzlich unzip. Abhängigkeiten löst der native Paketmanager auf.

Host-Preflight

Vor jedem Download gibt der Host-Installer rein lesende Fakten über die Maschine aus und verändert nichts:

shelltrap: kernel=6.8.0-… CAP_SYS_ADMIN=absent provisional_tier=unknown (requires shelltrapd --check)
shelltrap: SELinux=enforcing AppArmor=enabled LSWS=OLS
shelltrap: mount_probe=/home mount_target=/home mount_fs=xfs mount_options=rw,relatime

SELinux kann enforcing, permissive, disabled oder unknown lauten; AppArmor wird als enabled, disabled oder unknown gemeldet. LSWS=OLS stammt aus dem CyberPanel-Muster /usr/local/lsws/bin/openlitespeed; liegt stattdessen das Enterprise-Steuerbinary vor, lautet der Wert enterprise, und ohne beide Merkmale bleibt er unknown. Die Mount-Angaben stammen aus findmnt; fehlt das Werkzeug, melden alle drei Felder unknown, statt zu raten.

Ein unknown ist eine Diagnose und keine stillschweigende Zusicherung von Stufe A. Maßgeblich ist immer der Aufruf nach der Installation:

shelltrapd --config /etc/shelltrap/shelltrap.toml --check

Plattform- und Degradationsstufen

Vier Beobachtungsstufen, nach Laufzeitfähigkeit statt Kernelversion gewähltDer Installer probiert die Fähigkeiten des Hosts. Stufe A nutzt fanotify mit Filehandles und liefert vollständige Echtzeit. Stufe B verzichtet auf Filehandles, Umbenennungen kommen verzögert. Stufe C arbeitet ohne CAP_SYS_ADMIN mit budgetiertem inotify und einem Crawler. Stufe D installiert nicht und liefert nur Diagnose.LAUFZEITPROBE, KEINE VERSIONSANNAHMEAvollständigfanotify mit FAN_REPORT_DFID_NAME, Marks je MountUbuntu 22.04/24.04 · Alma/Rocky/RHEL 9 und 10Echtzeit, alle FunktionenBfd-modefanotify ohne Filehandles, Renames über ctime-AbgleichAlma/Rocky/RHEL/CloudLinux 8 · Ubuntu 20.04 GA-KernelEchtzeit beim Schreiben, Umbenennen verzögertCcontainerbudgetiertes inotify plus checkpointbarer Crawlerunprivilegiertes LXC/OpenVZ ohne CAP_SYS_ADMINErkennung mit Verzögerung, im Produkt ausgewiesenDnicht unterstütztkein verwendbares Backend oder unbekanntes DateisystemRestkeine Installation, nur Diagnose
Watcher-Stufe und Scanner-Profil sind zwei getrennte Achsen: Stufe A bedeutet nicht automatisch, dass genug Arbeitsspeicher für das ClamAV-Full-Profil vorhanden ist.

--check liefert JSON mit tier, diagnostic.tier und je Mount reason und error. Ist ein Backend ausdrücklich konfiguriert, gibt das tier auf oberster Ebene diese Wahl wieder — für eine belastbare Aussage über die Capabilities lesen Sie zusätzlich diagnostic.tier.

Verifizierte Installation

Release-Artefakte werden mit make dist gebaut, und jede der vier Paketdateien erhält eine .sha256 sowie eine abgetrennte, ASCII-armored .asc-Signatur. Vor der Veröffentlichung müssen diese Dateien je Version vorliegen:

shelltrap_<version>_<arch>.deb                  + .sha256 + .asc
shelltrap-cyberpanel_<version>_all.deb          + .sha256 + .asc
shelltrap-<version>-1.<arch>.rpm                + .sha256 + .asc
shelltrap-cyberpanel-<version>-1.noarch.rpm     + .sha256 + .asc

Aus dem Repository, wobei der Paketmanager die Signatur des Index prüft:

sudo apt-get update && sudo apt-get install shelltrap shelltrap-cyberpanel
# oder
sudo dnf install shelltrap shelltrap-cyberpanel

Aus lokalen Dateien, mit vorheriger Prüfung:

gpgv --keyring /usr/share/keyrings/shelltrap-archive.gpg \
  dist/shelltrap_1.0.0_amd64.deb.asc dist/shelltrap_1.0.0_amd64.deb
dpkg-deb --info dist/shelltrap_1.0.0_amd64.deb
sudo apt-get install ./dist/shelltrap_1.0.0_amd64.deb

Der Host-Installer unter scripts/install.sh — ebenfalls ausgeliefert als /usr/share/shelltrap/install.sh — lädt über HTTPS herunter, prüft SHA-256 und die abgetrennte Signatur und übergibt dann an den nativen Paketmanager. Der curl-Pfad lässt ausschließlich HTTPS-Weiterleitungen zu; der wget-Fallback verweigert Weiterleitungen vollständig. Das Skript muss als Datei vorliegen und unterstützt curl | bash nicht.

Full- und Lite-Profil

Der Preflight entscheidet erst nach der Messung:

  • Fullclamd läuft oder ist installierbar, der konfigurierte Socket ist für shelltrap-scan tatsächlich erreichbar, und nach der Reserve für die Reload-Spitze verbleiben mindestens 1,5 GiB MemAvailable. ClamAV-, YARA-, Hash- und Heuristik-Engines sind sämtlich im Einsatz.
  • Lite — diese Bedingungen sind nicht erfüllt. Die Konfiguration hält scanner.enable_clamd = false fest, die Abdeckung ist geringer, und ClamAV-Funde können nicht zugesichert werden.

Ein später gestarteter clamd hebt den Host nicht stillschweigend auf Full an. Prüfen Sie die Entscheidung:

grep -n 'enable_clamd' /etc/shelltrap/shelltrap.toml
shelltrapd --config /etc/shelltrap/shelltrap.toml --check

Pfade, Units und der PHP-Adapter

PfadWas es ist
/etc/shelltrap/shelltrap.tomlKonfiguration (eine conffile; übersteht Upgrades)
/var/lib/shelltrap/state.db, feeds/, cache/, quarantine/persistenter Zustand
/run/shelltrap/api.sock, /run/shelltrap/upload.socklokale Sockets
/usr/lib/shelltrap/php/shelltrap-prepend.phpder Upload-Adapter
/etc/shelltrap/upload-policy.jsonatomarer Richtlinienspiegel für den Adapter
/var/log/shelltrap/Text- und Audit-Logs

Die Verzeichnisrechte unterhalb von /var/lib/shelltrap sind bewusst gestaffelt: das übergeordnete Verzeichnis hat 0711, feeds/ hat 0755 mit Dateien 0644, damit der unprivilegierte Worker Regelgenerationen lesen kann, während quarantine/, cache/ und state.db root-exklusiv bleiben (0700 / 0600).

Das Paket liefert shelltrapd.service, shelltrap-scan.service mit Timer und shelltrap-feeds.service mit Timer aus. Tragen Sie eigene Limits in ein Drop-in ein, niemals in die Vendor-Unit:

sudo install -d /etc/systemd/system/shelltrapd.service.d
sudo systemctl daemon-reload
sudo systemctl restart shelltrapd.service

Die Vendor-Unit beschränkt RestrictAddressFamilies bewusst auf AF_UNIX. Netzwerkzugriff für SMTP- oder Webhook-Ziele ist ein eigenes, bewusst installiertes Drop-in, das als Beispiel unter /usr/share/shelltrap/systemd/ ausgeliefert wird. NoNewPrivileges=yes ist gesetzt; RestrictSUIDSGID=no ist eine enge, bewusste Ausnahme, weil die Wiederherstellung die ursprünglichen setuid- und setgid-Rechte mit fchmod zurückschreiben muss.

Für jede vorhandene lsphp-Version schreibt das Paket eine ini-Datei mit folgendem Inhalt:

auto_prepend_file=/usr/lib/shelltrap/php/shelltrap-prepend.php

und berührt anschließend den CyberPanel-Marker /usr/local/lsws/admin/tmp/.lsphp_restart.txt, bevor ein sanfter Neustart mit systemctl restart lsws oder dem Enterprise-Befehl lswsctrl restart versucht wird. killall -9 lsphp ist nicht zulässig. Lässt sich der Marker nicht schreiben oder scheitert der sanfte Neustart, bricht die Aktivierung mit einem Fehler ab, statt PHP in einem unklaren Zustand zu hinterlassen.

Opt-out: Wird SHELLTRAP_SKIP_PHP_ADAPTER=1 in der Umgebung der Paketinstallation gesetzt, entfällt die Aktivierung vollständig — keine ini-Änderung, kein LiteSpeed-Neustart. Das ist der Modus für eine Report-only-Teststufe; aktivieren können Sie später, indem Sie die Paketkonfiguration ohne die Variable erneut ausführen (dpkg-reconfigure shelltrap oder dnf reinstall shelltrap).

Report-only starten auf einem Host mit Kunden

Die Paketinstallation startet den Dienst sofort. Damit er auf einem Produktivhost nie mit den voreingestellten Aktionen läuft, setzen Sie zuerst die Richtlinie und nehmen den Adapter aus dem Spiel:

SHELLTRAP_SKIP_PHP_ADAPTER=1 apt-get install -y ./dist/shelltrap_<version>_amd64.deb
shelltrap policy set global signature.action=report hash.action=report \
  heuristics.action=report upload.enabled=false
shelltrap policy get global

Ein systemd-Drop-in mit CPUQuota, IOWeight, Nice und MemoryHigh vor dem ersten Start ist die zwei Minuten wert, die es kostet: Ein erster Start ohne Marker für ein sauberes Herunterfahren plant einen vollständigen Abgleichlauf, und auf einem ausgelasteten Host ist das echte Arbeit. Auf unserem eigenen Referenzhost lief dieser Durchlauf mit zwei Workern bei etwa 114 Scans pro Minute und mit vier bei rund 270.

root@web1 — /root
# start in report-only: record everything, move nothing
$ shelltrap policy set global signature.action=report hash.action=report heuristics.action=report upload.enabled=false
policy generation 18
$ shelltrap --json findings list --verdict malicious --page-size 1
{"items":[{"id":"f_01J9…","path":"…/wp-content/uploads/2026/03/thumb-cache.php",
  "verdict":"malicious","confidence":0.97,"action":"report",
  "signals":[{"engine":"heuristics","id":"php.dynamic_eval","score":45},
             {"engine":"yara","name":"WEBSHELL_PHP_Generic","author":"…","license":"DRL-1.1"}]}],
 "total":1,"page":1,"page_size":1}
# nothing was quarantined: the policy said report, so the policy won

Die Richtlinie, die alles aufzeichnet und nichts verschiebt, und der Fund, den sie erzeugt hat.

Danach prüfen Sie:

shelltrap health
shelltrap status
stat -c '%a %U:%G %n' /run/shelltrap/api.sock /run/shelltrap/upload.sock
ps -o pid,user,stat,cmd -C shelltrap-scanner

Erwartet werden Stufe A, ein gesunder Store, zwei als shelltrap-scan laufende Worker, aktives Landlock, ein Site-Index, der zu Ihrer CyberPanel-Datenbank passt, und eine aktive Feed-Generation. Ohne Feed-Generation laufen nur ClamAV (im Full-Profil) und die Heuristiken, was für eine Teststufe vertretbar ist, aber als degraded gemeldet und nicht beschönigt wird.

Upgrade, Rollback und Reparatur

sudo apt-get update && sudo apt-get install --only-upgrade shelltrap
sudo dnf upgrade shelltrap

Sichern Sie zuvor die Ausgabe von shelltrap feeds list, die Konfiguration sowie die Audit- und Quarantänedaten. Feed-Generationen lassen sich im laufenden Betrieb des Brokers über die CLI zurückrollen:

shelltrap feeds list
shelltrap feeds rollback GENERATION

Da shelltrap.toml eine conffile ist, sollte ein Upgrade auf einem Host mit geänderter Konfiguration so ausgeführt werden:

apt-get -o Dpkg::Options::=--force-confold install ./dist/shelltrap_<version>_amd64.deb

Andernfalls kann das Paket in install ok unpacked hängen bleiben, während der alte Daemon weiterläuft — und ein Versionsmix ist schlimmer als beides: Startet ein alter Daemon neue Worker-Binaries, trifft er auf einen strikten Protokolldecoder, der unbekannte Felder ablehnt, und die Worker sterben bis zum Neustart.

Nach einem CyberPanel-Upgrade führen Sie den mitgelieferten Reparaturpfad erneut aus:

sudo /usr/share/shelltrap-cyberpanel/install.sh

Broker und CLI müssen auch dann weiterarbeiten, wenn die Panel-Oberfläche defekt ist. Weichen die Panel-Mechanik oder die erwartete Struktur des Plugin-Archivs von dem ab, was die Reparatur erwartet, ist das ein offenes Integrationsproblem und darf nicht durch das Patchen von Zeilen auf Verdacht „behoben“ werden.

Deinstallation und das Purge-Gate

Eine normale Deinstallation stoppt die Dienste und entfernt die Programmdateien. Konfiguration, Logs, Zustand und Quarantäne bleiben erhalten:

sudo apt-get remove shelltrap-cyberpanel shelltrap
sudo dnf remove shelltrap-cyberpanel shelltrap

purge entfernt Konfiguration und Logs. Die Quarantäne ist Beweismaterial und wird nur hinter einem ausdrücklichen Umgebungs-Gate entfernt:

sudo SHELLTRAP_PURGE_QUARANTINE=1 apt-get purge shelltrap

RPM kennt keinen Purge-Schritt im Paketmanager. Für eine bewusste Bereinigung rufen Sie den mitgelieferten Maintainer-Pfad mit dem Gate vor dem Entfernen auf:

sudo env SHELLTRAP_PURGE_QUARANTINE=1 /usr/libexec/shelltrap/maintainer/postrm purge
sudo dnf remove shelltrap-cyberpanel shelltrap

Der Purge-Helfer öffnet /var/lib/shelltrap als übergeordneten Deskriptor, verifiziert den root-eigenen Eintrag quarantine, benennt ihn atomar in einen Staging-Namen um und entfernt Inhalte ausschließlich relativ zu Deskriptoren, wobei er auf jeder Ebene die Linux-Mount-IDs aus /proc/self/fdinfo/<fd> vergleicht. Unsichere Typen oder Identitätsrennen führen zu einem sicheren Abbruch und lassen die Staging-Daten zur manuellen Prüfung zurück. Symlinks und Hardlinks werden als Verzeichniseinträge entfernt und niemals verfolgt.

Fehlersuche

Stufe D oder eine unerwartete Degradation

shelltrapd --config /etc/shelltrap/shelltrap.toml --check
grep '^CapEff:' /proc/self/status

Lesen Sie diagnostic.mounts[].capabilities.reason und .error — typischerweise permission_denied, not_supported oder not_found. Schieben Sie es nicht reflexhaft auf die Kernel-Version: Die häufigen Ursachen sind ein fehlendes CAP_SYS_ADMIN, ein Overlay- oder Netzwerkdateisystem oder nicht exportierbare File-Handles.

clamd und das Full-Profil

test -S /run/clamav/clamd.ctl
systemctl status clamav-daemon.service clamd.service
grep -nE 'enable_clamd|clamd_socket' /etc/shelltrap/shelltrap.toml

Socket-Rechte, der Benutzer clamav und die gemessene Speicherspitze müssen zusammenpassen. Im Fehlerfall bleibt das Ergebnis degraded; ein Neustart darf einen früheren Scan niemals nachträglich als clean umdeuten.

Der PHP-Adapter und Uploads

  1. Existiert für jedes lsphp-ABI eine passende shelltrap.ini, und zeigt auto_prepend_file auf /usr/lib/shelltrap/php/shelltrap-prepend.php?
  2. Existiert /run/shelltrap/upload.sock, und sind die Richtliniendatei und das DOCUMENT_ROOT-Präfix gültig?
  3. Bei deny muss der Adapter HTTP 403 zurückgeben und die temporäre Datei löschen; mit on_error = "closed" ist HTTP 503 zu erwarten. Mit open läuft die Anwendung weiter, der Fehler muss aber diagnostizierbar bleiben.

Weiter

Gekürzt aus dem Shelltrap-Installationshandbuch, Revision 2026-09-04.