FAQ

Dette er en veiledning for installasjon, konfigurasjon og vedlikehold av Arcivéo Monitor. Seksjonene er gruppert: generell oversikt, utrulling av panelet, tilkobling av sikkerhetsverktøy, innebygde moduler og diagnostikk. Kommandoene kan kopieres med knappen til høyre.

Kom i gang

01. Installasjon av panelet — velg metode

Installasjonen av panelet finnes på egne trinnvise sider. Velg metode:

Usikker — velg automatisk. Denne håndboken er fortsatt den samlede kilden for SSL, verktøy, cron og diagnostikk — install-sidene lenker til seksjonene her uten å duplisere noe.

Oversikt

02. Hva er Arcivéo Monitor

Arcivéo Monitor — et sikkerhetspanel for serveren. Det samler inn data fra installerte verktøy (Fail2ban, UFW, Lynis, ModSecurity, AIDE, ClamAV, Auditd, CrowdSec, Suricata, Falco m.fl.) og viser dem i ett enhetlig grensesnitt med dashbord, angrepskart og detaljerte sider for hvert verktøy.

Monitor er ikke et aktivt beskyttelsesverktøy — det blokkerer ikke angrep selv. Oppgaven er å aggregere informasjon fra verktøy som allerede kjører, og presentere den på en oversiktlig måte.

03. Slik fungerer monitoren på serveren

Monitoren fungerer kun lokalt — den må installeres på den samme serveren som den overvåker. Ingen SSH eller eksternt API.

Alle kommandoer (fail2ban-client, ufw status, ipset list osv.) kjører dashbordet som webserverens bruker (vanligvis www-data, på hostingpaneler — nettstedets konto) med et snevert sett rettigheter for sudo — kun til bestemte verktøy, uten generell root-tilgang. Resultatene tolkes og vises i nettleseren.

For flere servere installerer du monitoren separat på hver enkelt, med et unikt domene.

04. Slik beregnes sikkerhetsscoren

Scoren starter på maksimum og reduseres for hvert problem som oppdages:

  • UFW er ikke aktiv — −30
  • Fail2ban kjører ikke (ingen aktive jail) — −25
  • Ingen WebAuthn-nøkler — −15
  • Lynis hardening index < 60 — −20; 60–79 — −10
  • IPset ipsum er ikke lastet inn — −10
  • Trusler funnet av ClamAV — −20
  • Filendringer i AIDE — −15
  • SSL utløpt — −30, utløper om <14 dager — −15, <30 dager — −5
  • CrowdSec er installert, men kjører ikke — −5
  • Suricata er installert, men kjører ikke — −5
  • Databaser/cache (MySQL, PostgreSQL, Redis…) tilgjengelig utenfra — −10
  • Root-innlogging via SSH er tillatt (PermitRootLogin yes) — −20
  • Sikkerhetsoppdateringer venter på installasjon — −5

Resultat: 80+ = Beskyttet, 60–79 = Advarsel, <60 = Truet.

Fradrag for ClamAV, AIDE, CrowdSec og Suricata gjelder bare hvis verktøyet er installert. Lynis og AIDE uten en initialisert database vises som «ingen data» og trekker ikke fra poeng. Antall angrep i dag vises på dashbordet, men påvirker ikke sikkerhetsscoren.

Innstillinger og lisens

05. WebAuthn — tofaktorautentisering

WebAuthn er en standard for passordløs autentisering med en maskinvarenøkkel. Støtter YubiKey, Touch ID, Face ID, Windows Hello og Passkey.

Etter pålogging med passord ber systemet om bekreftelse via en registrert nøkkel. Selv om passordet lekker, er det umulig å logge inn uten den fysiske nøkkelen eller biometri.

For å sette opp dette åpner du WebAuthn-nøkler i sidemenyen og klikker «Registrer nøkkel». Registrer to nøkler med en gang: hvis den eneste nøkkelen mistes eller går i stykker, blir det umulig å logge inn i dashbordet med den.

WebAuthn fungerer kun via HTTPS. På en HTTP-tilkobling er registrering og pålogging med nøkkel ikke tilgjengelig.

06. Varsler: Telegram og e-post

Panelet kan sende sikkerhetsrapporten til Telegram og på e-post (med knapp og etter tidsplan). Dette settes opp under «Innstillinger».

Telegram. Du trenger bot-token og chat id:

  1. Skriv @BotFather i Telegram → /newbot → få en token av typen 123456:ABC....
  2. Send en hvilken som helst melding til den nye boten (slik at den kan svare deg).
  3. Finn din chat id: skriv til boten @userinfobot, eller åpne https://api.telegram.org/bot<TOKEN>/getUpdates og finn "chat":{"id":...}.
  4. Lim inn token og chat id under «Innstillinger» → Telegram, og trykk «Lagre og send test».

E-post. To metoder å velge mellom under «Innstillinger» → E-post:

  • SMTP — vert, port (465/SSL eller 587/TLS), brukernavn og passord til postboksen din;
  • Resend — et moderne API: oppgi API-nøkkel (re_...) og et bekreftet avsenderdomene.
Knappen «Send test» sjekker kanalen umiddelbart. Tidsplanen for automatisk rapport går via cron (delen «Alle cron-jobber»): den utløser sendingen, mens kanalene hentes fra innstillingene.

Rapportstatus: «OBS» eller «OK». Overskriften blir «OBS» bare ved et reelt problem eller en handling som venter: ClamAV har funnet en trussel, filendringer i AIDE, kritiske Falco-hendelser (Emergency/Alert/Critical de siste 24 t), en tjeneste som er nede i Monit, omstart kreves, SSL utløper (≤14 dager) eller sikkerhetsoppdateringer venter. Bakgrunnsstøy — SSH-forsøk fra boter, IP-adresser bannet av fail2ban, Suricata-varsler, Lynis-advarsler og allerede avviste ModSecurity-forespørsler — hever ikke statusen, så slike tall i rapporten betyr ikke «OBS» i seg selv.

07. Lisens – oppgi og aktiver

De detaljerte overvåkingsmodulene (Lynis, UFW, ModSecurity, angrepskart, AIDE, ClamAV m.fl.) åpnes når du har en gyldig lisens. Uten den fungerer dashbordet, innstillingene og kontoen, mens modulene viser kortet «Lisens kreves».

Etter kjøp har du på kontoen en aktiveringskode på formen ARCIVEO-XXXX-XXXX-XXXX-XXXX. Den må «aktiveres» mot domenet til panelet ditt – det gjør koden om til en signert lisensfil (blokken [license]) som du limer inn i panelet.

Slik aktiverer du (3 trinn):

  1. Hent aktiveringskoden. Kontoen my.arciveo.com → seksjonen «Lisenser» / «Lisensaktivering» – kopier koden ARCIVEO-….
  2. Aktiver koden mot ditt domene. Åpne «Lisensaktivering» samme sted på kontoen, og oppgi: aktiveringskode, e-postadressen din og paneldomenet (adressen der Monitor åpnes, f.eks. monitor.example.com). Trykk aktiver – systemet genererer en lisensfil knyttet til dette domenet og viser den i et felt med knappen «Kopier».
  3. Lim nøkkelen inn i panelet. Kopier hele lisensteksten → åpne «Innstillinger» → blokken «Lisens» i panelet, lim inn og trykk «Lagre». Modulene låses opp umiddelbart.

Panelet kontrollerer nøkkelen kryptografisk: signatur, binding til domenet og gyldighetstid.

Domenet ved aktivering må stemme nøyaktig med paneladressen. Hent det fra konstanten APP_URL i config.php og oppgi kun vertsnavnet – uten https:// og uten www-prefiks. Aktivering skjer én gang: koden blir til en lisens for det oppgitte domenet og kan ikke aktiveres på nytt – med feil i domenet passer ikke nøkkelen panelet ditt, og koden er brukt opp. Skriv derfor domenet nøye.
Er gyldighetstiden utløpt eller domenet endret, vises en advarsel øverst i panelet. Lisensen er bundet til domenet for alltid og overføres ikke til et annet domene: for ny periode eller nytt domene trengs en ny nøkkel (kjøpes på kontoen og aktiveres én gang).

08. Filen config.php — alle innstillinger for panelet

Alle hovedparametere for panelet er definert i én fil config.php i rotmappen (ved siden av mappen public/) med vanlige define()-konstanter. Filen opprettes ved installasjon; du trenger sjelden å redigere den manuelt — hovedsakelig ved bytte av domene, flytting eller tilkobling til en annen database. Etter enhver endring start PHP-FPM på nytt (ellers blir ikke endringene tatt i bruk på grunn av OPcache).

Sett inn dine egne verdier i de uthevede feltene; la resten være som det er:

// --- Database --- define('DB_HOST', 'localhost'); // la stå define('DB_NAME', 'db_name'); // det du anga ved opprettelse av databasen define('DB_USER', 'user'); // det du anga ved opprettelse av databasen define('DB_PASS', 'db_password'); // det du anga ved opprettelse av databasen define('DB_CHARSET', 'utf8mb4'); // la stå // --- Applikasjon --- define('APP_URL', 'https://monitor.example.com'); // adressen til panelet, uten skråstrek til slutt define('TIMEZONE', 'Europe/Oslo'); // din tidssone // --- Sesjonstid --- define('SESSION_LIFETIME', 28800); // inaktivitet før ny innlogging, sek (28800 = 8 t)

Database. Tilkoblingsdetaljer for MySQL/MariaDB:

  • DB_HOST — databasevert, nesten alltid localhost;
  • DB_NAME — navnet på panelets database;
  • DB_USER — databasebruker (tilgang kun til egen database);
  • DB_PASS — passordet til denne brukeren;
  • DB_CHARSET — tegnkoding for tilkoblingen, la utf8mb4 stå.

Applikasjon.

  • APP_URL — full adresse til panelet (f.eks. https://monitor.example.com). Må stemme med domenet lisensen er aktivert for — ellers avvises nøkkelen (se avsnittet «Lisens»);
  • TIMEZONE — tidssone for PHP: påvirker bare hvordan panelet viser datoer og klokkeslett. Den påvirker ikke når cron-oppgavene kjøres — der gjelder systemets tidssone (se «Alle cron-oppgaver»).

Sesjonstid. SESSION_LIFETIME — tidsavbrudd for inaktiv sesjon i sekunder (glidende: fornyes ved aktivitet). Standard er 28800 = 8 timer; etter denne tiden med inaktivitet ber panelet deg logge inn på nytt. For eksempel 3600 = 1 time, 86400 = ett døgn.

Feillogging. Feil vises aldri for besøkende, men skrives til logs/php_errors.log — de er synlige på siden «Applikasjonslogger». Disse linjene (display_errors=0, log_errors=1, stien error_log) trenger du vanligvis ikke å endre — innstillingene er angitt direkte i filen og avhenger ikke av php.ini.

config.php er en hemmelig fil. Den inneholder databasepassordet. Den ligger i panelets rotmappe (ved siden av public/), og for dette panelet er webroten (DocumentRoot) nettopp panelets rotmappe, ikke public/. Filen «lekker» ikke av seg selv: i roten er det i .htaccess et eksplisitt forbud mot den (Require all denied) — serveren returnerer 403. Selv uten denne regelen ville ikke kildekoden lekket: dette er PHP — serveren kjører den, i stedet for å levere den som tekst. For sikkerhets skyld: ikke legg den ut i offentlige kodelagre, og ikke send den til support med et ekte passord. Filrettigheter — 640.
Ved flytting eller gjenoppretting av tilgang er denne filen hovedkilden til tilkoblingsdetaljer: databasenavn, bruker og passord hentes nettopp herfra (se avsnittene «Oppdatering og flytting av panelet» og «Gjenoppretting av tilgang»).

Sikkerhetsverktøy

09. UFW-brannmur

UFW (Uncomplicated Firewall) er et enkelt grensesnitt til nftables/iptables. Det stenger alle innkommende porter unntatt de som eksplisitt er tillatt. Siden «UFW-brannmur» viser status og regler.

sudo apt install ufw # Tillat SSH (obligatorisk FØR aktivering!) og web sudo ufw allow OpenSSH sudo ufw allow 80,443/tcp # Steng databasen utenfra (kun lokal tilgang) sudo ufw deny 3306 # Aktiver og sjekk sudo ufw enable sudo ufw status verbose
Før ufw enable må du tillate SSH (ufw allow OpenSSH), ellers mister du tilgangen til serveren.
«Ekstern eksponering» på dashbordet tar hensyn til UFW: en port som er stengt med en deny-regel, regnes ikke som tilgjengelig utenfra.
Skipping adding existing rule er ikke en feil. UFW melder på denne måten at nøyaktig samme regel allerede finnes, og legger den ikke til på nytt. Ved gjentatt kjøring av autooppsettet (som er idempotent) er dette en normal melding – ingen handling er nødvendig.

10. Installere Fail2ban

Blokkerer automatisk IP-adresser når antallet mislykkede innloggingsforsøk overskrides. Analyserer logger fra SSH, nginx, Apache og andre tjenester.

sudo apt install fail2ban sudo systemctl enable --now fail2ban # Sjekk status: sudo fail2ban-client status
Fungerende konfigurasjon (jail.local med titalls jails og autoban fra ipsum) — i neste avsnitt.

11. Fungerende konfigurasjon Fail2ban + ipsum

Grunnleggende installasjon står ovenfor. Her følger en fungerende konfigurasjon som gir dusinvis av aktive jail-er og tusenvis av blokkeringer: felles innstillinger, sentrale jail-er og autoban av skadelige IP-er fra ipsum-lista.

Fila /etc/fail2ban/jail.local — felles innstillinger og de viktigste jail-ene:

[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: hver gjentakelse varer lenger bantime.increment = true bantime.factor = 2 bantime.maxtime = 5w bantime.rndtime = 300 [sshd] enabled = true maxretry = 5 bantime = -1 # permanent ban ved SSH-bruteforce findtime = 3600 # Gjengangere: den som har fått flere baner, bannes for alltid [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 # Webtjenester (apache-*, nginx-*, php-url-fopen, phpmyadmin-syslog): [nginx-http-auth] enabled = true port = http,https [apache-badbots] enabled = true port = http,https # … og resten av jail-ene per tjeneste (dovecot, exim, postfix-sasl, # mysqld-auth, vsftpd, portscan, pam-generic) — enabled = true
I ignoreip må du legge inn din egen IP og dine betrodde nett, ellers kan du banne deg selv. Etter endringer: sudo fail2ban-client reload.

Automatisk innlasting av blokklista ipsum — i root-cron (sudo crontab -e): level 1 (100 000+ IP-er) lastes inn i settet ipsum, som avskjæres på brannmuren (mer i avsnittet «Blokklista IPset»):

# 04:00 — oppdatering av ipset ipsum (level 1, maksimal dekning): 0 4 * * * /usr/local/bin/load-ipsum.sh >> /path/to/monitor/logs/cron.log 2>&1
Settet må hete ipsum — det er nettopp dette dashbordet leser (kortet «IPset ipsum»). Nivåer: levels/1.txt — maksimal dekning, levels/3.txt — mer presist (3+ kilder).

Hvorfor «Sikkerhetsmonitor» er delt i to soner. Beskyttelsen jobber på to nivåer, og dashbordet blander dem ikke:

  • Reelle angrep (reaktivt) — alt fail2ban har fanget: reelle innbruddsforsøk (jail-ene sshd, apache-*, nginx-* osv.) og notoriske gjengangere (jail-en recidive — de som allerede er bannet flere ganger). Dette er IP-er som faktisk forsøkte å bryte seg inn hos deg — de vises på angrepskartet og «Tidslinjen».
  • Preventiv blokkering (proaktivt) — den offentlige blokklista over kjente skadelige IP-er ipset ipsum, avskåret på brannmuren med regelen DROP. De fleste av disse adressene har aldri vært i kontakt med serveren din — de kuttes på forhånd; telleren «IPset ipsum» viser hvor mange som er avskåret preventivt.

Forskjellen er enkel: reaktivt — «disse angrep og ble bannet», preventivt — «disse ble blokkert før de i det hele tatt forsøkte». Tidligere ble list-3 ipsum kunstig lagt inn i recidive (derav den gamle inndelingen «liste-recidive»); nå er recidive bare ekte gjengangere, mens preventivt kjører helt på brannmuren.

12. Blokkeringsliste IPset (ipsum)

ipsum — en offentlig liste over skadelige IP-er som oppdateres daglig. Monitor viser antall innlastede adresser på dashbordet og angrepskartet og tar det med i sikkerhetsvurderingen (−10 hvis settet ikke er lastet inn).

Den minimale varianten uten fail2ban — et eget sett ipsum med blokkering via iptables:

# Opprett settet (én gang): sudo ipset create ipsum hash:ip # Oppdateringsskript /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, daglig kl. 4:00): 0 4 * * * /usr/local/bin/update-ipsum.sh
Den utvidede varianten med fail2ban-recidive finner du i avsnittet «Fungerende konfigurasjon for Fail2ban + ipsum».
ipset lever i minnet og går tapt ved omstart. Bare et daglig cron-jobb vil la settet stå tomt fra omstarten skjer og fram til neste kjøring (dashbordet viser 0). Last inn settet også ved oppstart — flytt innlastingen til et skript og koble det til @reboot. Samtidig setter kommandoen create … -exist grensen maxelem 300000 (standard er 65536 — level 1 får ikke plass og gir «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 — daglig kl. 04:00 OG ved hver oppstart: 0 4 * * * /usr/local/bin/load-ipsum.sh @reboot sleep 60 && /usr/local/bin/load-ipsum.sh
Slik fungerer det ved automatisk installasjon. Skriptet laster inn hele listen level 1 (100 000+ IP-er) i settet ipsum, og hvis brannmuren styres av installasjonsprogrammet (fersk VPS — profilene «Full»/«Lettvekt»), kobles settet til UFW med en DROP-regel — trafikk fra disse IP-ene blir faktisk blokkert. Regelen står etter ESTABLISHED,RELATED, så eksisterende tilkoblinger (inkludert din SSH) brytes ikke — kun nye tilkoblinger fra listen blokkeres. Settet gjenopprettes ved oppstart av tjenesten ipsum-load.service før brannmuren (ellers ville ikke UFW starte opp), og oppdateres av cron kl. 04:00. På en allerede konfigurert server (kontrollpanel, egen brannmur) rører ikke installasjonsprogrammet brannmuren — der forblir ipsum en liste for dashbordet og angrepskartet, mens DROP-regelen kan legges til manuelt ved behov (den minimale varianten med iptables … --match-set ipsum … -j DROP — ovenfor). Ved automatisk installasjon trenger du ikke gjøre noe manuelt.

13. Installere CrowdSec

En moderne erstatning for Fail2ban med kollektiv trusseletterretning: blokkeringer fra fellesskapet pluss egne regler. Krever en egen bouncer for å håndheve blokkeringer i brannmuren.

curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash sudo apt install crowdsec sudo systemctl enable --now crowdsec # Bouncer for iptables/nftables: sudo apt install crowdsec-firewall-bouncer-iptables # Sjekk status: sudo systemctl status crowdsec sudo cscli decisions list sudo cscli bouncers list
Statusen «Ikke startet» i panelet = tjenesten er installert, men den kjører ikke (Monitor sjekker den via systemctl is-active crowdsec). Start den: sudo systemctl enable --now crowdsec; ved feil, se sudo journalctl -u crowdsec -n 30. Samme regel gjelder for enhver tjeneste med statusen «Ikke startet» (Suricata, Falco, Monit, MySQL).
«0 scenarioer» eller «0 bouncers» på dashbordet. CrowdSec kommer nesten tom rett ut av boksen — uten samlinger oppdager den ingenting, og uten en registrert bouncer håndheves ikke blokkeringene i brannmuren. Installer grunnleggende samlinger og forsikre deg om at bounceren er i listen:
# Grunnleggende samlinger (Linux + SSH + webserver): sudo cscli collections install crowdsecurity/linux crowdsecurity/sshd crowdsecurity/base-http-scenarios sudo systemctl reload crowdsec # Bounceren skal være i listen og ha status som aktiv tilkobling: sudo cscli bouncers list
I bouncer-loggen står stream halted / blokkeringer håndheves ikke. Dette er en foreldreløs api-nøkkel: bounceren ble fjernet fra cscli bouncers list, men den gamle nøkkelen ligger fortsatt i /etc/crowdsec/bouncers/*.yaml. Registrer bounceren på nytt og legg inn en ny nøkkel:
sudo cscli bouncers add fw-bouncer # skriver ut en ny api_key # skriv denne nøkkelen inn i api_key: i /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml sudo systemctl restart crowdsec-firewall-bouncer
Automatisk installasjon (profilen «Full beskyttelse») installerer samlingene og registrerer firewall-bouncer selv — manuelt trengs dette bare ved manuell installasjon eller etter manuelle inngrep i CrowdSec.

14. Installere AIDE

AIDE (Advanced Intrusion Detection Environment) tar et øyeblikksbilde av filsystemet og rapporterer ved hver kontroll om endringer i /etc, /bin, /usr. Etter installasjonen er initialisering av databasen (aideinit) obligatorisk.

sudo apt install aide # Initialisering av databasen (5–15 minutter): sudo aideinit sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db # Ubuntu 24.04: katalogen /var/lib/aide opprettes med rettighetene 700 (eier _aide), # og panelet (www-data) ser ikke databasen → viser «Ikke initialisert». # Åpne katalogen for gjennomgang (databasefilene forblir 600): sudo chmod 755 /var/lib/aide # Første kontroll MED SKRIVING til loggen som Monitor leser. # På Ubuntu/Debian krever aide en eksplisitt --config (ellers «missing configuration»; # binærfilen aide.wrapper følger ikke med i nyere versjoner): sudo bash -c 'aide --config /etc/aide/aide.conf --check > /var/log/aide/aide.log 2>&1'
Under aideinit står terminalen 5–15 minutter på linjen Running aide --init... — det er normalt (hashing av hele filsystemet, belastning på disken). Ikke avbryt med Ctrl+C. Hvis prosessen «henger», men ikke skriver noe — venter den kanskje på svar på en skjult forespørsel Overwrite existing aide.db.new [Yn]? (trykk Y). Sjekk aktiviteten fra en annen økt: pgrep -af aide.
Feil i aideinit: «21_aide_spamassassin … printf: invalid number» (return code 20) — en kjent feil i AIDE-konfigsnutten i Ubuntu 22.04. Databasen opprettes ikke. Flytt ut den ødelagte snutten og prøv på nytt:
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
Statuser på dashbordet. «Ikke initialisert» = panelet ser ikke databasefilen: enten er ikke aideinit kjørt, eller (Ubuntu 24.04) er katalogen /var/lib/aide opprettet med rettighetene 700 og utilgjengelig for www-data — løses med sudo chmod 755 /var/lib/aide (se blokken over). «Ingen kontroller er utført» = databasen finnes, men det er ennå ikke utført noen kontroll — det er ikke en feil. Monitor leser resultatene fra /var/log/aide/aide.log.
Regelmessig kontroll → logg for panelet. Standard /etc/cron.daily/aide på nyere Ubuntu/Debian skriver kanskje ikke /var/log/aide/aide.log i riktig format (og aide.wrapper finnes ikke lenger i dem). Det er tryggere å legge til en egen cron-jobb med eksplisitt --config — den skriver loggen som root med rettighetene 644, og Monitor leser den uten ekstra 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 # Kjør nå, uten å vente på tidsplanen: sudo bash -c 'aide --config /etc/aide/aide.conf --check > /var/log/aide/aide.log 2>&1'
Automatisk installasjon gjør allerede alt dette: chmod 755 /var/lib/aide og cron-kontroll kl. 02:00 — du trenger ikke å gjøre noe manuelt.
Gjør den første initialiseringen på en ren server — før du installerer webapplikasjoner. Etter legitime endringer bygger du databasen på nytt: sudo aideinit && sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db.

15. Installasjon av ClamAV

Antivirusskanner for Linux. Spesielt nyttig for å sjekke /var/www for PHP-skjell og skadelig kode.

sudo apt install clamav clamav-daemon sudo systemctl enable --now clamav-daemon # Oppdater signaturdatabasen: sudo freshclam # Skann en mappe manuelt: sudo clamscan -r /var/www --infected
Viser clamd-demonen «Inaktiv» etter enable --now? Tre typiske årsaker:

1. Linjen Example står fortsatt i konfigurasjonen — clamd nekter å starte så lenge den er der:

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

2. Signaturdatabasen er ikke lastet ned — clamd starter ikke uten den:

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

3. Den holder rett og slett på å laste — clamd laster ~8 mill. signaturer inn i minnet på 30–60 sek. Vent litt og sjekk: systemctl is-active clamav-daemon (status activating → laster fortsatt).

Diagnostikk: sudo journalctl -u clamav-daemon -n 30 --no-pager.
Viser dashbordet «Filer sjekket: 0» / «Siste skanning: —»? Demonen clamd holder bare signaturene i minnet, den skanner ingenting etter en tidsplan selv. Panelet viser resultatet av en planlagt skanning, så du trenger et cron-jobb som skanner og skriver til logg. Autoinstallasjonen legger inn en wrapper /usr/local/bin/clamav-scan.sh og cron kl. 01:30 — etter første kjøring fylles «Filer sjekket» og «Siste skanning». Kjør umiddelbart uten å vente på tidsplanen: sudo /usr/local/bin/clamav-scan.sh.

16. Installere Linux Malware Detect (maldet)

Linux Malware Detect (LMD) — en skadevareskanner for webtrusler: PHP-skall, web-bakdører, nedlastere. Bruker ClamAV-motoren og supplerer den med egne 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 # Oppdater signaturer: sudo maldet -u # Skann /var/www: sudo maldet -a /var/www
LMD og ClamAV fungerer godt sammen. Siste rapport: maldet --report.
Under installasjonen kan linjen update-rc.d: error: unable to read /etc/init.d/maldet dukke opp — den er harmløs. maldet bruker ikke init.d; oppdatering av signaturer og skanninger kjøres via /etc/cron.daily/maldet. Hvis du ser installation completed nedenfor, er alt installert.
Står det «Ikke installert» på LMD-siden selv om den er installert? maldet installeres ikke via apt, men i /usr/local/maldetect, og når open_basedir er aktivert, sjekkes tilstedeværelsen via shell — se avsnittet «Siden er tom selv om dataene finnes på serveren».

17. Installasjon av Suricata

Nettverksbasert system for inntrengingsdeteksjon: analyserer trafikk på pakkenivå og kjenner tusenvis av angrepssignaturer. Utfyller ModSecurity (som jobber på HTTP-nivå, mens Suricata jobber på TCP/IP-nivå).

sudo add-apt-repository ppa:oisf/suricata-stable sudo apt update && sudo apt install suricata # Last ned oppdaterte regler: sudo suricata-update sudo systemctl enable --now suricata
Suricata er «Aktiv», men panelet viser ingen varsler / antall hendelser er 0? Suricata skriver til /var/log/suricata/eve.json som root med modus 750 på katalogen, og webserveren (www-data) kan ikke lese den. Åpne katalogen for gjennomgang – filene inni forblir beskyttet:
sudo chmod o+rx /var/log/suricata
Automatisk installasjon gjør dette selv – ingen manuell handling nødvendig.

18. Installasjon av Falco

Fanger opp systemkall via eBPF/kernel module og oppdager avvik i sanntid: shell fra nginx, lesing av /etc/passwd fra en webprosess, skriving til /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
Monitor leser Falco-hendelser via journalctl -u falco (uten sudo — via gruppen systemd-journal). Kontroller at www-data er i denne gruppen — se «Oppsett av sudo» (pkt. 2) på siden for manuell installasjon.
«0 hendelser på 24 timer» er normalt, ikke en feil. Falco er hendelsesdrevet: den er stille så lenge alt er i orden, og logger en hendelse bare ved avvik (shell fra en webprosess, lesing av /etc/passwd, skriving til systemkataloger). Null kritiske på et døgn på en rolig server er en sunn tilstand.
For dashbordet er filutdata mer pålitelig. Lesing via journalctl krever tilgang til loggen; for at dashbordet skal se hendelser stabilt aktiverer autoinstallasjonen file_output hos Falco → /var/log/falco/falco.log og setter UMask=0022 på tjenesten (loggen leses av webserveren). Ved en ny installasjon trenger du ikke å sette dette opp manuelt.

19. Installasjon av ModSecurity (WAF)

ModSecurity — en webbrannmur (WAF) for Apache eller Nginx. Blokkerer angrep på applikasjonsnivå: SQL-injeksjoner, XSS, katalogtraversering, skannere.

# Apache: sudo apt install libapache2-mod-security2 sudo a2enmod security2 # Regelsett OWASP Core Rule Set: sudo apt install modsecurity-crs # OBLIGATORISK: uten denne filen er regelmotoren avslått 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: skal returnere 403 curl -s -o /dev/null -w '%{http_code}\n' "https://monitor.example.com/?id=1%20UNION%20SELECT%201,2--"
Å installere pakken beskytter ikke noe i seg selv. Apache inkluderer konfigene med linjen IncludeOptional /etc/modsecurity/*.conf, mens pakken bare legger inn modsecurity.conf-recommended — som ikke matcher masken *.conf. Kopierer du den ikke til modsecurity.conf, forblir SecRuleEngine Off: modulen er lastet, CRS-reglene er lastet, men trafikken sjekkes ikke og auditloggen opprettes ikke. Mellommodusen DetectionOnly skriver bare hendelser til loggen uten å blokkere forespørsler — panelet viser den med gult.

Panelets tilgang til auditloggen. Loggen /var/log/apache2/modsec_audit.log eies av root (rettigheter 640), og webbrukeren kan ikke lese den. Panelet henter data via en wrapper — opprett den:

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 (bruker = den som PHP-FPM kjører som): # www-data ALL=(ALL) NOPASSWD: /usr/local/bin/monitor-modsec
Wrapperen henter siste SecRuleEngine-direktiv uten innrykk: innrykkede linjer ligger inne i blokker <LocationMatch>/<Directory> (for eksempel avslåing av WAF for phpMyAdmin) og bestemmer ikke den globale modusen.
Brukeren i sudoers må stemme overens med brukeren i FPM-poolen: på vanlig Apache/Debian er det www-data, i HestiaCP kjører nettstedets pool som nettstedseieren (for eksempel admin) — sjekk grep -E '^user' /etc/php/*/fpm/pool.d/monitor.example.com.conf.
Hvis nettstedet står bak en Nginx-proxy (HestiaCP), ser Apache proxyen selv som klient — panelet henter angriperens reelle IP fra headeren X-Forwarded-For. Bare transaksjoner der en regel utløste, kommer med i statistikken: direktivet SecAuditLogRelevantStatus skriver alle 4xx/5xx-svar til auditloggen, så vanlige 403/500 havner også der — panelet regner dem ikke som WAF-hendelser.
Blokken ---RULES--- trengs av seksjonen «Alle aktive regler» — panelet viser ikke bare de utløste, men absolutt alle innlastede CRS-regler + egendefinerte. De tre stiene i løkken for f in … er typiske plasseringer for CRS-regler og lokale tillegg; har du en annen oppsett (pakken legger filer i sin egen katalog, eller egendefinerte regler ligger ikke i /etc/modsecurity/custom-rules.conf), finn de reelle stiene med kommandoen sudo grep -rl 'IncludeOptional\|^Include ' /etc/apache2/mods-enabled/security2.conf /etc/apache2/conf-enabled/*.conf 2>/dev/null og sett dem inn i listen. Er wrapperen gammel (uten denne seksjonen) — viser seksjonen bare advarselen «utilgjengelig», resten av siden fungerer som før.

20. Installere Auditd

Auditd (Linux Audit Daemon) logger systemkall på kjernenivå: innlogginger og utlogginger, sudo-kommandoer, mislykkede autentiseringsforsøk og filendringer. Monitor viser innlogginger, mislykkede forsøk og sudo-kommandoer i dag.

sudo apt install auditd audispd-plugins sudo systemctl enable --now auditd # Sjekk status og hendelser: sudo systemctl status auditd sudo ausearch -m USER_LOGIN -ts today
Monitor leser hendelser via ausearch (/usr/sbin/ausearch) og ved behov fra /var/log/audit/audit.log med kommandoen tail. Begge må ligge i sudoers.

21. Installere Monit

Overvåker tjenester (nginx, php-fpm, mysql osv.) og starter dem på nytt hvis de faller. Kan sende varsler på e-post.

sudo apt install monit sudo systemctl enable --now monit # Konfigurasjonsfiler: sudo nano /etc/monit/monitrc ls /etc/monit/conf.d/
Monitor henter tjenestelisten via monit status. I /etc/monit/monitrc må HTTP-grensesnittet være aktivert (blokken set httpd med allow localhost), ellers returnerer monit status en feil.
Viser dashbordet «0 tjenester overvåkes»? To årsaker. (1) HTTP-grensesnittet er avslått — i monitrc er linjen set httpd kommentert ut (som standard står den som # set httpd port 2812 …). Fjern kommentaren fra blokken og tillat localhost. (2) Et aktivert httpd overvåker ikke noe i seg selv — Monit teller bare det som beskrives i check-stanser; uten dem er listen tom selv når grensesnittet kjører. Minimal fungerende konfigurasjon:
# /etc/monit/conf.d/00-httpd — HTTP-grensesnitt for localhost: set httpd port 2812 use address localhost allow localhost # eksempler på check-stanser (hva som skal overvåkes): 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 # sjekk syntaks (Control file syntax OK) sudo systemctl reload monit sudo monit status
Autoinstallasjonen legger på plass en ferdig conf.d med httpd på 2812 og et sett med sjekker — på en ny installasjon trenger du ikke å sette opp noe manuelt.
Har en tjeneste status «Med feil»? Monitor viser bare tilstanden og starter bevisst ikke tjenester på nytt fra nettpanelet (det ville vært ekstern kjøring av root-kommandoer i et sikkerhetspanel). Diagnostikk og omstart gjøres via SSH med Monit:
sudo monit status <service> # årsak til feilen sudo monit restart <service> # omstart via Monit # hvis Monit ikke får tjenesten opp — se på dens egen enhet: sudo systemctl status <unit> --no-pager sudo journalctl -u <unit> -n 50 --no-pager

22. Installere PSAD (deteksjon av portskanning)

PSAD analyserer iptables-loggen og oppdager portskanning og nettverksangrep, og gir hver kilde et trusselnivå (1–5). Utfyller fail2ban og Suricata.

sudo apt install psad # PSAD leser iptables-loggen — logging må være aktivert (UFW gjør dette selv). # For rent iptables legger du til LOG-regler i INPUT/FORWARD-kjedene. sudo psad --sig-update sudo systemctl enable --now psad
Monitor leser data via psad --Status (må ligge i sudoers). Uten iptables-logging vil siden være tom — det er normalt så lenge ingen skanninger har forekommet.

23. AppArmor / SELinux (tilgangskontroll)

Mandatory Access Control begrenser hvilke filer og ressurser et program kan få tilgang til, selv om det er blitt hacket. I Ubuntu/Debian brukes AppArmor som standard (vanligvis allerede installert og aktivt).

# AppArmor (Ubuntu/Debian): sudo apt install apparmor apparmor-utils sudo systemctl enable --now apparmor sudo aa-status # sjekk profiler
Monitor leser statusen via aa-status (må ligge i sudoers). Viser antall profiler i modus enforce/complain og prosesser uten profil.

«Profiler lastet» er flere enn enforce + complain — det er normalt. I AppArmor 4.x (Ubuntu 24.04 og nyere) kom det en unconfined-modus: profilen er lastet inn i kjernen, men begrenser ingenting. Ubuntu merker slik titalls profiler for programmer som bruker user namespaces (nettlesere, torrent-klienter og lignende). Når slike profiler finnes, blir kortet «Profiler lastet» ravgult og viser antallet — for eksempel unconfined: 90 ved 120 lastede og 26 i enforce. Bare profiler i enforce gir reell beskyttelse; på Ubuntu 22.04 (AppArmor 3.x) finnes ikke denne modusen, og tallene stemmer alltid.

sudo aa-status | grep -E "profiles are" # fordeling etter modus sudo aa-enforce /etc/apparmor.d/profile-name # sett profilen i enforce
Å sette profiler som Ubuntu bevisst har latt stå i unconfined over i enforce bør bare gjøres med omtanke: de er ikke slått av ved en feil, men fordi programmene selv ellers slutter å fungere. Profiler i complain er en annen sak: der er reglene allerede skrevet og bare ikke håndhevet.

24. Installere debsums (pakkeintegritet)

debsums kontrollerer at filene til installerte pakker stemmer med kontrollsummene fra depotet — avslører utskiftede systembinærfiler (utfyller AIDE). En full kontroll tar 1–2 minutter, derfor kjøres den via cron, og panelet leser resultatet fra data/debsums/debsums.log og sorterer det selv i kategorier (bare binærfiler og biblioteker er viktige).

Oppføringen legges i root-cron (sudo crontab -e). Den ferdige innpakningen debsums-scan.sh legges i /usr/local/bin/ (chmod +x; se oversikten over cron-oppgaver) og skriver selv rapporten til panelets data/debsums/.

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

Innpakningen debsums-scan.sh finner selv panelets data/ — du trenger ikke oppgi banen.

Endringer i /etc/ (konfigurasjoner) og /usr/share/ (ressurser) på serveren er vanligvis normale — panelet merker dem med egen farge. Bekymringsfullt er endringer i binærfiler og biblioteker (/bin, /sbin, /usr/lib osv.) — kortet «Binærfiler / biblioteker» viser nettopp disse.

25. Konfigurere Lynis-rapporter

Lynis kjøres manuelt eller via cron. Rapporten må lagres i prosjektmappen data/lynis/ — monitoren leser filen lynis-report.dat.

# Enkeltkjøring (sett inn din egen sti til panelroten): sudo lynis audit system --report-file /path/to/monitor/data/lynis/lynis-report.dat # Daglig revisjon — cron-linje (ferdig wrapper lynis-scan.sh i /usr/local/bin/, se sammendraget): 0 3 * * * /usr/local/bin/lynis-scan.sh >> /path/to/monitor/logs/cron.log 2>&1
Etter første kjøring viser siden «Lynis-revisjon» straks hardening-indeks, advarsler og anbefalinger.
Knappen «Kjør revisjon» på Lynis-siden. Den kjører lynis-scan.sh i bakgrunnen direkte fra panelet (uten å vente på cron): viser «Skanner…» og oppdaterer rapporten selv når den er ferdig. For dette trenger web-brukeren en sudoers-linje for å kjøre skriptet — installasjonsprogrammet legger den til automatisk i /etc/sudoers.d/monitor. Hvis panelet ble installert manuelt/tidligere, legg den til med samme bruker som allerede står 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. Oppsett av Logwatch-rapporter

Logwatch skal lagre daglige rapporter i mappen data/logwatch/ i prosjektet i formatet .txt. Monitor viser den siste rapporten og arkivet.

# Daglig (6:00) — cron-linje (ferdig innpakning logwatch_daily.sh i /usr/local/bin/, se oversikten): 0 6 * * * /usr/local/bin/logwatch_daily.sh >> /path/to/monitor/logs/cron.log 2>&1

Panelmoduler

27. Nettverksmonitor (innebygd)

Nettverksmonitoren krever ingen installasjon — det er en innebygd side i panelet. Den viser serverens nettverkstilstand fra lokale kilder:

  • grensesnitt og trafikk — fra /proc/net/dev;
  • lenkestatus (UP/DOWN) og IP — via ip;
  • tilkoblinger og lyttende porter — via ss;
  • nettverkshendelser i kjernen siste 24 t — via journalctl -k.

De tre første kildene fungerer uten sudo, så grensesnitt, trafikk, tilkoblinger og porter vises umiddelbart. Blokken «Kjernehendelser» bruker journalctl -k — den leses via gruppen systemd-journal («Oppsett av sudo», pkt. 2), sudo trengs ikke. Kontroller at alt er tilgjengelig for webbrukeren:

# Sjekk som www-data (PHP kjører under denne): 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
Blokken «Nettverkshendelser i kjernen» viser hendelser i kjernens nettverksstakk (lenke opp/ned, bærebølgefeil, «network unreachable»). Brannmuroppføringer med UFW BLOCK havner ikke her — de finnes på sidene «UFW-brannmur» og «Angrepskart». Tom blokk med grønn hake = ingen nettverksfeil siste døgn.

28. Disk og SMART

Den innebygde siden viser tre ting:

  • Filsystemer — hvor fulle partisjonene er (df); skalaen blir rød ved ≥90 %;
  • Lagringsenheter — liste over disker (lsblk), kun reelle (loop/snap er skjult);
  • Helse (SMART) — diskstatus og attributter (smartctl).

Diskplass og enhetslisten fungerer med én gang, uten oppsett. For SMART trengs pakken smartmontools. Webprosessen har ikke direkte tilgang til diskenhetene, derfor hentes SMART via cron til filen data/disk/smart.txt, og panelet leser den.

Jobben ligger i root-cron (sudo crontab -e). Den ferdige innpakningen smart-scan.sh legges i /usr/local/bin/ (chmod +x; se oversikten over cron-jobber) og skriver selv til panelets data/disk/.

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

Innpakningen smart-scan.sh finner selv panelets data/ — banen trenger du ikke å angi. Inne i den ekskluderer lsblk -e7,11 loop/cdrom.

På virtuelle disker (QEMU/KVM og lignende) er vanligvis bare den generelle statusen «helse: OK» tilgjengelig, mens temperatur, driftstimer og omfordelte sektorer kan være tomme — det er normalt. På en fysisk server vises alle attributter.

29. Ytelse (CPU/RAM/Nettverk/Disk)

Siden viser historikken over serverbelastningen de siste 24 timene — Load Average, CPU-bruk og I/O-venting, RAM/Swap, nettverkstrafikk (mottak/sending), disk-I/O (lesing/skriving), diskfylling og inodes, åpne fildeskriptorer og MySQL-tilkoblinger, pluss gjeldende antall TCP-tilkoblinger og prosesser.

Dataene samles inn av cron/collect_metrics.php — hvert 5. minutt skrives ett «rått» øyeblikksbilde av tellerne (/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') til databasetabellen system_metrics; prosenter og hastigheter regner siden ut selv fra differansen mellom nabosnapshots (diskfylling/inodes/deskriptorer/MySQL-tilkoblinger er øyeblikksverdier, uten omregning). Sudo trengs ikke — kildene leses uten root-rettigheter. Punkter eldre enn 24 timer slettes automatisk ved hver skriving.

# Cron-linje (hvert 5. minutt): */5 * * * * /usr/local/bin/collect-metrics-all.sh >> /path/to/monitor/logs/cron.log 2>&1

Wrapperen collect-metrics-all.sh (se oversikten over cron-oppgaver) finner selv alle installerte panelinstanser på serveren og kjører hver enkelts cron/collect_metrics.php som eier av nettstedet.

Inntil samleren har kjørt minst to ganger (de første ~10 minuttene etter installasjon), viser siden «data samles inn» — grafene trenger minst ett par nabopunkter for å regne ut hastigheter og prosenter.

Belastningsvarsler (seksjonen «Innstillinger» → «Belastningsvarsler») — når terskelen for CPU/RAM/disk/inodes overskrides, sender panelet et varsel til Telegram/Email (de samme kanalene som den daglige rapporten — de trenger ikke slås på separat for varsler), og enda ett når metrikken har normalisert seg. Det spammer ikke på nytt mens terskelen holdes: neste varsel kommer først etter en syklus «normalisert → overskredet igjen».

Tersklene sjekkes av samme collect_metrics.php ved hver kjøring (hvert 5. minutt) — egen cron trengs ikke. Tilstanden «allerede varslet / ennå ikke» lagres i data/alerts_state.json, tersklene i panelinnstillingene.

30. Angrepskart (GeoIP)

Siden «Angrepskart» finner landet ut fra IP-adressen med kommandoen geoiplookup. Uten GeoIP-pakken blir ikke landene funnet, og punktene vises ikke på kartet:

sudo apt install geoip-bin geoip-database # Sjekk: geoiplookup 8.8.8.8
Sudo er ikke nødvendig — databasen /usr/share/GeoIP/GeoIP.dat kan leses av alle, og resultatene bufres i tmp/geoip_cache.json. Selve kartet (Leaflet + fliser fra OpenStreetMap) lastes i nettleseren — det kreves internett på maskinen der dashbordet er åpent.

31. Ekstern eksponering, oppdateringer og automatiske oppdateringer

To innebygde dashbordkort som viser ikke «på/av» for et verktøy, men serverens faktiske sikkerhet. Krever ingen installasjon, leses lokalt uten sudo.

Ekstern eksponering — hvor mange tjenester som lytter på alle grensesnitt (0.0.0.0/[::]) og er tilgjengelige utenfra. Markerer med rødt hvis en database eller cache er eksponert (MySQL, PostgreSQL, Redis, MongoDB, Memcached, Elasticsearch) — det er et direkte sikkerhetshull (−10 på sikkerhetsvurderingen). Kilde: ss -tuln.

Er kortet rødt — steng databasen for omverdenen: bind den til 127.0.0.1 (bind-address i MySQL/PostgreSQL-konfigurasjonen, bind 127.0.0.1 i Redis) eller steng porten i UFW.
«Åpen port» ≠ «tilgjengelig utenfra». En tjeneste som lytter på 127.0.0.1 (loopback) er kun synlig for serveren selv — den kan ikke nås utenfra, selv om porten er «åpen». Derfor er Postfix på port 25 bundet til loopback trygg: autokonfigurasjonen setter inet_interfaces = loopback-only (pluss et nøytralt smtpd_banner — som lukker Lynis-merknaden MAIL-8818 om versjonseksponering). Kortet «Ekstern eksponering» regner som eksponert kun det som lytter på 0.0.0.0/[::]; loopback-tjenester teller ikke med.
Lynis MAIL-8818 manuelt (hvis du satte opp e-post selv): sett smtpd_banner = $myhostname ESMTP (uten versjon og OS) og inet_interfaces = loopback-only i /etc/postfix/main.cf, og kjør deretter sudo systemctl restart postfix.

Sikkerhetsoppdateringer — hvor mange sikkerhetsoppdateringer som venter på installasjon og om en omstart trengs etter kjerneoppdatering (−5 på sikkerhetsvurderingen hvis det finnes oppdateringer). Kilde: /usr/lib/update-notifier/apt-check, filen /var/run/reboot-required. Detaljert liste — på siden «Sikkerhetsoppdateringer».

# Installer oppdateringer: sudo apt update && sudo apt upgrade # Sjekk hva som lytter utad: ss -tuln | grep -E '0\.0\.0\.0|\[::\]'
Oppdateringskortet fungerer på Ubuntu/Debian (update-notifier-common). Hvis apt-check mangler — teller Monitor oppdateringene via apt-get -s upgrade.

Automatiske sikkerhetsoppdateringer (unattended-upgrades) — på siden «Sikkerhetsoppdateringer» viser et eget kort om automatisk installasjon av sikkerhetsoppdateringer er aktivert og når den sist ble kjørt. Sudo trengs ikke — statusen leses via apt-config dump.

sudo apt install unattended-upgrades sudo dpkg-reconfigure -plow unattended-upgrades # aktiver # Sjekk hva som er aktivert: apt-config dump | grep Unattended-Upgrade

Vedlikehold

32. Sikkerhetskopiering

Sikkerhetskopi er den viktigste forsikringen: tap av data er verre enn ethvert innbrudd. Du trenger to ting — sikkerhetskopi av server/nettsteder og separat en sikkerhetskopi av panelets database (der ligger brukere, WebAuthn-nøkler, innstillinger og lisensen).

Alternativ A — HestiaCP: fanen Backup hos brukeren → knappen for å lage sikkerhetskopi (eller etter tidsplan i serverinnstillingene). Sikkerhetskopien inkluderer nettsteder og databasene deres.

Alternativ B — manuelt (cron): databasedump + arkiv av panelets katalog data/:

# root-cron (sudo crontab -e) — daglig sikkerhetskopi kl. 2:30 (sett inn dine egne navn/stier): 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 # Slett arkiver eldre enn 14 dager: 0 3 * * * find /var/backups -name 'monitor-*' -mtime +14 -delete
Sikkerhetskopi på samme server redder deg fra feil, men ikke fra tap av serveren. Kopier arkivene til ekstern lagring (en annen server, S3, rclone til skyen). Kontroller at gjenoppretting faktisk fungerer.

33. Oppdatering og flytting av panelet

Oppdatering til ny versjon. Ta først en sikkerhetskopi. Last deretter opp kodefilene på nytt, og behold dataene dine:

  • overskriv (kode): public/, includes/, assets/, cron/, database/, samt .htaccess i rota (frontkontrolleren — rutingen kan ikke beholdes fra den gamle versjonen), manifest.json, sw.js;
  • ikke rør: config.php (databasedata), data/ (rapporter), logs/, tmp/ (økter og buffer).
# Etter opplasting — tøm PHP-bufferen (hvis opcache er på): sudo systemctl reload php*-fpm
FileZilla melder SSH_FX_PERMISSION_DENIEDPermission denied. Panelets filer eies av www-data (slik ble de satt under installasjonen), mens SFTP-klienten kobler til som din egen bruker, som ikke har skriverettighet. Å gi www-data hele panelet «for at det skal virke» er nettopp det som fører til denne feilen; nedenfor er tre måter, alle løser problemet.
# Alternativ A (anbefalt) – skille eierne: koden er din, arbeidsmappene tilhører nettserveren. # Nettserveren får ingen som helst skriverettighet til panelets KODE: 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 oppå nåværende eiere (vi flytter 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. Enklere, men skriverettighet til panelets # filer får også nettserveren (ved en PHP-sårbarhet kan koden byttes 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
Hvorfor alternativ A er trygt. Panelet skriver bare til tre kataloger – data/ (rapporter), tmp/ (økter og buffer), logs/; de forblir hos www-data. Resten er kode, og nettserveren trenger den kun til lesing, som gruppen www-data gir med rettighetene 644. En sidegevinst: ved en PHP-sårbarhet kan ikke panelets filer lenger overskrives. På hosting-paneler (HestiaCP og lignende) trengs ikke alternativ A: der eies nettstedets filer uansett av kontoen du logger inn med via SFTP, og nettserveren leser dem via gruppen.
Fellen med alternativ B: enhver senere chmod på filene nullstiller ACL-masken, og tilgangen forsvinner stille. Hvis opplastingen etter en «opprydding i rettighetene» igjen stopper på Permission denied – kjør begge setfacl-kommandoene på nytt.
Bit 2 i alternativ C er setgid: filer som lastes opp via SFTP blir værende i gruppen www-data, ellers kan ikke panelet overskrive dem. Etter alternativ C – koble til på nytt i FileZilla: den nye gruppen trer i kraft først ved en ny innlogging. Kontroll: id deploy (gruppen www-data skal dukke opp) og ls -ld /path/to/monitor (drwxrwsr-x – bokstaven s betyr at setgid er satt).

Flytting til en annen server:

  1. Sett opp nettstedet + HTTPS på den nye serveren (se siden for manuell installasjon).
  2. Kopier alle panelfilene sammen med config.php, data/.
  3. Flytt databasen: mysqldump på den gamle → import på den nye; oppdater databasedataene i config.php.
  4. Gjenta på den nye serveren: sudoers, medlemskap i gruppa adm, cron-jobber.
  5. Lisensen er knyttet til domenet — hvis domenet er det samme, fortsetter nøkkelen å virke.

34. Gjenopprette tilgang (mistet nøkkel, passord, IP-blokk)

Hvis du ikke får logget inn, kan alt fikses direkte i databasen fra serveren. Åpne databasen (navnet finner du i config.php):

sudo mysql MY_DB

Mistet WebAuthn-nøkkel (den andre faktoren feiler) — slå av 2FA, logg inn med passord og registrer en ny nøkkel:

UPDATE users SET webauthn_enabled = 0;

Glemt passord — sett en ny hash (generer den på serveren og lim den inn):

# Generer hash for nytt passord: php -r "echo password_hash('NEW_PASSWORD', PASSWORD_BCRYPT), \"\n\";" # I databasen (lim inn hashen du fikk): # UPDATE users SET password = '$2y$10$...' WHERE username = 'admin';

Låst deg selv ute med IP-filteret — slå av begrensningen:

UPDATE settings SET value = '0' WHERE name = 'ip_restriction_enabled';
Du har alltid tilgang til databasen: sudo mysql på serveren, eller phpMyAdmin / databaseseksjonen i hostingpanelet. Etter gjenopprettingen må du slå på WebAuthn og IP-filteret igjen.

35. Alle cron-jobber på ett sted

Oversikten over jobber ligger i server-cron for root (legges til via sudo crontab -e). Behold bare linjene for verktøyene du bruker, og juster stiene til din egen server.

# Serverens cron for monitoren (root) — skriv inn via: sudo crontab -e # 01:30 — ClamAV-skann av utsatte stier (web, home, temp) → kortene «Filer sjekket» og «Siste skann» 30 1 * * * /usr/local/bin/clamav-scan.sh >> /path/to/monitor/logs/cron.log 2>&1 # 02:00 — filintegritetssjekk med AIDE (krever eksplisitt --config) 0 2 * * * /usr/bin/aide --config /etc/aide/aide.conf --check > /var/log/aide/aide.log 2>&1 # ved oppstart — gjenopprett rettigheter på /var/lib/aide (pakkens tmpfiles-fil # aide-common.conf setter dem til 0700, og panelet slutter å se databasen) @reboot chmod 755 /var/lib/aide # 03:00 — sikkerhetsrevisjon med Lynis 0 3 * * * /usr/local/bin/lynis-scan.sh >> /path/to/monitor/logs/cron.log 2>&1 # 04:00 — oppdatering av ipsum-blokkliste (level 1) 0 4 * * * /usr/local/bin/load-ipsum.sh >> /path/to/monitor/logs/cron.log 2>&1 # ipsum-settet lastes ved oppstart av tjenesten ipsum-load.service (FØR brannmuren, ellers # ser ikke UFW settet i before.rules) — ikke cron. Her bare den daglige oppfriskingen over. # 06:00 — Logwatch-rapport 0 6 * * * /usr/local/bin/logwatch_daily.sh >> /path/to/monitor/logs/cron.log 2>&1 # hvert 30. min — SMART-sjekk av disker */30 * * * * /usr/local/bin/smart-scan.sh >> /path/to/monitor/logs/cron.log 2>&1 # 04:30 — pakkeintegritet med debsums 30 4 * * * /usr/local/bin/debsums-scan.sh >> /path/to/monitor/logs/cron.log 2>&1 # 08:00 — planlagt rapport til Email og Telegram 0 8 * * * /usr/local/bin/daily-report-all.sh >> /path/to/monitor/logs/cron.log 2>&1 # hver time — oppdatering av pakkelister (for kortet «Sikkerhetsoppdateringer») 0 * * * * /usr/bin/apt-get update -qq >/dev/null 2>&1 # hvert 5. min — øyeblikksbilde av ressurser (CPU/RAM/nett/disk) for siden «Ytelse» */5 * * * * /usr/local/bin/collect-metrics-all.sh >> /path/to/monitor/logs/cron.log 2>&1
Detaljer om hvert enkelt finner du i de tilhørende seksjonene. Sikkerhetskopieringsjobbene (forrige seksjon) legges til i samme cron. Etter endringer, sjekk: sudo crontab -l og at cron-tjenesten er aktiv.
Cron-tider følger serverens tidssone, ikke TIMEZONE fra config.php. Konstanten TIMEZONE påvirker bare PHP (hvordan panelet viser datoer), men cron-demonen kjører jobbene etter operativsystemets systemtid. Hvis serverens sone ikke stemmer med din, kommer «08:00»-rapporten på feil tidspunkt. Eksempel: serveren står i en annen sone (Europe/London, UTC+1), og du er i Oslo (UTC+2) → «08:00»-rapporten kommer 09:00 for deg. Sjekk og juster ved behov systemets sone til din egen:
# Sjekk serverens gjeldende sone: timedatectl # Sett din egen sone (eksempel) og start cron på nytt: sudo timedatectl set-timezone Europe/Oslo sudo systemctl restart cron
Etter dette utløses linjen 0 8 * * * klokka 08:00 lokal tid. Ellers måtte du forskyve selve cron, men ved overgang til vinter-/sommertid ville forskyvningen igjen komme ut av takt — derfor er det riktigere å stille inn systemets sone.
Ferdige wrapper-skript. Arbeidskopiene og en eksempel-crontab (crontab.txt) ligger i mappen system/ ved siden av prosjektet, utenfor public_html. Dette er ikke en del av nettstedet — de skal ikke lastes opp til web-roten; plasser dem på serveren etter systemstiene (som i crontab over):
  • lynis-scan.sh/usr/local/bin/ (chmod +x) — kjører lynis audit system, setter flagget /tmp/lynis-running under skanningen og kopierer lynis-report.dat til panelets data/lynis/;
  • logwatch_daily.sh/usr/local/bin/ (chmod +x) — lager en daglig Logwatch-rapport (sshd, fail2ban, sudo, postfix) i data/logwatch/;
  • smart-scan.sh/usr/local/bin/ (chmod +x) — henter diskstatus (smartctl) til data/disk/;
  • debsums-scan.sh/usr/local/bin/ (chmod +x) — sjekker pakkeintegritet (debsums) i data/debsums/;
  • clamav-scan.sh/usr/local/bin/ (chmod +x) — ClamAV-antivirusskann av utsatte stier (web, home, temp); skriver en oversikt til /var/log/clamav/scan.log, der ClamAV-siden leser den fra (linjen 01:30 i crontab over);
  • load-ipsum.sh/usr/local/bin/ (chmod +x) — oppdaterer ipset-settet ipsum (level 1) på stedet, uten å bryte de aktive brannmurreglene (linjen 04:00 i crontab over);
  • daily-report-all.sh/usr/local/bin/ (chmod +x) — kjører panelets rapport cron/daily_report.php (linjen 08:00 i crontab over);
  • daily_report.php — inngår allerede i panelet (cron/daily_report.php), kjøres via daily-report-all.sh, trenger ikke settes opp separat;
  • collect-metrics-all.sh/usr/local/bin/ (chmod +x) — kjører panelets cron/collect_metrics.php (siden «Ytelse», linjen */5 i crontab over); collect_metrics.php inngår allerede i panelet, trenger ikke settes opp separat;
  • crontab.txt (system/cron/) — eksempel på jobber; skriv inn de linjene du trenger via sudo crontab -e.
Stien til skriptet i crontab må stemme med der du la det.
Slik legger du skriptet i /usr/local/bin/. Du kan ikke skrive dit direkte fra FileZilla — katalogen tilhører root, og SFTP-klienten får SSH_FX_PERMISSION_DENIED. Fremgangsmåten er slik: last først filen opp til /tmp (der kan alle skrive), og flytt den så på plass med én kommando:
# i FileZilla: skriv /tmp i feltet «Eksternt nettsted» og last skriptet opp dit, # deretter via SSH (install setter eier og rettigheter med en gang, chown/chmod trengs ikke): 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 er på plass, rettigheter rwxr-xr-x, syntaksen er intakt bash -n /usr/local/bin/lynis-scan.sh && ls -l /usr/local/bin/lynis-scan.sh
Ikke bland sammen katalogene: du trenger /tmp i serverens rot — ikke /var/tmp og ikke tmp/ inne i selve panelet (sistnevnte tilhører www-data og er stengt for din bruker). I FileZilla-treet er /tmp en gren på øverste nivå, ved siden av var, ikke inne i den.
Satte du opp serveren med automatisk konfigurering? Disse wrapperne og deres cron-jobber er allerede installert av skriptet (i /usr/local/bin/, logg — /var/log/arciveo-cron.log) — du trenger ikke gjøre noe manuelt.
Hvor skriptene leter etter panelet. Wrapperne er domenenøytrale: de finner panelinstallasjoner ved å gå gjennom /home/*/web/*/public_html og /var/www/*, og legger rapportene i deres data/. Hvis panelet ligger på en annen sti — legg den til i linjen for app in … inne i skriptene, ellers havner ikke rapportene fra Lynis/SMART/debsums/Logwatch i panelet.
cron.log og tilgangsrettigheter. Filen logs/cron.log opprettes først av root-cron — den vil tilhøre root, og fanen «Cron-logg» i panelet kan verken lese eller tømme den. Opprett filen på forhånd som web-brukeren (eier av nettstedskatalogen; på HestiaCP er dette kontoen, f.eks. admin) — da vil root-cron bare skrive til den uten å endre eier:
# opprett på forhånd som web-brukeren (før du legger til cron-linjer): sudo -u OWNER touch /path/to/monitor/logs/cron.log # hvis cron.log allerede er opprettet av root-cron — gi den til web-brukeren: sudo chown OWNER:OWNER /path/to/monitor/logs/cron.log sudo chmod 644 /path/to/monitor/logs/cron.log
Finn ut eieren av katalogen: stat -c %U /path/to/monitor.
Styring fra panelet. I seksjonen «System» finnes en side «Crontab» — der kan du se og legge til jobber uten SSH. Panelet redigerer bare jobber som er lagt til gjennom det selv (en egen blokk i root-crontab, merket med tjenestekommentarer); alt som allerede står i crontab (listen over) vises der read-only i listen «Andre serverjobber» med knappen «Kopier til redigeringsverktøy» — den flytter bare tidsplanen/kommandoen inn i skjemaet for å legge til, uten å røre den opprinnelige linjen. For å «flytte» en eksisterende jobb under panelets styring — kopier den til redigeringsverktøyet, lagre, og slett deretter den gamle linjen manuelt (sudo crontab -e), ellers kjøres den to ganger.
Engangsoppsett på serveren. Siden trenger et privilegert wrapper-skript — ikke en ren sudo crontab (det ville vært direkte eskalering til root for hvem som helst som får tilgang til paneløkta), men et smalt skript med to kommandoer (list/set), som bare rører sin egen blokk mellom tjenestekommentarene. Installer én gang:
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
Web-brukeren kan avvike fra www-data — sjekk hvilken bruker nettstedets PHP-FPM-pool kjører under (ps -o user= -C php-fpm), og sett den inn i sudoers-linjen.
Den nye filen ble lastet opp med feil eier — siden svarer «Access denied.». Hvis filen public/crontab_monitor.php er lastet opp via FTP/SFTP under en annen systembruker (for eksempel root) enn resten av nettstedets filer, kan webserveren ikke lese den. Sammenlign eier og rettigheter med en nabofil og bring dem i samsvar:
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

Diagnostikk

36. Verktøyet er installert, men viser «Ikke installert»

Monitor oppdager tilgjengelige verktøy via dpkg-query — pakkedatabasen til APT. Hvis verktøyet ikke er installert via apt (manuelt, fra snap eller fra kildekode), ser ikke dpkg det.

# Sjekk via dpkg: dpkg -l fail2ban | grep '^ii' dpkg -l auditd | grep '^ii' # Finn stien til binærfilen: which ufw fail2ban-client auditctl # Test sudo som www-data: sudo -u www-data sudo fail2ban-client status sudo -u www-data sudo ufw status verbose

37. Feilsøking (500, ingen data)

Feil 500 — sjekk loggene til PHP, nginx og selve monitoren:

tail -50 /var/log/nginx/error.log tail -50 /var/log/php*-fpm.log # Monitorlogger: tail -50 logs/monitor_$(date +%Y-%m-%d).log # Rettigheter på mapper: ls -la data/ tmp/ logs/
Dashboard på et hosting-kontrollpanel (HestiaCP, ISPmanager, cPanel)? Der kjører PHP ikke som www-data, men som brukerkontoen (for eksempel admin — eier av nettstedskatalogen). Alle sudo-regler og gruppemedlemskap (adm, systemd-journal) må settes opp for denne brukeren, ellers viser modulene «Ikke aktiv / 0» selv om tjenestene kjører. Finn den faktiske PHP-brukeren: ps -o user= -C php-fpm | sort -u eller eieren av nettstedskatalogen stat -c '%U' /path/to/monitor. Bruk deretter denne i stedet for www-data i alle kommandoene under. Autoinstallasjonen finner nettbrukeren selv og setter opp sudoers for den.

Data vises ikke — nesten alltid manglende sudo-rettigheter. Sjekk den aktuelle kommandoen som nettbruker (bytt ut www-data med din egen). Flagget -n = uten passord, slik som PHP — hvis den ber om passord, finnes ikke regelen 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 viser «Ikke aktiv» / «0» selv om verktøyet kjører (for eksempel sudo aa-status i terminalen viser profiler, mens siden «AppArmor» viser «Inaktiv»). Årsak: nettbrukeren mangler sudo-rettighet til kommandoen for denne modulen. Sjekk den fra listen over: hvis den ber om passord — legg til den manglende linjen i /etc/sudoers.d/monitor («Sudo-oppsett»). Vanlige «nye» kommandoer: /usr/sbin/aa-status (MAC), /usr/sbin/psad --Status (PSAD).
Hvis en bestemt side (Falco, ModSecurity, Auditd, åpne UFW-porter) er tom — sammenlign med listen i avsnittet om sudo: sannsynligvis er ikke apache2ctl, ausearch, aa-status eller ss tillatt, eller nettbrukeren er ikke i gruppene adm/systemd-journal (derfra leses loggene til fail2ban/auth/modsec og journalctl — Falco og kjernehendelser).

38. Siden er tom selv om det finnes data på serveren

Symptom: det finnes data på serveren (synlig via shell), men siden viser «ingen data» eller feil status — for eksempel skriver AIDE «Ikke initialisert» selv om databasen er opprettet.

Årsaken er open_basedir: mange paneler og hostinger begrenser PHP-FPM-poolen til domenets katalog, så PHP-funksjonene file_exists(), file_get_contents(), filemtime() blokkeres for systemstier (/var/lib/aide, /var/log, /proc…). Monitor omgår dette ved å lese slike stier med vanlige systemkommandoer (cat, test, stat).

# Er filen synlig via shell (slik leser Monitor den): sudo -u www-data bash -lc 'test -e /var/lib/aide/aide.db && echo VISIBLE || echo NO' # Nåværende verdi av open_basedir for domenets pool: grep -ri open_basedir /etc/php/*/fpm/pool.d/ 2>/dev/null
Hvis shell «ser» filen (VISIBLE), men siden ikke gjør det — er det open_basedir. Riktig løsning er lesing via systemkommandoer (allerede gjort for AIDE og Nettverksmonitor). Å utvide open_basedir til /var, /proc er unødvendig og mindre sikkert.

39. SSL-siden fungerer ikke

Monitor sjekker sertifikater ved å koble seg direkte til domenene via port 443. Hvis domenet ikke er tilgjengelig fra serveren selv, eller porten er blokkert av brannmuren, feiler kontrollen.

# Sjekk sertifikatet manuelt: echo | openssl s_client -connect monitor.example.com:443 2>/dev/null \ | openssl x509 -noout -dates # Sjekk tilgjengeligheten: curl -I https://monitor.example.com
Monitor henter domenene automatisk fra nginx-konfigurasjonene (/etc/nginx/sites-enabled/, /etc/nginx/conf.d/) og Apache (/etc/apache2/sites-enabled/), pluss den nåværende verten fra HTTP_HOST.
Automatisk gjenkjenning av underdomener. Underdomener gjenkjennes automatisk fra offentlige Certificate Transparency-logger og kontrolleres over nettverket — selv om de ligger på andre servere. Du trenger ikke å legge til noe manuelt.

40. Bare én av flere databaser er synlig

Monitor kobler til MySQL med brukeren fra config.php, som bare har tilgang til sin egen database. MySQL viser i information_schema kun databaser med rettigheter — derfor er de andre ikke synlige.

For at Monitor skal se alle databaser, gi denne brukeren lesetilgang (én gang som root; sett inn brukernavnet fra config.php):

sudo mysql -u root GRANT SELECT, PROCESS, SHOW DATABASES ON *.* TO 'DB_USER'@'localhost'; FLUSH PRIVILEGES; EXIT;
SELECT ON *.* gir kun lesetilgang — det er ikke mulig å endre, slette eller opprette noe, så det er trygt for overvåking.
Uten denne GRANT-en ser dashbordet bare sin egen database — det er ingen feil, men en rettighetsbegrensning. Dashbordet bruker ingen sudo mysql: databaselisten hentes via dets egen PDO-tilkobling.

41. PostgreSQL vises ikke på siden «Database»

PostgreSQL krever tilgang på nivå med brukeren postgres, som panelets nettbruker ikke har. Å åpne en bred sudo psql fra PHP er utrygt – i stedet kaller panelet en snever innpakning uten parametere, som kun skriver ut versjon, antall tilkoblinger og listen over databaser med størrelser. Opprett den:

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 (bruker = den som PHP-FPM kjører under): # www-data ALL=(ALL) NOPASSWD: /usr/local/bin/monitor-pgstat
Bruker du ikke PostgreSQL – fjern linjen monitor-pgstat fra sudoers (steg 13 i manuell installasjon) og la være å opprette selve skriptet: PostgreSQL-kortet forblir bare inaktivt.

42. Et varsel ble utløst – hva gjør du

Dashbordet viser hva som skjer; nedenfor står hva du skal gjøre i typiske situasjoner. Grunnprinsippet: ikke få panikk, sammenlign med legitim aktivitet (dine handlinger, oppdateringer, sikkerhetskopier), og reager etter alvorlighetsgrad.

  • Angrepskart / mange fail2ban-blokkeringer – dette er normalt for enhver server på nettet (boter prøver stadig SSH/web). Det viktige er at blokkeringene utløses. Sørg for at SSH-pålogging kun skjer med nøkkel (passord deaktivert), og at din IP står i ignoreip.
  • ModSecurity blokkerte forespørsler – WAF avverger angrep på nettstedet, det er jobben dens. Hvis din legitime trafikk blir blokkert (falsk positiv) – finn rule id i detaljene og legg til et unntak i CRS-konfigurasjonen.
  • AIDE: filer endret – sammenlign listen med det du har gjort (pakkeoppdatering, konfigredigering – normalt). Endringer i systembinærfiler du ikke har rørt, er grunn til å være på vakt. Etter legitime endringer bør du oppdatere AIDE-databasen.
  • debsums: binærfiler/biblioteker endret (utenfor /etc, utenfor /usr/share) – mulig utbytting. Sjekk pakken: debsums PACKAGE_NAME, og installer den på nytt ved tvil (apt install --reinstall).
  • ClamAV / maldet: trussel funnet – sjekk filen i karantene, ikke åpne den. Er det et webshell i nettstedets katalog – isoler serveren og let etter inngangspunktet (sårbar plugin, lekket tilgang).
  • Falco: kritiske hendelser (shell startet i en container, tilgang til sensitive filer) – analyser hendelsen: hvilken prosess, hva startet den. Ofte er dette legitim adminaktivitet.
  • Ekstern eksponering: database/cache i rødt – steng umiddelbart: bind tjenesten til 127.0.0.1 eller steng porten i UFW. Dette er et reelt sikkerhetshull.
  • SSL utløper / er utløpt – forny sertifikatet (Let's Encrypt fornyes selv; hvis ikke – sjekk certbot renew eller innstillingene i dashbordet).
  • Sikkerhetsoppdateringer venter – installer dem: sudo apt update && sudo apt upgrade; start serveren på nytt etter en kjerneoppdatering.
Tegn på et reelt innbrudd (ukjente prosesser/brukere, endrede binærfiler, utgående spam, ukjente cron-jobber): koble serveren fra ekstern tilgang, ta en sikkerhetskopi for analyse, og hvis dataene er kritiske, sett opp en ren server fra en pålitelig sikkerhetskopi – å fjerne et rootkit helt er vanskelig.
Arcivéo - Security Monitor © 2026