Dies ist die Anleitung zur Installation, Konfiguration und Wartung von Arcivéo Security Monitor. Die Abschnitte sind gruppiert: allgemeine Übersicht, Bereitstellung des Dashboards, Anbindung von Sicherheitswerkzeugen, integrierte Module und Diagnose. Befehle lassen sich per Schaltfläche rechts kopieren.
Die Installation des Panels ist auf eigene Schritt-für-Schritt-Seiten ausgelagert. Wählen Sie eine Methode:
Arcivéo Security Monitor — Sicherheits-Dashboard für Ihren Server. Sammelt Daten der installierten Tools (Fail2ban, UFW, Lynis, ModSecurity, AIDE, ClamAV, Auditd, CrowdSec, Suricata, Falco u. a.) und zeigt sie in einer einheitlichen Oberfläche mit Dashboard, Angriffskarte und Detailseiten zu jedem Tool.
Der Monitor ist kein aktives Schutzmittel — er blockiert Angriffe nicht selbst. Seine Aufgabe ist es, Informationen der bereits laufenden Tools zu bündeln und übersichtlich darzustellen.
Der Monitor arbeitet ausschließlich lokal — er muss auf demselben Server installiert sein, den er überwacht. Es gibt kein SSH und keine Remote-API.
Alle Befehle (fail2ban-client, ufw status, ipset list usw.) führt das Dashboard unter dem Benutzer des Webservers aus (in der Regel www-data, bei Hosting-Panels das Website-Konto) mit einem eng begrenzten Satz an sudo-Rechten — nur für bestimmte Werkzeuge, ohne allgemeinen Root-Zugriff. Die Ergebnisse werden geparst und im Browser angezeigt.
Zwei Arbeitsrhythmen. Die Seiten des Dashboards fragen die Werkzeuge beim Öffnen ab — Sie sehen immer den aktuellen Stand. Zusätzlich laufen Hintergrundaufgaben nach Zeitplan (cron):
Die vollständige Liste der Aufgaben steht im Abschnitt „Alle cron-Aufgaben an einem Ort“.
Der Wert beginnt beim Maximum und sinkt für jedes erkannte Problem:
PermitRootLogin yes) — −20PasswordAuthentication yes) — −10X11Forwarding aktiviert, MaxAuthTries über 3 oder sshd_config für alle Konten lesbar — −5TRACE ist aktiviert oder der Header Strict-Transport-Security bzw. X-Frame-Options fehlt — −5Ergebnis: 80+ = Geschützt, 60–79 = Achtung, <60 = Gefährdet.
WebAuthn ist ein Standard für die passwortlose Authentifizierung über einen Hardware-Schlüssel. Unterstützt werden YubiKey, Touch ID, Face ID, Windows Hello und Passkey.
Nach der Anmeldung mit Passwort fordert das System eine Bestätigung über den registrierten Schlüssel an. Selbst bei einem Passwortleck ist eine Anmeldung ohne physischen Schlüssel oder Biometrie unmöglich.
Zum Einrichten öffnen Sie WebAuthn-Schlüssel im Seitenmenü und klicken auf „Schlüssel registrieren“. Registrieren Sie gleich zwei Schlüssel: Geht der einzige Schlüssel verloren oder wird er beschädigt, ist die Anmeldung im Dashboard darüber nicht mehr möglich.
Es gibt vier Kanäle: Telegram, E-Mail, Webhook und Push im Browser. Sie sind unabhängig voneinander — aktivieren Sie beliebige davon, auch alle vier. Über dieselben Kanäle laufen der tägliche Sicherheitsbericht, die Auslastungsbenachrichtigungen und die Funde des Ereignissensors; eingerichtet werden sie einmalig hier, im Bereich „Einstellungen“.
Telegram. Erforderlich sind Bot-Token und chat id:
@BotFather → /newbot → Sie erhalten ein Token der Form 123456:ABC....@userinfobot oder öffnen Sie https://api.telegram.org/bot<TOKEN>/getUpdates und suchen Sie "chat":{"id":...}.E-Mail. Zwei Möglichkeiten zur Auswahl unter „Einstellungen“ → E-Mail:
re_...) und die bestätigte Absender-Domain an.Webhook. Eine einzige Adresse, die POST annimmt, deckt Slack, Discord, Mattermost, n8n und einen eigenen Handler ab. „Einstellungen“ → Webhook: Adresse eintragen und den Schalter aktivieren.
{"text": …}, an Discord {"content": …} (Discord weist Nachrichten über 2000 Zeichen ab, der Text wird daher gekürzt);text, event, severity, source, count, host, ts — den Nachrichtentext muss niemand erneut zerlegen.Push-Benachrichtigungen. Die Meldung kommt direkt im Browser an, und wenn das Dashboard auf dem Startbildschirm des Telefons liegt, als gewöhnliche App-Benachrichtigung — ohne Bot und ohne Mailserver dazwischen. „Einstellungen“ → Push-Benachrichtigungen: den Schalter aktivieren und auf jedem Gerät, das Benachrichtigungen erhalten soll, „Dieses Gerät verbinden“ drücken. Der Zähler „Verbundene Geräte“ zeigt, wie viele es sind.
Berichtsstatus: „ACHTUNG“ oder „OK“. Der Titel wird nur bei einem echten Problem oder einer ausstehenden Aktion zu „ACHTUNG“: ClamAV hat eine Bedrohung gefunden, Dateiänderungen in AIDE, kritische Falco-Ereignisse (Emergency/Alert/Critical in den letzten 24 h), ein ausgefallener Dienst in Monit, ein Neustart ist erforderlich, ein SSL-Zertifikat läuft ab (≤14 Tage) oder Sicherheitsupdates stehen an. Hintergrundrauschen — SSH-Bruteforce durch Bots, von fail2ban gebannte IP-Adressen, Suricata-Alerts, Lynis-Warnungen und bereits abgewehrte ModSecurity-Anfragen — hebt den Status nicht an, daher bedeuten solche Zahlen im Bericht für sich allein noch kein „ACHTUNG“.
Die detaillierten Monitoring-Module (Lynis, UFW, ModSecurity, Angriffskarte, AIDE, ClamAV usw.) werden mit einer gültigen Lizenz freigeschaltet. Ohne sie funktionieren Dashboard, Einstellungen und Konto, während die Module die Karte „Lizenz erforderlich“ anzeigen.
Nach dem Kauf im Benutzerkonto liegt Ihnen ein Aktivierungscode der Form ARCIVEO-XXXX-XXXX-XXXX-XXXX vor. Er muss auf die Domain Ihres Panels „aktiviert“ werden – dadurch wird der Code in eine signierte Lizenzdatei (Block [license]) umgewandelt, die Sie in das Panel einfügen.
So aktivieren Sie (3 Schritte):
my.arciveo.com → Bereich „Lizenzen“ / „Lizenzaktivierung“ – kopieren Sie den Code ARCIVEO-….monitor.example.com). Klicken Sie auf Aktivieren – das System erzeugt eine an diese Domain gebundene Lizenzdatei und zeigt sie im Feld mit der Schaltfläche „Kopieren“ an.Das Panel prüft den Schlüssel kryptografisch: Signatur, Domain-Bindung und Gültigkeitsdauer.
APP_URL in config.php und geben Sie nur den Hostnamen ein – ohne https:// und ohne Präfix www. Die Aktivierung ist einmalig: Der Code wird zur Lizenz für die eingegebene Domain und lässt sich nicht erneut aktivieren – bei einem Fehler in der Domain passt der Schlüssel nicht zu Ihrem Panel, und der Code ist verbraucht. Geben Sie die Domain daher sorgfältig ein.
Alle wesentlichen Parameter des Dashboards stehen in einer einzigen Datei config.php im Stammverzeichnis (neben dem Ordner public/) als gewöhnliche Konstanten via define(). Die Datei wird bei der Installation erstellt; ein manuelles Bearbeiten ist selten nötig — meist beim Wechsel der Domain, beim Umzug oder bei der Anbindung an eine andere Datenbank. Nach jeder Änderung starten Sie PHP-FPM neu (sonst greifen die Änderungen wegen OPcache nicht).
Tragen Sie Ihre Werte an den hervorgehobenen Stellen ein; den Rest lassen Sie unverändert:
Datenbank. Verbindungsdaten zu MySQL/MariaDB:
DB_HOST — Host des DBMS, fast immer localhost;DB_NAME — Name der Datenbank des Dashboards;DB_USER — DB-Benutzer (Zugriff nur auf die eigene Datenbank);DB_PASS — Passwort dieses Benutzers;DB_CHARSET — Zeichensatz der Verbindung, belassen Sie utf8mb4.Anwendung.
APP_URL — vollständige Adresse des Dashboards (z. B. https://monitor.example.com). Muss mit der Domain übereinstimmen, für die die Lizenz aktiviert wurde — sonst wird der Schlüssel abgelehnt (siehe Abschnitt „Lizenz“);TIMEZONE — Zeitzone von PHP: wirkt sich nur darauf aus, wie das Dashboard Datum und Uhrzeit anzeigt. Auf die Startzeit der Cron-Aufträge hat sie keinen Einfluss — dort gilt die Systemzeitzone (siehe „Alle Cron-Aufträge“).Sitzungsdauer. SESSION_LIFETIME — Leerlauf-Timeout der Sitzung in Sekunden (gleitend: wird bei Aktivität erneuert). Standard ist 28800 = 8 Stunden; nach dieser Zeit ohne Aktivität verlangt das Dashboard eine erneute Anmeldung. Beispiel: 3600 = 1 Stunde, 86400 = ein Tag.
Fehlerprotokollierung. Fehler werden Besuchern nie angezeigt, sondern in logs/php_errors.log geschrieben — sie sind auf der Seite „Anwendungsprotokolle“ sichtbar. Diese Zeilen (display_errors=0, log_errors=1, Pfad error_log) müssen in der Regel nicht geändert werden — die Einstellungen stehen direkt in der Datei und hängen nicht von php.ini ab.
public/), und bei diesem Dashboard ist der Web-Stamm (DocumentRoot) genau dieses Stammverzeichnis, nicht public/. Für sich genommen „leckt“ die Datei nicht: In der .htaccess im Stammverzeichnis gilt für sie ein explizites Verbot (Require all denied) — der Server liefert 403. Auch ohne diese Regel würde der Quelltext nicht austreten: Es ist PHP — der Server führt es aus und gibt es nicht als Text zurück. Sicherheitshalber: Legen Sie sie nicht in öffentliche Repositorys und geben Sie sie nicht mit dem echten Passwort an den Support weiter. Dateirechte — 640.
Das Dashboard ist durch die Anmeldung mit Passwort und, falls aktiviert, durch den IP-Filter geschützt. Für ein Programm passt beides nicht, deshalb gibt es für externe Systeme einen eigenen Zugang — zwei Adressen nur zum Lesen, abgesichert durch ein Token. Das Token ändert nichts auf dem Server: Damit lassen sich ausschließlich Kennzahlen abrufen.
Aktivierung — „Einstellungen“ → „API nur zum Lesen“: der Schalter „API aktivieren“; das Token wird beim ersten Speichern automatisch erzeugt. Die Schaltfläche „Neues Token“ vergibt ein anderes und trennt im selben Moment alle, die das bisherige genutzt haben.
/api/status.php — JSON: Sicherheitsbewertung, Zustand der Module, die letzte Auslastungsmessung samt Top-Prozessen und die Sicherheitsereignisse der letzten 24 Stunden;/api/metrics.php — dieselben Zahlen im Textformat von Prometheus (Metriken arciveo_*: arciveo_security_score, arciveo_fail2ban_banned, arciveo_cpu_busy_pct und so weiter).Kann der Client keinen Header setzen, wird das Token auch als Parameter angenommen — ?token=…. Beachten Sie, dass es in dieser Form im Zugriffsprotokoll des Webservers landet; der Header ist deshalb vorzuziehen.
Prometheus. Ein fertiger Block für scrape_configs:
api disabled — die API ist in den Einstellungen deaktiviert. Abgewiesene Anfragen werden mit der IP des Absenders in das Anwendungsprotokoll geschrieben, sodass ein Durchprobieren des Tokens auf der Seite „Anwendungsprotokolle“ sichtbar ist.
Das Dashboard wird pro Server installiert und beantwortet die Frage „wie steht es um diese Maschine“ gut. Die Frage „wie steht es um alle meine Maschinen“ beantwortet es nicht — dafür kann jedes Dashboard eine kurze Übersicht an das Benutzerkonto senden, wo die Server in einer einzigen Liste erscheinen.
Was Sie im Benutzerkonto holen my.arciveo.com → Bereich „Meine Server“: Dort wird ein Token (in der Form fk_…) ausgegeben und die Adresse des Empfängers https://my.arciveo.com/api/fleet.php genannt. Das Token gilt pro Konto — für alle Ihre Server dasselbe.
Was Sie im Dashboard einstellen — „Einstellungen“ → „Serverübersicht“: Adresse des Empfängers, Token, Servername (wie er in der Liste bezeichnet wird; bleibt das Feld leer, wird die Domain des Dashboards genommen) und der Schalter „Übersicht senden“. Die Schaltfläche „Jetzt senden“ prüft die Verbindung sofort, ohne auf den Zeitplan zu warten.
Danach geht die Übersicht per cron heraus, alle 15 Minuten:
Was genau gesendet wird: Name und Domain des Servers, Betriebssystem, Laufzeit, PHP-Version; die Sicherheitsbewertung; der Zustand der Module (UFW, Anzahl der Fail2ban-Jails, Sperren heute, ob CrowdSec, Suricata und Falco laufen, ClamAV-Bedrohungen, AIDE-Änderungen, Lynis-Index, ausstehende Updates, ob ein Neustart nötig ist, Tage bis zum Ablauf des Zertifikats, Anzahl gefährlich offener Ports); die letzte Auslastungsmessung (Load, CPU, RAM, Festplatte, Inodes); die Ereigniszähler der letzten 24 Stunden und das letzte kritische Ereignis. Protokolle, Passwörter und Dateiinhalte sind in der Übersicht nicht enthalten.
sudo crontab -l) und was die Schaltfläche „Jetzt senden“ antwortet. Sendefehler werden mit der Kennung FLEET in das Anwendungsprotokoll geschrieben — dort ist zu sehen, ob das Token abgewiesen wurde (HTTP 401) oder die Verbindung selbst nicht zustande kam.
UFW (Uncomplicated Firewall) — eine einfache Schnittstelle zu nftables/iptables. Sie sperrt alle eingehenden Ports außer den ausdrücklich erlaubten. Die Seite „UFW-Firewall“ zeigt Status und Regeln an.
ufw enable unbedingt SSH frei (ufw allow OpenSSH), sonst verlieren Sie den Zugriff auf den Server.
deny-Regel gesperrter Port gilt nicht als von außen erreichbar.
Skipping adding existing rule ist kein Fehler. UFW meldet damit, dass genau diese Regel bereits existiert und nicht erneut hinzugefügt wird. Beim erneuten Ausführen der automatischen Einrichtung (sie ist idempotent) ist das eine normale Meldung — es ist keine Reaktion nötig.
Sperrt IP-Adressen automatisch nach zu vielen fehlgeschlagenen Anmeldeversuchen. Analysiert die Logs von SSH, nginx, Apache und anderen Diensten.
Die Basisinstallation steht oben. Hier folgt eine funktionierende Konfiguration mit Dutzenden aktiver jails und Tausenden Sperren: allgemeine Einstellungen, zentrale jails und Auto-Bann bösartiger IPs aus der Liste ipsum.
Datei /etc/fail2ban/jail.local — allgemeine Einstellungen und wichtigste jails:
ignoreip unbedingt Ihre eigene IP und vertrauenswürdige Netze ein, sonst sperren Sie sich womöglich selbst aus. Nach Änderungen: sudo fail2ban-client reload.
Automatisches Laden der Blockliste ipsum per Root-Cron (sudo crontab -e): Level 1 (100.000+ IPs) wird in das Set ipsum geladen, das auf der Firewall abgeblockt wird (mehr dazu im Abschnitt „IPset-Blockliste“):
ipsum heißen — genau dieses liest das Dashboard (Karte „IPset ipsum“). Level: levels/1.txt — maximale Abdeckung, levels/3.txt — genauer (3+ Quellen).
Warum der „Sicherheitsmonitor“ in zwei Zonen unterteilt ist. Der Schutz arbeitet auf zwei Ebenen, und das Dashboard vermischt sie nicht:
sshd, apache-*, nginx-* usw.) und hartnäckige Wiederholungstäter (jail recidive — jene, die schon mehrfach gesperrt wurden). Das sind IPs, die tatsächlich bei Ihnen einzubrechen versuchten — sie erscheinen auf der Angriffskarte und in der „Zeitleiste“.ipset ipsum, die auf der Firewall per DROP-Regel abgeblockt wird. Diese Adressen haben Ihren Server meist nie berührt — sie werden vorab abgeschnitten; der Zähler „IPset ipsum“ zeigt, wie viele präventiv abgeblockt wurden.Der Unterschied ist einfach: reaktiv — „diese haben angegriffen und wurden gesperrt“, präventiv — „diese wurden schon vor dem Versuch blockiert“. Früher wurde in recidive künstlich list-3 ipsum eingespeist (daher die alte Trennung „gelistete recidive“); jetzt sind in recidive nur echte Wiederholungstäter, und die Prävention läuft vollständig auf der Firewall.
ipsum — eine öffentliche, täglich aktualisierte Liste bösartiger IP-Adressen. Der Monitor zeigt die Anzahl der geladenen Adressen im Dashboard und auf der Angriffskarte und berücksichtigt sie in der Sicherheitsbewertung (−10, wenn das Set nicht geladen ist).
Die Minimalvariante ohne fail2ban — ein eigenes Set ipsum mit Sperrung über iptables:
@reboot. Zugleich setzt der Befehl create … -exist das Limit maxelem 300000 (Standard ist 65536 — Level 1 passt nicht hinein, es kommt „Hash is full“):
ipsum und bindet, falls die Firewall vom Installer verwaltet wird (frisches VPS — Profile „Vollständig“/„Reduziert“), das Set über die UFW-Regel DROP ein — Traffic von diesen IP-Adressen wird tatsächlich blockiert. Die Regel steht nach ESTABLISHED,RELATED, sodass bestehende Verbindungen (auch Ihr SSH) nicht abreißen — es werden nur neue Verbindungen aus der Liste gekappt. Das Set wird beim Start des Dienstes ipsum-load.service vor der Firewall wiederhergestellt (sonst würde UFW nicht hochkommen) und per Cron um 04:00 aktualisiert. Auf einem bereits eingerichteten Server (Panel, eigene Firewall) greift der Installer nicht in die Firewall ein — dort bleibt ipsum eine Liste für Dashboard und Angriffskarte, und die Regel DROP wird bei Bedarf manuell hinzugefügt (die Minimalvariante mit iptables … --match-set ipsum … -j DROP — oben). Bei der Autoinstallation ist manuell nichts zu tun.
Moderner Ersatz für Fail2ban mit kollektiver Threat Intelligence: Sperren aus der Community plus eigene Regeln. Benötigt einen separaten bouncer, um Sperren auf die Firewall anzuwenden.
systemctl is-active crowdsec). Starten: sudo systemctl enable --now crowdsec; bei Absturz siehe sudo journalctl -u crowdsec -n 30. Dieselbe Regel gilt für jeden Dienst im Status „Nicht gestartet“ (Suricata, Falco, Monit, MySQL).
stream halted / Sperren werden nicht angewendet. Das ist ein verwaister API-Schlüssel: Der bouncer wurde aus cscli bouncers list entfernt, aber sein alter Schlüssel blieb in /etc/crowdsec/bouncers/*.yaml. Registrieren Sie den bouncer neu und tragen Sie den frischen Schlüssel ein:
AIDE (Advanced Intrusion Detection Environment) erstellt einen Snapshot des Dateisystems und meldet bei jeder Prüfung Änderungen in /etc, /bin, /usr. Nach der Installation ist die Initialisierung der Datenbank zwingend (aideinit).
aideinit bleibt das Terminal 5–15 Minuten bei der Zeile Running aide --init... stehen — das ist normal (Hashing des gesamten Dateisystems, Festplattenlast). Nicht mit Ctrl+C abbrechen. Wenn der Prozess „hängt“, aber nichts ausgibt — möglicherweise wartet er auf eine Antwort zu einer versteckten Abfrage Overwrite existing aide.db.new [Yn]? (drücken Sie Y). Aktivität aus einer anderen Sitzung prüfen: pgrep -af aide.
aideinit: „21_aide_spamassassin … printf: invalid number“ (return code 20) — ein bekannter Bug des AIDE-Konfig-Snippets in Ubuntu 22.04. Die Datenbank wird nicht erstellt. Verschieben Sie das defekte Snippet und wiederholen Sie:
aideinit nicht ausgeführt, oder (Ubuntu 24.04) das Verzeichnis /var/lib/aide wurde mit Modus 700 angelegt und ist für www-data nicht zugänglich — behoben mit sudo chmod 755 /var/lib/aide (siehe Block oben). „Keine Prüfungen“ = die Datenbank ist vorhanden, aber es wurde noch keine Prüfung ausgeführt — das ist kein Fehler. Die Ergebnisse liest der Monitor aus /var/log/aide/aide.log.
/etc/cron.daily/aide auf neueren Ubuntu/Debian schreibt /var/log/aide/aide.log möglicherweise nicht im benötigten Format (und aide.wrapper gibt es dort nicht mehr). Zuverlässiger ist ein eigener Cron mit explizitem --config — er schreibt das Log als root im Modus 644, und der Monitor liest es ohne zusätzliche Gruppen:
chmod 755 /var/lib/aide und den Prüf-Cron um 02:00 — manuell ist nichts nötig.
sudo aideinit && sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db.
Antivirus-Scanner für Linux. Besonders nützlich, um /var/www auf PHP-Shells und Schadcode zu prüfen.
enable --now „Inaktiv“? Drei typische Ursachen:
1. In der Konfiguration steht noch die Zeile Example — clamd startet nicht, solange sie vorhanden ist:
2. Die Signaturdatenbank ist nicht heruntergeladen — clamd startet ohne sie nicht:
3. Es lädt einfach noch — clamd lädt ~8 Mio. Signaturen 30–60 Sek. in den Speicher. Warten und prüfen: systemctl is-active clamav-daemon (Status activating → lädt noch).
sudo journalctl -u clamav-daemon -n 30 --no-pager.
clamd hält nur die Signaturen im Speicher, er scannt selbst nichts nach Zeitplan. Das Dashboard zeigt Ergebnisse des geplanten Scans, daher ist ein Cronjob nötig, der scannt und ins Log schreibt. Die automatische Installation richtet den Wrapper /usr/local/bin/clamav-scan.sh und einen Cronjob um 01:30 ein — nach dem ersten Lauf werden „Geprüfte Dateien“ und „Letzter Scan“ befüllt. Sofort starten, ohne auf den Zeitplan zu warten: sudo /usr/local/bin/clamav-scan.sh.
Linux Malware Detect (LMD) — Malware-Scanner für Web-Bedrohungen: PHP-Shells, Web-Backdoors, Downloader. Nutzt die ClamAV-Engine und ergänzt sie um eigene Signaturen.
maldet --report.
update-rc.d: error: unable to read /etc/init.d/maldet erscheinen — sie ist harmlos. maldet nutzt kein init.d, Signatur-Updates und Scans laufen über /etc/cron.daily/maldet. Erscheint darunter installation completed, ist alles installiert.
apt installiert, sondern nach /usr/local/maldetect, und bei aktivem open_basedir wird seine Präsenz über die Shell geprüft — siehe Abschnitt „Seite leer, obwohl Daten auf dem Server vorhanden sind“.
Netzwerkbasiertes Angriffserkennungssystem: analysiert den Datenverkehr auf Paketebene und kennt Tausende von Angriffssignaturen. Ergänzt ModSecurity (das auf HTTP-Ebene arbeitet, Suricata auf TCP/IP-Ebene).
/var/log/suricata/eve.json als root mit Modus 750 auf das Verzeichnis, und der Webserver (www-data) kann es nicht lesen. Geben Sie das Verzeichnis für den Durchgang frei – die Dateien darin bleiben geschützt:
Fängt Systemaufrufe über eBPF/Kernel-Modul ab und erkennt Anomalien in Echtzeit: Shell aus nginx, Lesen von /etc/passwd durch einen Webprozess, Schreiben nach /bin usw.
journalctl -u falco (ohne sudo — über die Gruppe systemd-journal). Stellen Sie sicher, dass www-data in dieser Gruppe ist — siehe „sudo einrichten“ (Punkt 2) auf der Seite zur manuellen Installation.
/etc/passwd, Schreiben in Systemverzeichnisse). Null kritische Ereignisse an einem Tag auf einem ruhigen Server sind ein gesunder Zustand.
journalctl erfordert Rechte am Journal; damit das Dashboard Ereignisse zuverlässig sieht, aktiviert die automatische Installation bei Falco file_output → /var/log/falco/falco.log und setzt für den Dienst UMask=0022 (das Log ist für den Webserver lesbar). Bei einer Neuinstallation muss dies nicht manuell eingerichtet werden.
ModSecurity — eine Web-Firewall (WAF) für Apache oder Nginx. Blockiert Angriffe auf Anwendungsebene: SQL-Injektionen, XSS, Path Traversal, Scanner.
IncludeOptional /etc/modsecurity/*.conf ein, das Paket legt aber nur modsecurity.conf-recommended ab — diese fällt nicht unter die Maske *.conf. Wird sie nicht nach modsecurity.conf kopiert, bleibt SecRuleEngine auf Off: Das Modul ist geladen, die CRS-Regeln sind geladen, aber der Verkehr wird nicht geprüft und kein Audit-Log erstellt. Der Zwischenmodus DetectionOnly schreibt Ereignisse nur ins Log, ohne Anfragen zu blockieren — das Dashboard zeigt ihn gelb an.
Zugriff des Dashboards auf das Audit-Log. Das Log /var/log/apache2/modsec_audit.log gehört root (Rechte 640), der Webbenutzer kann es nicht lesen. Das Dashboard bezieht die Daten über einen Wrapper — legen Sie ihn an:
SecRuleEngine ohne Einrückung: eingerückte Zeilen stehen innerhalb von Blöcken <LocationMatch>/<Directory> (z. B. Deaktivierung der WAF für phpMyAdmin) und legen den globalen Modus nicht fest.www-data, in HestiaCP läuft der Site-Pool unter dem Site-Eigentümer (z. B. admin) — prüfen Sie grep -E '^user' /etc/php/*/fpm/pool.d/monitor.example.com.conf.X-Forwarded-For. In die Statistik gelangen nur Transaktionen mit ausgelöster Regel: die Direktive SecAuditLogRelevantStatus schreibt alle 4xx/5xx-Antworten ins Audit-Log, daher landen dort auch gewöhnliche 403/500 — als WAF-Ereignisse zählt das Dashboard sie nicht.---RULES--- wird für den Bereich „Alle aktiven Regeln“ benötigt — das Dashboard zeigt nicht nur die ausgelösten, sondern alle geladenen CRS-Regeln + benutzerdefinierte an. Die drei Pfade in der Schleife for f in … sind die typischen Orte für CRS-Regeln und lokale Ergänzungen; bei einer anderen Aufteilung (das Paket legt Dateien in ein eigenes Verzeichnis, oder benutzerdefinierte Regeln liegen nicht in /etc/modsecurity/custom-rules.conf) ermitteln Sie die tatsächlichen Pfade mit sudo grep -rl 'IncludeOptional\|^Include ' /etc/apache2/mods-enabled/security2.conf /etc/apache2/conf-enabled/*.conf 2>/dev/null und tragen sie in die Liste ein. Ist der Wrapper alt (ohne diesen Abschnitt) — zeigt der Bereich einfach die Warnung „nicht verfügbar“ an, der Rest der Seite funktioniert wie zuvor.
Auditd (Linux Audit Daemon) protokolliert Systemaufrufe auf Kernel-Ebene: An- und Abmeldungen, sudo-Befehle, fehlgeschlagene Authentifizierungsversuche, Dateiänderungen. Der Monitor zeigt Anmeldungen, fehlgeschlagene Versuche und sudo-Befehle von heute.
ausearch (/usr/sbin/ausearch) und bei Bedarf aus /var/log/audit/audit.log per tail. Beide müssen in sudoers eingetragen sein.
Überwacht Dienste (nginx, php-fpm, mysql usw.) und startet sie bei einem Ausfall neu. Kann Warnmeldungen per E-Mail senden.
monit status. In /etc/monit/monitrc muss die HTTP-Schnittstelle aktiviert sein (Block set httpd mit allow localhost), sonst gibt monit status einen Fehler zurück.
monitrc ist die Zeile set httpd auskommentiert (standardmäßig als # set httpd port 2812 …). Kommentieren Sie den Block ein und erlauben Sie localhost. (2) Ein aktivierter httpd allein überwacht nichts — Monit zählt nur das, was in check-Stanzas beschrieben ist; ohne diese bleibt die Liste selbst bei laufender Schnittstelle leer. Minimale funktionierende Konfiguration:
conf.d mit httpd auf 2812 und einer Reihe von Prüfungen an — bei einer Neuinstallation ist keine manuelle Konfiguration nötig.
PSAD analysiert das iptables-Protokoll und erkennt Portscans sowie Netzwerkangriffe, wobei jeder Quelle eine Bedrohungsstufe (1–5) zugewiesen wird. Ergänzt fail2ban und Suricata.
psad --Status (in sudoers erforderlich). Ohne iptables-Protokollierung bleibt die Seite leer — das ist normal, solange keine Scans stattgefunden haben.
Mandatory Access Control schränkt ein, auf welche Dateien und Ressourcen ein Programm zugreifen darf – selbst wenn es kompromittiert wurde. Unter Ubuntu/Debian kommt standardmäßig AppArmor zum Einsatz (meist bereits installiert und aktiv).
aa-status (in sudoers erforderlich). Er zeigt die Anzahl der Profile im Modus enforce/complain sowie Prozesse ohne Profil.
„Geladene Profile“ sind mehr als enforce + complain – das ist normal. In AppArmor 4.x (Ubuntu 24.04 und neuer) gibt es den Modus unconfined: Das Profil ist in den Kernel geladen, schränkt aber nichts ein. Ubuntu markiert so Dutzende Profile für Programme, die user namespaces nutzen (Browser, Torrent-Clients und Ähnliches). Wenn solche Profile vorhanden sind, wird die Karte „Geladene Profile“ bernsteinfarben und zeigt ihre Anzahl – etwa unconfined: 90 bei 120 geladenen und 26 im enforce-Modus. Tatsächlich schützen nur Profile im enforce-Modus; unter Ubuntu 22.04 (AppArmor 3.x) gibt es diesen Modus nicht und die Zahlen stimmen immer überein.
unconfined belassen hat, sollten nur mit Bedacht in den enforce-Modus versetzt werden: Sie sind nicht aus Versehen deaktiviert, sondern weil sonst die Programme selbst nicht mehr funktionieren. Profile im Modus complain sind etwas anderes: Dort sind die Regeln bereits geschrieben und werden nur nicht angewendet.
debsums prüft, ob die Dateien installierter Pakete mit den Prüfsummen aus dem Repository übereinstimmen — erkennt manipulierte System-Binärdateien (ergänzt AIDE). Eine vollständige Prüfung dauert 1–2 Minuten und läuft daher per cron; das Dashboard liest das Ergebnis aus data/debsums/debsums.log und ordnet es selbst in Kategorien ein (wichtig sind nur Binärdateien und Bibliotheken).
Der Job gehört in den root-cron (sudo crontab -e). Der fertige Wrapper debsums-scan.sh wird in /usr/local/bin/ abgelegt (chmod +x; siehe cron-Übersicht) und schreibt den Bericht selbst nach data/debsums/ im Dashboard.
Der Wrapper debsums-scan.sh findet data/ im Dashboard selbst — der Pfad muss nicht eingetragen werden.
/etc/ (Konfigurationen) und /usr/share/ (Ressourcen) auf dem Server sind meist normal — das Dashboard markiert sie mit einer eigenen Farbe. Bedenklich sind Änderungen an Binärdateien und Bibliotheken (/bin, /sbin, /usr/lib usw.) — die Karte „Binärdateien / Bibliotheken“ zeigt genau diese an.
Lynis wird manuell oder per cron gestartet. Der Bericht muss im Ordner data/lynis/ des Projekts abgelegt werden — der Monitor liest die Datei lynis-report.dat.
lynis-scan.sh im Hintergrund direkt aus dem Panel (ohne auf cron zu warten): zeigt „Wird gescannt…“ an und aktualisiert nach Abschluss den Bericht selbst. Dafür braucht der Web-Benutzer eine sudoers-Zeile zum Ausführen des Skripts — das Installationsprogramm fügt sie automatisch in /etc/sudoers.d/monitor ein. Wurde das Panel manuell/früher installiert, ergänzen Sie sie mit demselben Benutzer, der bereits in der Datei angegeben ist:
Logwatch muss die täglichen Berichte im Format .txt im Ordner data/logwatch/ des Projekts speichern. Der Monitor zeigt den letzten Bericht und das Archiv an.
Der Netzwerk-Monitor erfordert keine Installation — er ist eine integrierte Seite des Dashboards. Sie zeigt den Netzwerkstatus des Servers aus lokalen Quellen:
/proc/net/dev;ip;ss;journalctl -k.Die ersten drei Quellen funktionieren ohne sudo, daher sind Schnittstellen, Traffic, Verbindungen und Ports sofort sichtbar. Der Block „Kernel-Ereignisse“ nutzt journalctl -k — er wird über die Gruppe systemd-journal gelesen („sudo einrichten“, Pkt. 2), sudo ist nicht nötig. So prüfen Sie, dass alles für den Web-Benutzer verfügbar ist:
UFW BLOCK erscheinen hier nicht — sie stehen auf den Seiten „UFW-Firewall“ und „Angriffskarte“. Ein leerer Block mit grünem Haken = in den letzten 24 h gab es keine Netzwerkstörungen.
Die integrierte Seite zeigt drei Dinge:
df); die Skala wird bei ≥90% rot;lsblk), nur reale (loop/snap ausgeblendet);smartctl).Speicherplatz und Geräteliste funktionieren sofort, ohne Konfiguration. Für SMART wird das Paket smartmontools benötigt. Der Web-Prozess hat keinen direkten Zugriff auf die Festplattengeräte, daher wird SMART per cron in die Datei data/disk/smart.txt geschrieben, und das Dashboard liest sie aus.
Der Auftrag gehört in den root-cron (sudo crontab -e). Der fertige Wrapper smart-scan.sh wird nach /usr/local/bin/ abgelegt (chmod +x; siehe die Übersicht der cron-Aufträge) und schreibt selbst in data/disk/ des Dashboards.
Der Wrapper smart-scan.sh findet data/ des Dashboards selbst — der Pfad muss nicht angegeben werden. Intern schließt lsblk -e7,11 loop/cdrom aus.
Die Seite zeigt den Auslastungsverlauf des Servers der letzten 24 Stunden — Load Average, CPU-Auslastung und I/O-Wartezeit, RAM/Swap, Netzwerkverkehr (Empfang/Sendung), Festplatten-I/O (Lesen/Schreiben), Festplatten- und Inode-Belegung, offene Dateideskriptoren und MySQL-Verbindungen sowie die aktuelle Anzahl der TCP-Verbindungen und Prozesse. Voreingestellt ist das 24-Stunden-Fenster: Mit den Schaltflächen oben schalten Sie auf 7 Tage oder 30 Tage um.
Die Daten erfasst cron/collect_metrics.php — alle 5 Minuten wird ein „roher“ Snapshot der Zähler (/proc/loadavg, /proc/meminfo, /proc/stat, /proc/net/dev, /proc/diskstats, df/df -i, /proc/sys/fs/file-nr, SHOW GLOBAL STATUS LIKE 'Threads_connected') in die DB-Tabelle system_metrics geschrieben; Prozentwerte und Geschwindigkeiten berechnet die Seite selbst aus der Differenz benachbarter Snapshots (Festplatten-/Inode-/Deskriptor-Belegung und MySQL-Verbindungen sind Momentanwerte, ohne Neuberechnung). Sudo wird nicht benötigt — die Quellen werden ohne Root-Rechte gelesen.
Zwei Speichertiefen. Die „rohen“ Fünf-Minuten-Snapshots bleiben einen Tag lang erhalten (plus eine Stunde Reserve, damit der älteste Punkt der Grafik noch einen Vorgänger für die Berechnung hat). Jede abgeschlossene Stunde wird zu einer einzigen Zeile zusammengefasst; diese Stundenreihe wird 30 Tage aufbewahrt und genau sie lesen die Ansichten „7 Tage“ und „30 Tage“. Ein Monat Verlauf kostet so etwa 720 Zeilen statt rund 8600.
Der Wrapper collect-metrics-all.sh (siehe Übersicht der Cron-Aufgaben) findet selbst alle auf dem Server installierten Panel-Instanzen und startet cron/collect_metrics.php jeder Instanz im Namen des Website-Eigentümers.
Top-Prozesse. Unter den Grafiken stehen zwei Tabellen mit den fünf CPU-hungrigsten Prozessen:
Beide Tabellen beschreiben immer die letzten 24 Stunden, auch wenn die Grafiken einen Monat zeigen: Einen Prozess-Snapshot tragen nur die Fünf-Minuten-Zeilen, und die werden nicht länger als einen Tag aufbewahrt.
ps, das PHP-Skript der Erfassung und die cron/sudo-Kette darüber) werden aus der Liste ausgeschlossen — sonst stünden sie in jedem Snapshot ganz oben: ps meldet im Moment des Starts nahezu 100 % CPU. Andere cron-Aufgaben, die in derselben Minute liefen, erscheinen sehr wohl — genau dafür ist die Tabelle da.
Auslastungsbenachrichtigungen (Bereich „Einstellungen“ → „Auslastungsbenachrichtigungen“) — bei Überschreiten des Schwellenwerts für CPU/RAM/Festplatte/Inodes sendet das Panel eine Benachrichtigung über alle aktivierten Kanäle (Telegram, E-Mail, Webhook, Push — dieselben wie beim Tagesbericht; für die Alerts muss nichts zusätzlich aktiviert werden) und eine weitere, sobald die Metrik wieder normal ist. Während der Schwellenwert gehalten wird, wird nicht erneut gespammt: Die nächste Benachrichtigung kommt erst nach einem Zyklus „wieder normal → erneut überschritten“.
collect_metrics.php bei jedem Lauf (alle 5 Minuten) — ein separater Cron ist nicht nötig. Der Status „bereits benachrichtigt / noch nicht“ wird in data/alerts_state.json gespeichert, die Schwellenwerte in den Panel-Einstellungen.
Der Tagesbericht beantwortet die Frage „wie steht es um den Server“. Der Sensor beantwortet eine andere — „was ist gerade passiert“. Alle 5 Minuten fragt er die schnellen Quellen ab und hält nur fest, was sich seit der letzten Prüfung geändert hat; die Seite „Sicherheitsereignisse“ im Menü zeigt die Liste der Funde.
Langsame Prüfungen — Lynis, debsums, Paketaktualisierungen, SSL-Laufzeit — rührt der Sensor nicht an: Ihre Zahlen ändern sich ohnehin nur einmal täglich und bleiben beim Tagesbericht.
Was er bemerkt — neun Quellen:
[Priority: 1] hebt den Fund auf „kritisch“;FOUND-Zeilen im Scan-Protokoll;root (kritisch) und eine Anmeldung von einer bisher unbekannten Adresse (Warnung);Ein Werkzeug, das nicht installiert ist oder dessen Protokoll das Dashboard nicht lesen kann, schweigt einfach — das ist weder ein Fehler noch ein Ereignis.
data/secwatch_state.json), und der erste Lauf schreibt nur diese Marke. Sonst käme beim Einschalten der Überwachung eine Benachrichtigung über alles, was sich in den Protokollen über Monate angesammelt hat.
Einrichtung — „Einstellungen“ → „Ereignisüberwachung“:
23-7, in dem Warnungen nicht versendet werden.Die Benachrichtigungen laufen über dieselben Kanäle wie der Tagesbericht (Telegram, E-Mail, Webhook, Push) — nichts muss zusätzlich aktiviert werden. Alle Funde werden unabhängig davon in die Liste geschrieben, ob eine Benachrichtigung herausging, und 90 Tage aufbewahrt.
Die Ereignisliste. Filter: Zeitraum (24 Stunden, 7, 30 oder 90 Tage), Wichtigkeit und Quelle; angezeigt werden die letzten 500 Einträge. Die Schaltfläche „Jetzt prüfen“ startet genau denselben Durchlauf wie cron — praktisch direkt nach der Einrichtung, damit Sie keine fünf Minuten warten müssen; sie nennt auch den Grund, wenn keine Benachrichtigung herausging („unterhalb der Wichtigkeitsschwelle“, „Ruhezeiten“, „kein Benachrichtigungskanal eingerichtet“). Der rote Zähler am Menüpunkt ist die Zahl der kritischen Ereignisse der letzten 24 Stunden.
Die Adresskarte. Ein Klick auf eine Zeile der Ereignisliste oder des Blocks Zusammenhängende Adressen öffnet alles, was über eine Adresse bekannt ist: den zeitlichen Ablauf ihrer Ereignisse, das Land und in der ersten Zeile eine Bewertung. Eine Zeile der Liste öffnet die Karte, wenn das Ereignis genau eine Adresse betrifft; nennt es mehrere, sind die Adressen in der Zeile selbst die Links. Es gibt vier Bewertungen:
Unter dem Ablauf steht der Block Was zur selben Zeit auf dem Server geschah: Ereignisse, die überhaupt keine Adresse haben. AIDE weiß nicht, wer die Datei geändert hat, ClamAV nicht, wer die infizierte gebracht hat. Gezeigt werden jene aus der Aktivität der Adresse und den sechs Stunden danach. Erst die Anmeldung zusammen mit dem, was folgte, trennt einen Versuch von tatsächlichem Zugriff.
Zeitplan. Die Aufgabe kommt in den root-crontab (sudo crontab -e), um 2 Minuten gegenüber der Metrik-Erfassung versetzt, damit beide nicht gleichzeitig starten:
php cron/security_watch.php. Der Wrapper findet alle Installationen des Dashboards auf dem Server und startet die Prüfung im Namen des Website-Eigentümers — mit genau den sudo-Rechten, die das Dashboard aus dem Web heraus nutzt. Ein direkter Aufruf aus dem root-crontab würde die Statusdatei data/secwatch_state.json mit dem Eigentümer root anlegen, und die Schaltfläche „Jetzt prüfen“ im Dashboard würde nicht mehr funktionieren.
Die Seite „Webserver“ wertet das Zugriffsprotokoll aus und zeigt, wie viele Anfragen es gab, welcher Anteil davon fehlschlug und wer diese Anfragen gestellt hat. ModSecurity beantwortet die Frage „was wurde blockiert“, diese Seite die Frage „was kam überhaupt auf der Website an“.
Zu sehen sind: Anzahl der Anfragen, RPS, Fehlerquote, ein eigener 5xx-Zähler und das übertragene Datenvolumen; eine Grafik der Anfragen nach Stunden; die Verteilung der Codes 2xx/3xx/4xx/5xx; häufige Adressen, häufige IPs, häufige Fehler (Code plus Pfad) und Clients (User-Agent). Zeitraum: 24 Stunden oder 7 Tage.
Quelle ist das Zugriffsprotokoll im Format combined, deshalb passen sowohl Nginx als auch Apache, und ein zusätzliches Modul wird nicht gebraucht. Das Dashboard sucht das Protokoll unter den Standarddateien:
/var/log/nginx/access.log/var/log/apache2/access.log/var/log/apache2/other_vhosts_access.log/var/log/httpd/access_logAußerdem prüft das Dashboard Dateien namens *access*.log und *requests*.log in /var/log/nginx/, /var/log/apache2/ und /var/log/httpd/. So wird auch ein Protokoll gefunden, das eine Website per CustomLog-Direktive in eine eigene Datei schreibt — etwa arciveo-monitor_requests.log, das der Arcivéo-Installer anlegt.
Gelesen wird nur ein Protokoll: Steht Nginx vor Apache, würde das Addieren zweier Protokolle jede Anfrage doppelt zählen. Genommen wird das erste Protokoll aus der Liste oben, in das während des letzten Tages geschrieben wurde (die per Namensmuster gefundenen werden danach geprüft, die neuesten zuerst); wurde einen Tag lang in keines geschrieben, das zuletzt geänderte nicht leere. Ein von logrotate geleertes oder von einem abgeschalteten Webserver übrig gebliebenes Protokoll verdeckt das aktive daher nicht. Gelesen wird der letzte Abschnitt des Protokolls (3 MB), das Ergebnis wird 5 Minuten zwischengespeichert — auf einer stark besuchten Website kann der gewählte Zeitraum daher unvollständig abgedeckt sein; die tatsächlich erreichte Abdeckung steht über der Grafik.
adm, und der Webbenutzer ist nicht darin. Der Arcivéo-Installer nimmt ihn in diese Gruppe auf; nach einer manuellen Installation hilft ein kleiner Wrapper von root, dem genau eine Sache erlaubt ist — das Protokoll auszugeben (die ModSecurity-Seite funktioniert genauso). Der Wrapper wählt das Protokoll nach denselben Regeln wie das Dashboard. Der Befehl steht direkt auf der Seite; hier noch einmal. Fügen Sie ihn vollständig ein — es ist ein einziger Befehl:
Der Webbenutzer kann von www-data abweichen — prüfen Sie, unter welchem Benutzer der PHP-FPM-Pool der Website läuft (ps -o user= -C php-fpm), und tragen Sie ihn in die sudoers-Zeile ein. Enthält der Name des Protokolls weder access noch requests, ergänzen Sie seinen Pfad am Anfang der Zeile L=… im Wrapper.
Versuche bekannter Exploits. Das Panel gleicht Anfragen aus dem Log mit Signaturen von rund zwanzig verbreiteten Exploits ab: PHP-CGI, Path Traversal in Apache, PHPUnit, Log4Shell, Schwachstellen in Routern, Kameras und VPN-Gateways. Für jeden Versuch beantwortet es, ob er auf diesem Server funktionieren kann, und stützt sich dabei auf Fakten: die installierten Versionen von Apache und PHP, ob Java vorhanden ist, und den Antwortcode des Servers auf den Dateiabruf. Rot markiert ist nur, was tatsächlich funktionieren kann.
Webserver-Härtung. Das Panel ruft jede Website des Servers über 127.0.0.1 ab und prüft, was ein Besucher erhält: ob die Versionen von Webserver und PHP sichtbar sind, ob die Methode TRACE aktiviert ist und ob die Schutz-Header Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy und Content-Security-Policy vorhanden sind. Die Websites stammen aus der Adresse, unter der das Panel geöffnet ist, und aus den Dateien der virtuellen Hosts, sofern das Panel sie lesen kann. Das Ergebnis wird alle 10 Minuten aktualisiert.
Fehlt etwas, erscheint unter der Tabelle ein einzelner Befehl. Er legt die eigene Datei zz-arciveo-hardening.conf an und lädt den Webserver erst nach bestandenem Konfigurationstest neu; Header, die eine Website bereits selbst sendet, werden nicht doppelt gesetzt. CSP wird nicht als eine Zeile angeboten: Die Richtlinie wird für die jeweilige Website erstellt, sonst lädt sie ihre eigenen Skripte, Styles und Schriften nicht mehr. Rückgängig machen lässt sich die Änderung unter Apache so:
ServerSignature) wird nicht markiert, wenn die Webserver-Version bereits verborgen ist: Ohne Version zeigt sie nur den Servernamen und den Hostnamen.
Die Seite „Angriffskarte“ ermittelt das Land anhand der IP-Adresse mit dem Befehl geoiplookup. Ohne das GeoIP-Paket werden keine Länder erkannt und es erscheinen keine Punkte auf der Karte:
/usr/share/GeoIP/GeoIP.dat ist für alle lesbar, die Ergebnisse werden in tmp/geoip_cache.json zwischengespeichert. Die Karte selbst (Leaflet + OpenStreetMap-Kacheln) wird im Browser geladen – der Rechner, auf dem das Dashboard geöffnet ist, benötigt Internetzugang.
Zwei integrierte Dashboard-Karten, die nicht „ein/aus“ eines Tools zeigen, sondern die tatsächliche Absicherung des Servers. Sie erfordern keine Installation und werden lokal ohne sudo ausgelesen.
Externe Exposition — wie viele Dienste auf allen Schnittstellen lauschen (0.0.0.0/[::]) und von außen erreichbar sind. Wird rot hervorgehoben, wenn eine Datenbank oder ein Cache nach außen offensteht (MySQL, PostgreSQL, Redis, MongoDB, Memcached, Elasticsearch) — das ist ein direktes Sicherheitsleck (−10 auf die Sicherheitsbewertung). Quelle: ss -tuln.
127.0.0.1 (bind-address in der MySQL-/PostgreSQL-Konfiguration, bind 127.0.0.1 in Redis) oder schließen Sie den Port in UFW.
127.0.0.1 (loopback) lauscht, ist nur für den Server selbst sichtbar — von außen nicht erreichbar, selbst wenn der Port „offen“ ist. Deshalb ist Postfix auf Port 25, gebunden an loopback, sicher: Die Autokonfiguration setzt inet_interfaces = loopback-only (dazu ein neutraler smtpd_banner — behebt den Lynis-Hinweis MAIL-8818 zur Preisgabe der Version). Die Karte „Externe Exposition“ zählt nach außen nur, was auf 0.0.0.0/[::] lauscht; Loopback-Dienste fallen nicht darunter.
/etc/postfix/main.cf smtpd_banner = $myhostname ESMTP (ohne Version und OS) und inet_interfaces = loopback-only, dann sudo systemctl restart postfix.
Sicherheitsupdates — wie viele Sicherheitspatches zur Installation anstehen und ob nach einem Kernel-Update ein Neustart nötig ist (−5 auf die Sicherheitsbewertung, wenn Patches vorliegen). Quelle: /usr/lib/update-notifier/apt-check, Datei /var/run/reboot-required. Die detaillierte Liste finden Sie auf der Seite „Sicherheitsupdates“.
update-notifier-common). Fehlt apt-check — zählt der Monitor die Patches über apt-get -s upgrade.
Automatische Sicherheitsupdates (unattended-upgrades) — auf der Seite „Sicherheitsupdates“ zeigt eine eigene Karte, ob die automatische Installation von Sicherheitspatches aktiviert ist und wann sie zuletzt lief. Sudo ist nicht nötig — der Status wird über apt-config dump ausgelesen.
Ein Backup ist die wichtigste Absicherung: Datenverlust ist schlimmer als jeder Einbruch. Zwei Dinge sind nötig — ein Backup des Servers/der Websites und separat ein Backup der Panel-Datenbank (dort liegen Benutzer, WebAuthn-Schlüssel, Einstellungen, Lizenz).
Variante A — HestiaCP: Reiter Backup beim Benutzer → Schaltfläche zum Erstellen eines Backups (oder zeitgesteuert in den Servereinstellungen). Das Backup umfasst Websites und ihre Datenbanken.
Variante B — manuell (cron): Datenbank-Dump + Archiv des Verzeichnisses data/ des Panels:
Aktualisierung auf eine neue Version. Erstellen Sie zuerst ein Backup. Laden Sie dann die Code-Dateien neu hoch und behalten Sie Ihre Daten:
public/, includes/, assets/, cron/, database/ sowie die Root-.htaccess (Front-Controller — das Routing darf nicht von der alten Version stammen), manifest.json, sw.js;config.php (DB-Daten), data/ (Berichte), logs/, tmp/ (Sitzungen und Cache).SSH_FX_PERMISSION_DENIED — Permission denied. Die Panel-Dateien gehören www-data (so wurden sie bei der Installation gesetzt), während sich der SFTP-Client unter Ihrem eigenen Benutzer verbindet, der keine Schreibrechte hat. Dem www-data das gesamte Panel „damit es läuft“ zu übergeben — genau das führt zu diesem Fehler; unten drei Wege, jeder löst das Problem.
data/ (Berichte), tmp/ (Sitzungen und Cache), logs/; diese bleiben bei www-data. Der Rest ist Code, und der Webserver braucht ihn nur zum Lesen, was die Gruppe www-data mit den Rechten 644 ermöglicht. Als Nebeneffekt: Bei einer PHP-Schwachstelle lassen sich die Panel-Dateien nicht mehr überschreiben. Auf Hosting-Panels (HestiaCP und ähnliche) ist Variante A nicht nötig: Dort gehören die Website-Dateien ohnehin dem Konto, mit dem Sie sich per SFTP anmelden, und der Webserver liest sie über die Gruppe.
chmod auf die Dateien setzt die ACL-Maske zurück, und der Zugriff verschwindet stillschweigend. Wenn nach dem „Aufräumen der Rechte“ das Hochladen erneut an Permission denied scheitert — führen Sie beide setfacl-Befehle noch einmal aus.
2 in Variante C ist setgid: per SFTP hochgeladene Dateien bleiben in der Gruppe www-data, sonst kann das Panel sie nicht überschreiben. Nach Variante C verbinden Sie sich in FileZilla neu — die neue Gruppe wird erst bei einer neuen Anmeldung wirksam. Prüfen: id deploy (die Gruppe www-data muss erscheinen) und ls -ld /path/to/monitor (drwxrwsr-x — das s bedeutet, dass setgid gesetzt ist).
Umzug auf einen anderen Server:
config.php, data/.mysqldump auf dem alten → Import auf dem neuen; passen Sie die DB-Daten in config.php an.adm, cron-Aufgaben.Das Dashboard läuft bereits und auf demselben Server wird eine weitere Website gebraucht — mit eigener Domain neben dem Monitor. Nach der automatischen Einrichtung ist der Server ein gewöhnlicher Apache + PHP-FPM, die Website braucht also drei Dinge: ein eigenes Verzeichnis, einen eigenen vhost und ein eigenes Zertifikat. Das Dashboard bleibt dabei unangetastet: Es überwacht den gesamten Server, eine zweite Instanz für die zweite Domain ist nicht nötig.
site2.example.com ist die Adresse der neuen Website. Das kann sowohl eine eigene Domain (mycompany.com) als auch eine Subdomain (shop.mycompany.com) sein — für Apache macht das keinen Unterschied, es unterscheiden sich nur der DNS-Eintrag (Schritt 1) und die Zertifikatsausstellung (Schritt 5). site2 ist lediglich ein Kurzname der Website: So heißen das Verzeichnis /var/www/site2 und die Konfigurationsdatei site2.conf. Mit der Domain hat er nichts zu tun, Apache nimmt die Adresse ausschließlich aus ServerName; der Name ist frei wählbar — für shop.mycompany.com bietet sich etwa shop an: Verzeichnis /var/www/shop, Konfiguration shop.conf.
1. DNS. Legen Sie im DNS-Bereich Ihres Domain-Registrars einen A-Eintrag auf die IP dieses Servers an:
Prüfen Sie es nach einigen Minuten: dig +short site2.example.com muss die IP des Servers zurückgeben.
2. Verzeichnis der Website.
3. Der vhost. Der Block wird komplett ins Terminal eingefügt — der Pfad zum PHP-FPM-Socket wird automatisch ermittelt:
4. Website aktivieren und die Konfiguration vor dem Neuladen prüfen:
5. SSL. certbot wurde von der automatischen Einrichtung bereits installiert; das DNS muss zu diesem Zeitpunkt auf den Server zeigen:
Eine dritte und weitere Domains werden genauso hinzugefügt — wiederholen Sie die Schritte 1–5 mit anderer Domain und anderem Verzeichnis.
Host zu keinem ServerName (Aufruf über die IP oder eine fremde Domain, die auf Ihren Server zeigt), liefert Apache die alphabetisch erste aktivierte Website aus /etc/apache2/sites-enabled/ aus. Das Standard-000-default deaktiviert die automatische Einrichtung, daher bleibt der vhost des Dashboards (arciveo-monitor.conf) der „Dienst habende“ — auf Websites, die über ihre eigenen Namen aufgerufen werden, wirkt sich das nicht aus. Soll über die IP eine andere Website öffnen, benennen Sie deren Datei so, dass sie alphabetisch vorne steht (zum Beispiel 000-site2.conf).
site2_error.log und site2_access.log unter /var/log/apache2/.
.htaccess gesteuert (Front Controller), und eine verschachtelte Website würde etwas anderes ausliefern als erwartet. Halten Sie die Websites nebeneinander: /var/www/monitor, /var/www/site2.
Wenn Sie sich nicht anmelden können, lässt sich alles direkt in der Datenbank auf dem Server beheben. Öffnen Sie die Datenbank (Name aus config.php):
WebAuthn-Schlüssel verloren (zweiter Faktor scheitert) — 2FA deaktivieren, per Passwort anmelden, neuen Schlüssel registrieren:
Passwort vergessen — neuen Hash setzen (auf dem Server erzeugen und einsetzen):
Selbst per IP-Filter ausgesperrt — Einschränkung deaktivieren:
sudo mysql auf dem Server oder phpMyAdmin / Datenbankbereich im Hosting-Panel. Aktivieren Sie nach der Wiederherstellung WebAuthn und den IP-Filter erneut.
Die Aufgabenübersicht liegt im root-Cron des Servers (hinzugefügt über sudo crontab -e). Behalten Sie nur die Zeilen der Tools, die Sie nutzen; passen Sie die Pfade an Ihren Server an.
sudo crontab -l und ob der cron-Dienst aktiv ist.
TIMEZONE aus config.php. Die Konstante TIMEZONE wirkt nur auf PHP (wie das Dashboard Datumsangaben anzeigt), aber der cron-Daemon startet Aufgaben nach der Systemzeit des OS. Stimmt die Serverzeitzone nicht mit Ihrer überein, kommt der „08:00“-Bericht zur falschen Zeit. Beispiel: Der Server steht in einer anderen Zone (Europe/London, UTC+1), Sie aber in Berlin (UTC+2) → der „08:00“-Bericht kommt bei Ihnen um 09:00. Prüfen Sie die Systemzone und passen Sie sie bei Bedarf an Ihre an:
0 8 * * * um 08:00 Ortszeit. Andernfalls müsste man den Cron selbst verschieben, aber bei der Zeitumstellung Winter/Sommer würde die Verschiebung wieder abweichen — daher ist es korrekter, die Systemzone einzustellen.
crontab.txt) liegen im Ordner system/ neben dem Projekt, außerhalb von public_html. Das ist kein Teil der Website — sie müssen nicht ins Web-Root geladen werden; platzieren Sie sie auf dem Server unter den Systempfaden (wie in der crontab oben):
lynis-scan.sh → /usr/local/bin/ (chmod +x) — startet lynis audit system, setzt während des Scans das Flag /tmp/lynis-running und kopiert lynis-report.dat in data/lynis/ des Dashboards;logwatch_daily.sh → /usr/local/bin/ (chmod +x) — erstellt den täglichen Logwatch-Bericht (sshd, fail2ban, sudo, postfix) in data/logwatch/;smart-scan.sh → /usr/local/bin/ (chmod +x) — erfasst den Zustand der Datenträger (smartctl) in data/disk/;debsums-scan.sh → /usr/local/bin/ (chmod +x) — prüft die Paketintegrität (debsums) in data/debsums/;clamav-scan.sh → /usr/local/bin/ (chmod +x) — ClamAV-Virenscan gefährlicher Pfade (web, home, temp); schreibt die Übersicht nach /var/log/clamav/scan.log, von wo sie die ClamAV-Seite liest (Zeile 01:30 in der crontab oben);load-ipsum.sh → /usr/local/bin/ (chmod +x) — aktualisiert das ipset-Set ipsum (Level 1) an Ort und Stelle, ohne die aktiven Firewall-Regeln zu unterbrechen (Zeile 04:00 in der crontab oben);daily-report-all.sh → /usr/local/bin/ (chmod +x) — startet den Bericht cron/daily_report.php des Dashboards (Zeile 08:00 in der crontab oben);daily_report.php — ist bereits im Dashboard enthalten (cron/daily_report.php), wird über daily-report-all.sh gestartet, muss nicht separat installiert werden;collect-metrics-all.sh → /usr/local/bin/ (chmod +x) — startet cron/collect_metrics.php des Dashboards (Seite „Leistung“, Zeile */5 in der crontab oben); collect_metrics.php ist bereits im Dashboard enthalten, muss nicht separat installiert werden;security-watch-all.sh → /usr/local/bin/ (chmod +x) — startet cron/security_watch.php des Dashboards im Namen des Website-Eigentümers (Seite „Sicherheitsereignisse“, Zeile 2-57/5 im crontab oben); security_watch.php gehört bereits zum Dashboard und muss nicht separat installiert werden;fleet-push-all.sh → /usr/local/bin/ (chmod +x) — sendet die Serverübersicht über cron/fleet_push.php des Dashboards an das Benutzerkonto (Zeile 3,18,33,48 oben);crontab.txt (system/cron/) — Muster-Aufgaben; tragen Sie die benötigten Zeilen über sudo crontab -e ein./usr/local/bin/. Direkt aus FileZilla lässt sich dort nichts schreiben — das Verzeichnis gehört root, und der SFTP-Client erhält SSH_FX_PERMISSION_DENIED. Vorgehen: zuerst die Datei nach /tmp hochladen (dorthin dürfen alle schreiben), dann mit einem Befehl an ihren Platz verschieben:
/tmp im Wurzelverzeichnis des Servers — nicht /var/tmp und nicht tmp/ innerhalb des Dashboards selbst (Letzteres gehört www-data und ist für Ihren Benutzer gesperrt). Im FileZilla-Baum ist /tmp ein Zweig der obersten Ebene, neben var, nicht darin.
/usr/local/bin/, Log — /var/log/arciveo-cron.log) — manuell ist nichts zu tun.
/home/*/web/*/public_html und /var/www/* durchgehen, und legen Berichte in deren data/ ab. Liegt das Dashboard unter einem anderen Pfad — fügen Sie ihn in der Zeile for app in … innerhalb der Skripte hinzu, sonst gelangen die Berichte von Lynis/SMART/debsums/Logwatch nicht ins Dashboard.
logs/cron.log wird zuerst vom root-Cron erstellt — sie gehört dann root, und der Tab „Cron-Journal“ im Dashboard kann sie weder lesen noch leeren. Erstellen Sie die Datei vorab als Web-Benutzer (Eigentümer des Website-Verzeichnisses; bei HestiaCP das Konto, z. B. admin) — dann schreibt der root-Cron nur an, ohne den Eigentümer zu ändern:
stat -c %U /path/to/monitor.
sudo crontab -e), sonst wird sie doppelt ausgeführt.
sudo crontab (das wäre eine direkte Eskalation zu root für jeden, der Zugriff auf die Dashboard-Sitzung erhält), sondern ein enges Skript mit zwei Befehlen (list/set), das nur seinen eigenen Block zwischen den Dienstkommentaren berührt. Einmalig installieren:
www-data unterscheiden — prüfen Sie, unter wem der PHP-FPM-Pool der Website läuft (ps -o user= -C php-fpm), und setzen Sie ihn in der sudoers-Zeile ein.
public/crontab_monitor.php per FTP/SFTP unter einem anderen Systembenutzer (z. B. root) als die übrigen Website-Dateien hochgeladen wurde, kann der Webserver sie nicht lesen. Gleichen Sie Eigentümer und Rechte mit einer benachbarten Datei ab und passen Sie sie an:
Der Monitor erkennt vorhandene Werkzeuge über dpkg-query — die APT-Paketdatenbank. Wenn ein Werkzeug nicht über apt installiert wurde (manuell, per snap oder aus dem Quellcode), sieht dpkg es nicht.
Fehler 500 — prüfen Sie die Logs von PHP, Nginx und des Monitors selbst:
www-data, sondern unter dem Benutzerkonto (z. B. admin — Eigentümer des Website-Verzeichnisses). Alle sudo-Regeln und Gruppenmitgliedschaften (adm, systemd-journal) müssen für diesen Benutzer eingetragen werden, sonst zeigen die Module „Nicht aktiv / 0“ bei laufenden Diensten. Den realen PHP-Benutzer ermitteln: ps -o user= -C php-fpm | sort -u oder den Eigentümer des Website-Verzeichnisses stat -c '%U' /path/to/monitor. Ersetzen Sie in allen folgenden Befehlen www-data durch diesen. Die automatische Installation erkennt den Web-Benutzer selbst und trägt sudoers darauf ein.
Daten werden nicht angezeigt — fast immer fehlen sudo-Rechte. Prüfen Sie den konkreten Befehl als Web-Benutzer (ersetzen Sie www-data durch Ihren). Der Schalter -n = ohne Passwort, wie bei PHP — wenn ein Passwort verlangt wird, fehlt die Regel in sudoers:
sudo aa-status im Terminal zeigt Profile, aber die Seite „AppArmor“ zeigt „Inaktiv“). Ursache: Der Web-Benutzer hat kein sudo-Recht für den Befehl dieses Moduls. Prüfen Sie ihn aus der Liste oben: Wird ein Passwort verlangt — fügen Sie die fehlende Zeile in /etc/sudoers.d/monitor hinzu („sudo-Einrichtung“). Häufige „neue“ Befehle: /usr/sbin/aa-status (MAC), /usr/sbin/psad --Status (PSAD).
apache2ctl, ausearch, aa-status oder ss nicht erlaubt, oder der Web-Benutzer ist nicht in den Gruppen adm/systemd-journal (von dort werden die Logs von fail2ban/auth/modsec und journalctl gelesen — Falco und Kernel-Ereignisse).
Symptom: Auf dem Server sind Daten vorhanden (per Shell sichtbar), doch die Seite zeigt „keine Daten“ oder einen falschen Status – zum Beispiel meldet AIDE „Nicht initialisiert“, obwohl die Datenbank erstellt wurde.
Ursache ist open_basedir: Viele Panels und Hoster beschränken den PHP-FPM-Pool auf das Domain-Verzeichnis, daher werden die PHP-Funktionen file_exists(), file_get_contents(), filemtime() auf Systempfaden (/var/lib/aide, /var/log, /proc…) blockiert. Der Monitor umgeht dies, indem er solche Pfade mit regulären Systembefehlen (cat, test, stat) liest.
open_basedir. Die richtige Lösung ist das Lesen über Systembefehle (für AIDE und den Netzwerk-Monitor bereits umgesetzt). open_basedir auf /var, /proc auszuweiten ist unnötig und weniger sicher.
Der Monitor prüft Zertifikate, indem er sich direkt über Port 443 mit den Domains verbindet. Ist eine Domain vom Server selbst nicht erreichbar oder der Port durch die Firewall gesperrt, schlägt die Prüfung fehl.
/etc/nginx/sites-enabled/, /etc/nginx/conf.d/) und Apache (/etc/apache2/sites-enabled/) sowie dem aktuellen Host aus HTTP_HOST.
Der Monitor verbindet sich mit MySQL unter einem Benutzer aus config.php, der nur Zugriff auf seine eigene Datenbank hat. MySQL zeigt in information_schema nur Datenbanken mit entsprechenden Rechten – die übrigen bleiben daher unsichtbar.
Damit der Monitor alle Datenbanken sieht, erteilen Sie diesem Benutzer nur Leserechte (einmalig als root; setzen Sie den Benutzernamen aus config.php ein):
sudo mysql: Die Datenbankliste wird über die eigene PDO-Verbindung abgerufen.
PostgreSQL erfordert Zugriff auf der Ebene des Benutzers postgres, den der Web-Benutzer des Dashboards nicht hat. Ein weit gefasstes sudo psql aus PHP zu öffnen, ist unsicher — stattdessen ruft das Dashboard einen eng begrenzten Wrapper ohne Parameter auf, der nur die Version, die Anzahl der Verbindungen und die Liste der Datenbanken mit Größen ausgibt. Erstellen Sie ihn:
monitor-pgstat aus sudoers (Schritt 13 der manuellen Installation) und erstellen Sie das Skript nicht: Die PostgreSQL-Karte bleibt einfach inaktiv.
Das Dashboard zeigt, was passiert; unten steht, was zu tun ist in typischen Situationen. Grundprinzip: nicht in Panik geraten, mit legitimer Aktivität abgleichen (Ihre Aktionen, Updates, Backups) und je nach Schweregrad reagieren.
ignoreip steht./etc, außerhalb von /usr/share) — potenziell manipuliert. Prüfen Sie das Paket: debsums PACKAGE_NAME, installieren Sie es im Zweifel neu (apt install --reinstall).127.0.0.1 oder schließen Sie den Port in UFW. Das ist ein echtes Loch.certbot renew oder die Einstellungen im Panel).sudo apt update && sudo apt upgrade; nach einem Kernel-Update den Server neu starten.