FAQ

Detta är en guide för installation, konfiguration och underhåll av Arcivéo Monitor. Avsnitten är grupperade: allmän översikt, driftsättning av panelen, anslutning av säkerhetsverktyg, inbyggda moduler och diagnostik. Kommandon kan kopieras med knappen till höger.

Kom igång

01. Installera panelen — välj metod

Installationen av panelen finns på separata steg-för-steg-sidor. Välj metod:

Är du osäker — välj den automatiska. Denna handbok förblir den enda källan för SSL, verktyg, cron och diagnostik — installationssidorna hänvisar till dess avsnitt utan att dubblera något.

Översikt

02. Vad är Arcivéo Monitor

Arcivéo Monitor — en säkerhetspanel för servern. Samlar in data från installerade verktyg (Fail2ban, UFW, Lynis, ModSecurity, AIDE, ClamAV, Auditd, CrowdSec, Suricata, Falco m.fl.) och visar den i ett enhetligt gränssnitt med dashboard, angreppskarta och detaljsidor för varje verktyg.

Monitor är inte ett aktivt skyddsverktyg — den blockerar inte angrepp på egen hand. Dess uppgift är att aggregera information från redan aktiva verktyg och presentera den på ett överskådligt sätt.

03. Så fungerar monitorn på servern

Monitorn körs endast lokalt — den måste installeras på samma server som den övervakar. Ingen SSH eller fjärr-API används.

Alla kommandon (fail2ban-client, ufw status, ipset list osv.) körs av panelen som webbserverns användare (vanligtvis www-data, på hostingpaneler webbplatsens konto) med en snäv uppsättning rättigheter i sudo — enbart för specifika verktyg, utan generell root-åtkomst. Resultaten tolkas och visas i webbläsaren.

För flera servrar, installera monitorn på var och en separat, med en unik domän.

04. Så beräknas säkerhetspoängen

Poängen startar på max och sänks för varje upptäckt problem:

  • UFW är inte aktivt — −30
  • Fail2ban körs inte (inga aktiva jail) — −25
  • Inga WebAuthn-nycklar — −15
  • Lynis hardening index < 60 — −20; 60–79 — −10
  • IPset ipsum är inte laddat — −10
  • Hot funna av ClamAV — −20
  • Filändringar enligt AIDE — −15
  • SSL har gått ut — −30, går ut om <14 dagar — −15, <30 dagar — −5
  • CrowdSec är installerat men körs inte — −5
  • Suricata är installerat men körs inte — −5
  • Databas/cache (MySQL, PostgreSQL, Redis…) är åtkomliga utifrån — −10
  • root-inloggning via SSH tillåten (PermitRootLogin yes) — −20
  • Säkerhetsuppdateringar väntar på installation — −5

Resultat: 80+ = Skyddad, 60–79 = Observera, <60 = Hotad.

Avdrag för ClamAV, AIDE, CrowdSec och Suricata tillämpas endast om verktyget är installerat. Lynis och AIDE utan initierad databas visas som ”inga data” och sänker inte poängen. Antalet attacker idag visas på dashboarden men påverkar inte säkerhetspoängen.

Inställningar och licens

05. WebAuthn — tvåfaktorsautentisering

WebAuthn — standard för lösenordsfri autentisering via en fysisk säkerhetsnyckel. Stöder YubiKey, Touch ID, Face ID, Windows Hello, Passkey.

Efter inloggning med lösenord begär systemet bekräftelse via den registrerade nyckeln. Även om lösenordet läcker går det inte att logga in utan den fysiska nyckeln eller biometrin.

För att ställa in det, öppna WebAuthn-nycklar i sidomenyn och klicka på ”Registrera nyckel”. Registrera två nycklar direkt: om din enda nyckel tappas bort eller går sönder blir det omöjligt att logga in på panelen med den.

WebAuthn fungerar endast via HTTPS. Över en HTTP-anslutning går det inte att registrera eller logga in med nyckel.

06. Aviseringar: Telegram och e-post

Panelen kan skicka säkerhetsrapporter till Telegram och e-post (via knapp och enligt schema). Konfigureras under ”Inställningar”.

Telegram. Du behöver en bot-token och ett chat id:

  1. Skriv till @BotFather i Telegram → /newbot → få en token i formatet 123456:ABC....
  2. Skicka valfritt meddelande till din nya bot (så att den kan svara dig).
  3. Ta reda på ditt chat id: skriv till boten @userinfobot, eller öppna https://api.telegram.org/bot<TOKEN>/getUpdates och hitta "chat":{"id":...}.
  4. Klistra in token och chat id i ”Inställningar” → Telegram och klicka på ”Spara och skicka test”.

E-post. Två metoder att välja mellan under ”Inställningar” → E-post:

  • SMTP — värd, port (465/SSL eller 587/TLS), inloggning och lösenord för din brevlåda;
  • Resend — modernt API: ange API-nyckel (re_...) och en verifierad avsändardomän.
Knappen ”Skicka test” kontrollerar kanalen direkt. Schemat för den automatiska rapporten sköts via cron (avsnittet ”Alla cron-jobb”): den utlöser sändningen, och kanalerna hämtas från inställningarna.

Rapportstatus: ”VARNING” eller ”OK”. Rubriken blir ”VARNING” endast vid ett verkligt problem eller en väntande åtgärd: ett hot hittat av ClamAV, filändringar i AIDE, kritiska Falco-händelser (Emergency/Alert/Critical de senaste 24 h), en nedstånen tjänst i Monit, omstart krävs, SSL löper ut (≤14 dagar) eller säkerhetsuppdateringar väntar. Bakgrundsbrus — SSH-forcering av bottar, IP-adresser bannade av fail2ban, Suricata-varningar, Lynis-varningar och redan avvärjda ModSecurity-förfrågningar — höjer inte statusen, så sådana siffror i rapporten betyder inte ”VARNING” i sig.

07. Licens — inmatning och aktivering

Detaljerade övervakningsmoduler (Lynis, UFW, ModSecurity, attackkarta, AIDE, ClamAV m.fl.) låses upp när du har en giltig licens. Utan den fungerar instrumentpanelen, inställningarna och kontot, men modulerna visar kortet ”Licens krävs”.

Efter köpet i din kundportal har du en aktiveringskod av typen ARCIVEO-XXXX-XXXX-XXXX-XXXX. Den måste ”aktiveras” för din panels domän — det förvandlar koden till en signerad licensfil (blocket [license]) som du klistrar in i panelen.

Så här aktiverar du (3 steg):

  1. Hämta aktiveringskoden. Kundportal my.arciveo.com → avsnittet ”Licenser” / ”Licensaktivering” — kopiera koden ARCIVEO-….
  2. Aktivera koden för din domän. Öppna ”Licensaktivering” i samma kundportal, ange: aktiveringskod, din e-post och panelens domän (adressen där övervakningen öppnas, t.ex. monitor.example.com). Klicka på aktivera — systemet genererar en licensfil kopplad till denna domän och visar den i ett fält med knappen ”Kopiera”.
  3. Klistra in nyckeln i panelen. Kopiera hela licenstexten → öppna ”Inställningar” → blocket ”Licens” i panelen, klistra in och klicka på ”Spara”. Modulerna låses upp direkt.

Panelen kontrollerar nyckeln kryptografiskt: signatur, domänkoppling och giltighetstid.

Domänen vid aktiveringen måste exakt matcha panelens adress. Hämta den från konstanten APP_URL i config.php och ange endast värdnamnet — utan https:// och utan prefixet www. Aktiveringen är engångs: koden förvandlas till en licens för den angivna domänen och kan inte aktiveras igen — vid fel i domänen passar nyckeln inte din panel, och koden är förbrukad. Ange därför domänen noggrant.
Om giltighetstiden gått ut eller domänen ändrats visas en varning i panelens sidhuvud. Licensen är permanent kopplad till domänen och kan inte flyttas till en annan domän: för en ny period eller ny domän behövs en ny nyckel (köps i kundportalen och aktiveras en gång).

08. Filen config.php — alla panelinställningar

Alla huvudparametrar för panelen anges i en enda fil, config.php, i roten (bredvid mappen public/) med vanliga define()-konstanter. Filen skapas vid installationen; den behöver sällan redigeras manuellt — främst vid domänbyte, flytt eller anslutning till en annan databas. Efter varje ändring, starta om PHP-FPM (annars tillämpas inte ändringarna på grund av OPcache).

Ange dina egna värden på de markerade ställena; lämna resten som det är:

// --- Databas --- define('DB_HOST', 'localhost'); // lämna orört define('DB_NAME', 'db_name'); // det du angav när databasen skapades define('DB_USER', 'user'); // det du angav när databasen skapades define('DB_PASS', 'db_password'); // det du angav när databasen skapades define('DB_CHARSET', 'utf8mb4'); // lämna orört // --- Applikation --- define('APP_URL', 'https://monitor.example.com'); // panelens adress, utan avslutande snedstreck define('TIMEZONE', 'Europe/Stockholm'); // din tidszon // --- Sessionstid --- define('SESSION_LIFETIME', 28800); // inaktivitet till nästa inloggning, sek (28800 = 8 tim)

Databas. Anslutningsuppgifter till MySQL/MariaDB:

  • DB_HOST — databasvärd, nästan alltid localhost;
  • DB_NAME — namnet på panelens databas;
  • DB_USER — databasanvändare (åtkomst endast till sin egen databas);
  • DB_PASS — lösenordet för denna användare;
  • DB_CHARSET — anslutningens teckenkodning, lämna utf8mb4.

Applikation.

  • APP_URL — panelens fullständiga adress (t.ex. https://monitor.example.com). Måste stämma med domänen som licensen aktiverats för — annars avvisas nyckeln (se avsnittet ”Licens”);
  • TIMEZONEPHP-tidszon: påverkar bara hur panelen visar datum och tid. Den påverkar inte när cron-jobben körs — där gäller systemets tidszon (se ”Alla cron-jobb”).

Sessionstid. SESSION_LIFETIME — timeout för inaktiv session i sekunder (glidande: uppdateras vid aktivitet). Standard är 28800 = 8 timmar; efter så lång tids inaktivitet ber panelen dig logga in igen. Till exempel 3600 = 1 timme, 86400 = ett dygn.

Felloggning. Fel visas aldrig för besökare, utan skrivs till logs/php_errors.log — de syns på sidan ”Applikationsloggar”. Dessa rader (display_errors=0, log_errors=1, sökvägen error_log) behöver vanligtvis inte ändras — inställningarna anges direkt i filen och är oberoende av php.ini.

config.php — en hemlig fil. Den innehåller databaslösenordet. Den ligger i panelens rot (bredvid public/), och för denna panel är webbroten (DocumentRoot) just panelens rot, inte public/. Filen ”läcker” inte i sig själv: i rotens .htaccess finns ett uttryckligt förbud för den (Require all denied) — servern returnerar 403. Även utan denna regel skulle källkoden inte läcka: detta är PHP — servern kör den och skickar den inte som text. För säkerhets skull: lägg inte ut den i offentliga repositorier och skicka den inte till supporten med det riktiga lösenordet. Filens rättigheter — 640.
Vid flytt eller återställning av åtkomst är denna fil den viktigaste källan till uppgifter: databasnamn, användare och lösenord hämtas just härifrån (se avsnitten ”Uppdatering och flytt av panelen” och ”Återställning av åtkomst”).

Säkerhetsverktyg

09. UFW-brandvägg

UFW (Uncomplicated Firewall) är ett enkelt gränssnitt till nftables/iptables. Stänger alla inkommande portar utom de som uttryckligen tillåts. Sidan ”UFW-brandvägg” visar status och regler.

sudo apt install ufw # Tillåt SSH (obligatoriskt FÖRE aktivering!) och webb sudo ufw allow OpenSSH sudo ufw allow 80,443/tcp # Stäng databasen utifrån (endast lokal åtkomst) sudo ufw deny 3306 # Aktivera och kontrollera sudo ufw enable sudo ufw status verbose
Innan ufw enable måste du tillåta SSH (ufw allow OpenSSH), annars förlorar du åtkomsten till servern.
”Extern exponering” på dashboarden tar hänsyn till UFW: en port som stängts med regeln deny räknas inte som åtkomlig utifrån.
Skipping adding existing rule är inget fel. UFW meddelar så att en exakt likadan regel redan finns och lägger inte till den igen. Vid ny körning av autokonfigurationen (den är idempotent) är detta ett normalt meddelande — inget behöver göras.

10. Installation av Fail2ban

Blockerar automatiskt IP-adresser när antalet misslyckade inloggningsförsök överskrids. Analyserar loggar från SSH, nginx, Apache och andra tjänster.

sudo apt install fail2ban sudo systemctl enable --now fail2ban # Kontrollera status: sudo fail2ban-client status
En färdig konfiguration (jail.local med dussintals jail och autoban från ipsum) finns i nästa avsnitt.

11. Fungerande konfiguration av Fail2ban + ipsum

Grundinstallationen finns ovan. Här är en fungerande konfiguration som ger dussintals aktiva jail och tusentals blockeringar: allmänna inställningar, viktiga jail och autoban av skadliga IP från listan ipsum.

Filen /etc/fail2ban/jail.local — allmänna inställningar och de viktigaste jail:

[DEFAULT] bantime = 1w findtime = 900 maxretry = 3 backend = systemd banaction = nftables-multiport ignoreip = 127.0.0.1/8 ::1 <YOUR_IP> <TRUSTED_NETS> # Progressiv ban: varje upprepning — längre bantime.increment = true bantime.factor = 2 bantime.maxtime = 5w bantime.rndtime = 300 [sshd] enabled = true maxretry = 5 bantime = -1 # permanent ban vid brute force mot SSH findtime = 3600 # Återfallsförbrytare: den som fått flera ban — bannas permanent [recidive] enabled = true logpath = /var/log/fail2ban.log banaction = %(banaction_allports)s bantime = -1 findtime = 86400 maxretry = 2 [http-get-dos] enabled = true maxretry = 100 findtime = 300 bantime = 1w # Webbtjänster (apache-*, nginx-*, php-url-fopen, phpmyadmin-syslog): [nginx-http-auth] enabled = true port = http,https [apache-badbots] enabled = true port = http,https # … och övriga jail per tjänst (dovecot, exim, postfix-sasl, # mysqld-auth, vsftpd, portscan, pam-generic) — enabled = true
Ange alltid din egen IP och betrodda nätverk i ignoreip, annars kan du banna dig själv. Efter ändringar: sudo fail2ban-client reload.

Automatisk inläsning av blocklistan ipsum — i root-cron (sudo crontab -e): level 1 (100 000+ IP) läses in i uppsättningen ipsum, som filtreras bort i brandväggen (mer i avsnittet ”Blocklista IPset”):

# 04:00 — uppdatering av ipset ipsum (level 1, maximal täckning): 0 4 * * * /usr/local/bin/load-ipsum.sh >> /path/to/monitor/logs/cron.log 2>&1
Uppsättningen måste heta ipsum — det är den dashboarden läser (kortet ”IPset ipsum”). Nivåer: levels/1.txt — maximal täckning, levels/3.txt — mer precist (3+ källor).

Varför ”Säkerhetsmonitor” är uppdelad i två zoner. Skyddet arbetar på två nivåer, och dashboarden blandar dem inte:

  • Verkliga attacker (reaktivt) — allt som fail2ban fångat: aktiva intrångsförsök (jail sshd, apache-*, nginx-* osv.) och grova återfallsförbrytare (jail recidive — de som redan bannats flera gånger). Detta är IP-adresser som faktiskt försökte ta sig in — de finns på attackkartan och i ”Tidslinjen”.
  • Preventiv blockering (proaktivt) — den publika blocklistan över kända skadliga IP ipset ipsum, som filtreras bort i brandväggen med regeln DROP. De flesta av dessa adresser har aldrig ens rört din server — de stoppas i förväg; räknaren ”IPset ipsum” visar hur många som stoppats preventivt.

Skillnaden är enkel: reaktivt — ”dessa attackerade och fick ban”, preventivt — ”dessa blockerades redan före försöket”. Tidigare tvingades list-3 ipsum artificiellt in i recidive (därav den gamla uppdelningen ”list-baserade recidive”); nu innehåller recidive bara verkliga återfallsförbrytare, och preventiv blockering sker helt i brandväggen.

12. Blocklista IPset (ipsum)

ipsum — en offentlig lista över skadliga IP-adresser som uppdateras dagligen. Monitorn visar antalet inlästa adresser på instrumentpanelen och attackkartan och räknar in det i säkerhetspoängen (−10 om uppsättningen inte är inläst).

Minimal variant utan fail2ban — en separat uppsättning ipsum med blockering via iptables:

# Skapa uppsättningen (en gång): sudo ipset create ipsum hash:ip # Uppdateringsskript /usr/local/bin/update-ipsum.sh: #!/bin/bash ipset flush ipsum for ip in $(curl -s https://raw.githubusercontent.com/stamparm/ipsum/master/levels/3.txt); do ipset add ipsum "$ip" 2>/dev/null done iptables -C INPUT -m set --match-set ipsum src -j DROP 2>/dev/null \ || iptables -I INPUT -m set --match-set ipsum src -j DROP # Cron (sudo crontab -e, dagligen kl. 4:00): 0 4 * * * /usr/local/bin/update-ipsum.sh
Utökad variant med fail2ban-recidive — i avsnittet ”Fungerande konfiguration Fail2ban + ipsum”.
ipset ligger i minnet och försvinner vid omstart. Enbart en daglig cron lämnar uppsättningen tom från omstart till nästa körning (instrumentpanelen visar 0). Läs in uppsättningen även vid start — flytta inläsningen till ett skript och koppla det till @reboot. Samtidigt sätter kommandot create … -exist gränsen maxelem 300000 (standard är 65536 — level 1 får inte plats, det blir ”Hash is full”):
# /usr/local/bin/load-ipsum.sh #!/bin/bash curl -s https://raw.githubusercontent.com/stamparm/ipsum/master/levels/1.txt \ | grep -v '^#' | sed 's/^/add ipsum /' \ | (echo "create ipsum hash:ip hashsize 131072 maxelem 300000 -exist"; echo "flush ipsum"; cat) \ | ipset restore -exist # sudo crontab -e — dagligen kl. 04:00 OCH vid varje start: 0 4 * * * /usr/local/bin/load-ipsum.sh @reboot sleep 60 && /usr/local/bin/load-ipsum.sh
Så fungerar det vid autoinstallation. Skriptet läser in hela level 1-listan (100 000+ IP) i uppsättningen ipsum och, om brandväggen hanteras av installationsprogrammet (ny VPS — profilerna ”Fullständig”/”Förenklad”), ansluter uppsättningen till UFW med en DROP-regel — trafik från dessa IP-adresser blockeras på riktigt. Regeln ligger efter ESTABLISHED,RELATED, så befintliga anslutningar (inklusive din SSH) bryts inte — bara nya anslutningar från listan stoppas. Uppsättningen återställs när tjänsten ipsum-load.service startas före brandväggen (annars skulle UFW inte kunna starta), och uppdateras av cron kl. 04:00. På en redan konfigurerad server (panel, egen brandvägg) rör installationsprogrammet inte brandväggen — där förblir ipsum en lista för instrumentpanelen och attackkartan, och DROP-regeln läggs vid behov till manuellt (den minimala varianten med iptables … --match-set ipsum … -j DROP — ovan). Vid autoinstallation behöver du inte göra något manuellt.

13. Installation av CrowdSec

En modern ersättare för Fail2ban med kollektiv threat intelligence: blockeringar från gemenskapen plus egna regler. Kräver en separat bouncer för att tillämpa blockeringar på brandväggen.

curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash sudo apt install crowdsec sudo systemctl enable --now crowdsec # Bouncer för iptables/nftables: sudo apt install crowdsec-firewall-bouncer-iptables # Kontrollera status: sudo systemctl status crowdsec sudo cscli decisions list sudo cscli bouncers list
Statusen ”Inte startad” i panelen = tjänsten är installerad men inte aktiv (monitorn kontrollerar den via systemctl is-active crowdsec). Starta: sudo systemctl enable --now crowdsec; vid krasch kontrollera sudo journalctl -u crowdsec -n 30. Samma regel gäller alla tjänster med statusen ”Inte startad” (Suricata, Falco, Monit, MySQL).
”0 scenarier” eller ”0 bouncers” på instrumentpanelen. CrowdSec är nästan tomt direkt ur lådan — utan samlingar upptäcker det ingenting, och utan en registrerad bouncer tillämpas inte blockeringarna på brandväggen. Lägg till grundläggande samlingar och kontrollera att din bouncer finns i listan:
# Grundläggande samlingar (Linux + SSH + webbserver): sudo cscli collections install crowdsecurity/linux crowdsecurity/sshd crowdsecurity/base-http-scenarios sudo systemctl reload crowdsec # Bouncern ska finnas i listan och ha status som aktiv anslutning: sudo cscli bouncers list
I bouncerns logg stream halted / blockeringar tillämpas inte. Det är en föräldralös api-nyckel: bouncern togs bort från cscli bouncers list, men dess gamla nyckel finns kvar i /etc/crowdsec/bouncers/*.yaml. Registrera bouncern på nytt och ange en ny nyckel:
sudo cscli bouncers add fw-bouncer # skriver ut en ny api_key # skriv in denna nyckel i api_key: i /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml sudo systemctl restart crowdsec-firewall-bouncer
Autoinstallation (profilen ”Fullständigt skydd”) installerar själv samlingarna och registrerar firewall-bouncer — det behöver bara göras manuellt vid manuell installation eller efter manuellt ingrepp i CrowdSec.

14. Installera AIDE

AIDE (Advanced Intrusion Detection Environment) tar en ögonblicksbild av filsystemet och rapporterar vid varje kontroll om ändringar i /etc, /bin, /usr. Efter installationen är initiering av databasen obligatorisk (aideinit).

sudo apt install aide # Initiering av databasen (5–15 minuter): sudo aideinit sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db # Ubuntu 24.04: katalogen /var/lib/aide skapas med läge 700 (ägare _aide), # och panelen (www-data) ser inte databasen → visar ”Ej initierad”. # Öppna katalogen för genomgång (databasfilerna förblir 600): sudo chmod 755 /var/lib/aide # Första kontroll MED SKRIVNING till loggen som monitorn läser. # På Ubuntu/Debian kräver aide explicit --config (annars ”missing configuration”; # binären aide.wrapper levereras inte i nyare versioner): sudo bash -c 'aide --config /etc/aide/aide.conf --check > /var/log/aide/aide.log 2>&1'
Under aideinit står terminalen i 5–15 minuter på raden Running aide --init... — det är normalt (hashning av hela filsystemet, belastning på disken). Avbryt inte med Ctrl+C. Om processen ”hänger” men inte skriver något — väntar den kanske på svar på en dold fråga Overwrite existing aide.db.new [Yn]? (tryck Y). Kontrollera aktiviteten från en annan session: pgrep -af aide.
Fel i aideinit: ”21_aide_spamassassin … printf: invalid number” (return code 20) — en känd bugg i AIDE:s konfigurationssnutt i Ubuntu 22.04. Databasen skapas inte. Flytta ut den trasiga snutten och försök igen:
sudo mv /etc/aide/aide.conf.d/21_aide_spamassassin /etc/aide/21_aide_spamassassin.disabled sudo aideinit sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db
Statusar på instrumentpanelen. ”Ej initierad” = panelen ser inte databasfilen: antingen har aideinit inte körts, eller (Ubuntu 24.04) katalogen /var/lib/aide är skapad med läge 700 och är otillgänglig för www-data — åtgärdas med sudo chmod 755 /var/lib/aide (se blocket ovan). ”Inga kontroller har gjorts” = databasen finns, men kontroll har ännu inte utförts — det är inte ett fel. Resultaten läser monitorn från /var/log/aide/aide.log.
Regelbunden kontroll → logg för panelen. Standard-/etc/cron.daily/aide på nyare Ubuntu/Debian skriver kanske inte /var/log/aide/aide.log i rätt form (och aide.wrapper finns inte längre i dem). Det är säkrare att lägga till en egen cron med explicit --config — den skriver loggen som root med läge 644, och monitorn läser den utan extra grupper:
# sudo crontab -e — daglig kontroll kl. 02:00: 0 2 * * * /usr/bin/aide --config /etc/aide/aide.conf --check > /var/log/aide/aide.log 2>&1 # Kör nu, utan att vänta på schemat: sudo bash -c 'aide --config /etc/aide/aide.conf --check > /var/log/aide/aide.log 2>&1'
Automatisk installation gör redan allt detta: chmod 755 /var/lib/aide och en cron-kontroll kl. 02:00 — inget behöver göras manuellt.
Gör den första initieringen på en ren server — innan du installerar webbapplikationer. Efter legitima ändringar återskapar du databasen: sudo aideinit && sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db.

15. Installation av ClamAV

Antivirusskanner för Linux. Särskilt användbar för att kontrollera /var/www efter PHP-skal och skadlig kod.

sudo apt install clamav clamav-daemon sudo systemctl enable --now clamav-daemon # Uppdatera signaturdatabasen: sudo freshclam # Skanna en mapp manuellt: sudo clamscan -r /var/www --infected
Visar clamd-demonen ”Inaktiv” efter enable --now? Tre vanliga orsaker:

1. Raden Example finns kvar i konfigurationen — clamd vägrar starta så länge den finns:

sudo sed -i '/^Example/d' /etc/clamav/clamd.conf sudo systemctl restart clamav-daemon

2. Signaturdatabasen är inte nedladdad — clamd startar inte utan den:

sudo systemctl stop clamav-freshclam sudo freshclam sudo systemctl start clamav-freshclam sudo systemctl restart clamav-daemon

3. Den laddar helt enkelt — clamd läser in ~8 miljoner signaturer i minnet på 30–60 sek. Vänta och kontrollera: systemctl is-active clamav-daemon (status activating → laddar fortfarande).

Diagnostik: sudo journalctl -u clamav-daemon -n 30 --no-pager.
Visar instrumentpanelen ”Filer kontrollerade: 0” / ”Senaste skanning: —”? Demonen clamd håller bara signaturerna i minnet, den skannar inget schemalagt av sig själv. Panelen visar resultatet av en schemalagd skanning, så det behövs en cron som skannar och skriver logg. Autoinstallationen lägger in omslaget /usr/local/bin/clamav-scan.sh och en cron kl. 01:30 — efter första körningen fylls ”Filer kontrollerade” och ”Senaste skanning” i. Kör direkt utan att vänta på schemat: sudo /usr/local/bin/clamav-scan.sh.

16. Installation av Linux Malware Detect (maldet)

Linux Malware Detect (LMD) — en skanner för skadlig kod mot webbhot: PHP-skal, webbakdörrar, nedladdare. Använder ClamAV-motorn och kompletterar den med egna signaturer.

wget https://www.rfxn.com/downloads/maldetect-current.tar.gz tar -xzf maldetect-current.tar.gz dir=$(ls -d maldetect-*/ | head -1) && cd "$dir" && sudo bash install.sh && cd ~ rm -rf maldetect-* maldetect-current.tar.gz # Uppdatera signaturer: sudo maldet -u # Skanna /var/www: sudo maldet -a /var/www
LMD och ClamAV fungerar bra tillsammans. Senaste rapporten: maldet --report.
Vid installationen kan raden update-rc.d: error: unable to read /etc/init.d/maldet visas — den är ofarlig. maldet använder inte init.d, uppdatering av signaturer och skanningar körs via /etc/cron.daily/maldet. Om installation completed visas nedan — allt installerades.
Står det ”Inte installerad” för LMD på sidan trots att den är installerad? maldet installeras inte via apt, utan i /usr/local/maldetect, och när open_basedir är aktiverat kontrolleras dess närvaro via shell — se avsnittet ”Sidan är tom trots att data finns på servern”.

17. Installera Suricata

Nätverksbaserat intrångsdetekteringssystem: analyserar trafiken på paketnivå och känner till tusentals attacksignaturer. Kompletterar ModSecurity (som arbetar på HTTP-nivå, medan Suricata arbetar på TCP/IP-nivå).

sudo add-apt-repository ppa:oisf/suricata-stable sudo apt update && sudo apt install suricata # Hämta aktuella regler: sudo suricata-update sudo systemctl enable --now suricata
Suricata är ”Aktiv” men panelen visar inga larm / antalet händelser är 0? Suricata skriver /var/log/suricata/eve.json som root med läget 750 på katalogen, och webbservern (www-data) kan inte läsa den. Öppna katalogen för genomgång – filerna inuti förblir skyddade:
sudo chmod o+rx /var/log/suricata
Automatisk installation gör detta själv – behövs inte manuellt.

18. Installation av Falco

Fångar upp systemanrop via eBPF/kernel-modul och upptäcker avvikelser i realtid: shell från nginx, läsning av /etc/passwd av en webbprocess, skrivning till /bin osv.

curl -fsSL https://falco.org/repo/falcosecurity-packages.asc > /tmp/falco.asc gpg --dearmor < /tmp/falco.asc | sudo tee /usr/share/keyrings/falco-archive-keyring.gpg > /dev/null sudo chmod 644 /usr/share/keyrings/falco-archive-keyring.gpg && rm /tmp/falco.asc echo "deb [signed-by=/usr/share/keyrings/falco-archive-keyring.gpg] https://download.falco.org/packages/deb stable main" \ | sudo tee /etc/apt/sources.list.d/falcosecurity.list sudo apt update && sudo apt install falco sudo systemctl enable --now falco
Monitorn läser Falco-händelser via journalctl -u falco (utan sudo — via gruppen systemd-journal). Kontrollera att www-data finns i den gruppen — se ”Konfigurera sudo” (p.2) på sidan för manuell installation.
”0 händelser under 24 timmar” är normalt, inte ett fel. Falco är händelsestyrt: det är tyst så länge allt är i sin ordning och skriver en händelse endast vid en avvikelse (shell från en webbprocess, läsning av /etc/passwd, skrivning till systemkataloger). Noll kritiska under ett dygn på en lugn server är ett friskt tillstånd.
För panelen är filutdata mer tillförlitligt. Läsning via journalctl kräver rättigheter till loggen; för att panelen ska se händelser stabilt aktiverar autoinstallationen file_output för Falco → /var/log/falco/falco.log och sätter UMask=0022 på tjänsten (loggen läses av webbservern). På en ny installation behöver detta inte konfigureras manuellt.

19. Installation av ModSecurity (WAF)

ModSecurity — en webbrandvägg (WAF) för Apache eller Nginx. Blockerar attacker på applikationsnivå: SQL-injektioner, XSS, sökvägstraversering, skannrar.

# Apache: sudo apt install libapache2-mod-security2 sudo a2enmod security2 # Regeluppsättningen OWASP Core Rule Set: sudo apt install modsecurity-crs # OBLIGATORISKT: utan denna fil är regelmotorn avstängd sudo cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf sudo sed -i 's/^SecRuleEngine DetectionOnly/SecRuleEngine On/' /etc/modsecurity/modsecurity.conf sudo apache2ctl configtest && sudo systemctl reload apache2 # Kontroll: ska returnera 403 curl -s -o /dev/null -w '%{http_code}\n' "https://monitor.example.com/?id=1%20UNION%20SELECT%201,2--"
Att installera paketet skyddar i sig ingenting. Apache inkluderar konfigurationer via raden IncludeOptional /etc/modsecurity/*.conf, men paketet lägger bara modsecurity.conf-recommended — den matchar inte mönstret *.conf. Om den inte kopieras till modsecurity.conf förblir SecRuleEngine Off: modulen är laddad, CRS-reglerna är laddade, men trafiken kontrolleras inte och ingen granskningslogg skapas. Mellanläget DetectionOnly skriver bara händelser till loggen utan att blockera förfrågningar — panelen visar det i gult.

Panelens åtkomst till granskningsloggen. Loggen /var/log/apache2/modsec_audit.log ägs av root (rättigheter 640) och kan inte läsas av webbanvändaren. Panelen hämtar data via ett omslag — skapa det:

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 # i /etc/sudoers.d/monitor (användare = den som PHP-FPM körs som): # www-data ALL=(ALL) NOPASSWD: /usr/local/bin/monitor-modsec
Omslaget tar den sista SecRuleEngine-direktivet utan indrag: rader med indrag ligger inne i block <LocationMatch>/<Directory> (t.ex. avstängning av WAF för phpMyAdmin) och bestämmer inte det globala läget.
Användaren i sudoers måste stämma överens med användaren i FPM-poolen: på vanlig Apache/Debian är det www-data, i HestiaCP körs webbplatsens pool som webbplatsens ägare (t.ex. admin) — kontrollera med grep -E '^user' /etc/php/*/fpm/pool.d/monitor.example.com.conf.
Om webbplatsen står bakom en Nginx-proxy (HestiaCP) ser Apache själva proxyn som klient — panelen hämtar angriparens verkliga IP från rubriken X-Forwarded-For. Endast transaktioner där en regel utlösts hamnar i statistiken: direktivet SecAuditLogRelevantStatus skriver alla 4xx/5xx-svar till granskningsloggen, så även vanliga 403/500 hamnar där — panelen räknar dem inte som WAF-händelser.
Blocket ---RULES--- behövs av avsnittet ”Alla aktiva regler” — panelen visar inte bara de utlösta reglerna, utan över huvud taget alla laddade CRS-regler + anpassade. De tre sökvägarna i slingan for f in … är typiska platser för CRS-regler och lokala tillägg; om du har en annan uppsättning (paketet lägger filer i sin egen katalog, eller om anpassade regler inte ligger i /etc/modsecurity/custom-rules.conf) hittar du de verkliga sökvägarna med kommandot sudo grep -rl 'IncludeOptional\|^Include ' /etc/apache2/mods-enabled/security2.conf /etc/apache2/conf-enabled/*.conf 2>/dev/null och lägger in dem i listan. Om omslaget är gammalt (utan detta avsnitt) visar avsnittet bara varningen ”otillgängligt”, resten av sidan fungerar som förut.

20. Installation av Auditd

Auditd (Linux Audit Daemon) registrerar systemanrop på kärnnivå: inloggningar och utloggningar, sudo-kommandon, misslyckade autentiseringsförsök, filändringar. Monitorn visar inloggningar, misslyckade försök och sudo-kommandon för idag.

sudo apt install auditd audispd-plugins sudo systemctl enable --now auditd # Kontrollera status och händelser: sudo systemctl status auditd sudo ausearch -m USER_LOGIN -ts today
Monitorn läser händelser via ausearch (/usr/sbin/ausearch) och vid behov från /var/log/audit/audit.log med kommandot tail. Båda måste finnas i sudoers.

21. Installera Monit

Övervakar tjänster (nginx, php-fpm, mysql osv.) och startar om dem vid krasch. Kan skicka aviseringar via e-post.

sudo apt install monit sudo systemctl enable --now monit # Konfigurationsfiler: sudo nano /etc/monit/monitrc ls /etc/monit/conf.d/
Monitorn hämtar tjänstlistan via monit status. I /etc/monit/monitrc måste HTTP-gränssnittet vara aktiverat (blocket set httpd med allow localhost), annars returnerar monit status ett fel.
Visar dashboarden ”0 tjänster under övervakning”? Två orsaker. (1) HTTP-gränssnittet är avstängt — i monitrc är raden set httpd bortkommenterad (standard är # set httpd port 2812 …). Avkommentera blocket och tillåt localhost. (2) Ett aktiverat httpd övervakar inget i sig — Monit räknar bara det som beskrivs i check-stanser; utan dem är listan tom även med fungerande gränssnitt. Minimal fungerande konfiguration:
# /etc/monit/conf.d/00-httpd — HTTP-gränssnitt för localhost: set httpd port 2812 use address localhost allow localhost # exempel på check-stanser (vad som ska övervakas): check process sshd with pidfile /run/sshd.pid start program = "/usr/bin/systemctl start ssh" stop program = "/usr/bin/systemctl stop ssh" check filesystem rootfs with path / if space usage > 90% then alert
sudo monit -t # kontrollera syntax (Control file syntax OK) sudo systemctl reload monit sudo monit status
Autoinstallationen lägger in en färdig conf.d med httpd på 2812 och en uppsättning kontroller — på en ny installation behöver inget konfigureras manuellt.
Tjänst i statusen ”Med fel”? Monitorn visar bara tillståndet och startar avsiktligt inte om tjänster från webbpanelen (det vore fjärrkörning av root-kommandon i en säkerhetspanel). Diagnostik och omstart görs via SSH med Monit:
sudo monit status <service> # orsak till felet sudo monit restart <service> # omstart via Monit # om Monit inte startar tjänsten — kontrollera dess egen enhet: sudo systemctl status <unit> --no-pager sudo journalctl -u <unit> -n 50 --no-pager

22. Installera PSAD (detektering av portskanning)

PSAD analyserar iptables-loggen och upptäcker portskanning och nätverksattacker genom att tilldela varje källa en hotnivå (1–5). Kompletterar fail2ban och Suricata.

sudo apt install psad # PSAD läser iptables-loggen — loggning måste vara aktiverad (UFW gör detta själv). # För ren iptables, lägg till LOG-regler i kedjorna INPUT/FORWARD. sudo psad --sig-update sudo systemctl enable --now psad
Monitorn läser data via psad --Status (krävs i sudoers). Utan iptables-loggning är sidan tom — det är normalt tills en skanning har inträffat.

23. AppArmor / SELinux (åtkomstkontroll)

Mandatory Access Control begränsar vilka filer och resurser ett program kan komma åt, även om det har blivit hackat. I Ubuntu/Debian används AppArmor som standard (vanligtvis redan installerat och aktivt).

# AppArmor (Ubuntu/Debian): sudo apt install apparmor apparmor-utils sudo systemctl enable --now apparmor sudo aa-status # kontrollera profiler
Monitorn läser status via aa-status (krävs i sudoers). Visar antalet profiler i läget enforce/complain och processer utan profil.

Att ”laddade profiler” är fler än enforce + complain är normalt. I AppArmor 4.x (Ubuntu 24.04 och senare) infördes läget unconfined: profilen laddas i kärnan men begränsar ingenting. Ubuntu markerar på så sätt tiotals profiler för program som använder user namespaces (webbläsare, torrent-klienter och liknande). När sådana profiler finns blir kortet ”laddade profiler” bärnstensfärgat och visar deras antal — till exempel unconfined: 90 vid 120 laddade och 26 i enforce. Egentligt skydd ger bara profiler i enforce; på Ubuntu 22.04 (AppArmor 3.x) finns inte detta läge och siffrorna stämmer alltid överens.

sudo aa-status | grep -E "profiles are" # uppdelning per läge sudo aa-enforce /etc/apparmor.d/profile-name # sätt profilen i enforce
Att sätta profiler som Ubuntu medvetet lämnat i unconfined till enforce bör göras endast med eftertanke: de är inte avstängda av misstag, utan för att programmen annars slutar fungera. Profiler i complain är en annan sak: där är reglerna redan skrivna och tillämpas bara inte.

24. Installation av debsums (paketintegritet)

debsums kontrollerar att filerna i installerade paket stämmer överens med kontrollsummorna från förrådet — upptäcker utbytta systembinärer (kompletterar AIDE). En fullständig kontroll tar 1–2 minuter och körs därför via cron, medan panelen läser resultatet från data/debsums/debsums.log och sorterar det själv i kategorier (endast binärer och bibliotek är viktiga).

Uppgiften läggs i root-cron (sudo crontab -e). Den färdiga wrappern debsums-scan.sh placeras i /usr/local/bin/ (chmod +x; se sammanställningen av cron-uppgifter) och skriver själv rapporten till data/debsums/ i panelen.

sudo apt install debsums # Cron-rad (dagligen 4:30): 30 4 * * * /usr/local/bin/debsums-scan.sh >> /path/to/monitor/logs/cron.log 2>&1

Wrappern debsums-scan.sh hittar själv panelens data/ — sökvägen behöver inte anges.

Ändringar i /etc/ (konfigurationer) och /usr/share/ (resurser) på servern är oftast normala — panelen markerar dem med en särskild färg. Oroande är ändringar av binärer och bibliotek (/bin, /sbin, /usr/lib osv.) — kortet ”Binärer / bibliotek” visar just dessa.

25. Konfigurera Lynis-rapporter

Lynis körs manuellt eller via cron. Rapporten ska sparas i projektets mapp data/lynis/ — monitorn läser filen lynis-report.dat.

# Engångskörning (ange din egen sökväg till panelens rot): sudo lynis audit system --report-file /path/to/monitor/data/lynis/lynis-report.dat # Daglig granskning — cron-rad (färdig wrapper lynis-scan.sh i /usr/local/bin/, se sammanfattningen): 0 3 * * * /usr/local/bin/lynis-scan.sh >> /path/to/monitor/logs/cron.log 2>&1
Efter första körningen visar sidan ”Lynis-granskning” direkt hardening-index, varningar och rekommendationer.
Knappen ”Kör granskning” på Lynis-sidan. Den kör lynis-scan.sh i bakgrunden direkt från panelen (utan att vänta på cron): visar ”Skannar…” och uppdaterar rapporten själv när den är klar. För detta behöver webbanvändaren en sudoers-rad för att köra skriptet — installationsprogrammet lägger till den automatiskt i /etc/sudoers.d/monitor. Om panelen installerats manuellt/tidigare, lägg till den med samma användare som redan anges i filen:
u=$(sudo awk '/NOPASSWD/ && !/lynis-scan/ {print $1; exit}' /etc/sudoers.d/monitor) [ -n "$u" ] && echo "$u ALL=(ALL) NOPASSWD: /usr/local/bin/lynis-scan.sh" | sudo tee -a /etc/sudoers.d/monitor sudo visudo -c && sudo chmod 440 /etc/sudoers.d/monitor

26. Konfigurera Logwatch-rapporter

Logwatch ska spara dagliga rapporter i projektmappen data/logwatch/ i formatet .txt. Monitorn visar den senaste rapporten och arkivet.

# Dagligen (6:00) — cron-rad (färdig wrapper logwatch_daily.sh i /usr/local/bin/, se sammanfattningen): 0 6 * * * /usr/local/bin/logwatch_daily.sh >> /path/to/monitor/logs/cron.log 2>&1

Panelmoduler

27. Nätverksmonitor (inbyggd)

Nätverksmonitorn kräver ingen installation — det är en inbyggd sida i panelen. Den visar serverns nätverksstatus från lokala källor:

  • gränssnitt och trafik — från /proc/net/dev;
  • länkstatus (UP/DOWN) och IP — via ip;
  • anslutningar och lyssnande portar — via ss;
  • nätverkshändelser i kärnan senaste 24 h — via journalctl -k.

De tre första källorna fungerar utan sudo, så gränssnitt, trafik, anslutningar och portar syns direkt. Blocket ”Kärnhändelser” använder journalctl -k — det läses via gruppen systemd-journal (”Konfigurera sudo”, p.2), sudo behövs inte. Kontrollera att allt är tillgängligt för webbanvändaren:

# Kontroll som www-data (PHP körs under den): sudo -u www-data bash -c 'cat /proc/net/dev' sudo -u www-data bash -c 'ip -o link show' sudo -u www-data bash -c 'ss -s' sudo -u www-data journalctl -k --no-pager -n 5
Blocket ”Nätverkshändelser i kärnan” visar händelser i kärnans nätverksstack (länk up/down, bärvågsfel, ”network unreachable”). Brandväggsposter UFW BLOCK hamnar inte här — de finns på sidorna ”Brandvägg UFW” och ”Attackkarta”. Ett tomt block med grön bock = inga nätverksfel senaste dygnet.

28. Disk och SMART

Den inbyggda sidan visar tre saker:

  • Filsystem — hur fulla partitionerna är (df); skalan blir röd vid ≥90 %;
  • Lagringsenheter — lista över diskar (lsblk), endast riktiga (loop/snap döljs);
  • Hälsa (SMART) — diskstatus och attribut (smartctl).

Utrymme och enhetslista fungerar direkt, utan konfiguration. För SMART krävs paketet smartmontools. Webbprocessen har ingen direkt åtkomst till diskenheterna, därför läses SMART av via cron till filen data/disk/smart.txt, och panelen läser den.

Jobbet läggs i root-cron (sudo crontab -e). Det färdiga skalet smart-scan.sh placeras i /usr/local/bin/ (chmod +x; se sammanställningen av cron-jobb) och skriver själv till panelens data/disk/.

sudo apt install smartmontools # Cron-rad (var 30:e minut): */30 * * * * /usr/local/bin/smart-scan.sh >> /path/to/monitor/logs/cron.log 2>&1

Skalet smart-scan.sh hittar själv panelens data/ — sökvägen behöver inte anges. Internt utesluter lsblk -e7,11 loop/cdrom.

På virtuella diskar (QEMU/KVM och liknande) är oftast bara den allmänna statusen ”hälsa: OK” tillgänglig, medan temperatur, drifttimmar och omfördelade sektorer kan vara tomma — det är normalt. På en fysisk server visas alla attribut.

29. Prestanda (CPU/RAM/Nätverk/Disk)

Sidan visar serverbelastningens historik för de senaste 24 timmarna — Load Average, CPU-användning och I/O-väntetid, RAM/Swap, nätverkstrafik (mottaget/skickat), disk-I/O (läsning/skrivning), diskfyllnad och inoder, öppna filbeskrivare och MySQL-anslutningar, plus aktuellt antal TCP-anslutningar och processer.

Data samlas in av cron/collect_metrics.php — var 5:e minut skrivs en ”rå” ögonblicksbild av räknarna (/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') till databastabellen system_metrics; procent och hastigheter beräknar sidan själv utifrån skillnaden mellan intilliggande ögonblicksbilder (diskfyllnad/inoder/beskrivare/MySQL-anslutningar är momentana värden, utan omräkning). Sudo krävs inte — källorna läses utan root-rättigheter. Punkter äldre än 24 timmar tas bort automatiskt vid varje skrivning.

# Cron-rad (var 5:e minut): */5 * * * * /usr/local/bin/collect-metrics-all.sh >> /path/to/monitor/logs/cron.log 2>&1

Wrappern collect-metrics-all.sh (se sammanställningen av cron-jobb) hittar själv alla installerade panelinstanser på servern och kör cron/collect_metrics.php för var och en som webbplatsens ägare.

Tills insamlaren har körts minst två gånger (de första ~10 minuterna efter installationen) visar sidan ”data samlas in” — graferna behöver minst ett par intilliggande punkter för att beräkna hastigheter och procent.

Belastningsaviseringar (avsnittet ”Inställningar” → ”Belastningsaviseringar”) — när tröskeln för CPU/RAM/disk/inoder överskrids skickar panelen en avisering till Telegram/Email (samma kanaler som den dagliga rapporten — de behöver inte aktiveras separat för aviseringar), och ytterligare en när mätvärdet återgått till det normala. Den spammar inte upprepat medan tröskeln hålls: nästa avisering kommer först efter cykeln ”återställt → överskridit igen”.

Trösklarna kontrolleras av samma collect_metrics.php vid varje körning (var 5:e minut) — ingen separat cron behövs. Tillståndet ”redan aviserat / inte än” lagras i data/alerts_state.json, trösklarna i panelens inställningar.

30. Attackkarta (GeoIP)

Sidan ”Attackkarta” fastställer landet utifrån IP med kommandot geoiplookup. Utan GeoIP-paketet kan länder inte identifieras och inga punkter visas på kartan:

sudo apt install geoip-bin geoip-database # Kontroll: geoiplookup 8.8.8.8
Sudo behövs inte – databasen /usr/share/GeoIP/GeoIP.dat kan läsas av alla, resultaten cachas i tmp/geoip_cache.json. Själva kartan (Leaflet + OpenStreetMap-rutor) laddas i webbläsaren – internet krävs på datorn där panelen är öppen.

31. Extern exponering, uppdateringar och automatiska uppdateringar

Två inbyggda dashboardkort som inte visar om ett verktyg är på/av, utan serverns verkliga skyddsnivå. Kräver ingen installation och läses lokalt utan sudo.

Extern exponering — hur många tjänster som lyssnar på alla gränssnitt (0.0.0.0/[::]) och är åtkomliga utifrån. Markeras rött om databaser eller cache exponeras utåt (MySQL, PostgreSQL, Redis, MongoDB, Memcached, Elasticsearch) — det är ett direkt säkerhetshål (−10 på säkerhetspoängen). Källa: ss -tuln.

Om kortet är rött — stäng databaserna för omvärlden: bind dem till 127.0.0.1 (bind-address i MySQL/PostgreSQL-konfigurationen, bind 127.0.0.1 i Redis) eller stäng porten i UFW.
”Öppen port” ≠ ”åtkomlig utifrån”. En tjänst som lyssnar på 127.0.0.1 (loopback) syns bara för servern själv — den går inte att nå utifrån, även om porten är ”öppen”. Därför är Postfix på port 25 bunden till loopback säker: autokonfigurationen sätter inet_interfaces = loopback-only (plus ett neutralt smtpd_banner — som avfärdar Lynis-anmärkningen MAIL-8818 om att versionen röjs). Kortet ”Extern exponering” räknar bara det som lyssnar på 0.0.0.0/[::] som utåtvänt; loopback-tjänster ingår inte.
Lynis MAIL-8818 manuellt (om du satte upp e-posten själv): sätt smtpd_banner = $myhostname ESMTP (utan version och OS) och inet_interfaces = loopback-only i /etc/postfix/main.cf, kör sedan sudo systemctl restart postfix.

Säkerhetsuppdateringar — hur många säkerhetspatchar som väntar på installation och om en omstart krävs efter en kärnuppdatering (−5 på säkerhetspoängen om patchar finns). Källa: /usr/lib/update-notifier/apt-check, filen /var/run/reboot-required. Detaljerad lista finns på sidan ”Säkerhetsuppdateringar”.

# Installera uppdateringar: sudo apt update && sudo apt upgrade # Kontrollera vad som lyssnar utåt: ss -tuln | grep -E '0\.0\.0\.0|\[::\]'
Uppdateringskortet fungerar på Ubuntu/Debian (update-notifier-common). Om apt-check saknas räknar monitorn patcharna via apt-get -s upgrade.

Automatiska säkerhetsuppdateringar (unattended-upgrades) — på sidan ”Säkerhetsuppdateringar” visar ett separat kort om automatisk installation av säkerhetspatchar är aktiverad och när den senast kördes. Sudo behövs inte — statusen läses via apt-config dump.

sudo apt install unattended-upgrades sudo dpkg-reconfigure -plow unattended-upgrades # aktivera # Kontrollera vad som är aktiverat: apt-config dump | grep Unattended-Upgrade

Underhåll

32. Säkerhetskopiering

Säkerhetskopior är den viktigaste försäkringen: dataförlust är värre än vilket intrång som helst. Du behöver två saker — säkerhetskopia av servern/webbplatserna och separat en säkerhetskopia av panelens databas (där finns användare, WebAuthn-nycklar, inställningar och licens).

Alternativ A — HestiaCP: fliken Backup hos användaren → knappen för att skapa en säkerhetskopia (eller schemalagt i serverinställningarna). Säkerhetskopian omfattar webbplatser och deras databaser.

Alternativ B — manuellt (cron): databasdump + arkiv av panelens katalog data/:

# root-cron (sudo crontab -e) — daglig säkerhetskopia kl. 2:30 (sätt in dina egna namn/sökvägar): 30 2 * * * mysqldump -u root MY_DB | gzip > /var/backups/monitor-db-$(date +\%F).sql.gz 40 2 * * * tar czf /var/backups/monitor-data-$(date +\%F).tar.gz -C /path/to/monitor data # Ta bort arkiv äldre än 14 dagar: 0 3 * * * find /var/backups -name 'monitor-*' -mtime +14 -delete
En säkerhetskopia på samma server räddar från misstag, men inte från att förlora servern. Kopiera arkiven till extern lagring (en annan server, S3, rclone till molnet). Kontrollera att återställningen verkligen fungerar.

33. Uppdatering och migrering av panelen

Uppdatering till en ny version. Gör först en säkerhetskopia. Ladda sedan upp kodfilerna på nytt och behåll dina data:

  • skriv över (kod): public/, includes/, assets/, cron/, database/, samt roten .htaccess (frontkontroller – routningen får inte vara kvar från den gamla versionen), manifest.json, sw.js;
  • rör inte: config.php (databasuppgifter), data/ (rapporter), logs/, tmp/ (sessioner och cache).
# Efter uppladdning – rensa PHP-cachen (om opcache är aktiverat): sudo systemctl reload php*-fpm
FileZilla säger SSH_FX_PERMISSION_DENIEDPermission denied. Panelens filer ägs av www-data (så sattes de vid installationen), medan SFTP-klienten ansluter som din egen användare, som inte har skrivrättighet. Att ge www-data hela panelen ”för att det ska fungera” är just det som leder till detta fel; nedan tre sätt, vart och ett löser problemet.
# Alternativ A (rekommenderas) — dela upp ägarna: koden är din, arbetsmapparna webbserverns. # Webbservern får ingen skrivrättighet till panelens KOD alls: sudo chown -R deploy:www-data /path/to/monitor sudo chown -R www-data:www-data /path/to/monitor/data /path/to/monitor/tmp /path/to/monitor/logs sudo find /path/to/monitor -type d -exec chmod 755 {} \; sudo find /path/to/monitor -type f -exec chmod 644 {} \; sudo chmod 750 /path/to/monitor/data /path/to/monitor/tmp /path/to/monitor/logs sudo chmod 640 /path/to/monitor/config.php # Alternativ B — ACL ovanpå nuvarande ägare (vi flyttar ingenting): sudo apt install -y acl sudo setfacl -R -m u:deploy:rwX /path/to/monitor sudo setfacl -R -d -m u:deploy:rwX /path/to/monitor # Alternativ C — via gruppen www-data. Enklare, men skrivrättighet till panelens # filer får även webbservern (vid en PHP-sårbarhet kan koden bytas ut): sudo usermod -aG www-data deploy sudo find /path/to/monitor -type d -exec chmod 2775 {} \; sudo find /path/to/monitor -type f -exec chmod 664 {} \; sudo chmod 640 /path/to/monitor/config.php sudo chmod 2750 /path/to/monitor/data /path/to/monitor/tmp /path/to/monitor/logs
Varför alternativ A är säkert. Panelen skriver bara till tre kataloger — data/ (rapporter), tmp/ (sessioner och cache), logs/; de förblir under www-data. Resten är kod, och webbservern behöver den bara för läsning, vilket gruppen www-data ger med rättigheterna 644. Sidovinst: vid en PHP-sårbarhet går panelens filer inte längre att skriva över. På hostingpaneler (HestiaCP och liknande) behövs inte alternativ A: där ägs webbplatsens filer redan av kontot som du loggar in med via SFTP, och webbservern läser dem via gruppen.
Fällan med alternativ B: varje efterföljande chmod på filerna nollställer ACL-masken, och åtkomsten försvinner tyst. Om uppladdningen efter en ”upprensning av rättigheterna” åter fastnar på Permission denied — kör båda setfacl-kommandona igen.
Biten 2 i alternativ C är setgid: filer som laddas upp via SFTP stannar kvar i gruppen www-data, annars kan panelen inte skriva över dem. Efter alternativ C — anslut på nytt i FileZilla: den nya gruppen börjar gälla först vid en ny inloggning. Kontroll: id deploy (gruppen www-data ska dyka upp) och ls -ld /path/to/monitor (drwxrwsr-x — bokstaven s betyder att setgid är satt).

Migrering till en annan server:

  1. På den nya servern, sätt upp webbplatsen + HTTPS (se sidan för manuell installation).
  2. Kopiera alla panelens filer tillsammans med config.php, data/.
  3. Migrera databasen: mysqldump på den gamla → import på den nya; uppdatera databasuppgifterna i config.php.
  4. Upprepa på den nya servern: sudoers, medlemskap i gruppen adm, cron-jobb.
  5. Licensen är knuten till domänen – om domänen är densamma fortsätter nyckeln att fungera.

34. Återställa åtkomst (förlorad nyckel, lösenord, IP-block)

Om du inte kan logga in kan allt åtgärdas direkt i databasen från servern. Öppna databasen (namnet finns i config.php):

sudo mysql MY_DB

Förlorad WebAuthn-nyckel (andra faktorn fungerar inte) — inaktivera 2FA, logga in med lösenord och registrera en ny nyckel:

UPDATE users SET webauthn_enabled = 0;

Glömt lösenord — ange en ny hash (generera den på servern och infoga den):

# Generera hash för det nya lösenordet: php -r "echo password_hash('NEW_PASSWORD', PASSWORD_BCRYPT), \"\n\";" # I databasen (infoga den erhållna hashen): # UPDATE users SET password = '$2y$10$...' WHERE username = 'admin';

Låst ute dig själv med IP-filtret — inaktivera begränsningen:

UPDATE settings SET value = '0' WHERE name = 'ip_restriction_enabled';
Åtkomst till databasen finns alltid: sudo mysql på servern, eller phpMyAdmin / databasavsnittet i hostingpanelen. Aktivera WebAuthn och IP-filtret igen efter återställningen.

35. Alla cron-jobb på ett ställe

Sammanställningen av jobb finns i serverns root-cron (läggs till via sudo crontab -e). Behåll bara raderna för de verktyg du använder; justera sökvägarna för din server.

# Monitorns servercron (root) — lägg till via: sudo crontab -e # 01:30 — ClamAV-skanning av farliga sökvägar (web, home, temp) → korten ”Filer kontrollerade” och ”Senaste skanning” 30 1 * * * /usr/local/bin/clamav-scan.sh >> /path/to/monitor/logs/cron.log 2>&1 # 02:00 — AIDE-integritetskontroll av filer (kräver uttryckligt --config) 0 2 * * * /usr/bin/aide --config /etc/aide/aide.conf --check > /var/log/aide/aide.log 2>&1 # vid uppstart — återställ rättigheter på /var/lib/aide (pakettets tmpfiles-fil # aide-common.conf sätter dem till 0700, och panelen slutar se databasen) @reboot chmod 755 /var/lib/aide # 03:00 — säkerhetsgranskning med Lynis 0 3 * * * /usr/local/bin/lynis-scan.sh >> /path/to/monitor/logs/cron.log 2>&1 # 04:00 — uppdatering av blocklistan ipsum (level 1) 0 4 * * * /usr/local/bin/load-ipsum.sh >> /path/to/monitor/logs/cron.log 2>&1 # ipsum-uppsättningen laddas vid uppstart av tjänsten ipsum-load.service (FÖRE brandväggen, annars # ser inte UFW uppsättningen i before.rules) — inte cron. Här bara den dagliga uppdateringen ovan. # 06:00 — Logwatch-rapport 0 6 * * * /usr/local/bin/logwatch_daily.sh >> /path/to/monitor/logs/cron.log 2>&1 # var 30:e min — SMART-kontroll av diskar */30 * * * * /usr/local/bin/smart-scan.sh >> /path/to/monitor/logs/cron.log 2>&1 # 04:30 — paketintegritet med debsums 30 4 * * * /usr/local/bin/debsums-scan.sh >> /path/to/monitor/logs/cron.log 2>&1 # 08:00 — schemalagd rapport till Email och Telegram 0 8 * * * /usr/local/bin/daily-report-all.sh >> /path/to/monitor/logs/cron.log 2>&1 # varje timme — uppdatering av paketlistor (för kortet ”Säkerhetsuppdateringar”) 0 * * * * /usr/bin/apt-get update -qq >/dev/null 2>&1 # var 5:e min — ögonblicksbild av resurser (CPU/RAM/nätverk/disk) för sidan ”Prestanda” */5 * * * * /usr/local/bin/collect-metrics-all.sh >> /path/to/monitor/logs/cron.log 2>&1
Detaljer om var och en finns i respektive avsnitt. Backupjobben (föregående avsnitt) läggs till i samma cron. Kontrollera efter ändringar: sudo crontab -l och att cron-tjänsten är aktiv.
Cron-tiden = serverns tidszon, inte TIMEZONE från config.php. Konstanten TIMEZONE påverkar bara PHP (hur panelen visar datum), men cron-demonen kör jobb enligt operativsystemets systemtid. Om serverns tidszon inte matchar din kommer rapporten ”08:00” vid fel tidpunkt. Exempel: servern står i en annan tidszon (Europe/London, UTC+1), medan du är i Stockholm (UTC+2) → rapporten ”08:00” kommer 09:00 hos dig. Kontrollera och ställ vid behov systemets tidszon till din egen:
# Kontrollera serverns aktuella tidszon: timedatectl # Ställ in din tidszon (exempel) och starta om cron: sudo timedatectl set-timezone Europe/Stockholm sudo systemctl restart cron
Därefter utlöses raden 0 8 * * * kl. 08:00 lokal tid. Annars skulle man behöva förskjuta själva cron, men vid övergång till vinter-/sommartid går förskjutningen isär igen — därför är det bättre att ställa in systemets tidszon.
Färdiga omslagsskript. Deras arbetskopior och en exempel-crontab (crontab.txt) ligger i mappen system/ bredvid projektet, utanför public_html. Det är inte en del av webbplatsen — de behöver inte laddas upp till webbroten; placera dem på servern enligt systemsökvägarna (som i crontab ovan):
  • lynis-scan.sh/usr/local/bin/ (chmod +x) — kör lynis audit system, sätter flaggan /tmp/lynis-running under skanningen och kopierar lynis-report.dat till panelens data/lynis/;
  • logwatch_daily.sh/usr/local/bin/ (chmod +x) — skapar en daglig Logwatch-rapport (sshd, fail2ban, sudo, postfix) i data/logwatch/;
  • smart-scan.sh/usr/local/bin/ (chmod +x) — läser av diskarnas status (smartctl) i data/disk/;
  • debsums-scan.sh/usr/local/bin/ (chmod +x) — kontrollerar paketintegritet (debsums) i data/debsums/;
  • clamav-scan.sh/usr/local/bin/ (chmod +x) — ClamAV-antivirusskanning av farliga sökvägar (web, home, temp); skriver en sammanställning till /var/log/clamav/scan.log, varifrån ClamAV-sidan läser den (raden 01:30 i crontab ovan);
  • load-ipsum.sh/usr/local/bin/ (chmod +x) — uppdaterar ipset-uppsättningen ipsum (level 1) på plats, utan att bryta de aktiva brandväggsreglerna (raden 04:00 i crontab ovan);
  • daily-report-all.sh/usr/local/bin/ (chmod +x) — kör panelens rapport cron/daily_report.php (raden 08:00 i crontab ovan);
  • daily_report.php — ingår redan i panelen (cron/daily_report.php), körs via daily-report-all.sh, behöver inte installeras separat;
  • collect-metrics-all.sh/usr/local/bin/ (chmod +x) — kör panelens cron/collect_metrics.php (sidan ”Prestanda”, raden */5 i crontab ovan); collect_metrics.php ingår redan i panelen, behöver inte installeras separat;
  • crontab.txt (system/cron/) — exempel på jobb; skriv in de rader du behöver via sudo crontab -e.
Sökvägen till skriptet i crontab måste matcha den plats där du lade det.
Så här lägger du ett skript i /usr/local/bin/. Direkt från FileZilla går det inte att skriva dit — katalogen ägs av root, och SFTP-klienten får SSH_FX_PERMISSION_DENIED. Gör så här: ladda först upp filen till /tmp (dit kan alla skriva), och flytta den sedan på plats med ett enda kommando:
# i FileZilla: ange /tmp i fältet ”Fjärrplats” och ladda upp skriptet dit, # sedan via SSH (install sätter ägare och rättigheter direkt, chown/chmod behövs inte): sudo install -o root -g root -m 755 /tmp/lynis-scan.sh /usr/local/bin/lynis-scan.sh rm -f /tmp/lynis-scan.sh # kontroll: filen på plats, rättigheter rwxr-xr-x, syntaxen hel bash -n /usr/local/bin/lynis-scan.sh && ls -l /usr/local/bin/lynis-scan.sh
Förväxla inte katalogerna: du behöver /tmp i serverns rot — inte /var/tmp och inte tmp/ inuti själva panelen (den sistnämnda ägs av www-data och är stängd för din användare). I FileZilla-trädet är /tmp en gren på översta nivån, bredvid var, inte inuti den.
Installerade du servern med autokonfiguration? Dessa omslag och deras cron-jobb är redan installerade av skriptet (i /usr/local/bin/, logg — /var/log/arciveo-cron.log) — du behöver inte göra något manuellt.
Var skripten letar efter panelen. Omslagen är domänneutrala: de hittar panelinstallationer genom att gå igenom /home/*/web/*/public_html och /var/www/*, och lägger rapporterna i deras data/. Om panelen ligger på en annan sökväg — lägg till den i raden for app in … inuti skripten, annars når inte rapporterna från Lynis/SMART/debsums/Logwatch panelen.
cron.log och åtkomsträttigheter. Filen logs/cron.log skapas först av root-cron — den kommer att ägas av root, och fliken ”Cron-logg” i panelen kan varken läsa eller tömma den. Skapa filen i förväg som webbanvändaren (ägare till webbplatsens katalog; på HestiaCP är det kontot, t.ex. admin) — då lägger root-cron bara till text utan att ändra ägaren:
# skapa i förväg som webbanvändaren (innan cron-rader läggs till): sudo -u OWNER touch /path/to/monitor/logs/cron.log # om cron.log redan skapats av root-cron — ge den till webbanvändaren: sudo chown OWNER:OWNER /path/to/monitor/logs/cron.log sudo chmod 644 /path/to/monitor/logs/cron.log
Ta reda på katalogens ägare: stat -c %U /path/to/monitor.
Hantering från panelen. I avsnittet ”System” finns sidan ”Crontab” — du kan visa och lägga till jobb utan SSH. Panelen redigerar bara jobb som lagts till via den själv (ett separat block i root-crontab, markerat med tjänstekommentarer); allt som redan finns i crontab (listan ovan) visas där som en skrivskyddad lista ”Övriga serverjobb” med knappen ”Kopiera till redigeraren” — den flyttar bara schemat/kommandot till formuläret för tillägg och rör inte den ursprungliga raden. För att ”flytta” ett befintligt jobb under panelens hantering — kopiera det till redigeraren, spara, och ta sedan bort den gamla raden manuellt (sudo crontab -e), annars körs det två gånger.
Engångskonfiguration på servern. Sidan behöver ett privilegierat omslagsskript — inte ren sudo crontab (det skulle vara en direkt eskalering till root av vem som helst som får åtkomst till panelens session), utan ett smalt skript med två kommandon (list/set) som bara rör sitt eget block mellan tjänstekommentarerna. Installera en gång:
sudo install -m 0755 -o root -g root /dev/stdin /usr/local/sbin/arciveo-cron <<'ARCIVEO_CRON_EOF' #!/bin/bash set -euo pipefail BEGIN='# >>> ARCIVEO-CRON-MANAGED (edited from the panel; do not edit by hand) >>>' END='# <<< ARCIVEO-CRON-MANAGED <<<' cmd=${1:-} case "$cmd" in list) [ "$#" -eq 1 ] || { echo "usage: ${0##*/} list" >&2; exit 2; } crontab -l -u root 2>/dev/null || true ;; set) [ "$#" -eq 1 ] || { echo "usage: ${0##*/} set (body on stdin)" >&2; exit 2; } body=$(cat) if grep -qF "$BEGIN" <<<"$body" || grep -qF "$END" <<<"$body"; then echo "invalid body: markers not allowed" >&2; exit 2 fi current=$(crontab -l -u root 2>/dev/null || true) tmp=$(mktemp); trap 'rm -f "$tmp"' EXIT { if grep -qF "$BEGIN" <<<"$current"; then awk -v b="$BEGIN" '{print} $0==b{exit}' <<<"$current" else [ -n "$current" ] && printf '%s\n' "$current" echo "$BEGIN" fi printf '%s\n' "$body" echo "$END" if grep -qF "$END" <<<"$current"; then awk -v e="$END" 'f{print} $0==e{f=1}' <<<"$current" fi } > "$tmp" crontab -u root "$tmp" ;; *) echo "usage: ${0##*/} <list|set>" >&2; exit 2 ;; esac ARCIVEO_CRON_EOF echo "www-data ALL=(ALL) NOPASSWD: /usr/local/sbin/arciveo-cron" | sudo tee -a /etc/sudoers.d/monitor sudo visudo -c
Webbanvändaren kan skilja sig från www-data — kontrollera vilken användare webbplatsens PHP-FPM-pool körs under (ps -o user= -C php-fpm) och sätt in den i sudoers-raden.
Den nya filen laddades upp med fel ägare — sidan svarar ”Access denied.”. Om filen public/crontab_monitor.php laddades upp via FTP/SFTP under en annan systemanvändare (till exempel root) än övriga webbplatsfiler kan webbservern inte läsa den. Jämför ägare och rättigheter med en intilliggande fil och gör dem enhetliga:
ls -la public/crontab_monitor.php public/ssl_monitor.php sudo chown OWNER:OWNER public/crontab_monitor.php sudo chmod 644 public/crontab_monitor.php

Diagnostik

36. Verktyget är installerat, men visar ”Inte installerat”

Monitorn identifierar tillgängliga verktyg via dpkg-query — APT:s paketdatabas. Om ett verktyg inte installerats via apt (manuellt, från snap eller från källkod) syns det inte för dpkg.

# Kontrollera via dpkg: dpkg -l fail2ban | grep '^ii' dpkg -l auditd | grep '^ii' # Hitta sökväg till binärfilen: which ufw fail2ban-client auditctl # Testa sudo som www-data: sudo -u www-data sudo fail2ban-client status sudo -u www-data sudo ufw status verbose

37. Felsökning (500, inga data)

Fel 500 — kontrollera loggarna för PHP, nginx och själva monitorn:

tail -50 /var/log/nginx/error.log tail -50 /var/log/php*-fpm.log # Monitorns loggar: tail -50 logs/monitor_$(date +%Y-%m-%d).log # Behörigheter på mappar: ls -la data/ tmp/ logs/
Panelen på en webbhotellpanel (HestiaCP, ISPmanager, cPanel)? Där körs PHP inte som www-data, utan under användarens konto (t.ex. admin — ägaren av webbplatsens katalog). Alla sudo-regler och gruppmedlemskap (adm, systemd-journal) måste anges för den användaren, annars visar modulerna ”Inte aktiv / 0” trots att tjänsterna körs. Ta reda på PHP:s verkliga användare: ps -o user= -C php-fpm | sort -u eller ägaren av webbplatsens katalog stat -c '%U' /path/to/monitor. Använd sedan den i alla kommandon nedan i stället för www-data. Autoinstallationen identifierar webbanvändaren själv och skriver sudoers för den.

Data visas inte — nästan alltid saknade sudo-behörigheter. Kontrollera det specifika kommandot som webbanvändaren (ersätt www-data med din egen). Flaggan -n = utan lösenord, som PHP — om det ber om lösenord finns regeln inte i sudoers:

sudo -u www-data sudo -n fail2ban-client status sudo -u www-data sudo -n ufw status verbose sudo -u www-data sudo -n ipset list -t ipsum sudo -u www-data sudo -n /usr/sbin/ausearch -m USER_LOGIN -ts today sudo -u www-data sudo -n /usr/sbin/aa-status sudo -u www-data sudo -n /usr/sbin/psad --Status sudo -u www-data journalctl -u falco --no-pager -n 5
Modulen visar ”Inte aktiv” / ”0” trots att verktyget körs (t.ex. sudo aa-status i terminalen visar profiler, men sidan ”AppArmor” visar ”Inaktiv”). Orsak: webbanvändaren saknar sudo-behörighet för den modulens kommando. Kontrollera det från listan ovan: om det ber om lösenord — lägg till den saknade raden i /etc/sudoers.d/monitor (”Konfigurera sudo”). Vanliga ”nya” kommandon: /usr/sbin/aa-status (MAC), /usr/sbin/psad --Status (PSAD).
Om en viss sida (Falco, ModSecurity, Auditd, öppna UFW-portar) är tom — jämför med listan i avsnittet om sudo: sannolikt är apache2ctl, ausearch, aa-status eller ss inte tillåtet, eller så är webbanvändaren inte med i grupperna adm/systemd-journal (därifrån läses loggarna för fail2ban/auth/modsec och journalctl — Falco och kärnhändelser).

38. Sidan är tom trots att data finns på servern

Symptom: data finns på servern (syns via shell) men sidan visar ”inga data” eller fel status – till exempel skriver AIDE ”Inte initierad” trots att databasen är skapad.

Orsaken är open_basedir: många paneler och webbhotell begränsar PHP-FPM-poolen till domänens katalog, så PHP-funktionerna file_exists(), file_get_contents(), filemtime() blockeras för systemsökvägar (/var/lib/aide, /var/log, /proc…). Monitorn kringgår detta genom att läsa sådana sökvägar med vanliga systemkommandon (cat, test, stat).

# Syns filen via shell (så här läser monitorn): sudo -u www-data bash -lc 'test -e /var/lib/aide/aide.db && echo VISIBLE || echo NO' # Aktuellt värde för open_basedir för domänens pool: grep -ri open_basedir /etc/php/*/fpm/pool.d/ 2>/dev/null
Om shell ”ser” filen (VISIBLE) men sidan inte gör det – då är det open_basedir. Rätt lösning är att läsa med systemkommandon (redan gjort för AIDE och Nätverksmonitorn). Att utöka open_basedir till /var, /proc behövs inte och är mindre säkert.

39. SSL-sidan fungerar inte

Monitorn kontrollerar certifikat genom att ansluta direkt till domänerna via port 443. Om domänen inte är nåbar från själva servern eller porten är blockerad av brandväggen — misslyckas kontrollen.

# Kontrollera certifikatet manuellt: echo | openssl s_client -connect monitor.example.com:443 2>/dev/null \ | openssl x509 -noout -dates # Kontrollera tillgänglighet: curl -I https://monitor.example.com
Domänerna hämtar monitorn automatiskt från nginx-konfigurationerna (/etc/nginx/sites-enabled/, /etc/nginx/conf.d/) och Apache (/etc/apache2/sites-enabled/) plus den aktuella värden från HTTP_HOST.
Automatisk identifiering av underdomäner. Underdomäner identifieras automatiskt från de publika Certificate Transparency-loggarna och kontrolleras via nätverket — även om de finns på andra servrar. Du behöver inte lägga till något manuellt.

40. Endast en av flera databaser syns

Monitorn ansluter till MySQL med användaren från config.php, som bara har åtkomst till sin egen databas. MySQL visar i information_schema endast databaser med behörighet – därför syns inte de övriga.

För att monitorn ska se alla databaser, ge den här användaren enbart läsbehörighet (en gång som root; ange användarnamnet från config.php):

sudo mysql -u root GRANT SELECT, PROCESS, SHOW DATABASES ON *.* TO 'DB_USER'@'localhost'; FLUSH PRIVILEGES; EXIT;
SELECT ON *.* ger endast läsbehörighet – det går inte att ändra, ta bort eller skapa något, vilket är säkert för övervakning.
Utan denna GRANT ser panelen bara sin egen databas – det är inte ett fel utan en behörighetsbegränsning. Panelen använder inget sudo mysql: databaslistan hämtas via dess egen PDO-anslutning.

41. PostgreSQL visas inte på sidan ”Databas”

PostgreSQL kräver åtkomst på nivån för användaren postgres, vilket panelens webbanvändare inte har. Att öppna en bred sudo psql från PHP är osäkert – i stället anropar panelen ett smalt omslag utan parametrar, som bara skriver ut versionen, antalet anslutningar och en lista över databaser med storlekar. Skapa det:

sudo tee /usr/local/bin/monitor-pgstat >/dev/null <<'EOF' #!/bin/sh # Arciveo Monitor - read-only PostgreSQL version, connections and per-database size sudo -u postgres psql -tAc "SELECT version();" | grep -oE 'PostgreSQL [0-9.]+' echo "---" sudo -u postgres psql -tAc "SELECT count(*) FROM pg_stat_activity;" echo "---" sudo -u postgres psql -tAc "SELECT datname || '|' || pg_size_pretty(pg_database_size(datname)) FROM pg_database WHERE datistemplate = false;" EOF sudo chown root:root /usr/local/bin/monitor-pgstat sudo chmod 755 /usr/local/bin/monitor-pgstat # i /etc/sudoers.d/monitor (användaren = den som PHP-FPM körs under): # www-data ALL=(ALL) NOPASSWD: /usr/local/bin/monitor-pgstat
Om du inte använder PostgreSQL – ta bort raden monitor-pgstat från sudoers (steg 13 i den manuella installationen) och skapa inte själva skriptet: PostgreSQL-kortet förblir bara inaktivt.

42. En avisering utlöstes — vad gör man

Panelen visar vad som händer; nedan står vad du ska göra i vanliga situationer. Grundprincipen: håll huvudet kallt, stäm av mot legitim aktivitet (dina åtgärder, uppdateringar, säkerhetskopior) och reagera efter allvarsgrad.

  • Attackkarta / många fail2ban-blockeringar — det är normalt för alla servrar på internet (bottar testar ständigt SSH/webb). Det viktiga är att blockeringarna utlöses. Se till att SSH-inloggning bara sker med nyckel (lösenord avstängt) och att din IP finns i ignoreip.
  • ModSecurity blockerade förfrågningar — WAF:en avvärjer attacker mot webbplatsen, det är dess uppgift. Om din legitima trafik blockeras (falsklarm) — hitta rule id i detaljerna och lägg till ett undantag i CRS-konfigurationen.
  • AIDE: filer ändrade — jämför listan med vad du har gjort (paketuppdateringar, konfigredigering — normalt). Ändringar i systembinärer som du inte rört är skäl att bli vaksam. Uppdatera AIDE-databasen efter legitima ändringar.
  • debsums: binärer/bibliotek ändrade (utanför /etc, utanför /usr/share) — potentiell manipulation. Kontrollera paketet: debsums PACKAGE_NAME, installera om det vid tvivel (apt install --reinstall).
  • ClamAV / maldet: hot funnet — kontrollera filen i karantän, öppna den inte. Om det är ett webbskal i webbplatsens katalog — isolera servern och leta efter ingångspunkten (sårbar plugin, läckta åtkomstuppgifter).
  • Falco: kritiska händelser (skal startat i en container, åtkomst till känsliga filer) — analysera händelsen: vems process, vad som startade den. Ofta är det legitim adminaktivitet.
  • Extern exponering: databas/cache i rött — stäng omedelbart: bind tjänsten till 127.0.0.1 eller stäng porten i UFW. Det är ett verkligt hål.
  • SSL går ut / har gått ut — förnya certifikatet (Let's Encrypt förnyas automatiskt; annars kontrollera certbot renew eller inställningarna i panelen).
  • Säkerhetsuppdateringar väntar — installera dem: sudo apt update && sudo apt upgrade; starta om servern efter en kärnuppdatering.
Tecken på ett verkligt intrång (okända processer/användare, ändrade binärer, utgående spam, okända cron-jobb): koppla bort servern från extern åtkomst, ta en säkerhetskopia för analys och, om data är kritiska, sätt upp en ren server från en betrodd säkerhetskopia — att rensa bort ett rootkit på ett tillförlitligt sätt är svårt.
Arcivéo - Security Monitor © 2026