Acesta este ghidul de instalare, configurare și întreținere a Arcivéo Monitor. Secțiunile sunt grupate: prezentare generală, implementarea panoului, conectarea instrumentelor de securitate, module integrate și diagnosticare. Comenzile pot fi copiate cu butonul din dreapta.
Instalarea panoului este descrisă pe pagini separate, pas cu pas. Alegeți metoda:
Arcivéo Monitor — panoul de securitate al serverului. Colectează date de la instrumentele instalate (Fail2ban, UFW, Lynis, ModSecurity, AIDE, ClamAV, Auditd, CrowdSec, Suricata, Falco etc.) și le afișează într-o interfață unică, cu dashboard, hartă a atacurilor și pagini detaliate pentru fiecare instrument.
Monitorul nu este un mijloc activ de protecție — el nu blochează atacurile de unul singur. Rolul său este să agrege informațiile de la instrumentele deja active și să le prezinte într-o formă comodă.
Monitorul funcționează doar local — trebuie instalat pe același server pe care îl monitorizează. Nu există niciun SSH sau API la distanță.
Toate comenzile (fail2ban-client, ufw status, ipset list etc.) sunt executate de panou în numele utilizatorului serverului web (de obicei www-data, iar pe panourile de hosting — contul site-ului) cu un set restrâns de drepturi sudo — doar pentru utilitare concrete, fără acces root general. Rezultatele sunt analizate și afișate în browser.
Scorul pornește de la maxim și scade pentru fiecare problemă identificată:
PermitRootLogin yes) — −20Rezultat: 80+ = Protejat, 60–79 = Atenție, <60 = În pericol.
WebAuthn — standard de autentificare fără parolă printr-o cheie hardware. Acceptă YubiKey, Touch ID, Face ID, Windows Hello, Passkey.
După autentificarea cu parolă, sistemul solicită confirmarea prin cheia înregistrată. Chiar dacă parola este compromisă, fără cheia fizică sau biometrie autentificarea este imposibilă.
Pentru configurare, deschideți Chei WebAuthn din meniul lateral și apăsați „Înregistrează cheia”. Înregistrați imediat două chei: dacă singura cheie se pierde sau se defectează, autentificarea în panou cu ea va fi imposibilă.
Panoul poate trimite raportul de securitate în Telegram și pe e-mail (la apăsarea unui buton și programat). Se configurează în secțiunea „Setări”.
Telegram. Sunt necesare tokenul botului și chat id:
@BotFather → /newbot → primiți tokenul de forma 123456:ABC....@userinfobot sau deschideți https://api.telegram.org/bot<TOKEN>/getUpdates și găsiți "chat":{"id":...}.Email. Două metode la alegere în „Setări” → Email:
re_...) și domeniul expeditor confirmat.Statusul raportului: „ATENȚIE” sau „OK”. Titlul devine „ATENȚIE” doar la o problemă reală sau o acțiune în așteptare: amenințare găsită de ClamAV, modificări de fișiere în AIDE, evenimente critice Falco (Emergency/Alert/Critical în ultimele 24 h), un serviciu picat în Monit, este necesară o repornire, expiră SSL (≤14 zile) sau așteaptă actualizări de securitate. Zgomotul de fond — atacuri SSH prin forță brută ale boților, IP-uri banate de fail2ban, alerte Suricata, avertizări Lynis și cererile deja respinse de ModSecurity — nu ridică statusul, așa că astfel de cifre din raport nu înseamnă „ATENȚIE” prin ele însele.
Modulele detaliate de monitorizare (Lynis, UFW, ModSecurity, harta atacurilor, AIDE, ClamAV etc.) se deblochează dacă aveți o licență validă. Fără ea funcționează dashboardul, setările și contul, iar modulele afișează cardul „Necesită licență”.
După achiziția din cont, aveți un cod de activare de forma ARCIVEO-XXXX-XXXX-XXXX-XXXX. Acesta trebuie „activat” pe domeniul panoului dumneavoastră — astfel codul devine un fișier de licență semnat (blocul [license]), pe care îl introduceți în panou.
Cum se activează (3 pași):
my.arciveo.com → secțiunea „Licențe” / „Activare licență” — copiați codul ARCIVEO-….monitor.example.com). Apăsați activare — sistemul va genera fișierul de licență legat de acest domeniu și îl va afișa în câmpul cu butonul „Copiază”.Panoul verifică cheia criptografic: semnătura, legarea la domeniu și termenul de valabilitate.
APP_URL din config.php și introduceți doar numele hostului — fără https:// și fără prefixul www. Activarea este unică: codul devine licență pentru domeniul introdus și nu se mai poate activa a doua oară — la o greșeală în domeniu, cheia nu se va potrivi panoului dumneavoastră, iar codul va fi consumat. De aceea introduceți domeniul cu atenție.
Toți parametrii principali ai panoului sunt definiți într-un singur fișier config.php din rădăcină (lângă folderul public/) prin constante obișnuite define(). Fișierul este creat la instalare; rareori trebuie editat manual — în principal la schimbarea domeniului, la migrare sau la conectarea la altă bază de date. După orice modificare reporniți PHP-FPM (altfel, din cauza OPcache, modificările nu se aplică).
Introduceți propriile valori în locurile evidențiate; restul lăsați-l așa cum este:
Baza de date. Datele de conectare la MySQL/MariaDB:
DB_HOST — gazda SGBD, aproape întotdeauna localhost;DB_NAME — numele bazei de date a panoului;DB_USER — utilizatorul BD (acces doar la propria bază);DB_PASS — parola acestui utilizator;DB_CHARSET — codificarea conexiunii, lăsați utf8mb4.Aplicație.
APP_URL — adresa completă a panoului (ex. https://monitor.example.com). Trebuie să coincidă cu domeniul pe care este activată licența — altfel cheia va fi respinsă (vezi secțiunea „Licență”);TIMEZONE — fusul orar PHP: influențează doar modul în care panoul afișează datele și orele. Asupra momentului rulării sarcinilor cron nu influențează — acolo se aplică fusul sistemului (vezi „Toate sarcinile cron”).Durata sesiunii. SESSION_LIFETIME — timpul de expirare al inactivității sesiunii, în secunde (glisant: se reînnoiește la activitate). Implicit 28800 = 8 ore; după acest timp de inactivitate panoul va cere reautentificarea. De exemplu, 3600 = 1 oră, 86400 = o zi.
Înregistrarea erorilor. Erorile nu sunt niciodată afișate vizitatorilor, ci sunt scrise în logs/php_errors.log — se văd pe pagina „Jurnale aplicație”. Aceste linii (display_errors=0, log_errors=1, calea error_log) de obicei nu trebuie modificate — setările sunt definite direct în fișier și nu depind de php.ini.
public/), iar la acest panou rădăcina web (DocumentRoot) este chiar rădăcina panoului, nu public/. Fișierul în sine nu „se scurge”: în .htaccess din rădăcină există o interdicție explicită pentru el (Require all denied) — serverul returnează 403. Chiar și fără această regulă, codul sursă nu s-ar scurge: este PHP — serverul îl execută, nu îl livrează ca text. Pentru orice eventualitate: nu îl publicați în depozite publice și nu îl trimiteți la suport cu parola reală. Drepturile fișierului — 640.
UFW (Uncomplicated Firewall) — o interfață simplă pentru nftables/iptables. Închide toate porturile de intrare, cu excepția celor permise explicit. Pagina „Firewall UFW” afișează starea și regulile.
ufw enable permiteți obligatoriu SSH (ufw allow OpenSSH), altfel veți pierde accesul la server.
deny nu este considerat accesibil din exterior.
Skipping adding existing rule — nu este o eroare. Astfel UFW anunță că exact aceeași regulă există deja și nu o adaugă din nou. La reluarea autoconfigurării (care este idempotentă) acesta este un mesaj normal — nu trebuie să reacționați.
Blochează automat adresa IP după depășirea numărului de încercări eșuate de autentificare. Analizează jurnalele SSH, nginx, Apache și ale altor servicii.
Instalarea de bază — mai sus. Aici — configurația funcțională care oferă zeci de jail-uri active și mii de blocări: setări generale, jail-urile cheie și banarea automată a IP-urilor malițioase din lista ipsum.
Fișierul /etc/fail2ban/jail.local — setări generale și cele mai importante jail-uri:
ignoreip treceți obligatoriu propriul IP și rețelele de încredere, altfel vă puteți bana pe dumneavoastră înșivă. După modificări: sudo fail2ban-client reload.
Încărcarea automată a listei de blocare ipsum — în cronul root (sudo crontab -e): level 1 (100+ mii de IP-uri) se încarcă în setul ipsum, care este blocat pe firewall (mai multe — în secțiunea „Listă de blocare IPset”):
ipsum — exact pe acesta îl citește dashboardul (cardul „IPset ipsum”). Niveluri: levels/1.txt — acoperire maximă, levels/3.txt — mai precis (3+ surse).
De ce „Monitorul de securitate” este împărțit în două zone. Protecția funcționează pe două niveluri, iar dashboardul nu le amestecă:
sshd, apache-*, nginx-* etc.) și recidiviști periculoși (jail-ul recidive — cei care au fost deja banați de mai multe ori). Acestea sunt IP-uri care chiar au încercat să vă spargă serverul — apar pe harta atacurilor și în „Cronologie”.ipset ipsum, blocată pe firewall prin regula DROP. Aceste adrese, în majoritate, nici nu au atins serverul dumneavoastră — sunt blocate din timp; contorul „IPset ipsum” arată câte au fost blocate preventiv.Diferența e simplă: reactiv — „aceștia au atacat și au primit ban”, preventiv — „aceștia au fost blocați încă înainte de încercare”. Anterior, în recidive se introducea artificial list-3 ipsum (de aici vechea împărțire „recidive de listă”); acum recidive conține doar recidiviști reali, iar preventivul este integral pe firewall.
ipsum — listă publică de IP-uri periculoase, actualizată zilnic. Monitorul afișează numărul de adrese încărcate pe dashboard și pe harta atacurilor și îl ia în calcul în Scorul de securitate (−10 dacă setul nu este încărcat).
Varianta minimă fără fail2ban — un set separat ipsum cu blocare prin iptables:
@reboot. În același timp, comanda create … -exist stabilește limita maxelem 300000 (implicit 65536 — level 1 nu încape, va apărea „Hash is full”):
ipsum și, dacă firewallul este gestionat de programul de instalare (VPS nou — profilurile „Completă”/„Ușoară”), conectează setul la UFW printr-o regulă DROP — traficul de la aceste IP-uri este blocat efectiv. Regula este plasată după ESTABLISHED,RELATED, așa că conexiunile curente (inclusiv SSH-ul dumneavoastră) nu se întrerup — se blochează doar conexiunile noi din listă. Setul se restaurează la pornirea serviciului ipsum-load.service înainte de firewall (altfel UFW nu ar porni) și se actualizează prin cron la 04:00. Pe un server deja configurat (panou, firewall propriu), programul de instalare nu atinge firewallul — acolo ipsum rămâne o listă pentru dashboard și harta atacurilor, iar regula DROP se adaugă manual la dorință (varianta minimă cu iptables … --match-set ipsum … -j DROP — mai sus). La instalarea automată nu trebuie făcut nimic manual.
Înlocuitor modern pentru Fail2ban cu threat intelligence colectiv: blocări de la comunitate plus reguli proprii. Necesită un bouncer separat pentru a aplica blocările la firewall.
systemctl is-active crowdsec). Pornire: sudo systemctl enable --now crowdsec; la cădere consultați sudo journalctl -u crowdsec -n 30. Aceeași regulă pentru orice serviciu în starea „Nepornit” (Suricata, Falco, Monit, MySQL).
stream halted / blocările nu se aplică. Este o cheie api orfană: bouncer-ul a fost șters din cscli bouncers list, dar cheia lui veche a rămas în /etc/crowdsec/bouncers/*.yaml. Reînregistrați bouncer-ul și treceți cheia nouă:
AIDE (Advanced Intrusion Detection Environment) realizează o imagine a sistemului de fișiere și, la fiecare verificare, raportează modificările din /etc, /bin, /usr. După instalare este obligatorie inițializarea bazei (aideinit).
aideinit terminalul rămâne 5–15 minute pe linia Running aide --init... — este normal (hashing-ul întregului sistem de fișiere, încărcare pe disc). Nu întrerupeți cu Ctrl+C. Dacă procesul „stă blocat”, dar nu scrie nimic — probabil așteaptă un răspuns la o solicitare ascunsă Overwrite existing aide.db.new [Yn]? (apăsați Y). Verificați activitatea dintr-o altă sesiune: pgrep -af aide.
aideinit: „21_aide_spamassassin … printf: invalid number” (return code 20) — un bug cunoscut al fragmentului de configurare AIDE în Ubuntu 22.04. Baza nu se creează. Scoateți fragmentul defect și reîncercați:
aideinit nu a fost rulat, fie (Ubuntu 24.04) directorul /var/lib/aide a fost creat în modul 700 și este inaccesibil pentru www-data — se rezolvă cu sudo chmod 755 /var/lib/aide (vezi blocul de mai sus). „Nicio verificare” = baza există, dar verificarea nu a fost încă efectuată — nu este o eroare. Monitorul citește rezultatele din /var/log/aide/aide.log.
/etc/cron.daily/aide pe versiunile noi de Ubuntu/Debian poate să nu scrie /var/log/aide/aide.log în forma necesară (iar aide.wrapper nu mai există în ele). Mai sigur este să adăugați propriul cron cu --config explicit — acesta scrie jurnalul de la root în modul 644, iar monitorul îl citește fără grupuri suplimentare:
chmod 755 /var/lib/aide și cronul de verificare la 02:00 — nu este nevoie de nimic manual.
sudo aideinit && sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db.
Scaner antivirus pentru Linux. Este util mai ales pentru verificarea /var/www în privința shell-urilor PHP și a codului malițios.
enable --now? Trei cauze tipice:
1. În configurație a rămas linia Example — clamd refuză să pornească atât timp cât aceasta există:
2. Baza de semnături nu a fost descărcată — clamd nu pornește fără ea:
3. Pur și simplu se încarcă — clamd încarcă ~8 mln. de semnături în memorie în 30–60 sec. Așteptați și verificați: systemctl is-active clamav-daemon (statusul activating → încă se încarcă).
sudo journalctl -u clamav-daemon -n 30 --no-pager.
clamd doar ține semnăturile în memorie, el nu scanează nimic după un program. Panoul afișează rezultatele scanării programate, de aceea este nevoie de un cron care scanează și scrie în jurnal. Instalarea automată pune wrapper-ul /usr/local/bin/clamav-scan.sh și un cron la 01:30 — după prima rulare se vor completa „Fișiere verificate” și „Ultima scanare”. Porniți imediat, fără a aștepta programul: sudo /usr/local/bin/clamav-scan.sh.
Linux Malware Detect (LMD) — scaner de programe malițioase pentru amenințări web: shell-uri PHP, backdoor-uri web, downloadere. Folosește motorul ClamAV și îl completează cu propriile semnături.
maldet --report.
update-rc.d: error: unable to read /etc/init.d/maldet — este inofensivă. maldet nu folosește init.d, actualizarea semnăturilor și scanările se lansează prin /etc/cron.daily/maldet. Dacă mai jos vedeți installation completed — totul s-a instalat.
apt, ci în /usr/local/maldetect, iar cu open_basedir activat prezența sa se verifică prin shell — vedeți secțiunea „Pagina este goală, deși datele există pe server”.
Sistem de detectare a intruziunilor la nivel de rețea: analizează traficul la nivel de pachete și cunoaște mii de semnături de atac. Completează ModSecurity (acela funcționează la nivel HTTP, Suricata — la nivel TCP/IP).
/var/log/suricata/eve.json sub root, cu modul 750 pe director, iar serverul web (www-data) nu îl poate citi. Deschideți directorul pentru parcurgere — fișierele din interior rămân protejate:
Interceptează apelurile de sistem prin eBPF/kernel module și detectează anomalii în timp real: shell din nginx, citirea /etc/passwd de către un proces web, scriere în /bin etc.
journalctl -u falco (fără sudo — prin grupul systemd-journal). Asigurați-vă că www-data este în acest grup — vedeți „Configurarea sudo” (pct. 2) pe pagina de instalare manuală.
/etc/passwd, scriere în directoarele de sistem). Zero evenimente critice într-o zi pe un server liniștit este o stare sănătoasă.
journalctl necesită drepturi pe jurnal; pentru ca dashboardul să vadă evenimentele stabil, instalarea automată activează la Falco file_output → /var/log/falco/falco.log și setează serviciului UMask=0022 (jurnalul este citit de serverul web). Pe o instalare nouă nu este nevoie să configurați asta manual.
ModSecurity — firewall web (WAF) pentru Apache sau Nginx. Blochează atacurile la nivel de aplicație: injecții SQL, XSS, traversare de căi, scanere.
IncludeOptional /etc/modsecurity/*.conf, iar pachetul pune doar modsecurity.conf-recommended — care nu se încadrează în masca *.conf. Dacă nu îl copiați în modsecurity.conf, SecRuleEngine rămâne Off: modulul este încărcat, regulile CRS sunt încărcate, dar traficul nu este verificat și jurnalul de audit nu este creat. Modul intermediar DetectionOnly doar scrie evenimentele în jurnal, fără a bloca cererile — panoul îl afișează cu galben.
Accesul panoului la jurnalul de audit. Jurnalul /var/log/apache2/modsec_audit.log aparține root (drepturi 640), utilizatorul web nu îl poate citi. Panoul preia datele printr-un wrapper — creați-l:
SecRuleEngine fără indentare: liniile indentate se află în interiorul blocurilor <LocationMatch>/<Directory> (de exemplu, dezactivarea WAF pentru phpMyAdmin) și nu definesc modul global.www-data, în HestiaCP pool-ul site-ului rulează de la proprietarul site-ului (de exemplu, admin) — verificați cu grep -E '^user' /etc/php/*/fpm/pool.d/monitor.example.com.conf.X-Forwarded-For. În statistici ajung doar tranzacțiile cu o regulă declanșată: directiva SecAuditLogRelevantStatus scrie în jurnalul de audit orice răspunsuri 4xx/5xx, așa că acolo ajung și obișnuitele 403/500 — panoul nu le consideră evenimente WAF.---RULES--- este necesar secțiunii „Toate regulile active” — panoul afișează nu doar regulile declanșate, ci în general toate regulile CRS încărcate + cele personalizate. Cele trei căi din bucla for f in … sunt locurile tipice pentru regulile CRS și adăugările locale; dacă aveți altă structură (pachetul pune fișierele în propriul director sau regulile personalizate nu se află în /etc/modsecurity/custom-rules.conf), găsiți căile reale cu comanda sudo grep -rl 'IncludeOptional\|^Include ' /etc/apache2/mods-enabled/security2.conf /etc/apache2/conf-enabled/*.conf 2>/dev/null și introduceți-le în listă. Dacă wrapper-ul este vechi (fără această secțiune) — secțiunea va afișa doar avertismentul „indisponibil”, restul paginii funcționează ca înainte.
Auditd (Linux Audit Daemon) înregistrează apelurile de sistem la nivelul nucleului: autentificări și deconectări, comenzi sudo, tentative de autentificare eșuate, modificări ale fișierelor. Monitorul afișează autentificările, tentativele eșuate și comenzile sudo de astăzi.
ausearch (/usr/sbin/ausearch) și, la nevoie, din /var/log/audit/audit.log cu comanda tail. Ambele trebuie să fie în sudoers.
Supraveghează serviciile (nginx, php-fpm, mysql etc.) și le repornește la cădere. Poate trimite alerte pe email.
monit status. În /etc/monit/monitrc trebuie activată interfața HTTP (blocul set httpd cu allow localhost), altfel monit status va returna o eroare.
monitrc linia set httpd este comentată (implicit apare ca # set httpd port 2812 …). Decomentați blocul și permiteți localhost. (2) Doar httpd activat nu supraveghează nimic — Monit ia în calcul doar ceea ce este descris prin stanțe check; fără ele lista este goală chiar și cu interfața funcțională. Configurație minimă funcțională:
conf.d gata pregătit, cu httpd pe 2812 și un set de verificări — pe o instalare nouă nu este nevoie de configurare manuală.
PSAD analizează jurnalul iptables și detectează scanările de porturi și atacurile de rețea, atribuind fiecărei surse un nivel de amenințare (1–5). Completează fail2ban și Suricata.
psad --Status (necesar în sudoers). Fără jurnalizarea iptables, pagina va fi goală — este normal, atât timp cât nu au existat scanări.
Mandatory Access Control limitează fișierele și resursele pe care le poate accesa un program, chiar dacă acesta a fost compromis. În Ubuntu/Debian se folosește implicit AppArmor (de obicei deja instalat și activ).
aa-status (necesar în sudoers). Afișează numărul de profiluri în modul enforce/complain și procesele fără profil.
„Profiluri încărcate” mai multe decât enforce + complain — este normal. În AppArmor 4.x (Ubuntu 24.04 și mai nou) a apărut modul unconfined: profilul este încărcat în nucleu, dar nu limitează nimic. Ubuntu marchează astfel zeci de profiluri pentru programe care folosesc user namespaces (browsere, clienți torrent și altele asemenea). Când există astfel de profiluri, cardul „Profiluri încărcate” devine chihlimbariu și le afișează numărul — de exemplu unconfined: 90 la 120 încărcate și 26 în enforce. Protejează cu adevărat doar profilurile în enforce; pe Ubuntu 22.04 (AppArmor 3.x) acest mod nu există și cifrele se potrivesc întotdeauna.
unconfined merită făcută doar în cunoștință de cauză: ele nu sunt dezactivate din greșeală, ci pentru că altfel se strică funcționarea programelor înseși. Profilurile în complain sunt altă poveste: acolo regulile sunt deja scrise și doar nu se aplică.
debsums verifică dacă fișierele pachetelor instalate corespund sumelor de control din depozit — depistează binarele de sistem înlocuite (completează AIDE). Verificarea completă durează 1–2 minute, de aceea rulează prin cron, iar panoul citește rezultatul din data/debsums/debsums.log și îl împarte singur pe categorii (contează doar binarele și bibliotecile).
Sarcina se pune în cron-ul root (sudo crontab -e). Wrapper-ul gata pregătit debsums-scan.sh se pune în /usr/local/bin/ (chmod +x; vezi rezumatul sarcinilor cron) și scrie singur raportul în data/debsums/ al panoului.
Wrapper-ul debsums-scan.sh găsește singur data/ al panoului — nu trebuie să specificați calea.
/etc/ (configurări) și /usr/share/ (resurse) de pe server sunt de obicei normale — panoul le marchează cu o culoare separată. Îngrijorătoare sunt modificările binarelor și bibliotecilor (/bin, /sbin, /usr/lib etc.) — cardul „Binare / biblioteci” le arată exact pe acestea.
Lynis se pornește manual sau prin cron. Raportul trebuie salvat în folderul data/lynis/ al proiectului — monitorul citește fișierul lynis-report.dat.
lynis-scan.sh în fundal direct din panou (fără a aștepta cron-ul): afișează „Se scanează…” și la finalizare actualizează singur raportul. Pentru aceasta, utilizatorul web are nevoie de o linie sudoers pentru rularea scriptului — programul de instalare o adaugă automat în /etc/sudoers.d/monitor. Dacă panoul a fost instalat manual/mai demult, adăugați-o cu același utilizator care este deja indicat în fișier:
Logwatch trebuie să salveze rapoartele zilnice în folderul data/logwatch/ al proiectului, în format .txt. Monitorul afișează ultimul raport și arhiva.
Monitorul de rețea nu necesită instalare — este o pagină integrată în panou. Ea afișează starea rețelei serverului din surse locale:
/proc/net/dev;ip;ss;journalctl -k.Primele trei surse funcționează fără sudo, de aceea interfețele, traficul, conexiunile și porturile sunt vizibile imediat. Blocul „Evenimente ale nucleului” folosește journalctl -k — se citește prin grupul systemd-journal („Configurarea sudo”, pct. 2), sudo nu este necesar. Verificați că totul este accesibil pentru utilizatorul web:
UFW BLOCK nu ajung aici — ele se află pe paginile „Firewall UFW” și „Harta atacurilor”. Un bloc gol cu bifă verde = în ultimele 24 h nu au existat defecțiuni de rețea.
Pagina integrată afișează trei lucruri:
df); scala devine roșie la ≥90%;lsblk), doar cele reale (loop/snap sunt ascunse);smartctl).Spațiul și lista dispozitivelor funcționează imediat, fără configurare. Pentru SMART este necesar pachetul smartmontools. Procesul web nu are acces direct la dispozitivele de disc, de aceea SMART este preluat prin cron în fișierul data/disk/smart.txt, iar panoul îl citește.
Sarcina se pune în crontabul root (sudo crontab -e). Wrapperul gata făcut smart-scan.sh se plasează în /usr/local/bin/ (chmod +x; vedeți sumarul sarcinilor cron) și scrie singur în data/disk/ al panoului.
Wrapperul smart-scan.sh găsește singur data/ al panoului — nu este nevoie să specificați calea. În interior, lsblk -e7,11 exclude loop/cdrom.
Pagina afișează istoricul încărcării serverului din ultimele 24 de ore — Load Average, ocuparea CPU și așteptarea I/O, RAM/Swap, traficul de rețea (recepție/transmisie), I/O de disc (citire/scriere), umplerea discului și inodes, descriptorii de fișiere deschiși și conexiunile MySQL, plus numărul curent de conexiuni TCP și procese.
Datele sunt colectate de cron/collect_metrics.php — o dată la 5 minute scrie un instantaneu „brut” al contoarelor (/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') în tabelul BD system_metrics; procentele și vitezele sunt calculate de pagină însăși pe baza diferenței dintre instantaneele vecine (umplerea discului/inodes/descriptori/conexiuni MySQL — valori instantanee, fără recalculare). Sudo nu este necesar — sursele se citesc fără drepturi root. Punctele mai vechi de 24 de ore se șterg automat la fiecare scriere.
Wrapper-ul collect-metrics-all.sh (vezi sumarul sarcinilor cron) găsește singur toate instanțele panoului instalate pe server și rulează cron/collect_metrics.php al fiecăreia în numele proprietarului site-ului.
Alerte de încărcare (secțiunea „Setări” → „Alerte de încărcare”) — la depășirea pragului CPU/RAM/disc/inodes, panoul trimite o notificare pe Telegram/Email (aceleași canale ca raportul zilnic — nu este nevoie să le activați separat pentru alerte), plus încă una — când metrica a revenit la normal. Nu spamează repetat în timp ce pragul se menține: următoarea notificare va veni doar după ciclul „revenit → depășit din nou”.
collect_metrics.php la fiecare rulare (o dată la 5 minute) — nu este nevoie de un cron separat. Starea „deja notificat / încă nu” este stocată în data/alerts_state.json, iar pragurile — în setările panoului.
Pagina „Harta atacurilor” determină țara după IP cu comanda geoiplookup. Fără pachetul GeoIP țările nu vor fi determinate și punctele nu vor apărea pe hartă:
/usr/share/GeoIP/GeoIP.dat poate fi citită de toți, rezultatele sunt stocate în cache în tmp/geoip_cache.json. Harta în sine (Leaflet + dale OpenStreetMap) se încarcă în browser — este nevoie de internet pe computerul unde este deschis panoul.
Două carduri integrate în tabloul de bord care arată nu „pornit/oprit” al unui instrument, ci gradul real de protecție al serverului. Nu necesită instalare, se citesc local fără sudo.
Expunere externă — câte servicii ascultă pe toate interfețele (0.0.0.0/[::]) și sunt accesibile din exterior. Evidențiază cu roșu dacă o bază de date sau un cache este expus în exterior (MySQL, PostgreSQL, Redis, MongoDB, Memcached, Elasticsearch) — este o breșă directă (−10 la Scorul de securitate). Sursă: ss -tuln.
127.0.0.1 (bind-address în configurația MySQL/PostgreSQL, bind 127.0.0.1 în Redis) sau închideți portul în UFW.
127.0.0.1 (loopback) este vizibil doar pentru serverul însuși — din exterior nu poate fi accesat, chiar dacă portul este „deschis”. De aceea Postfix pe portul 25, legat la loopback, este sigur: configurarea automată setează inet_interfaces = loopback-only (plus un smtpd_banner neutru — închide observația Lynis MAIL-8818 despre dezvăluirea versiunii). Cardul „Expunere externă” consideră expus doar ceea ce ascultă pe 0.0.0.0/[::]; serviciile loopback nu intră acolo.
/etc/postfix/main.cf setați smtpd_banner = $myhostname ESMTP (fără versiune și OS) și inet_interfaces = loopback-only, apoi sudo systemctl restart postfix.
Actualizări de securitate — câte patch-uri de securitate așteaptă instalarea și dacă este necesară o repornire după actualizarea kernelului (−5 la Scorul de securitate când există patch-uri). Sursă: /usr/lib/update-notifier/apt-check, fișierul /var/run/reboot-required. Lista detaliată — pe pagina „Actualizări de securitate”.
update-notifier-common). Dacă apt-check lipsește — monitorul numără patch-urile prin apt-get -s upgrade.
Actualizări automate de securitate (unattended-upgrades) — pe pagina „Actualizări de securitate” un card separat arată dacă instalarea automată a patch-urilor de securitate este activată și când a rulat ultima dată. Nu este nevoie de sudo — starea se citește prin apt-config dump.
Copia de rezervă este asigurarea principală: pierderea datelor este mai gravă decât orice atac. Aveți nevoie de două lucruri — o copie de rezervă a serverului/site-urilor și separat o copie de rezervă a bazei de date a panoului (acolo se află utilizatorii, cheile WebAuthn, setările, licența).
Varianta A — HestiaCP: fila Backup a utilizatorului → butonul de creare a copiei de rezervă (sau programat în setările serverului). Copia include site-urile și bazele lor de date.
Varianta B — manual (cron): dump al bazei de date + arhivă a directorului data/ al panoului:
Actualizarea la o versiune nouă. Faceți mai întâi o copie de rezervă. Apoi reîncărcați fișierele de cod, păstrându-vă datele:
public/, includes/, assets/, cron/, database/, precum și fișierele rădăcină .htaccess (controllerul frontal — rutarea nu poate rămâne din versiunea veche), manifest.json, sw.js;config.php (datele BD), data/ (rapoarte), logs/, tmp/ (sesiuni și cache).SSH_FX_PERMISSION_DENIED — Permission denied. Fișierele panoului aparțin lui www-data (așa au fost setate la instalare), în timp ce clientul SFTP se conectează cu utilizatorul dumneavoastră, care nu are drept de scriere. A da lui www-data întregul panou „ca să funcționeze” este tocmai ceea ce duce la această eroare; mai jos sunt trei metode, oricare rezolvă problema.
data/ (rapoarte), tmp/ (sesiuni și cache), logs/; acestea rămân ale lui www-data. Restul este cod, iar serverului web îi este necesar doar pentru citire, pe care o oferă grupul www-data cu drepturile 644. Câștig secundar: în caz de breșă în PHP, fișierele panoului nu mai pot fi rescrise. Pe panourile de hosting (HestiaCP și similare) varianta A nu este necesară: acolo fișierele site-ului aparțin oricum contului cu care vă conectați prin SFTP, iar serverul web le citește prin grup.
chmod ulterior asupra fișierelor resetează masca ACL, iar accesul dispare în tăcere. Dacă după „punerea în ordine a drepturilor” încărcarea se lovește din nou de Permission denied — repetați ambele comenzi setfacl.
2 din varianta C este setgid: fișierele încărcate prin SFTP rămân în grupul www-data, altfel panoul nu le va putea rescrie. După varianta C reconectați-vă în FileZilla — grupul nou se aplică abia la o autentificare nouă. Verificare: id deploy (trebuie să apară grupul www-data) și ls -ld /path/to/monitor (drwxrwsr-x — litera s înseamnă că setgid este activat).
Migrarea pe alt server:
config.php, data/.mysqldump pe cel vechi → import pe cel nou; corectați datele BD în config.php.adm, sarcinile cron.Dacă nu vă puteți autentifica — totul se repară direct în BD de pe server. Deschideți BD (numele — din config.php):
Cheie WebAuthn pierdută (nu trece al doilea factor) — dezactivați 2FA, autentificați-vă cu parola, înregistrați o cheie nouă:
Ați uitat parola — setați un hash nou (generați-l pe server și inserați-l):
V-ați blocat singur cu filtrul IP — dezactivați restricția:
sudo mysql pe server, ori phpMyAdmin / secțiunea BD din panoul de hosting. După recuperare, reactivați WebAuthn și filtrul IP.
Sumarul sarcinilor — în cron-ul root al serverului (se adaugă prin sudo crontab -e). Păstrați doar liniile instrumentelor pe care le folosiți; ajustați căile la propriul server.
sudo crontab -l și că serviciul cron este activ.
TIMEZONE din config.php. Constanta TIMEZONE afectează doar PHP (cum afișează panoul datele), dar demonul cron rulează sarcinile după ora de sistem a OS. Dacă fusul serverului nu coincide cu al dumneavoastră, raportul „08:00” va sosi la altă oră. Exemplu: serverul e în alt fus (Europe/Berlin, UTC+2), iar dumneavoastră — la București (UTC+3) → raportul „08:00” va sosi la 09:00 la dumneavoastră. Verificați și, dacă e nevoie, aliniați fusul sistemului la al dumneavoastră:
0 8 * * * se va declanșa la 08:00 ora locală. Altfel ar trebui deplasat cron-ul însuși, dar la trecerea la ora de iarnă/vară deplasarea s-ar dezacorda din nou — de aceea e mai corect să configurați fusul sistemului.
crontab.txt) se află în folderul system/ lângă proiect, în afara public_html. Aceasta nu face parte din site — nu trebuie încărcate în rădăcina web; plasați-le pe server la căile de sistem (ca în crontab de mai sus):
lynis-scan.sh → /usr/local/bin/ (chmod +x) — rulează lynis audit system, pe durata scanării pune indicatorul /tmp/lynis-running și copiază lynis-report.dat în data/lynis/ al panoului;logwatch_daily.sh → /usr/local/bin/ (chmod +x) — generează raportul zilnic Logwatch (sshd, fail2ban, sudo, postfix) în data/logwatch/;smart-scan.sh → /usr/local/bin/ (chmod +x) — preia starea discurilor (smartctl) în data/disk/;debsums-scan.sh → /usr/local/bin/ (chmod +x) — verifică integritatea pachetelor (debsums) în data/debsums/;clamav-scan.sh → /usr/local/bin/ (chmod +x) — scanare antivirus ClamAV pe căi periculoase (web, home, temp); scrie sumarul în /var/log/clamav/scan.log, de unde îl citește pagina ClamAV (linia 01:30 în crontab de mai sus);load-ipsum.sh → /usr/local/bin/ (chmod +x) — actualizează setul ipset ipsum (level 1) pe loc, fără a rupe regulile active ale firewallului (linia 04:00 din crontabul de mai sus);daily-report-all.sh → /usr/local/bin/ (chmod +x) — rulează raportul cron/daily_report.php al panoului (linia 08:00 în crontab de mai sus);daily_report.php — este deja inclus în panou (cron/daily_report.php), se rulează prin daily-report-all.sh, nu trebuie instalat separat;collect-metrics-all.sh → /usr/local/bin/ (chmod +x) — rulează cron/collect_metrics.php al panoului (pagina „Performanță”, linia */5 în crontab de mai sus); collect_metrics.php este deja inclus în panou, nu trebuie instalat separat;crontab.txt (system/cron/) — model de sarcini; introduceți liniile necesare prin sudo crontab -e./usr/local/bin/. Direct din FileZilla nu se poate scrie acolo — directorul aparține lui root, iar clientul SFTP va primi SSH_FX_PERMISSION_DENIED. Ordinea e următoarea: mai întâi încărcați fișierul în /tmp (acolo scriu toți), apoi mutați-l la locul lui cu o singură comandă:
/tmp în rădăcina serverului — nu de /var/tmp și nici de tmp/ din interiorul panoului însuși (ultimul aparține lui www-data și e închis pentru utilizatorul dumneavoastră). În arborele FileZilla /tmp este o ramură de nivel superior, lângă var, nu în interiorul ei.
/usr/local/bin/, jurnalul — /var/log/arciveo-cron.log) — nu trebuie făcut nimic manual.
/home/*/web/*/public_html și /var/www/*, și pun rapoartele în data/ al acestora. Dacă panoul se află la altă cale — adăugați-o în linia for app in … din interiorul scripturilor, altfel rapoartele Lynis/SMART/debsums/Logwatch nu vor ajunge în panou.
logs/cron.log este creat prima dată de cron-ul root — va aparține lui root, iar fila „Jurnal cron” din panou nu îl va putea nici citi, nici goli. Creați fișierul din timp în numele utilizatorului web (proprietarul directorului site-ului; pe HestiaCP este contul, de ex. admin) — atunci cron-ul root doar va adăuga, fără a schimba proprietarul:
stat -c %U /path/to/monitor.
sudo crontab -e), altfel se va executa de două ori.
sudo crontab (asta ar fi o escaladare directă la root pentru oricine obține acces la sesiunea panoului), ci de un script îngust cu două comenzi (list/set), care atinge doar propriul bloc dintre comentariile de serviciu. Instalați o singură dată:
www-data — verificați sub cine rulează pool-ul PHP-FPM al site-ului (ps -o user= -C php-fpm) și puneți-l în linia sudoers.
public/crontab_monitor.php a fost încărcat prin FTP/SFTP sub alt utilizator de sistem (de exemplu, root) decât restul fișierelor site-ului, serverul web nu îl va putea citi. Comparați proprietarul și drepturile cu un fișier vecin și aliniați-le:
Monitorul detectează prezența instrumentelor prin dpkg-query — baza de pachete APT. Dacă instrumentul nu este instalat prin apt (manual, din snap sau din surse), dpkg nu îl vede.
Eroare 500 — verificați jurnalele PHP, nginx și ale monitorului:
www-data, ci sub contul utilizatorului (de exemplu admin — proprietarul directorului site-ului). Toate regulile sudo și apartenența la grupuri (adm, systemd-journal) trebuie configurate pentru acest utilizator, altfel modulele vor afișa „Inactiv / 0” deși serviciile funcționează. Aflați utilizatorul real al PHP: ps -o user= -C php-fpm | sort -u sau proprietarul directorului site-ului stat -c '%U' /path/to/monitor. Apoi, în toate comenzile de mai jos, folosiți-l în locul lui www-data. Instalarea automată detectează singură utilizatorul web și configurează sudoers pentru el.
Datele nu se afișează — aproape întotdeauna sunt drepturi sudo neconfigurate. Verificați comanda concretă în numele utilizatorului web (înlocuiți www-data cu al dumneavoastră). Indicatorul -n = fără parolă, ca la PHP — dacă cere parola, înseamnă că regula nu există în sudoers:
sudo aa-status în terminal arată profilurile, iar pagina „AppArmor” arată „Inactiv”). Cauza: utilizatorul web nu are dreptul sudo pentru comanda acestui modul. Verificați-o din lista de mai sus: dacă cere parola — adăugați linia lipsă în /etc/sudoers.d/monitor („Configurarea sudo”). Comenzi „noi” frecvente: /usr/sbin/aa-status (MAC), /usr/sbin/psad --Status (PSAD).
apache2ctl, ausearch, aa-status sau ss, ori utilizatorul web nu este în grupurile adm/systemd-journal (de acolo se citesc jurnalele fail2ban/auth/modsec și journalctl — Falco și evenimentele nucleului).
Simptom: pe server există date (vizibile prin shell), dar pagina afișează „nu există date” sau un status incorect — de exemplu AIDE scrie „Neinițializat”, deși baza este creată.
Cauza este open_basedir: multe panouri și găzduiri restricționează pool-ul PHP-FPM la directorul domeniului, așa că funcțiile PHP file_exists(), file_get_contents(), filemtime() pe căi de sistem (/var/lib/aide, /var/log, /proc…) sunt blocate. Monitorul ocolește acest lucru citind astfel de căi prin comenzi de sistem standard (cat, test, stat).
open_basedir. Soluția corectă este citirea prin comenzi de sistem (deja realizată pentru AIDE și Monitorul de rețea). Extinderea open_basedir la /var, /proc nu este necesară și este mai puțin sigură.
Monitorul verifică certificatele conectându-se direct la domenii prin portul 443. Dacă domeniul nu este accesibil de pe serverul însuși sau portul este blocat de firewall, verificarea nu va reuși.
/etc/nginx/sites-enabled/, /etc/nginx/conf.d/) și Apache (/etc/apache2/sites-enabled/), plus hostul curent din HTTP_HOST.
Monitorul se conectează la MySQL cu utilizatorul din config.php, care are acces doar la propria bază. MySQL afișează în information_schema doar bazele pentru care există privilegii — de aceea celelalte nu sunt vizibile.
Pentru ca monitorul să vadă toate bazele, acordați acestui utilizator doar dreptul de citire (o singură dată, ca root; înlocuiți numele utilizatorului din config.php):
sudo mysql: lista bazelor este preluată prin propria sa conexiune PDO.
PostgreSQL necesită acces la nivelul utilizatorului postgres, pe care utilizatorul web al panoului nu îl are. Expunerea unui sudo psql larg din PHP este nesigură — în schimb, panoul apelează un înveliș restrâns, fără parametri, care afișează doar versiunea, numărul de conexiuni și lista bazelor de date cu dimensiunile lor. Creați-l:
monitor-pgstat din sudoers (pasul 13 al instalării manuale) și nu creați scriptul: cardul PostgreSQL va rămâne pur și simplu inactiv.
Panoul arată ce se întâmplă; mai jos — ce trebuie făcut în situații tipice. Principiul general: nu vă panicați, comparați cu activitatea legitimă (acțiunile dumneavoastră, actualizări, backupuri) și reacționați în funcție de gravitate.
ignoreip./etc, în afara /usr/share) — posibil o substituire. Verificați pachetul: debsums PACKAGE_NAME, iar la dubii reinstalați-l (apt install --reinstall).127.0.0.1 sau închideți portul în UFW. Este o breșă reală.certbot renew sau setările din panou).sudo apt update && sudo apt upgrade; după actualizarea nucleului, reporniți serverul.