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
shelltrapdläuft als root; der Worker läuft alsshelltrap-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
clamdund ein Unix-Socket, der für den Benutzershelltrap-scanerreichbar 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 Zustanddegradedund niemalsclean. - 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 entwedercurloderwgetfür den Host-Installer; für das CyberPanel-Paket zusätzlichunzip. 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
--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:
- Full —
clamdläuft oder ist installierbar, der konfigurierte Socket ist fürshelltrap-scantatsächlich erreichbar, und nach der Reserve für die Reload-Spitze verbleiben mindestens 1,5 GiBMemAvailable. 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 = falsefest, 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
| Pfad | Was es ist |
|---|---|
/etc/shelltrap/shelltrap.toml | Konfiguration (eine conffile; übersteht Upgrades) |
/var/lib/shelltrap/state.db, feeds/, cache/, quarantine/ | persistenter Zustand |
/run/shelltrap/api.sock, /run/shelltrap/upload.sock | lokale Sockets |
/usr/lib/shelltrap/php/shelltrap-prepend.php | der Upload-Adapter |
/etc/shelltrap/upload-policy.json | atomarer 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.
# 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
- Existiert für jedes lsphp-ABI eine passende
shelltrap.ini, und zeigtauto_prepend_fileauf/usr/lib/shelltrap/php/shelltrap-prepend.php? - Existiert
/run/shelltrap/upload.sock, und sind die Richtliniendatei und dasDOCUMENT_ROOT-Präfix gültig? - Bei
denymuss der Adapter HTTP 403 zurückgeben und die temporäre Datei löschen; miton_error = "closed"ist HTTP 503 zu erwarten. Mitopenläuft die Anwendung weiter, der Fehler muss aber diagnostizierbar bleiben.
Weiter
Gekürzt aus dem Shelltrap-Installationshandbuch, Revision 2026-09-04.