FAQ

Toto je průvodce instalací, konfigurací a údržbou nástroje Arcivéo Monitor. Sekce jsou rozděleny do skupin: obecný přehled, nasazení panelu, připojení bezpečnostních nástrojů, vestavěné moduly a diagnostika. Příkazy lze kopírovat tlačítkem vpravo.

Kde začít

01. Instalace panelu — vyberte způsob

Instalace panelu je popsána na samostatných stránkách krok za krokem. Vyberte způsob:

Pokud si nejste jistí, zvolte automatickou. Tento průvodce zůstává jediným zdrojem informací o SSL, nástrojích, cronu a diagnostice — instalační stránky odkazují na jeho sekce a nic neduplikují.

Přehled

02. Co je Arcivéo Monitor

Arcivéo Monitor — dashboard zabezpečení serveru. Sbírá data z nainstalovaných nástrojů (Fail2ban, UFW, Lynis, ModSecurity, AIDE, ClamAV, Auditd, CrowdSec, Suricata, Falco aj.) a zobrazuje je v jednotném rozhraní s dashboardem, mapou útoků a podrobnými stránkami ke každému nástroji.

Monitor není aktivní ochranný prostředek — sám o sobě útoky neblokuje. Jeho úkolem je agregovat informace z již běžících nástrojů a přehledně je zobrazit.

03. Jak monitor na serveru funguje

Monitor pracuje pouze lokálně — musí být nainstalován na stejném serveru, který sleduje. Žádné SSH ani vzdálené API neexistuje.

Všechny příkazy (fail2ban-client, ufw status, ipset list atd.) spouští panel pod uživatelem webového serveru (obvykle www-data, na hostingových panelech účet webu) s úzkou sadou práv sudo — jen pro konkrétní nástroje, bez obecného přístupu root. Výsledky se parsují a zobrazují v prohlížeči.

Pro více serverů nainstalujte monitor na každý zvlášť, s vlastní doménou.

04. Jak se počítá skóre zabezpečení

Skóre začíná na maximu a snižuje se za každý zjištěný problém:

  • UFW není aktivní — −30
  • Fail2ban neběží (žádný aktivní jail) — −25
  • Žádné klíče WebAuthn — −15
  • Lynis hardening index < 60 — −20; 60–79 — −10
  • IPset ipsum není načten — −10
  • Hrozby nalezené ClamAV — −20
  • Změny souborů AIDE — −15
  • SSL vypršel — −30, vyprší za <14 dní — −15, <30 dní — −5
  • CrowdSec je nainstalován, ale neběží — −5
  • Suricata je nainstalována, ale neběží — −5
  • Databáze/cache (MySQL, PostgreSQL, Redis…) jsou dostupné zvenčí — −10
  • Povolené přihlášení roota přes SSH (PermitRootLogin yes) — −20
  • Čekají bezpečnostní aktualizace — −5

Výsledek: 80+ = Zabezpečeno, 60–79 = Pozor, <60 = Ohroženo.

Srážky za ClamAV, AIDE, CrowdSec a Suricata se uplatňují jen tehdy, je-li nástroj nainstalován. Lynis a AIDE bez inicializované databáze se zobrazují jako „bez dat“ a skóre nesnižují. Počet útoků za dnešek se zobrazuje na dashboardu, ale skóre zabezpečení neovlivňuje.

Nastavení a licence

05. WebAuthn — dvoufaktorové ověření

WebAuthn — standard ověření bez hesla pomocí hardwarového klíče. Podporuje YubiKey, Touch ID, Face ID, Windows Hello, Passkey.

Po přihlášení heslem systém vyžádá potvrzení pomocí zaregistrovaného klíče. I když heslo unikne — bez fyzického klíče nebo biometrie se nelze přihlásit.

Nastavení otevřete v postranní nabídce v sekci Klíče WebAuthn a klikněte na „Zaregistrovat klíč“. Zaregistrujte si rovnou dva klíče: pokud se jediný klíč ztratí nebo poškodí, přihlášení do panelu jím nebude možné.

WebAuthn funguje pouze přes HTTPS. Na spojení HTTP není registrace ani přihlášení klíčem dostupné.

06. Oznámení: Telegram a Email

Panel umí posílat bezpečnostní hlášení do Telegramu a na e-mail (na tlačítko i podle plánu). Nastavuje se v sekci „Nastavení“.

Telegram. Potřebujete token bota a chat id:

  1. V Telegramu napište @BotFather/newbot → dostanete token ve tvaru 123456:ABC....
  2. Napište svému novému botovi libovolnou zprávu (aby vám mohl odpovídat).
  3. Zjistěte své chat id: napište botovi @userinfobot, nebo otevřete https://api.telegram.org/bot<TOKEN>/getUpdates a najděte "chat":{"id":...}.
  4. Vložte token a chat id do „Nastavení“ → Telegram a klikněte na „Uložit a odeslat test“.

Email. Na výběr jsou dva způsoby v „Nastavení“ → Email:

  • SMTP — hostitel, port (465/SSL nebo 587/TLS), přihlašovací jméno a heslo vaší poštovní schránky;
  • Resend — moderní API: zadejte API klíč (re_...) a ověřenou doménu odesílatele.
Tlačítko „Odeslat test“ hned prověří kanál. Plán automatického hlášení běží přes cron (sekce „Všechny cron úlohy“): ten vyvolá odeslání a kanály se berou z nastavení.

Stav hlášení: „POZOR“ nebo „OK“. Nadpis se změní na „POZOR“ jen při skutečném problému nebo čekající akci: nalezena hrozba ClamAV, změny souborů v AIDE, kritické události Falco (Emergency/Alert/Critical za posledních 24 h), spadlá služba v Monit, je nutný restart, vyprší SSL (≤14 dní) nebo čekají bezpečnostní aktualizace. Provozní šum — SSH pokusy o prolomení od botů, IP zabanované fail2ban, alerty Suricata, varování Lynis a už odražené požadavky ModSecurity — stav nezvyšuje, takže tato čísla v hlášení sama o sobě neznamenají „POZOR“.

07. Licence — zadání a aktivace

Podrobné moduly monitoringu (Lynis, UFW, ModSecurity, mapa útoků, AIDE, ClamAV aj.) se otevřou, pokud máte platnou licenci. Bez ní fungují dashboard, nastavení a účet, ale moduly zobrazují kartu „Vyžadována licence“.

Po nákupu v účtu máte aktivační kód ve tvaru ARCIVEO-XXXX-XXXX-XXXX-XXXX. Ten je potřeba „aktivovat“ na doménu vašeho panelu — tím se kód promění v podepsaný licenční soubor (blok [license]), který vložíte do panelu.

Jak aktivovat (3 kroky):

  1. Vezměte aktivační kód. Účet my.arciveo.com → sekce „Licence“ / „Aktivace licence“ — zkopírujte kód ARCIVEO-….
  2. Aktivujte kód na svou doménu. Tamtéž v účtu otevřete „Aktivace licence“, zadejte: aktivační kód, svůj e-mail a doménu panelu (adresa, na které se monitor otevírá, např. monitor.example.com). Klikněte na aktivovat — systém vygeneruje licenční soubor navázaný na tuto doménu a zobrazí jej v poli s tlačítkem „Kopírovat“.
  3. Vložte klíč do panelu. Zkopírujte celý text licence → v panelu otevřete „Nastavení“ → blok „Licence“, vložte a klikněte na „Uložit“. Moduly se okamžitě odemknou.

Panel klíč kryptograficky ověřuje: podpis, navázání na doménu a dobu platnosti.

Doména při aktivaci se musí přesně shodovat s adresou panelu. Vezměte ji z konstanty APP_URL v config.php a zadejte pouze název hostitele — bez https:// a bez prefixu www. Aktivace je jednorázová: kód se promění v licenci pro zadanou doménu a znovu se neaktivuje — při chybě v doméně klíč vašemu panelu nebude odpovídat a kód bude spotřebován. Doménu proto zadávejte pozorně.
Platnost vypršela nebo se změnila doména — v záhlaví panelu se objeví upozornění. Licence je navázaná na doménu natrvalo a na jinou doménu se nepřenáší: na nové období nebo novou doménu je potřeba nový klíč (kupuje se v účtu a aktivuje se jednorázově).

08. Soubor config.php — veškeré nastavení panelu

Všechny základní parametry panelu jsou uvedeny v jednom souboru config.php v kořenovém adresáři (vedle složky public/) jako běžné konstanty define(). Soubor se vytvoří při instalaci; upravovat ho ručně je potřeba jen zřídka — hlavně při změně domény, přenosu nebo připojení k jiné databázi. Po každé úpravě restartujte PHP-FPM (jinak se kvůli OPcache změny neuplatní).

Do zvýrazněných míst doplňte své hodnoty; zbytek nechte tak, jak je:

// --- Databáze --- define('DB_HOST', 'localhost'); // ponechat define('DB_NAME', 'db_name'); // co jste zadali při vytváření DB define('DB_USER', 'user'); // co jste zadali při vytváření DB define('DB_PASS', 'db_password'); // co jste zadali při vytváření DB define('DB_CHARSET', 'utf8mb4'); // ponechat // --- Aplikace --- define('APP_URL', 'https://monitor.example.com'); // adresa panelu, bez lomítka na konci define('TIMEZONE', 'Europe/Prague'); // vaše časové pásmo // --- Doba platnosti relace --- define('SESSION_LIFETIME', 28800); // nečinnost do opětovného přihlášení, s (28800 = 8 h)

Databáze. Údaje pro připojení k MySQL/MariaDB:

  • DB_HOST — hostitel databáze, téměř vždy localhost;
  • DB_NAME — název databáze panelu;
  • DB_USER — uživatel DB (přístup jen k vlastní databázi);
  • DB_PASS — heslo tohoto uživatele;
  • DB_CHARSET — kódování připojení, ponechte utf8mb4.

Aplikace.

  • APP_URL — úplná adresa panelu (např. https://monitor.example.com). Musí se shodovat s doménou, na kterou je licence aktivovaná — jinak bude klíč odmítnut (viz oddíl „Licence“);
  • TIMEZONE — časové pásmo PHP: ovlivňuje pouze to, jak panel zobrazuje datum a čas. Na dobu spuštění úloh cron nemá vliv — tam platí pásmo systému (viz „Všechny úlohy cron“).

Doba platnosti relace. SESSION_LIFETIME — časový limit nečinnosti relace v sekundách (plovoucí: obnovuje se při aktivitě). Výchozí hodnota 28800 = 8 hodin; po této době nečinnosti panel vyzve k opětovnému přihlášení. Například 3600 = 1 hodina, 86400 = den.

Protokolování chyb. Chyby se návštěvníkům nikdy nezobrazují, ale zapisují se do logs/php_errors.log — jsou vidět na stránce „Protokoly aplikace“. Tyto řádky (display_errors=0, log_errors=1, cesta error_log) obvykle není potřeba měnit — nastavení je zadáno přímo v souboru a nezávisí na php.ini.

config.php je tajný soubor. Obsahuje heslo k DB. Leží v kořenovém adresáři panelu (vedle public/) a webový kořen (DocumentRoot) tohoto panelu je právě kořen panelu, nikoli public/. Samotný soubor „neuniká“: v kořenovém .htaccess je pro něj nastaven výslovný zákaz (Require all denied) — server vrací 403. I bez tohoto pravidla by zdrojový kód neunikl: je to PHP — server ho vykonává, nevrací jako text. Pro jistotu: nezveřejňujte ho ve veřejných repozitářích a neposílejte ho podpoře se skutečným heslem. Oprávnění souboru — 640.
Při přenosu nebo obnovení přístupu je tento soubor hlavním zdrojem údajů: název DB, uživatel a heslo se berou právě odsud (viz oddíly „Aktualizace a přenos panelu“ a „Obnovení přístupu“).

Bezpečnostní nástroje

09. Firewall UFW

UFW (Uncomplicated Firewall) — jednoduché rozhraní k nftables/iptables. Uzavře všechny příchozí porty kromě výslovně povolených. Stránka „Firewall UFW“ zobrazuje stav a pravidla.

sudo apt install ufw # Povolit SSH (nutně PŘED zapnutím!) a web sudo ufw allow OpenSSH sudo ufw allow 80,443/tcp # Uzavřít DB zvenčí (přístup jen lokálně) sudo ufw deny 3306 # Zapnout a zkontrolovat sudo ufw enable sudo ufw status verbose
Před ufw enable nezapomeňte povolit SSH (ufw allow OpenSSH), jinak přijdete o přístup k serveru.
„Vnější expozice“ na dashboardu zohledňuje UFW: port uzavřený pravidlem deny se nepovažuje za dostupný zvenčí.
Skipping adding existing rule — to není chyba. UFW tím oznamuje, že přesně takové pravidlo už existuje, a znovu ho nepřidává. Při opakovaném spuštění automatického nastavení (je idempotentní) jde o běžné hlášení — není třeba na ně reagovat.

10. Instalace Fail2ban

Automaticky blokuje IP adresu po překročení počtu neúspěšných pokusů o přihlášení. Analyzuje logy SSH, nginx, Apache a dalších služeb.

sudo apt install fail2ban sudo systemctl enable --now fail2ban # Zkontrolovat stav: sudo fail2ban-client status
Funkční konfigurace (jail.local s desítkami jailů a automatickým banem z ipsum) — v následující sekci.

11. Funkční konfigurace Fail2ban + ipsum

Základní instalace je výše. Zde je funkční konfigurace, která dává desítky aktivních jailů a tisíce blokování: obecné nastavení, klíčové jaily a automatický ban škodlivých IP ze seznamu ipsum.

Soubor /etc/fail2ban/jail.local — obecné nastavení a nejdůležitější jaily:

[DEFAULT] bantime = 1w findtime = 900 maxretry = 3 backend = systemd banaction = nftables-multiport ignoreip = 127.0.0.1/8 ::1 <YOUR_IP> <TRUSTED_NETS> # Progresivní ban: každé opakování je delší bantime.increment = true bantime.factor = 2 bantime.maxtime = 5w bantime.rndtime = 300 [sshd] enabled = true maxretry = 5 bantime = -1 # trvalý ban za brute-force SSH findtime = 3600 # Recidivisté: kdo dostal několik banů — banuje se natrvalo [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 # Webové služby (apache-*, nginx-*, php-url-fopen, phpmyadmin-syslog): [nginx-http-auth] enabled = true port = http,https [apache-badbots] enabled = true port = http,https # … a ostatní jaily podle služeb (dovecot, exim, postfix-sasl, # mysqld-auth, vsftpd, portscan, pam-generic) — enabled = true
Do ignoreip nezapomeňte zapsat svou IP a důvěryhodné sítě, jinak si můžete zablokovat sám sebe. Po úpravách: sudo fail2ban-client reload.

Automatické načítání blok-listu ipsum — do root cronu (sudo crontab -e): level 1 (100+ tisíc IP) se načítá do sady ipsum, která se odřezává na firewallu (podrobněji v sekci „Blok-list IPset“):

# 04:00 — aktualizace ipset ipsum (level 1, maximální pokrytí): 0 4 * * * /usr/local/bin/load-ipsum.sh >> /path/to/monitor/logs/cron.log 2>&1
Sada se musí jmenovat ipsum — právě ji čte dashboard (karta „IPset ipsum“). Úrovně: levels/1.txt — maximální pokrytí, levels/3.txt — přesnější (3+ zdroje).

Proč je „Monitor bezpečnosti“ rozdělen do dvou zón. Ochrana funguje na dvou úrovních a dashboard je nemíchá:

  • Reálné útoky (reaktivní) — vše, co zachytil fail2ban: živé pokusy o průnik (jaily sshd, apache-*, nginx-* apod.) a zlomyslní recidivisté (jail recidive — ti, kdo už byli několikrát zabanováni). Jsou to IP, které se k vám skutečně dobývaly — jsou na mapě útoků a na „Časové ose“.
  • Preventivní blokace (proaktivní) — veřejný blok-list známých škodlivých IP ipset ipsum, odřezávaný na firewallu pravidlem DROP. Tyto adresy se vašeho serveru z větší části ani nedotkly — jsou odříznuty předem; počítadlo „IPset ipsum“ ukazuje, kolik jich bylo preventivně odříznuto.

Rozdíl je jednoduchý: reaktivní — „tito zaútočili a dostali ban“, preventivní — „tito byli zablokováni ještě před pokusem“. Dříve se do recidive uměle nahnal list-3 ipsum (odtud staré dělení „seznamoví recidivisté“); nyní jsou v recidive jen skuteční recidivisté a prevence je celá na firewallu.

12. Blokovací seznam IPset (ipsum)

ipsum — veřejný seznam škodlivých IP, aktualizovaný denně. Monitor zobrazuje počet načtených adres na dashboardu a mapě útoků a zohledňuje jej ve Skóre bezpečnosti (−10, pokud sada není načtena).

Minimální varianta bez fail2ban — samostatná sada ipsum s blokováním přes iptables:

# Vytvořit sadu (jednou): sudo ipset create ipsum hash:ip # Aktualizační skript /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, denně ve 4:00): 0 4 * * * /usr/local/bin/update-ipsum.sh
Rozšířená varianta s fail2ban-recidive — v sekci „Funkční konfigurace Fail2ban + ipsum“.
ipset žije v paměti a při restartu se ztrácí. Samotný denní cron nechá sadu prázdnou od okamžiku restartu až do dalšího spuštění (dashboard ukáže 0). Načítejte sadu i při startu — přesuňte načítání do skriptu a navažte jej na @reboot. Zároveň příkaz create … -exist nastaví limit maxelem 300000 (výchozích 65536 — level 1 se nevejde, objeví se „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 — denně ve 04:00 A při každém startu: 0 4 * * * /usr/local/bin/load-ipsum.sh @reboot sleep 60 && /usr/local/bin/load-ipsum.sh
Jak to funguje při automatické instalaci. Skript načte celý seznam level 1 (100+ tisíc IP) do sady ipsum a pokud firewall spravuje instalátor (čistý VPS — profily „Plná“/„Odlehčená“), připojí sadu k UFW pravidlem DROP — provoz z těchto IP se reálně blokuje. Pravidlo je za ESTABLISHED,RELATED, takže stávající spojení (včetně vašeho SSH) se nepřeruší — blokují se jen nová připojení ze seznamu. Sada se obnovuje při spuštění služby ipsum-load.service před firewallem (jinak by se UFW nezvedl) a aktualizuje se cronem ve 04:00. Na již nakonfigurovaném serveru (panel, vlastní firewall) instalátor do firewallu nezasahuje — tam ipsum zůstává seznamem pro dashboard a mapu útoků a pravidlo DROP se v případě potřeby přidá ručně (minimální varianta s iptables … --match-set ipsum … -j DROP — výše). Při automatické instalaci není třeba nic dělat ručně.

13. Instalace CrowdSec

Moderní náhrada Fail2ban s kolektivní threat intelligence: bany od komunity plus vlastní pravidla. Pro aplikaci banů na firewall vyžaduje samostatný bouncer.

curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash sudo apt install crowdsec sudo systemctl enable --now crowdsec # Bouncer pro iptables/nftables: sudo apt install crowdsec-firewall-bouncer-iptables # Kontrola stavu: sudo systemctl status crowdsec sudo cscli decisions list sudo cscli bouncers list
Stav „Neběží“ v panelu = služba je nainstalována, ale není aktivní (monitor ji ověřuje přes systemctl is-active crowdsec). Spuštění: sudo systemctl enable --now crowdsec; při pádu se podívejte na sudo journalctl -u crowdsec -n 30. Totéž platí pro jakoukoli službu ve stavu „Neběží“ (Suricata, Falco, Monit, MySQL).
„0 scénářů“ nebo „0 bouncers“ na dashboardu. CrowdSec je po instalaci téměř prázdný — bez kolekcí nic nedetekuje a bez registrovaného bounceru se bany na firewall neaplikují. Doinstalujte základní kolekce a ověřte, že je bouncer v seznamu:
# Základní kolekce (Linux + SSH + webový server): sudo cscli collections install crowdsecurity/linux crowdsecurity/sshd crowdsecurity/base-http-scenarios sudo systemctl reload crowdsec # Bouncer musí být v seznamu a se stavem aktivního připojení: sudo cscli bouncers list
V logu bounceru stream halted / bany se neaplikují. Jde o osiřelý api-klíč: bouncer byl odstraněn z cscli bouncers list, ale jeho starý klíč zůstal v /etc/crowdsec/bouncers/*.yaml. Zaregistrujte bouncer znovu a zapište čerstvý klíč:
sudo cscli bouncers add fw-bouncer # vypíše nový api_key # zapište tento klíč do api_key: v /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml sudo systemctl restart crowdsec-firewall-bouncer
Automatická instalace (profil „Kompletní ochrana“) sama nainstaluje kolekce a zaregistruje firewall-bouncer — ručně je to potřeba jen při ruční instalaci nebo po ručním zásahu do CrowdSec.

14. Instalace AIDE

AIDE (Advanced Intrusion Detection Environment) vytvoří snímek souborového systému a při každé kontrole hlásí změny v /etc, /bin, /usr. Po instalaci je nutná inicializace databáze (aideinit).

sudo apt install aide # Inicializace databáze (5–15 minut): sudo aideinit sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db # Ubuntu 24.04: adresář /var/lib/aide se vytvoří v režimu 700 (vlastník _aide), # a panel (www-data) databázi nevidí → zobrazuje „Neinicializována“. # Otevřete adresář pro průchod (soubory databáze zůstávají 600): sudo chmod 755 /var/lib/aide # První kontrola SE ZÁPISEM do logu, který čte monitor. # Na Ubuntu/Debian aide vyžaduje explicitní --config (jinak „missing configuration“; # binárka aide.wrapper se v nových verzích nedodává): sudo bash -c 'aide --config /etc/aide/aide.conf --check > /var/log/aide/aide.log 2>&1'
Během aideinit terminál 5–15 minut stojí na řádku Running aide --init... — to je normální (hashování celého FS, zátěž disku). Nepřerušujte Ctrl+C. Pokud proces „visí“, ale nic nevypisuje — možná čeká na odpověď na skrytý dotaz Overwrite existing aide.db.new [Yn]? (stiskněte Y). Aktivitu ověříte z jiné relace: pgrep -af aide.
Chyba aideinit: „21_aide_spamassassin … printf: invalid number“ (return code 20) — známý bug konfiguračního snippetu AIDE v Ubuntu 22.04. Databáze se nevytvoří. Vyřaďte poškozený snippet a zopakujte:
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
Stavy na dashboardu. „Neinicializována“ = panel nevidí soubor databáze: buď se aideinit nespustil, nebo (Ubuntu 24.04) je adresář /var/lib/aide vytvořen v režimu 700 a nedostupný pro www-data — vyřeší sudo chmod 755 /var/lib/aide (viz blok výše). „Bez kontrol“ = databáze existuje, ale kontrola ještě neproběhla — to není chyba. Výsledky čte monitor z /var/log/aide/aide.log.
Pravidelná kontrola → log pro panel. Standardní /etc/cron.daily/aide na nových Ubuntu/Debian nemusí zapisovat /var/log/aide/aide.log v požadované podobě (a aide.wrapper v nich už není). Spolehlivější je přidat vlastní cron s explicitním --config — ten zapisuje log pod rootem v režimu 644 a monitor jej čte bez dalších skupin:
# sudo crontab -e — každodenní kontrola ve 02:00: 0 2 * * * /usr/bin/aide --config /etc/aide/aide.conf --check > /var/log/aide/aide.log 2>&1 # Spustit hned, bez čekání na rozvrh: sudo bash -c 'aide --config /etc/aide/aide.conf --check > /var/log/aide/aide.log 2>&1'
Automatická instalace už tohle všechno dělá: chmod 755 /var/lib/aide a cron kontroly ve 02:00 — ručně není potřeba nic.
První inicializaci provádějte na čistém serveru — před instalací webových aplikací. Po legitimních změnách databázi znovu vytvořte: sudo aideinit && sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db.

15. Instalace ClamAV

Antivirový skener pro Linux. Zvlášť užitečný pro kontrolu /var/www na PHP shelly a škodlivý kód.

sudo apt install clamav clamav-daemon sudo systemctl enable --now clamav-daemon # Aktualizovat databázi signatur: sudo freshclam # Prohledat složku ručně: sudo clamscan -r /var/www --infected
Démon clamd ukazuje „Neaktivní“ po enable --now? Tři typické příčiny:

1. V konfiguraci zůstal řádek Example — clamd se odmítá spustit, dokud tam je:

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

2. Není stažena databáze signatur — clamd se bez ní nespustí:

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

3. Prostě se načítá — clamd nahrává ~8 mil. signatur do paměti 30–60 s. Počkejte a zkontrolujte: systemctl is-active clamav-daemon (stav activating → ještě nahrává).

Diagnostika: sudo journalctl -u clamav-daemon -n 30 --no-pager.
Na dashboardu „Zkontrolováno souborů: 0“ / „Poslední kontrola: —“? Démon clamd jen drží signatury v paměti, sám podle plánu nic neskenuje. Panel zobrazuje výsledky plánované kontroly, proto je potřeba cron, který skenuje a zapisuje log. Automatická instalace nasadí wrapper /usr/local/bin/clamav-scan.sh a cron v 01:30 — po prvním spuštění se doplní „Zkontrolováno souborů“ a „Poslední kontrola“. Spustit hned, bez čekání na plán: sudo /usr/local/bin/clamav-scan.sh.

16. Instalace Linux Malware Detect (maldet)

Linux Malware Detect (LMD) — skener škodlivého softwaru zaměřený na webové hrozby: PHP shelly, webové backdoory, downloadery. Využívá jádro ClamAV a doplňuje jej vlastními signaturami.

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 # Aktualizace signatur: sudo maldet -u # Skenovat /var/www: sudo maldet -a /var/www
LMD a ClamAV spolu fungují dobře v páru. Poslední report: maldet --report.
Při instalaci se může objevit řádek update-rc.d: error: unable to read /etc/init.d/maldet — je neškodný. maldet nepoužívá init.d, aktualizace signatur a skeny se spouští přes /etc/cron.daily/maldet. Pokud níže vidíte installation completed — vše se nainstalovalo.
Na stránce se u LMD píše „Nenainstalováno“, i když je nainstalován? maldet se neinstaluje přes apt, ale do /usr/local/maldetect, a při zapnutém open_basedir se jeho přítomnost ověřuje přes shell — viz sekce „Stránka je prázdná, i když data na serveru jsou“.

17. Instalace Suricata

Síťový systém detekce průniků: analyzuje provoz na úrovni paketů a zná tisíce signatur útoků. Doplňuje ModSecurity (ten pracuje na úrovni HTTP, Suricata na úrovni TCP/IP).

sudo add-apt-repository ppa:oisf/suricata-stable sudo apt update && sudo apt install suricata # Stažení aktuálních pravidel: sudo suricata-update sudo systemctl enable --now suricata
Suricata je „Aktivní“, ale panel nezobrazuje výstrahy / počet událostí je 0? Suricata zapisuje /var/log/suricata/eve.json pod uživatelem root v režimu 750 na adresář a webový server (www-data) jej nemůže přečíst. Otevřete adresář pro průchod — soubory uvnitř zůstávají chráněné:
sudo chmod o+rx /var/log/suricata
Automatická instalace to provede sama — ručně to není potřeba.

18. Instalace Falco

Zachytává systémová volání přes eBPF/kernel module a odhaluje anomálie v reálném čase: shell z nginx, čtení /etc/passwd webovým procesem, zápis do /bin atd.

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 čte události Falco přes journalctl -u falco (bez sudo — přes skupinu systemd-journal). Ujistěte se, že www-data je v této skupině — viz „Nastavení sudo“ (bod 2) na stránce ruční instalace.
„0 událostí za 24 hodin“ je normální stav, ne chyba. Falco je event-driven: mlčí, dokud je vše v pořádku, a událost zapíše jen při anomálii (shell z webového procesu, čtení /etc/passwd, zápis do systémových adresářů). Nula kritických událostí za den na klidném serveru je zdravý stav.
Pro panel je spolehlivější výstup do souboru. Čtení přes journalctl vyžaduje oprávnění k žurnálu; aby panel viděl události stabilně, automatická instalace zapíná u Falco file_output/var/log/falco/falco.log a službě nastavuje UMask=0022 (log čte webový server). Při nové instalaci to není třeba nastavovat ručně.

19. Instalace ModSecurity (WAF)

ModSecurity — webový firewall (WAF) pro Apache nebo Nginx. Blokuje útoky na úrovni aplikace: SQL injection, XSS, průchod adresáři, skenery.

# Apache: sudo apt install libapache2-mod-security2 sudo a2enmod security2 # Sada pravidel OWASP Core Rule Set: sudo apt install modsecurity-crs # POVINNÉ: bez tohoto souboru je engine pravidel vypnutý 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 # Kontrola: musí vrátit 403 curl -s -o /dev/null -w '%{http_code}\n' "https://monitor.example.com/?id=1%20UNION%20SELECT%201,2--"
Samotná instalace balíčku nic nechrání. Apache načítá konfigurace řádkem IncludeOptional /etc/modsecurity/*.conf, ale balíček dodává jen modsecurity.conf-recommended — pod masku *.conf nespadá. Pokud ho nezkopírujete do modsecurity.conf, zůstává SecRuleEngine na Off: modul je načtený, pravidla CRS jsou načtená, ale provoz se nekontroluje a audit log se nevytváří. Přechodný režim DetectionOnly pouze zapisuje události do logu, aniž by požadavky blokoval — panel ho zobrazuje žlutě.

Přístup panelu k audit logu. Log /var/log/apache2/modsec_audit.log patří rootovi (práva 640), webový uživatel jej nepřečte. Panel získává data přes obalovací skript — vytvořte jej:

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 # v /etc/sudoers.d/monitor (uživatel = ten, pod kterým běží PHP-FPM): # www-data ALL=(ALL) NOPASSWD: /usr/local/bin/monitor-modsec
Obalovací skript bere poslední direktivu SecRuleEngine bez odsazení: odsazené řádky jsou uvnitř bloků <LocationMatch>/<Directory> (například vypnutí WAF pro phpMyAdmin) a globální režim neurčují.
Uživatel v sudoers se musí shodovat s uživatelem FPM poolu: na běžném Apache/Debianu je to www-data, v HestiaCP běží pool webu pod vlastníkem webu (například admin) — zkontrolujte grep -E '^user' /etc/php/*/fpm/pool.d/monitor.example.com.conf.
Pokud web stojí za Nginx proxy (HestiaCP), Apache vidí jako klienta samotnou proxy — panel bere reálnou IP adresu útočníka z hlavičky X-Forwarded-For. Do statistik se dostanou jen transakce s uplatněným pravidlem: direktiva SecAuditLogRelevantStatus zapisuje do audit logu jakékoli odpovědi 4xx/5xx, takže se tam dostanou i běžné 403/500 — panel je za události WAF nepovažuje.
Blok ---RULES--- potřebuje sekce „Všechna aktivní pravidla“ — panel zobrazuje nejen uplatněná, ale vůbec všechna načtená pravidla CRS + vlastní. Tři cesty v cyklu for f in … jsou typická místa pro pravidla CRS a lokální doplňky; pokud máte jiné rozložení (balíček ukládá soubory do svého adresáře, nebo vlastní pravidla neleží v /etc/modsecurity/custom-rules.conf), najděte reálné cesty příkazem sudo grep -rl 'IncludeOptional\|^Include ' /etc/apache2/mods-enabled/security2.conf /etc/apache2/conf-enabled/*.conf 2>/dev/null a doplňte je do seznamu. Pokud je obalovací skript starý (bez této sekce) — sekce jen zobrazí varování „nedostupné“, zbytek stránky funguje jako dříve.

20. Instalace Auditd

Auditd (Linux Audit Daemon) zaznamenává systémová volání na úrovni jádra: přihlášení a odhlášení, sudo příkazy, neúspěšné pokusy o autentizaci, změny souborů. Monitor zobrazuje dnešní přihlášení, neúspěšné pokusy a sudo příkazy.

sudo apt install auditd audispd-plugins sudo systemctl enable --now auditd # Ověření stavu a událostí: sudo systemctl status auditd sudo ausearch -m USER_LOGIN -ts today
Monitor čte události přes ausearch (/usr/sbin/ausearch) a v případě potřeby ze souboru /var/log/audit/audit.log příkazem tail. Oba musí být v sudoers.

21. Instalace Monit

Sleduje služby (nginx, php-fpm, mysql atd.) a při jejich pádu je restartuje. Umí posílat upozornění na e-mail.

sudo apt install monit sudo systemctl enable --now monit # Konfigurace: sudo nano /etc/monit/monitrc ls /etc/monit/conf.d/
Monitor získává seznam služeb přes monit status. V souboru /etc/monit/monitrc musí být zapnuté HTTP rozhraní (blok set httpd s allow localhost), jinak monit status vrátí chybu.
Na dashboardu „0 sledovaných služeb“? Dvě příčiny. (1) HTTP rozhraní je vypnuté — v souboru monitrc je řádek set httpd zakomentovaný (výchozí podoba je # set httpd port 2812 …). Odkomentujte blok a povolte localhost. (2) Samotné zapnuté httpd nic nesleduje — Monit počítá jen to, co je popsáno v check stanzách; bez nich je seznam prázdný i při funkčním rozhraní. Minimální funkční konfigurace:
# /etc/monit/conf.d/00-httpd — HTTP rozhraní pro localhost: set httpd port 2812 use address localhost allow localhost # příklady check stanz (co sledovat): 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 # ověřit syntaxi (Control file syntax OK) sudo systemctl reload monit sudo monit status
Automatická instalace vloží hotový conf.d s httpd na portu 2812 a sadou kontrol — na nové instalaci není potřeba nic nastavovat ručně.
Služba je ve stavu „S chybami“? Monitor pouze zobrazuje stav a záměrně nerestartuje služby z webového panelu (bylo by to vzdálené spouštění root příkazů v bezpečnostním panelu). Diagnostika a restart — přes SSH pomocí Monit:
sudo monit status <service> # příčina chyby sudo monit restart <service> # restart přes Monit # pokud Monit službu nespustí — podívejte se na její vlastní unit: sudo systemctl status <unit> --no-pager sudo journalctl -u <unit> -n 50 --no-pager

22. Instalace PSAD (detekce skenování portů)

PSAD analyzuje protokol iptables a odhaluje skenování portů a síťové útoky, přičemž každému zdroji přiřadí úroveň hrozby (1–5). Doplňuje fail2ban a Suricata.

sudo apt install psad # PSAD čte log iptables — je potřeba zapnout logování (UFW to dělá samo). # Pro čisté iptables přidejte pravidla LOG do řetězců INPUT/FORWARD. sudo psad --sig-update sudo systemctl enable --now psad
Monitor čte data přes psad --Status (musí být v sudoers). Bez logování iptables bude stránka prázdná — to je normální, dokud neproběhlo žádné skenování.

23. AppArmor / SELinux (řízení přístupu)

Mandatory Access Control omezuje, k jakým souborům a prostředkům může program přistupovat, i když byl napaden. V Ubuntu/Debian se ve výchozím nastavení používá AppArmor (obvykle je již nainstalován a aktivní).

# AppArmor (Ubuntu/Debian): sudo apt install apparmor apparmor-utils sudo systemctl enable --now apparmor sudo aa-status # zkontrolovat profily
Monitor čte stav přes aa-status (musí být v sudoers). Zobrazuje počet profilů v režimu enforce/complain a procesy bez profilu.

„Načtených profilů“ je více než enforce + complain — to je v pořádku. V AppArmor 4.x (Ubuntu 24.04 a novější) přibyl režim unconfined: profil je načten v jádře, ale nic neomezuje. Ubuntu takto označuje desítky profilů pro programy využívající user namespaces (prohlížeče, torrentové klienty a podobně). Když takové profily existují, karta „Načtených profilů“ zežloutne a zobrazí jejich počet — například unconfined: 90 při 120 načtených a 26 v enforce. Reálně chrání jen profily v enforce; na Ubuntu 22.04 (AppArmor 3.x) tento režim není a čísla vždy sedí.

sudo aa-status | grep -E "profiles are" # rozdělení podle režimů sudo aa-enforce /etc/apparmor.d/profile-name # převést profil do enforce
Převádět do enforce profily, které Ubuntu záměrně ponechalo v unconfined, se vyplatí jen s rozmyslem: nejsou vypnuté omylem, ale proto, že jinak se naruší fungování samotných programů. Profily v complain jsou jiná věc: tam jsou pravidla už napsaná a jen se neuplatňují.

24. Instalace debsums (integrita balíčků)

debsums ověřuje, že soubory nainstalovaných balíčků odpovídají kontrolním součtům z repozitáře — odhalí podvržené systémové binárky (doplňuje AIDE). Úplná kontrola trvá 1–2 minuty, proto se spouští přes cron a panel čte výsledek z data/debsums/debsums.log a sám jej rozdělí do kategorií (podstatné jsou jen binárky a knihovny).

Úloha patří do root-cronu (sudo crontab -e). Hotový obal debsums-scan.sh se umístí do /usr/local/bin/ (chmod +x; viz přehled cron-úloh) a sám zapíše zprávu do data/debsums/ panelu.

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

Obal debsums-scan.sh si sám najde data/ panelu — cestu není třeba zadávat.

Změny v /etc/ (konfigurace) a /usr/share/ (zdroje) na serveru bývají obvykle v pořádku — panel je označí zvláštní barvou. Znepokojivé jsou změny binárek a knihoven (/bin, /sbin, /usr/lib apod.) — karta „Binárky / knihovny“ ukazuje právě je.

25. Nastavení reportů Lynis

Lynis se spouští ručně nebo přes cron. Report se musí ukládat do složky data/lynis/ projektu — monitor čte soubor lynis-report.dat.

# Jednorázové spuštění (doplňte vlastní cestu ke kořeni panelu): sudo lynis audit system --report-file /path/to/monitor/data/lynis/lynis-report.dat # Denní audit — cron řádek (hotový wrapper lynis-scan.sh v /usr/local/bin/, viz přehled): 0 3 * * * /usr/local/bin/lynis-scan.sh >> /path/to/monitor/logs/cron.log 2>&1
Po prvním spuštění stránka „Audit Lynis“ ihned zobrazí hardening index, varování a doporučení.
Tlačítko „Spustit audit“ na stránce Lynis. Spustí lynis-scan.sh na pozadí přímo z panelu (bez čekání na cron): zobrazí „Skenování…“ a po dokončení samo aktualizuje report. K tomu potřebuje webový uživatel řádek v sudoers pro spuštění skriptu — instalátor jej přidá automaticky do /etc/sudoers.d/monitor. Pokud jste panel instalovali ručně/dříve, dopište jej týmž uživatelem, který už je v souboru uveden:
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. Nastavení reportů Logwatch

Logwatch musí ukládat denní reporty do složky data/logwatch/ projektu ve formátu .txt. Monitor zobrazuje poslední report a archiv.

# Denně (6:00) — cron-řádek (hotový wrapper logwatch_daily.sh v /usr/local/bin/, viz souhrn): 0 6 * * * /usr/local/bin/logwatch_daily.sh >> /path/to/monitor/logs/cron.log 2>&1

Moduly panelu

27. Síťový monitor (vestavěný)

Síťový monitor nevyžaduje instalaci — je to vestavěná stránka panelu. Zobrazuje síťový stav serveru z lokálních zdrojů:

  • rozhraní a provoz — z /proc/net/dev;
  • stav linek (UP/DOWN) a IP — přes ip;
  • spojení a naslouchající porty — přes ss;
  • síťové události jádra za 24 h — přes journalctl -k.

První tři zdroje fungují bez sudo, takže rozhraní, provoz, spojení a porty jsou vidět ihned. Blok „Události jádra“ používá journalctl -k — čte se přes skupinu systemd-journal („Nastavení sudo“, bod 2), sudo není potřeba. Ověření, že vše je dostupné webovému uživateli:

# Kontrola pod uživatelem www-data (pod ním běží PHP): 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
Blok „Síťové události jádra“ zobrazuje události síťového zásobníku jádra (změna linky up/down, chyby nosné, „network unreachable“). Záznamy firewallu UFW BLOCK sem nepatří — jsou na stránkách „Brána firewall UFW“ a „Mapa útoků“. Prázdný blok se zeleným zaškrtnutím = za posledních 24 h nedošlo k žádnému síťovému výpadku.

28. Disk a SMART

Vestavěná stránka zobrazuje tři věci:

  • Souborové systémy — zaplnění oddílů (df); ukazatel zčervená při ≥90 %;
  • Úložiště — seznam disků (lsblk), pouze reálné (loop/snap jsou skryté);
  • Stav (SMART) — stav disku a atributy (smartctl).

Místo a seznam zařízení fungují ihned, bez nastavení. Pro SMART je potřeba balíček smartmontools. Webový proces nemá přímý přístup k diskovým zařízením, proto se SMART snímá přes cron do souboru data/disk/smart.txt a dashboard jej čte.

Úloha patří do root-cronu (sudo crontab -e). Hotový wrapper smart-scan.sh se umístí do /usr/local/bin/ (chmod +x; viz přehled cron-úloh) a sám zapisuje do data/disk/ dashboardu.

sudo apt install smartmontools # Cron-řádek (každých 30 minut): */30 * * * * /usr/local/bin/smart-scan.sh >> /path/to/monitor/logs/cron.log 2>&1

Wrapper smart-scan.sh si sám najde data/ dashboardu — cestu není nutné zadávat. Uvnitř lsblk -e7,11 vylučuje loop/cdrom.

Na virtuálních discích (QEMU/KVM a podobných) je obvykle dostupný jen obecný stav „stav: OK“, zatímco teplota, hodiny provozu a přemapované sektory mohou být prázdné — to je normální. Na fyzickém serveru se zobrazují všechny atributy.

29. Výkon (CPU/RAM/Síť/Disk)

Stránka zobrazuje historii zatížení serveru za posledních 24 hodin — Load Average, vytížení CPU a čekání na I/O, RAM/Swap, síťový provoz (příjem/odesílání), diskové I/O (čtení/zápis), zaplnění disku a inodů, otevřené souborové deskriptory a MySQL připojení, plus aktuální počet TCP připojení a procesů.

Data sbírá cron/collect_metrics.php — jednou za 5 minut zapíše jeden „surový“ snímek čítačů (/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') do tabulky DB system_metrics; procenta a rychlosti si stránka počítá sama z rozdílu mezi sousedními snímky (zaplnění disku/inodů/deskriptorů/MySQL připojení jsou okamžité hodnoty, bez přepočtu). Sudo není potřeba — zdroje se čtou bez práv roota. Body starší 24 hodin se automaticky mažou při každém zápisu.

# Cron řádek (každých 5 minut): */5 * * * * /usr/local/bin/collect-metrics-all.sh >> /path/to/monitor/logs/cron.log 2>&1

Obal collect-metrics-all.sh (viz přehled cron úloh) sám najde všechny nainstalované instance panelu na serveru a spustí cron/collect_metrics.php každé z nich jménem vlastníka webu.

Dokud kolektor neproběhl alespoň dvakrát (prvních ~10 minut po instalaci), stránka zobrazuje „data se sbírají“ — grafy potřebují alespoň jednu dvojici sousedních bodů, aby mohly spočítat rychlosti a procenta.

Upozornění na zatížení (sekce „Nastavení“ → „Upozornění na zatížení“) — při překročení prahu CPU/RAM/disku/inodů panel pošle upozornění do Telegramu/Emailu (stejné kanály jako denní report — pro alerty je není třeba zapínat zvlášť) a další — když se metrika vrátí do normálu. Během udržení prahu opakovaně nespamuje: další upozornění přijde až po cyklu „obnoveno → znovu překročeno“.

Prahy kontroluje tentýž collect_metrics.php při každém spuštění (jednou za 5 minut) — samostatný cron není potřeba. Stav „již upozorněno / ještě ne“ se ukládá do data/alerts_state.json, prahy — v nastavení panelu.

30. Mapa útoků (GeoIP)

Stránka „Mapa útoků“ určuje zemi podle IP příkazem geoiplookup. Bez balíčku GeoIP se země neurčí a body se na mapě neobjeví:

sudo apt install geoip-bin geoip-database # Kontrola: geoiplookup 8.8.8.8
Sudo není potřeba — databázi /usr/share/GeoIP/GeoIP.dat čtou všichni, výsledky se ukládají do mezipaměti v tmp/geoip_cache.json. Samotná mapa (Leaflet + dlaždice OpenStreetMap) se načítá v prohlížeči — na počítači, kde je otevřený dashboard, je potřeba internet.

31. Vnější expozice, aktualizace a automatické aktualizace

Dvě vestavěné karty dashboardu, které nezobrazují „zap/vyp“ nástroje, ale skutečné zabezpečení serveru. Nevyžadují instalaci, čtou se lokálně bez sudo.

Vnější expozice — kolik služeb naslouchá na všech rozhraních (0.0.0.0/[::]) a je dostupných zvenčí. Zvýrazní červeně, pokud jsou navenek vystaveny databáze nebo cache (MySQL, PostgreSQL, Redis, MongoDB, Memcached, Elasticsearch) — to je přímá díra (−10 ke Skóre zabezpečení). Zdroj: ss -tuln.

Pokud je karta červená — uzavřete databázi před vnějším světem: navažte ji na 127.0.0.1 (bind-address v konfiguraci MySQL/PostgreSQL, bind 127.0.0.1 v Redis) nebo zavřete port v UFW.
„Otevřený port“ ≠ „dostupný zvenčí“. Služba naslouchající na 127.0.0.1 (loopback) je viditelná jen samotnému serveru — zvenčí se k ní nedostanete, i když je port „otevřený“. Proto je Postfix na portu 25 navázaný na loopback bezpečný: automatické nastavení nastaví inet_interfaces = loopback-only (plus neutrální smtpd_banner — uzavírá poznámku Lynis MAIL-8818 o odhalení verze). Karta „Vnější expozice“ počítá jako vnější jen to, co naslouchá na 0.0.0.0/[::]; loopback služby se do ní nezahrnují.
Lynis MAIL-8818 ručně (pokud jste poštu nastavovali sami): v /etc/postfix/main.cf nastavte smtpd_banner = $myhostname ESMTP (bez verze a OS) a inet_interfaces = loopback-only, poté sudo systemctl restart postfix.

Bezpečnostní aktualizace — kolik bezpečnostních záplat čeká na instalaci a zda je po aktualizaci jádra potřeba restart (−5 ke Skóre zabezpečení, pokud jsou k dispozici záplaty). Zdroj: /usr/lib/update-notifier/apt-check, soubor /var/run/reboot-required. Podrobný seznam — na stránce „Bezpečnostní aktualizace“.

# Nainstalovat aktualizace: sudo apt update && sudo apt upgrade # Zkontrolovat, co naslouchá navenek: ss -tuln | grep -E '0\.0\.0\.0|\[::\]'
Karta aktualizací funguje na Ubuntu/Debian (update-notifier-common). Pokud apt-check chybí — monitor počítá záplaty přes apt-get -s upgrade.

Automatické bezpečnostní aktualizace (unattended-upgrades) — na stránce „Bezpečnostní aktualizace“ samostatná karta ukazuje, zda je zapnutá automatická instalace bezpečnostních záplat a kdy proběhla naposledy. Sudo není potřeba — stav se čte přes apt-config dump.

sudo apt install unattended-upgrades sudo dpkg-reconfigure -plow unattended-upgrades # zapnout # Zkontrolovat, co je zapnuté: apt-config dump | grep Unattended-Upgrade

Údržba

32. Zálohování

Záloha je hlavní pojistka: ztráta dat je horší než jakýkoli průnik. Potřebujete dvě věci — zálohu serveru/webů a zvlášť zálohu databáze panelu (jsou v ní uživatelé, klíče WebAuthn, nastavení, licence).

Varianta A — HestiaCP: záložka Backup u uživatele → tlačítko vytvoření zálohy (nebo dle plánu v nastavení serveru). Záloha zahrnuje weby a jejich databáze.

Varianta B — ručně (cron): dump databáze + archiv adresáře data/ panelu:

# root-cron (sudo crontab -e) — denní záloha ve 2:30 (doplňte vlastní názvy/cesty): 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 # Mazat archivy starší než 14 dní: 0 3 * * * find /var/backups -name 'monitor-*' -mtime +14 -delete
Záloha na tomtéž serveru vás ochrání před chybami, ale ne před ztrátou serveru. Kopírujte archivy na externí úložiště (jiný server, S3, rclone do cloudu). Ověřujte, že obnovení skutečně funguje.

33. Aktualizace a přenos panelu

Aktualizace na novou verzi. Nejprve si vytvořte zálohu. Poté znovu nahrajte soubory kódu a zachovejte svá data:

  • přepsat (kód): public/, includes/, assets/, cron/, database/ a také kořenové .htaccess (front-controller — směrování nelze ponechat ze staré verze), manifest.json, sw.js;
  • nesahat na: config.php (údaje k DB), data/ (reporty), logs/, tmp/ (relace a cache).
# Po nahrání — vyprázdnit cache PHP (pokud je zapnutý opcache): sudo systemctl reload php*-fpm
FileZilla hlásí SSH_FX_PERMISSION_DENIEDPermission denied. Soubory panelu patří uživateli www-data (tak byly nastaveny při instalaci), zatímco SFTP klient se připojuje pod vaším vlastním uživatelem, který nemá právo zápisu. Dát www-data celý panel „aby to fungovalo“ — právě to vede k této chybě; níže jsou tři způsoby, kterýkoli problém vyřeší.
# Varianta A (doporučeno) — rozdělit vlastníky: kód váš, pracovní složky webového serveru. # Webový server nezíská právo zápisu ke KÓDU panelu vůbec: 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 # Varianta B — ACL nad stávajícími vlastníky (nic nepřenášíme): 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 # Varianta C — přes skupinu www-data. Jednodušší, ale právo zápisu k souborům # panelu získá i webový server (při zranitelnosti v PHP lze kód vyměnit): 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
Proč je varianta A bezpečná. Panel zapisuje jen do tří adresářů — data/ (reporty), tmp/ (relace a cache), logs/; ty zůstávají uživateli www-data. Zbytek je kód a webový server jej potřebuje jen ke čtení, které umožňuje skupina www-data s právy 644. Vedlejší výhoda: při zranitelnosti v PHP už soubory panelu nepřepíšete. Na hostingových panelech (HestiaCP a podobných) varianta A není potřeba: tam soubory webu tak jako tak patří účtu, pod kterým se přihlašujete přes SFTP, a webový server je čte přes skupinu.
Past varianty B: jakýkoli následný chmod na souborech resetuje ACL masku a přístup tiše zmizí. Pokud po „úklidu v právech“ nahrávání znovu narazí na Permission denied — zopakujte oba příkazy setfacl.
Bit 2 ve variantě C je setgid: soubory nahrané přes SFTP zůstávají ve skupině www-data, jinak je panel nedokáže přepsat. Po variantě C se ve FileZille připojte znovu — nová skupina se projeví až při novém přihlášení. Kontrola: id deploy (musí se objevit skupina www-data) a ls -ld /path/to/monitor (drwxrwsr-x — písmeno s znamená, že setgid je nastaven).

Přenos na jiný server:

  1. Na novém serveru zprovozněte web + HTTPS (viz stránka ruční instalace).
  2. Zkopírujte všechny soubory panelu spolu s config.php, data/.
  3. Přeneste DB: mysqldump na starém → import na novém; upravte údaje k DB v config.php.
  4. Zopakujte na novém serveru: sudoers, členství ve skupině adm, cron úlohy.
  5. Licence je vázaná na doménu — pokud je doména stejná, klíč bude fungovat dál.

34. Obnovení přístupu (ztracený klíč, heslo, blok podle IP)

Pokud se nemůžete přihlásit — vše se opraví přímo v databázi na serveru. Otevřete databázi (název — z config.php):

sudo mysql MY_DB

Ztracený klíč WebAuthn (neprojde druhý faktor) — vypněte 2FA, přihlaste se heslem a zaregistrujte nový klíč:

UPDATE users SET webauthn_enabled = 0;

Zapomněli jste heslo — nastavte nový hash (vygenerujte ho na serveru a doplňte):

# Vygenerovat hash nového hesla: php -r "echo password_hash('NEW_PASSWORD', PASSWORD_BCRYPT), \"\n\";" # V databázi (vložte získaný hash): # UPDATE users SET password = '$2y$10$...' WHERE username = 'admin';

Zablokovali jste se IP filtrem — vypněte omezení:

UPDATE settings SET value = '0' WHERE name = 'ip_restriction_enabled';
Přístup k databázi máte vždy: sudo mysql na serveru, nebo phpMyAdmin / sekce databází v panelu hostingu. Po obnovení znovu zapněte WebAuthn a IP filtr.

35. Všechny cron úlohy na jednom místě

Souhrn úloh je v root cronu serveru (přidávají se přes sudo crontab -e). Ponechte jen řádky nástrojů, které používáte; cesty upravte podle svého serveru.

# Serverový cron monitoru (root) — vložte přes: sudo crontab -e # 01:30 — sken ClamAV v nebezpečných cestách (web, home, temp) → karty „Zkontrolováno souborů“ a „Poslední skenování“ 30 1 * * * /usr/local/bin/clamav-scan.sh >> /path/to/monitor/logs/cron.log 2>&1 # 02:00 — kontrola integrity souborů AIDE (nutný explicitní --config) 0 2 * * * /usr/bin/aide --config /etc/aide/aide.conf --check > /var/log/aide/aide.log 2>&1 # při startu — obnovit práva /var/lib/aide (balíčkový tmpfiles soubor # aide-common.conf je resetuje na 0700 a panel přestane vidět databázi) @reboot chmod 755 /var/lib/aide # 03:00 — bezpečnostní audit Lynis 0 3 * * * /usr/local/bin/lynis-scan.sh >> /path/to/monitor/logs/cron.log 2>&1 # 04:00 — aktualizace blokovacího seznamu ipsum (level 1) 0 4 * * * /usr/local/bin/load-ipsum.sh >> /path/to/monitor/logs/cron.log 2>&1 # sadu ipsum při startu nahrává služba ipsum-load.service (PŘED firewallem, jinak # UFW sadu v before.rules neuvidí) — není to cron. Zde je jen denní refresh výše. # 06:00 — report Logwatch 0 6 * * * /usr/local/bin/logwatch_daily.sh >> /path/to/monitor/logs/cron.log 2>&1 # každých 30 min — kontrola disků SMART */30 * * * * /usr/local/bin/smart-scan.sh >> /path/to/monitor/logs/cron.log 2>&1 # 04:30 — integrita balíčků debsums 30 4 * * * /usr/local/bin/debsums-scan.sh >> /path/to/monitor/logs/cron.log 2>&1 # 08:00 — plánovaný report na Email a Telegram 0 8 * * * /usr/local/bin/daily-report-all.sh >> /path/to/monitor/logs/cron.log 2>&1 # každou hodinu — obnova seznamů balíčků (pro kartu „Bezpečnostní aktualizace“) 0 * * * * /usr/bin/apt-get update -qq >/dev/null 2>&1 # každých 5 min — snímek zdrojů (CPU/RAM/síť/disk) pro stránku „Výkon“ */5 * * * * /usr/local/bin/collect-metrics-all.sh >> /path/to/monitor/logs/cron.log 2>&1
Podrobnosti ke každému najdete v příslušných sekcích. Zálohovací úlohy (předchozí sekce) se přidávají do stejného cronu. Po úpravách zkontrolujte: sudo crontab -l a že je služba cron aktivní.
Čas cronu = časové pásmo serveru, ne TIMEZONE z config.php. Konstanta TIMEZONE ovlivňuje jen PHP (jak panel zobrazuje data), ale cron démon spouští úlohy podle systémového času OS. Pokud se pásmo serveru neshoduje s vaším, report „08:00“ přijde v jinou dobu. Příklad: server je v jiném pásmu (Europe/London, UTC+1) a vy v Praze (UTC+2) → report „08:00“ vám přijde v 09:00 podle vás. Zkontrolujte a v případě potřeby srovnejte pásmo systému se svým:
# Zkontrolovat aktuální pásmo serveru: timedatectl # Nastavit své pásmo (příklad) a restartovat cron: sudo timedatectl set-timezone Europe/Prague sudo systemctl restart cron
Poté se řádek 0 8 * * * spustí v 08:00 místního času. Jinak byste museli posouvat samotný cron, ale při přechodu na zimní/letní čas by se posun zase rozešel — proto je správnější nastavit pásmo systému.
Hotové obalové skripty. Jejich pracovní kopie a vzor crontabu (crontab.txt) jsou ve složce system/ vedle projektu, mimo public_html. Toto není součást webu — do webového kořene je nahrávat netřeba; umístěte je na server podle systémových cest (jako v crontabu výše):
  • lynis-scan.sh/usr/local/bin/ (chmod +x) — spouští lynis audit system, po dobu skenu nastaví příznak /tmp/lynis-running a zkopíruje lynis-report.dat do data/lynis/ panelu;
  • logwatch_daily.sh/usr/local/bin/ (chmod +x) — vytváří denní report Logwatch (sshd, fail2ban, sudo, postfix) do data/logwatch/;
  • smart-scan.sh/usr/local/bin/ (chmod +x) — snímá stav disků (smartctl) do data/disk/;
  • debsums-scan.sh/usr/local/bin/ (chmod +x) — kontroluje integritu balíčků (debsums) do data/debsums/;
  • clamav-scan.sh/usr/local/bin/ (chmod +x) — antivirový sken ClamAV v nebezpečných cestách (web, home, temp); zapisuje souhrn do /var/log/clamav/scan.log, odkud jej čte stránka ClamAV (řádek 01:30 v crontabu výše);
  • load-ipsum.sh/usr/local/bin/ (chmod +x) — aktualizuje ipset sadu ipsum (level 1) na místě, aniž by narušil aktivní pravidla firewallu (řádek 04:00 v crontabu výše);
  • daily-report-all.sh/usr/local/bin/ (chmod +x) — spouští report cron/daily_report.php panelu (řádek 08:00 v crontabu výše);
  • daily_report.php — už je součástí panelu (cron/daily_report.php), spouští se přes daily-report-all.sh, samostatně jej instalovat netřeba;
  • collect-metrics-all.sh/usr/local/bin/ (chmod +x) — spouští cron/collect_metrics.php panelu (stránka „Výkon“, řádek */5 v crontabu výše); collect_metrics.php už je součástí panelu, samostatně jej instalovat netřeba;
  • crontab.txt (system/cron/) — vzor úloh; potřebné řádky vložte přes sudo crontab -e.
Cesta ke skriptu v crontabu se musí shodovat s tím, kam jste jej umístili.
Jak umístit skript do /usr/local/bin/. Přímo z FileZilly tam zapsat nelze — adresář patří root a SFTP klient dostane SSH_FX_PERMISSION_DENIED. Postup je takový: nejprve nahrajte soubor do /tmp (tam zapisují všichni), poté jej přesuňte na místo jedním příkazem:
# ve FileZille: do pole „Vzdálený server“ zadejte /tmp a nahrajte tam skript, # poté přes SSH (install rovnou nastaví vlastníka a práva, chown/chmod netřeba): sudo install -o root -g root -m 755 /tmp/lynis-scan.sh /usr/local/bin/lynis-scan.sh rm -f /tmp/lynis-scan.sh # kontrola: soubor na místě, práva rwxr-xr-x, syntaxe v pořádku bash -n /usr/local/bin/lynis-scan.sh && ls -l /usr/local/bin/lynis-scan.sh
Nezaměňte adresáře: potřebujete /tmp v kořeni serveru — ne /var/tmp ani tmp/ uvnitř samotného panelu (ten patří www-data a je pro vašeho uživatele uzavřený). Ve stromu FileZilly je /tmp větev nejvyšší úrovně, vedle var, ne uvnitř ní.
Instalovali jste server automatickým nastavením? Tyto obaly a jejich cron úlohy už jsou nainstalovány skriptem (v /usr/local/bin/, log — /var/log/arciveo-cron.log) — ručně není třeba nic dělat.
Kde skripty hledají panel. Obaly jsou doménově neutrální: instalace panelu najdou procházením /home/*/web/*/public_html a /var/www/* a reporty ukládají do jejich data/. Pokud panel leží na jiné cestě — přidejte ji do řádku for app in … uvnitř skriptů, jinak se reporty Lynis/SMART/debsums/Logwatch do panelu nedostanou.
cron.log a přístupová práva. Soubor logs/cron.log vytvoří první root cron — bude patřit root a záložka „Log cronu“ v panelu jej nebude moci přečíst ani vyčistit. Vytvořte soubor předem jménem webového uživatele (vlastník adresáře webu; na HestiaCP je to účet, např. admin) — pak bude root cron jen dopisovat, aniž by měnil vlastníka:
# vytvořit předem pod webovým uživatelem (před přidáním cron řádků): sudo -u OWNER touch /path/to/monitor/logs/cron.log # pokud cron.log už vytvořil root cron — předat webovému uživateli: sudo chown OWNER:OWNER /path/to/monitor/logs/cron.log sudo chmod 644 /path/to/monitor/logs/cron.log
Zjistit vlastníka adresáře: stat -c %U /path/to/monitor.
Správa z panelu. V sekci „Systém“ je stránka „Crontab“ — úlohy lze prohlížet a přidávat bez SSH. Panel edituje pouze úlohy přidané přes něj samotný (samostatný blok v root-crontabu označený servisními komentáři); vše, co už v crontabu je (seznam výše), se zobrazuje jako read-only seznam „Ostatní úlohy serveru“ s tlačítkem „Zkopírovat do editoru“ — to jen přenese rozvrh/příkaz do formuláře pro přidání, původní řádek nechá být. Chcete-li „převést“ existující úlohu pod správu panelu — zkopírujte ji do editoru, uložte, poté starý řádek smažte ručně (sudo crontab -e), jinak se bude provádět dvakrát.
Jednorázové nastavení na serveru. Stránka potřebuje privilegovaný obalový skript — ne holý sudo crontab (to by byla přímá eskalace na root pro každého, kdo získá přístup k relaci panelu), ale úzký skript se dvěma příkazy (list/set), který se dotýká jen svého bloku mezi servisními komentáři. Nainstalujte jednou:
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
Webový uživatel se může lišit od www-data — zkontrolujte, pod kým běží PHP-FPM pool webu (ps -o user= -C php-fpm), a doplňte jej do řádku sudoers.
Nový soubor se nahrál pod jiným vlastníkem — stránka odpovídá „Access denied.“. Pokud je soubor public/crontab_monitor.php nahrán přes FTP/SFTP pod jiným systémovým uživatelem (například root) než ostatní soubory webu, webový server jej nedokáže přečíst. Porovnejte vlastníka a práva se sousedním souborem a uveďte do souladu:
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

Diagnostika

36. Nástroj je nainstalován, ale zobrazuje se „Nenainstalováno“

Monitor zjišťuje přítomnost nástrojů pomocí dpkg-query — databáze balíčků APT. Pokud nástroj není nainstalován přes apt (ručně, ze snapu nebo ze zdrojových kódů), dpkg jej nevidí.

# Ověřit přes dpkg: dpkg -l fail2ban | grep '^ii' dpkg -l auditd | grep '^ii' # Najít cestu k binárce: which ufw fail2ban-client auditctl # Test sudo z www-data: sudo -u www-data sudo fail2ban-client status sudo -u www-data sudo ufw status verbose

37. Řešení potíží (500, žádná data)

Chyba 500 — zkontrolujte logy PHP, nginx a samotného monitoru:

tail -50 /var/log/nginx/error.log tail -50 /var/log/php*-fpm.log # Logy monitoru: tail -50 logs/monitor_$(date +%Y-%m-%d).log # Práva ke složkám: ls -la data/ tmp/ logs/
Dashboard na hostingovém panelu (HestiaCP, ISPmanager, cPanel)? Tam PHP neběží pod www-data, ale pod uživatelským účtem (např. admin — vlastník adresáře webu). Všechna sudo pravidla a členství ve skupinách (adm, systemd-journal) je nutné nastavit na tohoto uživatele, jinak moduly u běžících služeb zobrazí „Neaktivní / 0“. Reálného uživatele PHP zjistíte: ps -o user= -C php-fpm | sort -u nebo vlastníka adresáře webu stat -c '%U' /path/to/monitor. Dále ve všech příkazech níže jej dosaďte místo www-data. Automatická instalace webového uživatele určí sama a sudoers nastaví na něj.

Data se nezobrazují — téměř vždy jde o nenastavená sudo práva. Zkontrolujte konkrétní příkaz jménem webového uživatele (nahraďte www-data svým). Přepínač -n = bez hesla, stejně jako PHP — pokud vyžaduje heslo, pravidlo v sudoers chybí:

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
Modul hlásí „Neaktivní“ / „0“, ačkoli nástroj funguje (např. sudo aa-status v terminálu profily zobrazí, ale stránka „AppArmor“ — „Neaktivní“). Příčina: webový uživatel nemá sudo právo na příkaz tohoto modulu. Ověřte jej ze seznamu výše: pokud vyžaduje heslo — doplňte chybějící řádek do /etc/sudoers.d/monitor („Nastavení sudo“). Časté „nové“ příkazy: /usr/sbin/aa-status (MAC), /usr/sbin/psad --Status (PSAD).
Pokud je konkrétní stránka (Falco, ModSecurity, Auditd, otevřené porty UFW) prázdná — porovnejte se seznamem v sekci o sudo: pravděpodobně není povolen apache2ctl, ausearch, aa-status nebo ss, případně webový uživatel není ve skupinách adm/systemd-journal (odtud se čtou logy fail2ban/auth/modsec a journalctl — Falco a události jádra).

38. Stránka je prázdná, i když data na serveru jsou

Příznak: na serveru data existují (přes shell jsou vidět), ale stránka zobrazuje „žádná data“ nebo špatný stav — například AIDE hlásí „Neinicializováno“, ačkoli databáze je vytvořena.

Příčinou je open_basedir: mnoho panelů a hostingů omezuje pool PHP-FPM na adresář domény, takže PHP funkce file_exists(), file_get_contents(), filemtime() jsou pro systémové cesty (/var/lib/aide, /var/log, /proc…) blokovány. Monitor to obchází tím, že takové cesty čte standardními systémovými příkazy (cat, test, stat).

# Je soubor vidět přes shell (takto ho čte monitor): sudo -u www-data bash -lc 'test -e /var/lib/aide/aide.db && echo VISIBLE || echo NO' # Aktuální hodnota open_basedir pro pool domény: grep -ri open_basedir /etc/php/*/fpm/pool.d/ 2>/dev/null
Pokud shell soubor „vidí“ (VISIBLE), ale stránka ne — jde o open_basedir. Správným řešením je čtení systémovými příkazy (u AIDE a Síťového monitoru už zavedeno). Rozšiřovat open_basedir na /var, /proc není potřeba a je to méně bezpečné.

39. SSL stránka nefunguje

Monitor kontroluje certifikáty připojením k doménám přímo přes port 443. Pokud je doména nedostupná ze samotného serveru nebo je port blokován firewallem, kontrola neproběhne.

# Ruční ověření certifikátu: echo | openssl s_client -connect monitor.example.com:443 2>/dev/null \ | openssl x509 -noout -dates # Ověření dostupnosti: curl -I https://monitor.example.com
Domény monitor přebírá automaticky z konfigurací Nginx (/etc/nginx/sites-enabled/, /etc/nginx/conf.d/) a Apache (/etc/apache2/sites-enabled/) plus aktuální host z HTTP_HOST.
Automatická detekce subdomén. Subdomény se zjišťují automaticky z veřejných logů Certificate Transparency a ověřují se po síti — i když jsou umístěny na jiných serverech. Ručně není třeba nic přidávat.

40. Z několika databází je vidět jen jedna

Monitor se připojuje k MySQL pod uživatelem z config.php, který má přístup jen ke své databázi. MySQL zobrazuje v information_schema pouze databáze s příslušnými oprávněními — proto ostatní nejsou vidět.

Aby monitor viděl všechny databáze, udělte tomuto uživateli oprávnění jen ke čtení (jednou pod root; doplňte jméno uživatele z config.php):

sudo mysql -u root GRANT SELECT, PROCESS, SHOW DATABASES ON *.* TO 'DB_USER'@'localhost'; FLUSH PRIVILEGES; EXIT;
SELECT ON *.* uděluje jen oprávnění ke čtení — nic nelze změnit, smazat ani vytvořit, což je pro monitorování bezpečné.
Bez tohoto GRANT vidí dashboard jen svou databázi — není to chyba, ale omezení oprávnění. Žádný sudo mysql dashboard nepoužívá: seznam databází získává přes vlastní připojení PDO.

41. PostgreSQL se nezobrazuje na stránce „Databáze“

PostgreSQL vyžaduje přístup na úrovni uživatele postgres, kterého webový uživatel panelu nemá. Otevírat z PHP široký sudo psql není bezpečné — panel místo toho volá úzkou obálku bez parametrů, která pouze vypíše verzi, počet spojení a seznam databází s velikostmi. Vytvořte ji:

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 # v /etc/sudoers.d/monitor (uživatel = ten, pod kterým běží PHP-FPM): # www-data ALL=(ALL) NOPASSWD: /usr/local/bin/monitor-pgstat
Pokud PostgreSQL nepoužíváte — odeberte řádek monitor-pgstat ze sudoers (krok 13 ruční instalace) a samotný skript nevytvářejte: karta PostgreSQL zůstane jen neaktivní.

42. Spustil se alert — co dělat

Dashboard ukazuje, co se děje; níže je co dělat v typických situacích. Obecné pravidlo: nepanikařit, ověřit oproti legitimní aktivitě (vaše akce, aktualizace, zálohy) a reagovat podle závažnosti.

  • Mapa útoků / mnoho banů fail2ban — to je norma pro každý server v internetu (boti neustále zkoušejí SSH/web). Hlavní je, aby bany fungovaly. Ujistěte se, že přihlášení přes SSH je jen klíčem (heslo vypnuté) a vaše IP je v ignoreip.
  • ModSecurity zablokoval požadavky — WAF odráží útoky na web, to je jeho práce. Pokud se blokuje váš legitimní provoz (falešný poplach), najděte rule id v detailech a přidejte výjimku do konfigurace CRS.
  • AIDE: změněné soubory — porovnejte seznam s tím, co jste dělali (aktualizace balíčků, úpravy konfigurací jsou norma). Změny systémových binárek, kterých jste se nedotkli, jsou důvod ke zpozornění. Po legitimních změnách aktualizujte databázi AIDE.
  • debsums: změněné binárky/knihovny (mimo /etc, mimo /usr/share) — potenciální podvržení. Ověřte balíček: debsums PACKAGE_NAME, při pochybnostech ho přeinstalujte (apt install --reinstall).
  • ClamAV / maldet: nalezena hrozba — zkontrolujte soubor v karanténě, neotevírejte ho. Pokud jde o web shell v adresáři webu, izolujte server a hledejte vstupní bod (zranitelný plugin, únik přístupů).
  • Falco: kritické události (spuštění shellu v kontejneru, přístup k citlivým souborům) — rozeberte událost: čí proces, co spouštěl. Často jde o legitimní administrátorskou aktivitu.
  • Externí expozice: červeně databáze/cache — okamžitě uzavřete: navažte službu na 127.0.0.1 nebo zavřete port v UFW. To je reálná díra.
  • SSL vyprší / vypršel — obnovte certifikát (Let's Encrypt se obnovuje sám; pokud ne, zkontrolujte certbot renew nebo nastavení v dashboardu).
  • Čekají bezpečnostní aktualizace — nainstalujte: sudo apt update && sudo apt upgrade; po aktualizaci jádra server restartujte.
Známky skutečného průniku (neznámé procesy/uživatelé, změněné binárky, odchozí spam, neznámé cron úlohy): odpojte server od externího přístupu, pořiďte zálohu k analýze a pokud jsou data kritická, postavte čistý server z důvěryhodné zálohy — spolehlivě vyčistit rootkit je obtížné.
Arcivéo - Security Monitor © 2026