Dit is de handleiding voor installatie, configuratie en onderhoud van Arcivéo Monitor. De secties zijn gegroepeerd: algemeen overzicht, uitrol van het dashboard, koppeling van beveiligingstools, ingebouwde modules en diagnostiek. Commando's kunt u kopiëren met de knop rechts.
De installatie van het paneel staat op aparte stapsgewijze pagina's. Kies een methode:
Arcivéo Monitor — een beveiligingsdashboard voor uw server. Het verzamelt gegevens van geïnstalleerde tools (Fail2ban, UFW, Lynis, ModSecurity, AIDE, ClamAV, Auditd, CrowdSec, Suricata, Falco e.a.) en toont ze in één interface met een dashboard, aanvalskaart en gedetailleerde pagina's per tool.
De monitor is geen actief beveiligingsmiddel — hij blokkeert zelf geen aanvallen. Zijn taak is om informatie van reeds werkende tools te verzamelen en overzichtelijk te presenteren.
De monitor werkt alleen lokaal — hij moet worden geïnstalleerd op dezelfde server die hij monitort. Er is geen SSH of externe API.
Alle commando's (fail2ban-client, ufw status, ipset list, enz.) voert het paneel uit namens de gebruiker van de webserver (meestal www-data, op hostingpanelen — het account van de site) met een beperkte set rechten sudo — alleen voor specifieke tools, zonder algemene root-toegang. De resultaten worden geparseerd en in de browser weergegeven.
De score begint op het maximum en daalt voor elk gevonden probleem:
PermitRootLogin yes) — −20Resultaat: 80+ = Beveiligd, 60–79 = Let op, <60 = Onder dreiging.
WebAuthn is een standaard voor authenticatie zonder wachtwoord via een hardwaresleutel. Ondersteunt YubiKey, Touch ID, Face ID, Windows Hello, Passkey.
Na het inloggen met een wachtwoord vraagt het systeem om bevestiging via een geregistreerde sleutel. Zelfs als het wachtwoord uitlekt, is inloggen zonder de fysieke sleutel of biometrie onmogelijk.
Open om dit in te stellen WebAuthn-sleutels in het zijmenu en klik op “Sleutel registreren”. Registreer meteen twee sleutels: als uw enige sleutel verloren gaat of kapot raakt, is inloggen op het dashboard daarmee onmogelijk.
Het dashboard kan een beveiligingsrapport naar Telegram en e-mail sturen (via een knop en volgens schema). In te stellen in het onderdeel “Instellingen”.
Telegram. U hebt een bot-token en chat id nodig:
@BotFather → /newbot → ontvang een token in de vorm 123456:ABC....@userinfobot, of open https://api.telegram.org/bot<TOKEN>/getUpdates en zoek naar "chat":{"id":...}.Email. Twee methoden naar keuze in “Instellingen” → Email:
re_...) en een geverifieerd afzenderdomein.Rapportstatus: “LET OP” of “OK”. De titel wordt alleen “LET OP” bij een echt probleem of een openstaande actie: een ClamAV-dreiging gevonden, bestandswijzigingen in AIDE, kritieke Falco-gebeurtenissen (Emergency/Alert/Critical in de laatste 24 u), een gecrashte service in Monit, herstart vereist, verlopend SSL (≤14 dagen) of wachtende beveiligingsupdates. Achtergrondruis — SSH-bruteforce door bots, door fail2ban geblokkeerde IP-adressen, Suricata-alerts, Lynis-waarschuwingen en reeds afgeslagen ModSecurity-verzoeken — verhoogt de status niet, dus zulke cijfers in het rapport betekenen op zichzelf geen “LET OP”.
Gedetailleerde monitoringmodules (Lynis, UFW, ModSecurity, aanvalskaart, AIDE, ClamAV enz.) worden ontgrendeld met een geldige licentie. Zonder licentie werken het dashboard, de instellingen en het account, maar tonen de modules de kaart “Licentie vereist”.
Na aankoop in uw account beschikt u over een activatiecode in de vorm ARCIVEO-XXXX-XXXX-XXXX-XXXX. Deze moet u “activeren” voor het domein van uw paneel — dat zet de code om in een ondertekend licentiebestand (blok [license]) dat u in het paneel plakt.
Zo activeert u (3 stappen):
my.arciveo.com → onderdeel “Licenties” / “Licentieactivatie” — kopieer de code ARCIVEO-….monitor.example.com). Klik op activeren — het systeem genereert een licentiebestand dat aan dit domein gekoppeld is en toont het in een veld met de knop “Kopiëren”.Het paneel controleert de sleutel cryptografisch: handtekening, domeinkoppeling en geldigheidsduur.
APP_URL in config.php en voer alleen de hostnaam in — zonder https:// en zonder www-prefix. Activatie is eenmalig: de code wordt een licentie voor het ingevoerde domein en kan niet opnieuw worden geactiveerd — bij een fout in het domein past de sleutel niet bij uw paneel en is de code verbruikt. Voer het domein daarom zorgvuldig in.
Alle belangrijke parameters van het dashboard staan in één bestand config.php in de root (naast de map public/) als gewone define()-constanten. Het bestand wordt bij de installatie aangemaakt; het handmatig bewerken is zelden nodig — meestal bij het wijzigen van het domein, een verhuizing of het koppelen aan een andere database. Na elke wijziging PHP-FPM opnieuw starten (anders worden de wijzigingen door OPcache niet toegepast).
Vul uw eigen waarden in op de gemarkeerde plekken; laat de rest zoals die is:
Database. Verbindingsgegevens voor MySQL/MariaDB:
DB_HOST — host van de DBMS, bijna altijd localhost;DB_NAME — naam van de database van het dashboard;DB_USER — DB-gebruiker (toegang alleen tot de eigen database);DB_PASS — wachtwoord van deze gebruiker;DB_CHARSET — tekenset van de verbinding, laat utf8mb4 staan.Applicatie.
APP_URL — volledig adres van het dashboard (bijv. https://monitor.example.com). Moet overeenkomen met het domein waarvoor de licentie is geactiveerd — anders wordt de sleutel geweigerd (zie het onderdeel “Licentie”);TIMEZONE — tijdzone van PHP: beïnvloedt alleen hoe het dashboard datums en tijden toont. Op de uitvoertijd van cron-taken heeft dit geen invloed — daar geldt de systeemtijdzone (zie “Alle cron-taken”).Sessieduur. SESSION_LIFETIME — time-out voor inactiviteit van de sessie in seconden (voortschrijdend: wordt bij activiteit vernieuwd). Standaard 28800 = 8 uur; na deze inactiviteitsduur vraagt het dashboard om opnieuw in te loggen. Bijvoorbeeld 3600 = 1 uur, 86400 = een etmaal.
Foutregistratie. Fouten worden nooit aan bezoekers getoond, maar weggeschreven naar logs/php_errors.log — ze zijn zichtbaar op de pagina “Applicatielogs”. Deze regels (display_errors=0, log_errors=1, pad error_log) hoeft u meestal niet te wijzigen — de instellingen staan direct in het bestand en zijn niet afhankelijk van php.ini.
public/), en de webroot (DocumentRoot) van dit dashboard is juist de root van het dashboard, niet public/. Het bestand “lekt” op zichzelf niet: in de .htaccess in de root staat er een expliciet verbod voor (Require all denied) — de server geeft 403 terug. Zelfs zonder deze regel zou de broncode niet lekken: dit is PHP — de server voert het uit en geeft het niet als tekst terug. Voor de zekerheid: plaats het niet in openbare repositories en stuur het niet met een echt wachtwoord naar de ondersteuning. Bestandsrechten — 640.
UFW (Uncomplicated Firewall) is een eenvoudige interface voor nftables/iptables. Sluit alle inkomende poorten af behalve die expliciet zijn toegestaan. De pagina “UFW-firewall” toont de status en regels.
ufw enable verplicht SSH toe (ufw allow OpenSSH), anders verliest u de toegang tot de server.
deny-regel is afgesloten, geldt niet als extern bereikbaar.
Skipping adding existing rule is geen fout. Zo meldt UFW dat exact dezelfde regel al bestaat en niet opnieuw wordt toegevoegd. Bij een herhaalde uitvoering van de automatische configuratie (die idempotent is) is dit een normale melding — er is geen actie nodig.
Blokkeert automatisch een IP-adres na te veel mislukte aanmeldpogingen. Analyseert de logs van SSH, nginx, Apache en andere diensten.
De basisinstallatie staat hierboven. Hier vindt u een werkende configuratie die tientallen actieve jails en duizenden bans oplevert: algemene instellingen, belangrijke jails en het automatisch bannen van kwaadaardige IP's uit de lijst ipsum.
Het bestand /etc/fail2ban/jail.local — algemene instellingen en de belangrijkste jails:
ignoreip beslist uw eigen IP en vertrouwde netwerken in, anders kunt u uzelf bannen. Na wijzigingen: sudo fail2ban-client reload.
Het automatisch laden van de blokkeerlijst ipsum gaat via de root-cron (sudo crontab -e): level 1 (100.000+ IP's) wordt geladen in de set ipsum, die op de firewall wordt geblokkeerd (meer hierover in het gedeelte “IPset-blokkeerlijst”):
ipsum heten — precies die wordt door het dashboard gelezen (kaart “IPset ipsum”). Levels: levels/1.txt — maximale dekking, levels/3.txt — nauwkeuriger (3+ bronnen).
Waarom de “Beveiligingsmonitor” in twee zones is verdeeld. De bescherming werkt op twee niveaus, en het dashboard vermengt ze niet:
sshd, apache-*, nginx-* enz.) en hardnekkige recidivisten (jail recidive — degenen die al meerdere keren gebannd zijn). Dit zijn IP's die echt bij u probeerden in te breken — ze staan op de aanvalskaart en de “Tijdlijn”.ipset ipsum, die op de firewall met een DROP-regel wordt geblokkeerd. Deze adressen hebben uw server in de meeste gevallen niet eens geraakt — ze worden vooraf afgesneden; de teller “IPset ipsum” toont hoeveel er preventief zijn afgesneden.Het verschil is simpel: reactief — “deze vielen aan en werden gebannd”, preventief — “deze werden geblokkeerd nog vóór de poging”. Vroeger werd list-3 ipsum kunstmatig in recidive gedreven (vandaar de oude indeling “lijst-recidivisten”); nu bevat recidive alleen echte recidivisten, en de preventie draait volledig op de firewall.
ipsum — een publieke lijst met kwaadaardige IP's, die dagelijks wordt bijgewerkt. De monitor toont het aantal geladen adressen op het dashboard en de aanvalskaart en verrekent dit in de beveiligingsscore (−10 als de set niet is geladen).
Een minimale variant zonder fail2ban — een aparte set ipsum met blokkering via iptables:
@reboot. Meteen stelt het commando create … -exist de limiet maxelem 300000 in (standaard 65536 — level 1 past er niet in, dan krijgt u “Hash is full”):
ipsum en, als de firewall wordt beheerd door de installer (verse VPS — profielen “Volledig”/“Lichtgewicht”), koppelt het de set aan UFW met een DROP-regel — verkeer van deze IP's wordt daadwerkelijk geblokkeerd. De regel staat na ESTABLISHED,RELATED, zodat bestaande verbindingen (waaronder uw SSH) niet worden verbroken — alleen nieuwe verbindingen uit de lijst worden afgekapt. De set wordt hersteld bij het laden van de service ipsum-load.service vóór de firewall (anders zou UFW niet opstarten), en wordt bijgewerkt door de cron om 04:00. Op een reeds geconfigureerde server (paneel, eigen firewall) raakt de installer de firewall niet aan — daar blijft ipsum een lijst voor het dashboard en de aanvalskaart, en de DROP-regel wordt desgewenst handmatig toegevoegd (de minimale variant met iptables … --match-set ipsum … -j DROP — hierboven). Bij automatische installatie hoeft u handmatig niets te doen.
Moderne vervanging voor Fail2ban met collectieve threat intelligence: blokkeringen van de community plus eigen regels. Vereist een aparte bouncer om blokkeringen op de firewall toe te passen.
systemctl is-active crowdsec). Starten: sudo systemctl enable --now crowdsec; bij een crash kijkt u naar sudo journalctl -u crowdsec -n 30. Dezelfde regel geldt voor elke service met de status “Niet actief” (Suricata, Falco, Monit, MySQL).
stream halted / blokkeringen worden niet toegepast. Dit is een verweesde api-sleutel: de bouncer is verwijderd uit cscli bouncers list, maar zijn oude sleutel bleef in /etc/crowdsec/bouncers/*.yaml. Registreer de bouncer opnieuw en zet de nieuwe sleutel erin:
AIDE (Advanced Intrusion Detection Environment) maakt een momentopname van het bestandssysteem en meldt bij elke controle wijzigingen in /etc, /bin, /usr. Na de installatie is initialisatie van de database (aideinit) verplicht.
aideinit blijft de terminal 5–15 minuten op de regel Running aide --init... staan — dat is normaal (hashing van het hele bestandssysteem, schijfbelasting). Onderbreek niet met Ctrl+C. Als het proces “blijft hangen” maar niets schrijft, wacht het mogelijk op een verborgen prompt Overwrite existing aide.db.new [Yn]? (druk op Y). Controleer de activiteit vanuit een andere sessie: pgrep -af aide.
aideinit: “21_aide_spamassassin … printf: invalid number” (return code 20) — een bekende bug in het AIDE-configuratiesnippet in Ubuntu 22.04. De database wordt niet aangemaakt. Verplaats het defecte snippet en probeer opnieuw:
aideinit niet uitgevoerd, ofwel (Ubuntu 24.04) is de map /var/lib/aide aangemaakt met modus 700 en niet toegankelijk voor www-data — op te lossen met sudo chmod 755 /var/lib/aide (zie het blok hierboven). “Geen controles” = de database bestaat, maar er is nog geen controle uitgevoerd — dit is geen fout. De monitor leest de resultaten uit /var/log/aide/aide.log.
/etc/cron.daily/aide schrijft op nieuwe Ubuntu/Debian mogelijk niet /var/log/aide/aide.log in de vereiste vorm (en aide.wrapper zit er niet meer in). Betrouwbaarder is een eigen cron met expliciete --config — die schrijft de log als root in modus 644, en de monitor leest hem zonder extra groepen:
chmod 755 /var/lib/aide en een controle-cron om 02:00 — handmatig is niets nodig.
sudo aideinit && sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db.
Antivirusscanner voor Linux. Vooral handig om /var/www te controleren op PHP-shells en kwaadaardige code.
enable --now? Drie typische oorzaken:
1. In de config staat nog de regel Example — clamd weigert te starten zolang die er staat:
2. De signaturedatabase is niet gedownload — clamd start niet zonder deze:
3. Hij is gewoon aan het laden — clamd laadt ~8 mln signatures in 30–60 sec. in het geheugen. Wacht even en controleer: systemctl is-active clamav-daemon (status activating → nog aan het laden).
sudo journalctl -u clamav-daemon -n 30 --no-pager.
clamd-daemon houdt alleen signatures in het geheugen, zelf scant hij niets volgens een schema. Het paneel toont de resultaten van een geplande scan, dus u hebt een cron nodig die scant en een log schrijft. De automatische installatie plaatst de wrapper /usr/local/bin/clamav-scan.sh en een cron om 01:30 — na de eerste run worden “Bestanden gecontroleerd” en “Laatste scan” gevuld. Meteen starten zonder op het schema te wachten: sudo /usr/local/bin/clamav-scan.sh.
Linux Malware Detect (LMD) — malwarescanner voor webdreigingen: PHP-shells, web-backdoors, loaders. Gebruikt de ClamAV-engine en vult die aan met eigen signatures.
maldet --report.
update-rc.d: error: unable to read /etc/init.d/maldet verschijnen — die is onschadelijk. maldet gebruikt geen init.d; het bijwerken van signatures en de scans worden gestart via /etc/cron.daily/maldet. Als u onderaan installation completed ziet, is alles geïnstalleerd.
apt geïnstalleerd, maar in /usr/local/maldetect, en bij ingeschakelde open_basedir wordt de aanwezigheid via de shell gecontroleerd — zie het hoofdstuk “De pagina is leeg terwijl er wel gegevens op de server zijn”.
Netwerkgebaseerd inbraakdetectiesysteem: analyseert verkeer op pakketniveau en kent duizenden aanvalssignaturen. Vult ModSecurity aan (die werkt op HTTP-niveau, Suricata op TCP/IP-niveau).
/var/log/suricata/eve.json als root met modus 750 op de map, en de webserver (www-data) kan hem niet lezen. Geef de map doorloop-rechten — de bestanden erin blijven beschermd:
Onderschept system calls via eBPF/kernel module en detecteert anomalieën in realtime: een shell vanuit nginx, het lezen van /etc/passwd door een webproces, schrijven naar /bin enz.
journalctl -u falco (zonder sudo — via de groep systemd-journal). Zorg dat www-data in deze groep zit — zie “sudo instellen” (punt 2) op de pagina voor handmatige installatie.
/etc/passwd, schrijven naar systeemmappen). Nul kritieke gebeurtenissen op een dag op een rustige server is een gezonde toestand.
journalctl vereist rechten op het logboek; om ervoor te zorgen dat het dashboard gebeurtenissen stabiel ziet, schakelt de automatische installatie bij Falco file_output → /var/log/falco/falco.log in en stelt de service UMask=0022 in (het log wordt door de webserver gelezen). Bij een nieuwe installatie hoeft u dit niet handmatig te configureren.
ModSecurity — een webfirewall (WAF) voor Apache of Nginx. Blokkeert aanvallen op applicatieniveau: SQL-injecties, XSS, path traversal, scanners.
IncludeOptional /etc/modsecurity/*.conf, maar het pakket plaatst alleen modsecurity.conf-recommended — dat valt niet onder het masker *.conf. Als u het niet naar modsecurity.conf kopieert, blijft SecRuleEngine op Off: de module is geladen, de CRS-regels zijn geladen, maar het verkeer wordt niet gecontroleerd en er wordt geen audit-log aangemaakt. De tussenstand DetectionOnly schrijft alleen gebeurtenissen naar het log zonder verzoeken te blokkeren — het paneel toont dit geel.
Toegang van het paneel tot het audit-log. Het log /var/log/apache2/modsec_audit.log is eigendom van root (rechten 640); de webgebruiker kan het niet lezen. Het paneel haalt de gegevens op via een wrapper — maak die aan:
SecRuleEngine-directive zonder inspringing: ingesprongen regels staan binnen <LocationMatch>/<Directory>-blokken (bijvoorbeeld het uitschakelen van de WAF voor phpMyAdmin) en bepalen de globale modus niet.www-data, in HestiaCP draait de sitepool onder de site-eigenaar (bijvoorbeeld admin) — controleer met grep -E '^user' /etc/php/*/fpm/pool.d/monitor.example.com.conf.X-Forwarded-For. Alleen transacties met een geactiveerde regel komen in de statistieken: de directive SecAuditLogRelevantStatus schrijft alle 4xx/5xx-antwoorden naar het audit-log, dus komen ook gewone 403/500 daarin terecht — het paneel telt die niet als WAF-gebeurtenissen.---RULES--- is nodig voor het onderdeel “Alle actieve regels” — het paneel toont niet alleen de geactiveerde, maar alle geladen CRS-regels + aangepaste regels. De drie paden in de lus for f in … zijn de typische plekken voor CRS-regels en lokale aanvullingen; hebt u een andere indeling (het pakket plaatst bestanden in zijn eigen map, of de aangepaste regels staan niet in /etc/modsecurity/custom-rules.conf), zoek dan de werkelijke paden met het commando sudo grep -rl 'IncludeOptional\|^Include ' /etc/apache2/mods-enabled/security2.conf /etc/apache2/conf-enabled/*.conf 2>/dev/null en zet ze in de lijst. Is de wrapper oud (zonder dit onderdeel), dan toont het onderdeel simpelweg de waarschuwing “niet beschikbaar”; de rest van de pagina werkt zoals voorheen.
Auditd (Linux Audit Daemon) registreert systeemaanroepen op kernelniveau: aan- en afmeldingen, sudo-opdrachten, mislukte authenticatiepogingen, bestandswijzigingen. De monitor toont aanmeldingen, mislukte pogingen en sudo-opdrachten van vandaag.
ausearch (/usr/sbin/ausearch) en indien nodig uit /var/log/audit/audit.log met het commando tail. Beide moeten in sudoers staan.
Bewaakt services (nginx, php-fpm, mysql enz.) en herstart ze bij een crash. Kan meldingen sturen naar e-mail.
monit status. In /etc/monit/monitrc moet de HTTP-interface ingeschakeld zijn (blok set httpd met allow localhost), anders geeft monit status een fout.
monitrc is de regel set httpd uitgecommentarieerd (standaard staat die als # set httpd port 2812 …). Verwijder het commentaarteken bij het blok en sta localhost toe. (2) Een ingeschakelde httpd bewaakt op zichzelf niets — Monit telt alleen wat met check-stanza's is beschreven; zonder die is de lijst leeg, zelfs met een werkende interface. Minimale werkende configuratie:
conf.d met httpd op 2812 en een set controles — op een nieuwe installatie hoeft u niets handmatig in te stellen.
PSAD analyseert het iptables-logboek en detecteert poortscans en netwerkaanvallen, waarbij elke bron een dreigingsniveau (1–5) krijgt. Vult fail2ban en Suricata aan.
psad --Status (vereist in sudoers). Zonder iptables-logging blijft de pagina leeg — dat is normaal zolang er geen scans zijn geweest.
Mandatory Access Control beperkt tot welke bestanden en bronnen een programma toegang heeft, zelfs als het gehackt is. In Ubuntu/Debian wordt standaard AppArmor gebruikt (meestal al geïnstalleerd en actief).
aa-status (moet in sudoers staan). Toont het aantal profielen in de modus enforce/complain en processen zonder profiel.
“Profielen geladen” is meer dan enforce + complain — dat is normaal. In AppArmor 4.x (Ubuntu 24.04 en nieuwer) is de modus unconfined geïntroduceerd: het profiel is in de kernel geladen, maar beperkt niets. Ubuntu markeert zo tientallen profielen voor programma's die user namespaces gebruiken (browsers, torrent-clients en dergelijke). Wanneer zulke profielen aanwezig zijn, wordt de kaart “Profielen geladen” amberkleurig en toont hun aantal — bijvoorbeeld unconfined: 90 bij 120 geladen en 26 in enforce. Alleen profielen in enforce beschermen daadwerkelijk; op Ubuntu 22.04 (AppArmor 3.x) bestaat deze modus niet en kloppen de cijfers altijd.
unconfined heeft gelaten, moet u alleen weloverwogen naar enforce zetten: ze zijn niet per abuis uitgeschakeld, maar omdat de programma's zelf anders stukgaan. Profielen in complain zijn een ander geval: daar zijn de regels al geschreven en worden ze alleen niet toegepast.
debsums controleert of de bestanden van geïnstalleerde pakketten overeenkomen met de controlesommen uit de repository — het spoort vervangen systeembinaries op (een aanvulling op AIDE). Een volledige controle duurt 1–2 minuten en wordt daarom via cron uitgevoerd; de dashboard leest het resultaat uit data/debsums/debsums.log en verdeelt het zelf over categorieën (alleen binaries en bibliotheken zijn belangrijk).
De taak staat in de root-cron (sudo crontab -e). De kant-en-klare wrapper debsums-scan.sh wordt in /usr/local/bin/ geplaatst (chmod +x; zie het overzicht van cron-taken) en schrijft zelf een rapport naar data/debsums/ van de dashboard.
De wrapper debsums-scan.sh vindt zelf de data/ van de dashboard — u hoeft geen pad in te vullen.
/etc/ (configuraties) en /usr/share/ (bronbestanden) op de server zijn meestal normaal — de dashboard markeert deze met een aparte kleur. Zorgwekkend zijn wijzigingen aan binaries en bibliotheken (/bin, /sbin, /usr/lib enz.) — de kaart “Binaries / bibliotheken” toont precies die.
Lynis start handmatig of via cron. Het rapport moet worden opgeslagen in de map data/lynis/ van het project — de monitor leest het bestand lynis-report.dat.
lynis-scan.sh op de achtergrond rechtstreeks vanuit het dashboard (zonder op cron te wachten): toont “Scannen…” en werkt na afloop zelf het rapport bij. Hiervoor heeft de webgebruiker een sudoers-regel nodig om het script uit te voeren — het installatieprogramma voegt die automatisch toe aan /etc/sudoers.d/monitor. Als het dashboard handmatig/eerder is geïnstalleerd, voeg die dan toe met dezelfde gebruiker die al in het bestand staat:
Logwatch moet dagelijkse rapporten opslaan in de projectmap data/logwatch/ in het formaat .txt. De monitor toont het laatste rapport en het archief.
De netwerkmonitor hoeft niet te worden geïnstalleerd — het is een ingebouwde pagina van het dashboard. Deze toont de netwerkstatus van de server uit lokale bronnen:
/proc/net/dev;ip;ss;journalctl -k.De eerste drie bronnen werken zonder sudo, dus interfaces, verkeer, verbindingen en poorten zijn direct zichtbaar. Het blok “Kernelgebeurtenissen” gebruikt journalctl -k — dit wordt gelezen via de groep systemd-journal (“sudo instellen”, punt 2), sudo is niet nodig. Controleer of alles toegankelijk is voor de webgebruiker:
UFW BLOCK komen hier niet in — die staan op de pagina's “UFW-firewall” en “Aanvalskaart”. Een leeg blok met een groen vinkje = geen netwerkstoringen in de afgelopen 24 uur.
De ingebouwde pagina toont drie dingen:
df); de balk wordt rood bij ≥90%;lsblk), alleen echte (loop/snap verborgen);smartctl).Ruimte en apparatenlijst werken meteen, zonder configuratie. Voor SMART is het pakket smartmontools nodig. Het webproces heeft geen directe toegang tot schijfapparaten, daarom wordt SMART via cron uitgelezen naar het bestand data/disk/smart.txt, dat het paneel vervolgens leest.
De taak staat in de root-cron (sudo crontab -e). De kant-en-klare wrapper smart-scan.sh plaatst u in /usr/local/bin/ (chmod +x; zie het overzicht van cron-taken) en schrijft zelf naar data/disk/ van het paneel.
De wrapper smart-scan.sh vindt zelf de data/ van het paneel — u hoeft geen pad op te geven. Intern sluit lsblk -e7,11 loop/cdrom uit.
De pagina toont de belastingsgeschiedenis van de server over de laatste 24 uur — Load Average, CPU-bezetting en I/O-wachttijd, RAM/Swap, netwerkverkeer (ontvangen/verzonden), schijf-I/O (lezen/schrijven), schijf- en inode-vulling, geopende bestandsdescriptoren en MySQL-verbindingen, plus het huidige aantal TCP-verbindingen en processen.
De gegevens verzamelt cron/collect_metrics.php — eens per 5 minuten wordt één “ruwe” momentopname van de tellers weggeschreven (/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') naar de databasetabel system_metrics; percentages en snelheden berekent de pagina zelf uit het verschil tussen naburige momentopnamen (schijf-/inode-/descriptorvulling/MySQL-verbindingen zijn momentwaarden, zonder herberekening). Sudo is niet vereist — de bronnen worden zonder rootrechten gelezen. Punten ouder dan 24 uur worden bij elke schrijfbewerking automatisch verwijderd.
De wrapper collect-metrics-all.sh (zie het overzicht van cron-taken) vindt zelf alle geïnstalleerde panelinstanties op de server en start voor elk de cron/collect_metrics.php onder de sitehouder.
Belastingsmeldingen (onderdeel “Instellingen” → “Belastingsmeldingen”) — bij overschrijding van de drempel voor CPU/RAM/schijf/inodes stuurt het paneel een melding naar Telegram/Email (dezelfde kanalen als het dagelijkse rapport — die apart inschakelen voor meldingen is niet nodig), en nog een — wanneer de metriek weer normaal is. Tijdens het aanhouden van de drempel spamt het niet opnieuw: de volgende melding komt pas na een cyclus “hersteld → opnieuw overschreden”.
collect_metrics.php bij elke uitvoering gecontroleerd (eens per 5 minuten) — een aparte cron is niet nodig. De status “al gemeld / nog niet” wordt bewaard in data/alerts_state.json, de drempels in de panelinstellingen.
De pagina “Aanvalskaart” bepaalt het land op basis van het IP met het commando geoiplookup. Zonder het GeoIP-pakket worden landen niet bepaald en verschijnen er geen punten op de kaart:
/usr/share/GeoIP/GeoIP.dat is voor iedereen leesbaar en de resultaten worden gecachet in tmp/geoip_cache.json. De kaart zelf (Leaflet + OpenStreetMap-tegels) laadt in de browser — er is internet nodig op de computer waarop het dashboard is geopend.
Twee ingebouwde dashboardkaarten die niet “aan/uit” van een tool tonen, maar de werkelijke beveiliging van de server. Vereisen geen installatie en worden lokaal gelezen zonder sudo.
Externe blootstelling — hoeveel diensten op alle interfaces luisteren (0.0.0.0/[::]) en van buitenaf bereikbaar zijn. Markeert rood als een database of cache naar buiten toe openstaat (MySQL, PostgreSQL, Redis, MongoDB, Memcached, Elasticsearch) — dat is een direct lek (−10 op de beveiligingsscore). Bron: ss -tuln.
127.0.0.1 (bind-address in de MySQL/PostgreSQL-config, bind 127.0.0.1 in Redis) of sluit de poort in UFW.
127.0.0.1 (loopback) luistert, is alleen voor de server zelf zichtbaar — van buitenaf kunt u er niet bij, ook al is de poort “open”. Daarom is Postfix op poort 25, gebonden aan loopback, veilig: de automatische configuratie zet inet_interfaces = loopback-only (plus een neutrale smtpd_banner — dit verhelpt de Lynis-opmerking MAIL-8818 over het tonen van de versie). De kaart “Externe blootstelling” telt naar buiten toe alleen wat op 0.0.0.0/[::] luistert; loopback-diensten tellen daar niet mee.
/etc/postfix/main.cf smtpd_banner = $myhostname ESMTP in (zonder versie en OS) en inet_interfaces = loopback-only, en daarna sudo systemctl restart postfix.
Beveiligingsupdates — hoeveel securitypatches op installatie wachten en of een herstart nodig is na een kernel-update (−5 op de beveiligingsscore als er patches zijn). Bron: /usr/lib/update-notifier/apt-check, bestand /var/run/reboot-required. De gedetailleerde lijst staat op de pagina “Beveiligingsupdates”.
update-notifier-common). Ontbreekt apt-check — dan telt de monitor de patches via apt-get -s upgrade.
Automatische beveiligingsupdates (unattended-upgrades) — op de pagina “Beveiligingsupdates” toont een aparte kaart of de automatische installatie van securitypatches is ingeschakeld en wanneer die voor het laatst is uitgevoerd. Sudo is niet nodig — de status wordt gelezen via apt-config dump.
Een back-up is uw belangrijkste vangnet: gegevensverlies is erger dan welke inbraak dan ook. U heeft twee dingen nodig — een back-up van de server/sites en apart een back-up van de paneeldatabase (daarin staan gebruikers, WebAuthn-sleutels, instellingen, licentie).
Optie A — HestiaCP: tabblad Backup bij de gebruiker → knop om een back-up te maken (of volgens schema in de serverinstellingen). De back-up omvat de sites en hun databases.
Optie B — handmatig (cron): databasedump + archief van de map data/ van het paneel:
Bijwerken naar een nieuwe versie. Maak eerst een back-up. Upload daarna de codebestanden opnieuw, met behoud van uw gegevens:
public/, includes/, assets/, cron/, database/, en ook de .htaccess in de root (front controller — de routing mag niet van de oude versie blijven staan), manifest.json, sw.js;config.php (DB-gegevens), data/ (rapporten), logs/, tmp/ (sessies en cache).SSH_FX_PERMISSION_DENIED — Permission denied. De bestanden van het paneel zijn eigendom van www-data (zo zijn ze bij de installatie ingesteld), terwijl de SFTP-client verbindt met uw eigen gebruiker, die geen schrijfrechten heeft. Het hele paneel aan www-data geven “om het maar werkend te krijgen” is precies wat tot deze fout leidt; hieronder drie manieren, elk lost het probleem op.
data/ (rapporten), tmp/ (sessies en cache), logs/; die blijven eigendom van www-data. De rest is code, en de webserver heeft die alleen nodig om te lezen, wat de groep www-data met rechten 644 biedt. Bijkomend voordeel: bij een PHP-lek zijn de bestanden van het paneel niet meer te overschrijven. Op hostingpanelen (HestiaCP en dergelijke) is variant A niet nodig: daar zijn de sitebestanden toch al eigendom van het account waarmee u via SFTP inlogt, en de webserver leest ze via de groep.
chmod op de bestanden reset het ACL-masker, en de toegang verdwijnt geruisloos. Als het uploaden na het “opschonen van de rechten” opnieuw op Permission denied stuit — herhaal beide setfacl-commando's.
2 in variant C is setgid: via SFTP geüploade bestanden blijven in de groep www-data, anders kan het paneel ze niet overschrijven. Na variant C maakt u opnieuw verbinding in FileZilla — de nieuwe groep werkt pas bij een nieuwe login. Controle: id deploy (de groep www-data moet verschijnen) en ls -ld /path/to/monitor (drwxrwsr-x — de letter s betekent dat setgid is gezet).
Migreren naar een andere server:
config.php, data/.mysqldump op de oude → import op de nieuwe; pas de DB-gegevens in config.php aan.adm, cron-taken.Als u niet kunt inloggen, is alles rechtstreeks in de database op de server te repareren. Open de database (naam staat in config.php):
WebAuthn-sleutel kwijt (tweede factor lukt niet) — schakel 2FA uit, log in met uw wachtwoord en registreer een nieuwe sleutel:
Wachtwoord vergeten — stel een nieuwe hash in (genereer deze op de server en vul in):
Uzelf buitengesloten met het IP-filter — schakel de beperking uit:
sudo mysql op de server, of phpMyAdmin / het databasegedeelte in het hostingpaneel. Schakel na het herstel WebAuthn en het IP-filter weer in.
Het overzicht van taken staat in de root-cron van de server (toevoegen via sudo crontab -e). Laat alleen de regels staan van de tools die u gebruikt; pas de paden aan uw eigen server aan.
sudo crontab -l en of de cron-service actief is.
TIMEZONE uit config.php. De constante TIMEZONE beïnvloedt alleen PHP (hoe het dashboard datums toont), maar de cron-daemon voert taken uit op de systeemtijd van het OS. Als de tijdzone van de server niet met de uwe overeenkomt, komt het rapport van “08:00” op het verkeerde moment binnen. Voorbeeld: de server staat in een andere zone (Europe/London, UTC+1) en u zit in Amsterdam (UTC+2) → het rapport van “08:00” komt bij u om 09:00 binnen. Controleer en breng zo nodig de systeemtijdzone in overeenstemming met de uwe:
0 8 * * * om 08:00 lokale tijd uitgevoerd. Anders zou u de cron zelf moeten verschuiven, maar bij de overgang naar winter-/zomertijd loopt die verschuiving weer uit de pas — daarom is het beter de systeemtijdzone in te stellen.
crontab.txt) staan in de map system/ naast het project, buiten public_html. Dit is geen onderdeel van de site — ze hoeven niet naar de webroot te worden geüpload; plaats ze op de server op de systeempaden (zoals in de crontab hierboven):
lynis-scan.sh → /usr/local/bin/ (chmod +x) — voert lynis audit system uit, zet tijdens de scan de vlag /tmp/lynis-running en kopieert lynis-report.dat naar data/lynis/ van het dashboard;logwatch_daily.sh → /usr/local/bin/ (chmod +x) — stelt het dagelijkse Logwatch-rapport op (sshd, fail2ban, sudo, postfix) in data/logwatch/;smart-scan.sh → /usr/local/bin/ (chmod +x) — legt de schijfstatus vast (smartctl) in data/disk/;debsums-scan.sh → /usr/local/bin/ (chmod +x) — controleert de pakketintegriteit (debsums) in data/debsums/;clamav-scan.sh → /usr/local/bin/ (chmod +x) — ClamAV-antivirusscan van gevaarlijke paden (web, home, temp); schrijft een overzicht naar /var/log/clamav/scan.log, waar de ClamAV-pagina het uitleest (regel 01:30 in de crontab hierboven);load-ipsum.sh → /usr/local/bin/ (chmod +x) — werkt de ipset-set ipsum (level 1) ter plekke bij, zonder de actieve firewallregels te breken (de regel 04:00 in de crontab hierboven);daily-report-all.sh → /usr/local/bin/ (chmod +x) — voert het rapport cron/daily_report.php van het dashboard uit (regel 08:00 in de crontab hierboven);daily_report.php — zit al in het dashboard (cron/daily_report.php), wordt uitgevoerd via daily-report-all.sh, hoeft niet apart geïnstalleerd te worden;collect-metrics-all.sh → /usr/local/bin/ (chmod +x) — voert cron/collect_metrics.php van het dashboard uit (pagina “Prestaties”, regel */5 in de crontab hierboven); collect_metrics.php zit al in het dashboard, hoeft niet apart geïnstalleerd te worden;crontab.txt (system/cron/) — voorbeeldtaken; voeg de gewenste regels toe via sudo crontab -e./usr/local/bin/ plaatst. Rechtstreeks vanuit FileZilla kunt u daar niet schrijven — de map is van root, en de SFTP-client krijgt SSH_FX_PERMISSION_DENIED. De volgorde is: eerst het bestand uploaden naar /tmp (daar mag iedereen schrijven), en het dan met één opdracht op zijn plaats zetten:
/tmp in de root van de server nodig — niet /var/tmp en niet tmp/ binnen het dashboard zelf (dat laatste is van www-data en afgeschermd van uw gebruiker). In de FileZilla-boom is /tmp een tak op het bovenste niveau, naast var, niet erin.
/usr/local/bin/, log — /var/log/arciveo-cron.log) — u hoeft handmatig niets te doen.
/home/*/web/*/public_html en /var/www/* af te lopen, en plaatsen de rapporten in hun data/. Als het dashboard op een ander pad staat — voeg dat toe aan de regel for app in … in de scripts, anders komen de rapporten van Lynis/SMART/debsums/Logwatch niet in het dashboard terecht.
logs/cron.log wordt als eerste aangemaakt door de root-cron — het is dan van root, en het tabblad “Cron-log” in het dashboard kan het noch lezen noch legen. Maak het bestand vooraf aan als de webgebruiker (de eigenaar van de sitemap; op HestiaCP is dat het account, bijv. admin) — dan voegt de root-cron er alleen aan toe zonder de eigenaar te wijzigen:
stat -c %U /path/to/monitor.
sudo crontab -e), anders wordt hij twee keer uitgevoerd.
sudo crontab (dat zou directe escalatie naar root betekenen voor iedereen die toegang tot de dashboardsessie krijgt), maar een beperkt script met twee opdrachten (list/set) dat alleen zijn eigen blok tussen de dienstcommentaren aanraakt. Installeer het eenmalig:
www-data — controleer onder welke gebruiker de PHP-FPM-pool van de site draait (ps -o user= -C php-fpm) en vul die in de sudoers-regel in.
public/crontab_monitor.php via FTP/SFTP onder een andere systeemgebruiker (bijvoorbeeld root) is geüpload dan de overige sitebestanden, kan de webserver het niet lezen. Vergelijk de eigenaar en rechten met een naastgelegen bestand en breng ze in overeenstemming:
De monitor detecteert de aanwezigheid van tools via dpkg-query — de APT-pakketdatabase. Als een tool niet via apt is geïnstalleerd (handmatig, uit snap of vanuit broncode), ziet dpkg het niet.
Fout 500 — controleer de logs van PHP, nginx en de monitor zelf:
www-data, maar onder het gebruikersaccount (bijvoorbeeld admin — de eigenaar van de sitemap). Alle sudo-regels en groepslidmaatschappen (adm, systemd-journal) moeten op deze gebruiker worden ingesteld, anders tonen de modules “Niet actief / 0” terwijl de services wel draaien. De echte PHP-gebruiker achterhalen: ps -o user= -C php-fpm | sort -u of de eigenaar van de sitemap stat -c '%U' /path/to/monitor. Vervang www-data daarna in alle onderstaande commando's door die gebruiker. De automatische installatie detecteert de webgebruiker zelf en stelt sudoers daarop in.
Gegevens worden niet weergegeven — bijna altijd ontbrekende sudo-rechten. Controleer het specifieke commando als webgebruiker (vervang www-data door de uwe). De vlag -n = zonder wachtwoord, net als PHP — als er om een wachtwoord wordt gevraagd, ontbreekt de regel in sudoers:
sudo aa-status in de terminal toont profielen, maar de pagina “AppArmor” toont “Inactief”). Oorzaak: de webgebruiker heeft geen sudo-recht op het commando van deze module. Controleer het uit de lijst hierboven: als er om een wachtwoord wordt gevraagd — voeg de ontbrekende regel toe aan /etc/sudoers.d/monitor (“Sudo instellen”). Veelvoorkomende “nieuwe” commando's: /usr/sbin/aa-status (MAC), /usr/sbin/psad --Status (PSAD).
apache2ctl, ausearch, aa-status of ss niet toegestaan, of zit de webgebruiker niet in de groepen adm/systemd-journal (daaruit worden de logs van fail2ban/auth/modsec en journalctl gelezen — Falco en kernelgebeurtenissen).
Symptoom: er staat data op de server (zichtbaar via shell), maar de pagina toont “geen data” of een onjuiste status — bijvoorbeeld AIDE meldt “Niet geïnitialiseerd” terwijl de database wel is aangemaakt.
Oorzaak is open_basedir: veel panelen en hostings beperken de PHP-FPM-pool tot de domeinmap, waardoor de PHP-functies file_exists(), file_get_contents(), filemtime() op systeempaden (/var/lib/aide, /var/log, /proc…) worden geblokkeerd. De monitor omzeilt dit door zulke paden met standaard systeemcommando's te lezen (cat, test, stat).
open_basedir. De juiste oplossing is lezen met systeemcommando's (al gedaan voor AIDE en de Netwerkmonitor). Het uitbreiden van open_basedir naar /var, /proc is niet nodig en minder veilig.
De monitor controleert certificaten door rechtstreeks via poort 443 verbinding te maken met domeinen. Als een domein vanaf de server zelf onbereikbaar is of de poort door de firewall wordt geblokkeerd, mislukt de controle.
/etc/nginx/sites-enabled/, /etc/nginx/conf.d/) en Apache (/etc/apache2/sites-enabled/) plus de huidige host uit HTTP_HOST.
De monitor verbindt met MySQL als de gebruiker uit config.php, die alleen toegang heeft tot zijn eigen database. MySQL toont in information_schema alleen databases waarvoor u rechten hebt — daarom zijn de andere niet zichtbaar.
Om de monitor alle databases te laten zien, geeft u deze gebruiker alleen-lezenrecht (eenmalig als root; vul de gebruikersnaam uit config.php in):
sudo mysql: de lijst met databases wordt opgehaald via zijn eigen PDO-verbinding.
PostgreSQL vereist toegang op het niveau van de gebruiker postgres, die de webgebruiker van het dashboard niet heeft. Een brede sudo psql vanuit PHP openen is onveilig — in plaats daarvan roept het dashboard een strakke wrapper zonder parameters aan die alleen de versie, het aantal verbindingen en de lijst met databases met groottes toont. Maak deze aan:
monitor-pgstat uit sudoers (stap 13 van de handmatige installatie) en maak het script zelf niet aan: de PostgreSQL-kaart blijft dan gewoon inactief.
Het dashboard toont wat er gebeurt; hieronder ziet u wat u moet doen in typische situaties. Algemeen principe: raak niet in paniek, vergelijk met legitieme activiteit (uw acties, updates, back-ups) en reageer naar ernst.
ignoreip staat./etc, buiten /usr/share) — mogelijk vervanging. Controleer het pakket: debsums PACKAGE_NAME, en installeer het bij twijfel opnieuw (apt install --reinstall).127.0.0.1 of sluit de poort in UFW. Dit is een echt gat.certbot renew of de instellingen in het paneel).sudo apt update && sudo apt upgrade; herstart de server na een kernel-update.