Manuelle Installation

Vollständig manuelle Installation: vom frisch gekauften VPS bis zum laufenden Dashboard, Schritt für Schritt. Serververbereitung, Website-Erstellung, Datenbank, config.php und SSL werden hier beschrieben. Befehle zu jedem Sicherheitstool und zu cron finden Sie im FAQ-Nachschlagewerk, Links folgen im Verlauf.

Grundregel: Wenn Sie SSH oder die Firewall ändern, schließen Sie die aktuelle Verbindung nicht, bevor Sie die neue in einem separaten Fenster geprüft haben. Falls der Zugriff dennoch verloren geht — fast alle Hoster bieten eine Notfallkonsole (VNC/Recovery) im Control Panel.

01. VPS mit Ubuntu/Debian gekauft — womit anfangen

Nach dem Kauf sendet Ihnen der Hoster: IP-Adresse, Benutzername (meist root) und Passwort (oder SSH-Schlüssel). Das genügt für die Anmeldung. Ablauf (jeder Schritt ist ein Abschnitt weiter unten):

  1. Per SSH mit dem Server verbinden;
  2. System aktualisieren, Hostname und Zeitzone festlegen;
  3. Einen normalen Benutzer mit sudo-Rechten anlegen (nicht als root arbeiten);
  4. Anmeldung per SSH-Schlüssel einrichten und Passwort-Anmeldung deaktivieren;
  5. Firewall und Autoschutz aktivieren;
  6. (optional) das Steuerungspanel HestiaCP installieren — Webserver, Datenbank und Mail „out of the box“.

02. Erste Verbindung per SSH

SSH ist ein sicheres Terminal zum Server. Setzen Sie Ihre eigene IP anstelle von 203.0.113.10 ein.

203.0.113.10 ist ein Beispiel, eine nicht existierende Adresse (für Dokumentation reserviert). Geben Sie sie nicht so ein – ersetzen Sie sie durch die echte IP Ihres Servers aus der Hoster-E-Mail. Andernfalls kommt keine Verbindung zustande.

Windows 10/11: Öffnen Sie PowerShell oder das „Terminal“ und nutzen Sie das eingebaute ssh (oder die Clients PuTTY / MobaXterm).
macOS / Linux: Öffnen Sie das „Terminal“.

# Anmeldung als root (das Passwort kam vom Hoster): ssh root@203.0.113.10 # Falls der Hoster eine Schlüsseldatei statt eines Passworts gegeben hat: ssh -i pfad/zum/schluessel root@203.0.113.10
Bei der ersten Verbindung fragt SSH nach der „authenticity of host“ – geben Sie yes ein. Das Passwort wird bei der Eingabe nicht angezeigt (das ist normal). Falls der Hoster ein temporäres Passwort gegeben hat, ändern Sie es mit dem Befehl passwd.

03. Systemaktualisierung und Grundeinrichtung

Zuerst alle Pakete aktualisieren und Hostname sowie Zeitzone festlegen.

# System aktualisieren: apt update && apt upgrade -y # Basis-Werkzeuge: apt install -y curl wget ufw fail2ban unattended-upgrades # Zeitzone (Beispiel) und Hostname: timedatectl set-timezone Europe/Berlin hostnamectl set-hostname myserver # Automatische Sicherheitsupdates: dpkg-reconfigure -plow unattended-upgrades
Liste der Zeitzonen — timedatectl list-timezones. Erscheint am Ende der Aktualisierung ein blaues Fenster „Daemons using outdated libraries“ — markieren Sie alle Dienste (Leertaste) und drücken Sie OK, das ist sicher.

04. Benutzer mit sudo anlegen

Dauerhaft als root zu arbeiten ist unsicher. Legen Sie einen normalen Benutzer an und geben Sie ihm sudo-Rechte (Admin-Befehle bei Bedarf ausführen). Ersetzen Sie deploy durch einen beliebigen Namen.

# Benutzer anlegen (setzt Passwort und fragt Daten ab — Enter möglich): adduser deploy # Zur Gruppe sudo hinzufügen: usermod -aG sudo deploy # Prüfen (als root): su - deploy sudo whoami # sollte ausgeben: root exit
Melden Sie sich künftig mit diesem Benutzer am Server an: ssh deploy@203.0.113.10, und führen Sie Admin-Befehle mit dem Präfix sudo aus.

05. SSH-Schlüssel und Passwort-Login deaktivieren

Die Anmeldung per Schlüssel ist sicherer als per Passwort: Ein Passwort lässt sich erraten, ein Schlüssel praktisch nicht. Zuerst erstellen wir den Schlüssel auf dem eigenen Rechner, kopieren ihn auf den Server, prüfen die Anmeldung – und erst danach deaktivieren wir das Passwort.

Schritt 1. Schlüssel auf dem eigenen Rechner erstellen (Windows PowerShell / macOS / Linux):

ssh-keygen -t ed25519 -C "my-laptop" # Enter bei allen Fragen (der Schlüssel landet in ~/.ssh/id_ed25519)

Schritt 2. Den öffentlichen Schlüssel auf den Server kopieren:

# macOS / Linux: ssh-copy-id deploy@203.0.113.10 # Windows (PowerShell): type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh deploy@203.0.113.10 "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

Schritt 3. Die Anmeldung per Schlüssel in einem neuen Fenster prüfen – sie sollte ohne Passwort funktionieren:

ssh deploy@203.0.113.10
Führen Sie Variante B nicht aus, solange die Anmeldung per Schlüssel nicht geprüft ist und funktioniert (Schritte 1–3), und schließen Sie die laufende Sitzung nicht. Sie deaktiviert den Passwort-Login für alle Benutzer, einschließlich root. Ohne funktionierenden Schlüssel verlieren Sie den Zugriff auf den Server vollständig – zurückholen lässt er sich dann nur über die Konsole des Hosters. Kein Schlüssel – nehmen Sie Variante A.

Schritt 4. Den SSH-Zugriff verschärfen. Die Einstellungen legen wir in eine separate Datei, die Hauptkonfiguration bleibt unberührt. Wählen Sie die passende Variante:

Variante A – nur root sperren, Passwort behalten. Kein Schlüssel nötig, kein Zugriffsverlust:

echo 'PermitRootLogin no' | sudo tee /etc/ssh/sshd_config.d/00-hardening.conf >/dev/null sudo systemctl restart ssh

Variante B – vollständiges Hardening. Passwort-Login deaktivieren und root nur per Schlüssel zulassen. Führen Sie dies nur aus, wenn Sie sich vergewissert haben, dass die Anmeldung per Schlüssel funktioniert:

sudo tee /etc/ssh/sshd_config.d/00-hardening.conf >/dev/null <<'EOF' PubkeyAuthentication yes PasswordAuthentication no PermitRootLogin prohibit-password KbdInteractiveAuthentication no EOF sudo systemctl restart ssh
In beiden Varianten ist root per Passwort gesperrt. PermitRootLogin no verbietet root vollständig, prohibit-password lässt die Anmeldung nur per Schlüssel zu (für die Administration melden Sie sich als deploy an und nutzen sudo). Wenn Sie den SSH-Port ändern möchten – fügen Sie die Zeile Port 2222 hinzu, aber öffnen Sie zuerst den neuen Port in der Firewall (nächster Abschnitt) und prüfen Sie die Anmeldung, sonst sperren Sie sich selbst aus.

06. Basis-Firewall und Autoschutz

Schließen Sie alles Unnötige per Firewall und aktivieren Sie fail2ban (bannt SSH-Passwortangriffe). Erlauben Sie zuerst SSH, sonst verlieren Sie nach dem Aktivieren von UFW den Zugriff.

# SSH (oder Ihren Port, falls geändert) und Web erlauben: sudo ufw allow OpenSSH sudo ufw allow 80,443/tcp # Firewall aktivieren: sudo ufw enable sudo ufw status verbose # fail2ban — SSH-Schutz gegen Angriffe (Basisprofil sofort aktiv): sudo systemctl enable --now fail2ban sudo fail2ban-client status sshd
Das ist das Minimum. Funktionierende fail2ban-Einstellungen, die ipsum-Sperrliste, erweitertes UFW und weitere Werkzeuge finden Sie in der Gruppe „Sicherheitswerkzeuge“ des Handbuchs. Das Arcivéo Monitor-Dashboard selbst zeigt Ihnen den Status all dessen übersichtlich an.

07. Installation der HestiaCP-Panel (optional)

HestiaCP — kostenlose Hosting-Verwaltungspanel: installiert und konfiguriert Webserver (nginx + apache), PHP, Datenbank (MariaDB), Mail, DNS und SSL-Zertifikate und bietet eine Weboberfläche für Websites. Praktisch, wenn Sie nicht alles manuell einrichten möchten und Websites hosten wollen (auch die Arcivéo Monitor-Panel selbst).

Installieren Sie HestiaCP auf einem sauberen Server (frisches unterstütztes Ubuntu/Debian, mindestens ~1–2 GB RAM), vor der Installation anderer Webserver und Datenbanken — sonst kommt es zu Konflikten. Die Installation dauert 10–20 Minuten und startet den Server neu.
# Installer herunterladen und starten: wget https://raw.githubusercontent.com/hestiacp/hestiacp/release/install/hst-install.sh sudo bash hst-install.sh

Der Installer fragt nach E-Mail und Hostname und richtet dann den gesamten Stack ein. Nach dem Neustart ist die Panel unter https://YOUR_IP:8083 erreichbar (Login und Passwort zeigt der Installer am Ende an).

HestiaCP verwaltet selbst UFW und fail2ban — diese müssen Sie nicht separat konfigurieren, sie werden automatisch übernommen. SSH-Schlüssel und das Deaktivieren des Passworts (vorheriger Abschnitt) sollten Sie dennoch einrichten.

08. Systemanforderungen und ionCube

Das Dashboard ist eine PHP-Anwendung auf einem typischen LAMP/LEMP-Stack:

  • Betriebssystem: Linux (Ubuntu/Debian empfohlen);
  • Webserver: nginx oder Apache mit PHP-FPM;
  • PHP 8.0+ mit Erweiterungen: pdo_mysql, openssl, curl, json, mbstring;
  • ionCube Loader — PHP-Erweiterung, die für den Betrieb des Dashboards erforderlich ist;
  • Datenbank: MySQL 5.7+ oder MariaDB 10.3+;
  • HTTPS — zwingend erforderlich (Anmeldung und WebAuthn funktionieren nur über https);
  • sudo für den Webserver-Benutzer (eingeschränkter Umfang — Schritt 13).
# PHP-Version und Erweiterungen prüfen: php -v php -m | grep -iE 'pdo_mysql|openssl|curl|mbstring|ioncube'

ionCube Loader installieren (falls noch nicht vorhanden). Bei Hosting mit Panel (HestiaCP, cPanel) wird ionCube per Häkchen in den PHP-Einstellungen aktiviert. Manuell unter Ubuntu/Debian:

# PHP-Version und Erweiterungsverzeichnis ermitteln: php -v EXTDIR=$(php -r 'echo ini_get("extension_dir");'); PHPVER=$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;') # Loader herunterladen und entpacken (64-bit): cd /tmp wget -q https://downloads.ioncube.com/loader_downloads/ioncube_loaders_lin_x86-64.tar.gz tar xzf ioncube_loaders_lin_x86-64.tar.gz # Loader für Ihre PHP-Version in das Erweiterungsverzeichnis kopieren: sudo cp ioncube/ioncube_loader_lin_${PHPVER}.so "$EXTDIR"/ # Einbinden (CLI + PHP-FPM) und neu starten: echo "zend_extension=ioncube_loader_lin_${PHPVER}.so" | sudo tee /etc/php/${PHPVER}/mods-available/ioncube.ini sudo phpenmod ioncube sudo systemctl restart php${PHPVER}-fpm # Prüfung — in der Ausgabe erscheint die Zeile "with the ionCube PHP Loader": php -v
Die Loader-Version muss mit der PHP-Version übereinstimmen (z. B. ioncube_loader_lin_8.1.so für PHP 8.1). Wenn Sie mehrere PHP-Versionen verwenden — binden Sie den Loader für jede ein.

09. Domain und DNS

Um das Dashboard unter einer Adresse wie monitor.example.com zu öffnen und ein kostenloses SSL zu erhalten, benötigen Sie eine Domain, die auf Ihren Server verweist. Erstellen Sie im DNS-Verwaltungsdashboard einen A-Eintrag:

Typ: A Name: monitor (Subdomain → monitor.example.com) oder @ (Domain-Root → example.com) Wert: 203.0.113.10 ← IP Ihres Servers TTL: 3600

Prüfen Sie nach einigen Minuten, ob die Domain auf den Server verweist:

dig +short monitor.example.com # sollte Ihre IP zurückgeben # oder, falls dig fehlt: getent hosts monitor.example.com
Das SSL-Zertifikat von Let's Encrypt wird nur für eine Domain ausgestellt — der DNS muss vor der Zertifikatsausstellung auf den Server verweisen.

10. Website erstellen und Panel-Dateien hochladen

Apache: DocumentRoot — auf das Panel-Stammverzeichnis, NICHT auf public/. Stile (CSS/JS), sw.js, manifest.json liegen in assets/ neben public/ und werden vom Website-Stamm angefordert. Die .htaccess im Stammverzeichnis ist der Front-Controller. Wenn Sie unter Apache DocumentRoot auf public/ setzen, öffnet sich das Panel ohne Stile. Bei reinem nginx ist es umgekehrt: als Stamm wird public/ genommen, und assets/ werden über eine separate Regel ausgeliefert (siehe nginx-Block unten).
Die Panel-Dateien (Distributions-Archiv) werden nach dem Kauf im Benutzerkonto unter my.arciveo.com„Downloads“ heruntergeladen. Entpacken Sie das Archiv vor dem Hochladen.

1) Erstellen Sie das Panel-Verzeichnis und laden Sie den Inhalt der Distribution hinein (sodass sich darin public/, assets/, config.php usw. befinden):

sudo mkdir -p /var/www/monitor # anschließend die Distributionsdateien nach /var/www/monitor hochladen (FileZilla / WinSCP / scp)

2) Konfigurieren Sie den Webserver. Apache: DocumentRoot — auf das Panel-Stammverzeichnis (NICHT auf /public); AllowOverride All ist erforderlich. Der Pfad zum PHP-FPM-Socket wird automatisch ermittelt. Der Block wird vollständig ins Terminal eingefügt:

PHPSOCK=$(ls -1 /run/php/php*-fpm.sock 2>/dev/null | head -1) # Auto-Erkennung des PHP-FPM-Sockets sudo tee /etc/apache2/sites-available/monitor.conf > /dev/null <<'EOF' <VirtualHost *:80> ServerName monitor.example.com DocumentRoot /var/www/monitor <Directory /var/www/monitor> AllowOverride All Require all granted </Directory> <FilesMatch \.php$> SetHandler "proxy:unix:__PHPSOCK__|fcgi://localhost" </FilesMatch> </VirtualHost> EOF sudo sed -i "s#__PHPSOCK__#${PHPSOCK}#" /etc/apache2/sites-available/monitor.conf sudo a2dissite 000-default.conf sudo a2ensite monitor.conf sudo apache2ctl configtest sudo systemctl reload apache2

nginx: nginx hat keine .htaccess, deshalb nehmen wir public/ als Stamm, und assets/, sw.js, manifest.json (eine Ebene höher) liefern wir über eine separate Regel aus:

PHPSOCK=$(ls -1 /run/php/php*-fpm.sock 2>/dev/null | head -1) # Auto-Erkennung des PHP-FPM-Sockets sudo tee /etc/nginx/sites-available/monitor.conf > /dev/null <<'EOF' server { listen 80; server_name monitor.example.com; root /var/www/monitor/public; index index.php; # assets, Service Worker und Manifest liegen eine Ebene über public/ location ~ ^/(assets/|sw\.js|manifest\.json) { root /var/www/monitor; } location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:__PHPSOCK__; } } EOF sudo sed -i "s#__PHPSOCK__#${PHPSOCK}#" /etc/nginx/sites-available/monitor.conf sudo ln -s /etc/nginx/sites-available/monitor.conf /etc/nginx/sites-enabled/ sudo nginx -t && sudo systemctl reload nginx

Dateien hochladen — SFTP/SCP (FileZilla, WinSCP) oder scp:

# Beispiel über scp vom lokalen Rechner: scp -r ./monitor/* deploy@203.0.113.10:/var/www/monitor/
Setzen Sie die Dateiberechtigungen — dieser Schritt ist obligatorisch. Wenn Sie als root oder per SFTP hochgeladen haben, gehören die Dateien root, und der Webserver (www-data) kann sie nicht lesen — das Panel öffnet sich leer oder mit Fehler 403 (im Protokoll: .htaccess unreadable / directory not executable). Der folgende Befehl behebt das:
# Berechtigungen des gesamten Webroots normalisieren: ein von root erstelltes Verzeichnis ist # für den Webserver (www-data) nicht zugänglich — ohne dies liefert das Panel eine leere Seite oder 403. # Apache läuft unter www-data; falls Sie einen anderen Web-Benutzer haben — ersetzen. cd /var/www/monitor # Arbeitsordner erstellen wir VOR chown — sonst bleiben die neuen Verzeichnisse root:root # und bei chmod 750 kann der Webserver (www-data) nicht in sie schreiben. sudo mkdir -p data/lynis data/logwatch tmp logs sudo chown -R www-data:www-data /var/www/monitor sudo find /var/www/monitor -type d -exec chmod 755 {} \; sudo find /var/www/monitor -type f -exec chmod 644 {} \; sudo chmod 640 /var/www/monitor/config.php sudo chmod 750 data tmp logs

3) Schalten Sie den SFTP-Upload für sich selbst frei. Nach dem Befehl oben gehören alle Dateien www-data, während FileZilla / WinSCP sich unter Ihrem eigenen Benutzer verbinden — der Upload scheitert dann mit SSH_FX_PERMISSION_DENIED (Permission denied). Als root hochzuladen ist keine Option — der root-Login wurde in Schritt 05 deaktiviert. Wählen Sie eine der beiden Varianten.

Variante A — eine ACL nur für Ihren Benutzer (empfohlen). Schreibrechte bekommen nur Sie; der Webserver kann den Panel-Code weiterhin nicht überschreiben:

sudo apt install -y acl # Schreibrechte für Ihren Benutzer auf das gesamte Panel-Verzeichnis: sudo setfacl -R -m u:deploy:rwX /var/www/monitor # Dieselbe Regel als Vorgabe — für später angelegte Dateien und Ordner: sudo setfacl -R -d -m u:deploy:rwX /var/www/monitor

Variante B — über die Gruppe www-data. Einfacher, aber der Webserver erhält ebenfalls Schreibrechte auf die Panel-Dateien: bei einer Schwachstelle in PHP ließe sich der Code austauschen. Die Reihenfolge der Befehle ist wichtig — config.php und die Arbeitsordner werden zuletzt abgesichert:

sudo usermod -aG www-data deploy # Schreibrecht für die Gruppe + setgid (Bit 2): per SFTP hochgeladene Dateien # bleiben in der Gruppe www-data — sonst kann das Panel sie nicht überschreiben. sudo find /var/www/monitor -type d -exec chmod 2775 {} \; sudo find /var/www/monitor -type f -exec chmod 664 {} \; sudo chmod 640 /var/www/monitor/config.php sudo chmod 2750 /var/www/monitor/data /var/www/monitor/tmp /var/www/monitor/logs
Nach Variante B verbinden Sie sich in FileZilla neu (Server → Trennen, danach erneut anmelden) — die neue Gruppe wird erst bei einer neuen Anmeldung wirksam, vorher haben Sie weiterhin keine Rechte. Prüfen: id deploy — in der Gruppenliste muss www-data erscheinen; ls -ld /var/www/monitor — Rechte drwxrwsr-x, das s anstelle von x bedeutet, dass setgid gesetzt ist.

11. Datenbank

Erstellen Sie Datenbank und Benutzer und importieren Sie anschließend das Schema. Der Block wird vollständig ins Terminal eingefügt. monitor_db und monitor_user sind Beispielnamen, Sie können beliebige eigene vergeben; merken Sie sich Datenbankname, Benutzer und Passwort – Sie tragen sie im nächsten Schritt in config.php ein:

# 1. Datenbank. Das Passwort wird EINMAL in DBPASS gesetzt und in alle Zeilen eingesetzt. # Der Block wird VOLLSTÄNDIG ins Terminal eingefügt; sudo mysql meldet sich als root über den Unix-Socket an # (kein root-Passwort nötig). Verwenden Sie NICHT das interaktive `sudo mysql -u root -p` # mit Copy-Paste – beim Einfügen landen die SQL-Zeilen in der Passwortabfrage und gehen verloren. DBPASS='CHOOSE_A_PASSWORD' # ← ändern Sie nur diese Zeile sudo mysql <<SQL CREATE DATABASE IF NOT EXISTS monitor_db CHARACTER SET utf8mb4; CREATE USER IF NOT EXISTS 'monitor_user'@'localhost' IDENTIFIED BY '$DBPASS'; GRANT ALL ON monitor_db.* TO 'monitor_user'@'localhost'; FLUSH PRIVILEGES; SQL # Prüfung (sollte monitor_db anzeigen): mysql -u monitor_user -p"$DBPASS" -e "SHOW DATABASES;" # Tragen Sie dasselbe Passwort in config.php → DB_PASS ein.
Das Schema muss nicht importiert werden – das Dashboard erstellt die Tabellen und das Konto admin beim ersten Aufruf im Browser selbst (aus database/db.sql), sofern die Datenbank leer ist. Ein manueller Schema-Import ist nur nötig, wenn die Auto-Initialisierung fehlschlägt.
Wenn Sie den Browser-Installer public/start_db.php verwendet haben – löschen Sie ihn unmittelbar nach der Installation: er erlaubt ohne Anmeldung ein Neuanlegen der Datenbank. Solange die Datei im Wurzelverzeichnis des Dashboards oder in public/ liegt, zeigt das Dashboard eine rote Warnung an.

12. Konfiguration von config.php

config.php im Stammverzeichnis des Panels (/var/www/monitor/config.php) ist die einzige Datei, die Sie manuell bearbeiten müssen. Alle Panel-Einstellungen sind darin als define()-Konstanten definiert. Öffnen Sie sie im Editor:

sudo nano /var/www/monitor/config.php

Setzen Sie an den hervorgehobenen Stellen Ihre eigenen Werte ein; den Rest lassen Sie unverändert:

// --- Datenbank (aus Schritt 11) --- define('DB_HOST', 'localhost'); // unverändert lassen define('DB_NAME', 'db_name'); // in Schritt 11 erstellt define('DB_USER', 'user'); // in Schritt 11 erstellt define('DB_PASS', 'db_password'); // in Schritt 11 festgelegt define('DB_CHARSET', 'utf8mb4'); // unverändert lassen // --- Anwendung --- define('APP_URL', 'https://monitor.example.com'); // Panel-Adresse, ohne Schrägstrich am Ende define('TIMEZONE', 'Europe/Berlin'); // Ihre Zeitzone // --- Sitzungsdauer --- define('SESSION_LIFETIME', 28800); // Inaktivität bis zur erneuten Anmeldung, Sek. (28800 = 8 Std.)

Was Sie ändern müssen:

  • DB_NAME, DB_USER, DB_PASS — genau derselbe Datenbankname, Benutzer und dasselbe Passwort, die Sie beim Erstellen der DB in Schritt 11 festgelegt haben (falls Sie die Beispiele behalten haben — monitor_db / monitor_user). DB_HOST und DB_CHARSET nicht anfassen.
  • APP_URL — die vollständige Panel-Adresse mit https://, ohne Schrägstrich am Ende und ohne www. Muss mit der Domain übereinstimmen, für die Sie die Lizenz aktivieren (Schritt 16), sonst wird der Schlüssel abgelehnt.
  • TIMEZONE — Ihre Zeitzone (Liste — timedatectl list-timezones). Beeinflusst nur, wie das Panel Datumsangaben anzeigt; auf die Startzeit der cron-Aufgaben hat es keinen Einfluss (dort gilt die Systemzeitzone).
  • SESSION_LIFETIME — nach wie vielen Sekunden Inaktivität das Panel eine erneute Anmeldung verlangt (Standard: 8 Stunden). Z. B. 3600 = 1 Stunde, 86400 = ein Tag.
  • Block zur Fehlerprotokollierung (display_errors, log_errors, error_log) — auf Standard belassen.

Speichern Sie die Datei (Ctrl+O, Enter, dann Ctrl+X) und starten Sie PHP-FPM neu — sonst werden die Änderungen wegen OPcache nicht übernommen:

sudo systemctl restart php*-fpm
config.php ist eine geheime Datei (sie enthält das DB-Passwort). Sie liegt im Stammverzeichnis des Panels, das zugleich das Web-Stammverzeichnis ist, ist aber gesperrt: Rechte 640 (in Schritt 10 gesetzt) und ein ausdrückliches Verbot in der Stamm-.htaccess. Veröffentlichen Sie sie nicht in öffentlichen Repositories und übermitteln Sie sie nicht mit dem echten Passwort an den Support.
Eine ausführliche Erläuterung aller Parameter — in den FAQ: „Die Datei config.php — alle Panel-Einstellungen“.

13. sudo für den Webserver einrichten

PHP läuft unter dem Webserver-Benutzer, der keine Rechte für Systembefehle hat. Der Zugriff wird eng vergeben: gezieltes sudo für einzelne Werkzeuge und Log-Lesen über Gruppen (ohne sudo). Ein Angriff auf die Web-Schicht liefert kein root.

In den Beispielen ist www-data der Standardbenutzer von Apache. Falls Sie einen anderen haben (in manchen Panels läuft PHP unter einem eigenen Benutzer) — überall ersetzen. Ermitteln: ps -o user= -C php-fpm | sort -u.

1. Erstellen Sie /etc/sudoers.d/monitor mit sudo visudo -f /etc/sudoers.d/monitor und fügen Sie ein (Zeilen nicht genutzter Module entfernen):

# UFW — Status und Regeln (Seite „Firewall“) www-data ALL=(ALL) NOPASSWD: /usr/sbin/ufw status, /usr/sbin/ufw status verbose, /usr/sbin/ufw status numbered www-data ALL=(ALL) NOPASSWD: /usr/sbin/ufw allow [0-9]*, /usr/sbin/ufw deny [0-9]*, /usr/sbin/ufw --force delete [0-9]* # Fail2ban — Status, Bannen und Entbannen (banned liefert die Bans aller jails mit einem Befehl; # ban/unban werden von den Buttons des Dashboards benötigt) www-data ALL=(ALL) NOPASSWD: /usr/bin/fail2ban-client status, /usr/bin/fail2ban-client status *, /usr/bin/fail2ban-client banned, /usr/bin/fail2ban-client set * banip *, /usr/bin/fail2ban-client set * unbanip * # Sicherheitsupdates (Karte „Updates“). Nur Lesen, aber zwingend als root: # der apt-Cache (~70 MB) ist nur für root zugänglich, non-root baut ihn bei jedem Aufruf neu auf # (4,2 s CPU gegenüber 0,01 s). Ohne Wildcard — exakt dieser eine Befehl, installiert nichts. www-data ALL=(ALL) NOPASSWD: /usr/bin/apt list --upgradable # IPset (Angriffskarte, Dashboard) www-data ALL=(ALL) NOPASSWD: /usr/sbin/ipset list -t ipsum # CrowdSec www-data ALL=(ALL) NOPASSWD: /usr/bin/cscli decisions list *, /usr/bin/cscli alerts list *, /usr/bin/cscli bouncers list *, /usr/bin/cscli scenarios list * # Auditd — Ereignissuche + Lesen der letzten Journalzeilen (exakter Pfad) www-data ALL=(ALL) NOPASSWD: /usr/sbin/ausearch -m * www-data ALL=(ALL) NOPASSWD: /usr/bin/tail -n 300 /var/log/audit/audit.log # Monit / ModSecurity / AppArmor / PSAD www-data ALL=(ALL) NOPASSWD: /usr/bin/monit status www-data ALL=(ALL) NOPASSWD: /usr/sbin/apache2ctl -M www-data ALL=(ALL) NOPASSWD: /usr/local/bin/monitor-modsec www-data ALL=(ALL) NOPASSWD: /usr/sbin/aa-status www-data ALL=(ALL) NOPASSWD: /usr/sbin/psad --Status # Offene Ports (Kernel-/SSH-/Falco-Journale werden OHNE sudo gelesen — über die Gruppe # systemd-journal, siehe Punkt 2; sudo für journalctl ist NICHT nötig und unsicher) www-data ALL=(ALL) NOPASSWD: /usr/bin/ss -tuln, /usr/sbin/ss -tuln, /bin/ss -tuln # PostgreSQL (nur falls Sie es nutzen) — festes read-only-Skript, # gemäß FAQ „PostgreSQL wird nicht angezeigt“ anlegen; ohne dieses die Zeile löschen www-data ALL=(ALL) NOPASSWD: /usr/local/bin/monitor-pgstat
sudo chmod 440 /etc/sudoers.d/monitor sudo visudo -c # sollte "parsed OK" sein

2. Zugriff auf Logs und das systemd-Journal. Die Module lesen /var/log/fail2ban.log, auth.log, ufw.log, apache2/*, aide direkt (unter Debian/Ubuntu gehören diese Logs zur Gruppe adm). Kernel-, SSH- und Falco-Ereignisse werden aus journald mit dem Befehl journalctl ohne sudo bezogen, über die Gruppe systemd-journal. Fügen Sie den Web-Benutzer zu beiden Gruppen hinzu und starten Sie PHP-FPM neu:

sudo usermod -aG adm,systemd-journal www-data sudo systemctl restart php*-fpm # zwingend, sonst greifen die Gruppen nicht

3. Falls ClamAV oder Suricata ihre Logs nicht in die Gruppe adm schreiben (vorkommt root:root) — Zugriff über ACL gewähren:

sudo apt install acl sudo setfacl -R -m u:www-data:rX /var/log/clamav /var/log/suricata 2>/dev/null sudo setfacl -d -m u:www-data:rX /var/log/clamav /var/log/suricata 2>/dev/null

4. ModSecurity-Wrapper. Das Audit-Log der WAF (/var/log/apache2/modsec_audit.log) gehört root mit Rechten 640, der Web-Benutzer kann es nicht direkt lesen. Die ModSecurity-Seite bezieht Engine-Modus, Ereignisse und die Liste der aktiven Regeln über ein festes read-only-Skript — genau dieses ist in sudoers mit der Zeile oben erlaubt:

sudo tee /usr/local/bin/monitor-modsec >/dev/null <<'EOF' #!/bin/sh echo "ENGINE=$(grep -hE '^SecRuleEngine[[:space:]]+' /etc/modsecurity/*.conf 2>/dev/null | tail -1 | awk '{print $2}')" echo "---LOG---" tail -n 3000 /var/log/apache2/modsec_audit.log 2>/dev/null echo "---RULES---" for f in /etc/modsecurity/crs/rules/*.conf /usr/share/modsecurity-crs/rules/*.conf /etc/modsecurity/custom-rules.conf; do [ -f "$f" ] && { echo "===FILE:$(basename "$f")==="; cat "$f"; } done EOF sudo chown root:root /usr/local/bin/monitor-modsec sudo chmod 755 /usr/local/bin/monitor-modsec
Ohne die Datei /etc/modsecurity/modsecurity.conf funktioniert die WAF selbst nicht: das Paket legt nur modsecurity.conf-recommended an, und die Regel-Engine bleibt ausgeschaltet — wie man sie einschaltet, siehe FAQ → „ModSecurity installieren“.
Der Benutzer in allen sudoers-Zeilen muss mit dem Benutzer des FPM-Pools übereinstimmen: bei normalem Apache/Debian ist das 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.

5. Falls Nginx vor Apache steht (HestiaCP, ISPmanager und andere Panels — dort proxyt Nginx PHP an Apache und liefert die statischen Dateien selbst aus). Die Service-Verzeichnisse sind durch .htaccess-Dateien geschützt, doch Nginx liest sie nicht: jede statische Datei (.json, .txt, .log, .dat) liefert es direkt aus, an Apache vorbei. Nach außen gelangen Panel-Caches und Daten — etwa tmp/modsec_cache.json mit WAF-Ereignissen und den IP der Angreifer. Fügen Sie das Verbot in die Site-Konfiguration von Nginx ein:

location ^~ /data/ { deny all; } location ^~ /tmp/ { deny all; } location ^~ /logs/ { deny all; } location ^~ /includes/ { deny all; } location ^~ /cron/ { deny all; } location ^~ /database/ { deny all; } location = /config.php { deny all; }
Das Präfix ^~ ist zwingend: es wird vor der regulären Regel für statische Dateien innerhalb von location / ausgewählt, sonst greift das Verbot nicht.
In HestiaCP legen Sie das als separate Datei /home/<user>/conf/web/<domain>/nginx.ssl.conf_deny ab (und nginx.conf_deny für HTTP) — die Site-Konfiguration bindet nginx.ssl.conf_* ein und überschreibt solche Dateien beim Neuaufbau nicht. Anwenden: sudo nginx -t && sudo systemctl reload nginx.
Prüfung: curl -s -o /dev/null -w '%{http_code}\n' https://monitor.example.com/tmp/modsec_cache.json — sollte 403 sein. Falls Apache ohne Nginx läuft (lauscht selbst auf 80/443), muss nichts hinzugefügt werden — .htaccess genügt.
Prüfen Sie die Pfade zu den Binärdateien mit which (z. B. which ufw cscli ausearch ss). Bearbeiten Sie sudoers nur über visudo. Die Liste aller MySQL-Datenbanken wird mit einem separaten GRANT aktiviert (FAQ → „Nur eine DB sichtbar“).

14. Zugriffsbeschränkung per IP

Beschränken Sie den Zugriff auf den Monitor per IP-Adresse — selbst wenn die URL bekannt wird, öffnet sich die Anmeldeseite nicht. Möglich auf Ebene des Webservers (Beispiel für Nginx unten) oder im Dashboard selbst („Einstellungen“ → „Zugriffsbeschränkung per IP“). Wenn Sie Apache nutzen, verwenden Sie die Beschränkung im Dashboard.

Wenn die Nginx-Site bereits gemäß Schritt 10 konfiguriert ist, fügen Sie keinen zweiten location / hinzu — tragen Sie die Zeilen allow/deny in den bereits vorhandenen Block ein. Zwei identische location / in einem server { } sind ein Konfigurationsfehler, Nginx startet nicht neu.
# In der Nginx-Konfiguration (innerhalb server { }): # Den ACME-Pfad von Let's Encrypt lassen wir unter Umgehung der IP-Beschränkung offen — # damit Ausstellung und automatische Verlängerung von SSL (Schritt 15) nicht vom IP-Filter abhängen. location ^~ /.well-known/acme-challenge/ { allow all; } location / { allow 203.0.113.10; # ← tragen Sie Ihre IP ein allow 10.0.0.0/8; # lokales Netz (falls nötig) deny all; try_files $uri $uri/ /index.php?$query_string; } # Nginx neu laden: sudo nginx -t && sudo systemctl reload nginx

15. SSL ausstellen (HTTPS)

Das Dashboard funktioniert nur über HTTPS. Die Anmeldesitzung nutzt ein sicheres Cookie, und WebAuthn (2FA) funktioniert nur über HTTPS. Über http:// ist keine Anmeldung möglich.

Das Zertifikat ist kostenlos (Let's Encrypt). Der DNS der Domain muss bereits auf den Server zeigen. Der Befehl hängt vom Webserver ab:

# Apache: sudo certbot --apache -d monitor.example.com # nginx — NUR wenn Sie tatsächlich nginx nutzen. Auf Apache NICHT ausführen: # apt zieht nginx nach und belegt Port 80, Konflikt mit Apache. # sudo apt install python3-certbot-nginx # sudo certbot --nginx -d monitor.example.com # certbot trägt HTTPS selbst in die Konfiguration ein und richtet die automatische Verlängerung ein
Was certbot fragt: E-Mail → Zustimmung zu den Terms (Y) → Weitergabe der E-Mail an EFF (nach Ihrem Ermessen). Danach stellt es das Zertifikat selbst aus, trägt <VirtualHost *:443> ein, richtet die Weiterleitung http→https und die automatische Verlängerung ein.
Der DNS muss VOR dem Start von certbot auf den Server zeigen (Besitznachweis über Port 80). Prüfung: dig +short monitor.example.com → IP des Servers. Ports 80/443 offen: sudo ufw allow 80,443/tcp.

Nach der Ausstellung: https://monitor.example.com öffnet mit Schloss, http:// leitet auf https:// um (APP_URL in config.php wurde bereits in Schritt 12 gesetzt).

16. Anmeldung und Ersteinrichtung

Öffnen Sie https://monitor.example.com, melden Sie sich mit admin / useradmin an und arbeiten Sie die Checkliste ab:

  1. admin-Passwort ändern — Bereich „Benutzer“ im Menü.
  2. WebAuthn (2FA) aktivieren — „WebAuthn-Schlüssel“ → Schlüssel/Passkey registrieren (erfordert HTTPS). Registrieren Sie gleich zwei: Geht der einzige Schlüssel verloren, ist die Anmeldung damit nicht mehr möglich. Mehr dazu.
  3. Zugriff per IP beschränken — „Einstellungen“ → „Zugriffsbeschränkung per IP“ (tragen Sie Ihre IP vor dem Aktivieren ein, sonst sperren Sie sich selbst aus).
  4. Lizenz eingeben — aktivieren Sie den Code ARCIVEO-… aus dem Benutzerkonto für Ihre Domain und fügen Sie den Schlüssel unter „Einstellungen“ → „Lizenz“ ein. Mehr dazu.
  5. Benachrichtigungen einrichten — Telegram und/oder E-Mail unter „Einstellungen“. Mehr dazu.
  6. Installer entfernen public/start_db.php, falls noch vorhanden (Schritt 11).

17. Sicherheitswerkzeuge (optional)

Das Dashboard läuft bereits. Die Werkzeuge werden nach Bedarf installiert — Sie installieren nur, was Sie brauchen, und das Dashboard zeigt den Status sofort an. Die Installationsbefehle für jedes finden Sie im Handbuch (eigene Abschnitte je Werkzeug):

18. Cron und Wartung

Wird einmalig eingerichtet, ebenfalls optional, aber empfohlen. Ausführliche Befehle finden Sie im Handbuch:

  1. Cron-Aufgaben (Berichte, Listen-Aktualisierung, Prüfungen);
  2. Datensicherung;
  3. Aktualisierung und Umzug des Panels;
  4. Zugriffswiederherstellung — für den Fall eines verlorenen Schlüssels/Passworts.
Etwas funktioniert nicht oder zeigt „keine Daten“? Werfen Sie einen Blick in die Gruppe „Diagnose“ des Handbuchs.
Arcivéo - Security Monitor © 2026