Instalare manuală

Instalare complet manuală: de la un VPS abia achiziționat până la un panou funcțional, pas cu pas. Pregătirea serverului, crearea site-ului, baza de date, config.php și SSL sunt descrise aici. Comenzile pentru fiecare instrument de securitate și pentru cron se află în ghidul FAQ, cu link-uri pe parcurs.

Regula principală: când modificați SSH sau firewall-ul, nu închideți conexiunea curentă până nu ați testat noua conexiune într-o fereastră separată. Dacă totuși pierdeți accesul — aproape toți furnizorii de hosting oferă o consolă de urgență (VNC/Recovery) în panoul de control.

01. Am cumpărat un VPS cu Ubuntu/Debian — de unde încep

După achiziție, furnizorul de hosting trimite: adresa IP, numele de utilizator (de obicei root) și parola (sau cheia SSH). Este suficient pentru autentificare. Ordinea acțiunilor (fiecare pas este o secțiune mai jos):

  1. Conectați-vă la server prin SSH;
  2. Actualizați sistemul, setați numele de gazdă și fusul orar;
  3. Creați un utilizator obișnuit cu drepturi sudo (nu lucrați ca root);
  4. Configurați autentificarea prin cheie SSH și dezactivați autentificarea prin parolă;
  5. Activați firewallul și autoprotecția;
  6. (opțional) instalați panoul de administrare HestiaCP — server web, BD, e-mail „din start”.

02. Prima conectare prin SSH

SSH este un terminal securizat către server. Puneți propriul IP în locul 203.0.113.10.

203.0.113.10 este un exemplu, o adresă inexistentă (rezervată pentru documentație). Nu o introduceți ca atare — înlocuiți-o cu IP-ul real al serverului dumneavoastră din e-mailul de la găzduitor. Altfel conectarea nu va reuși.

Windows 10/11: deschideți PowerShell sau „Terminal” și folosiți ssh integrat (ori clienții PuTTY / MobaXterm).
macOS / Linux: deschideți „Terminal”.

# Autentificare ca root (parola a venit de la găzduitor): ssh root@203.0.113.10 # Dacă găzduitorul v-a dat un fișier-cheie în loc de parolă: ssh -i cale/către/cheie root@203.0.113.10
La prima conectare, SSH va întreba despre „authenticity of host” — introduceți yes. Parola nu se afișează la tastare (este normal). Dacă găzduitorul v-a dat o parolă temporară — schimbați-o cu comanda passwd.

03. Actualizarea sistemului și configurarea de bază

Primul pas — actualizați toate pachetele și setați numele de gazdă și fusul orar.

# Actualizați sistemul: apt update && apt upgrade -y # Utilitare de bază: apt install -y curl wget ufw fail2ban unattended-upgrades # Fus orar (exemplu) și nume de gazdă: timedatectl set-timezone Europe/Bucharest hostnamectl set-hostname myserver # Actualizări automate de securitate: dpkg-reconfigure -plow unattended-upgrades
Lista fusurilor orare — timedatectl list-timezones. Dacă la finalul actualizării apare fereastra albastră „Daemons using outdated libraries” — bifați toate serviciile (Spațiu) și apăsați OK, este sigur.

04. Crearea unui utilizator cu sudo

Lucrul permanent sub root nu este sigur. Creați un utilizator obișnuit și acordați-i drepturi sudo (rularea comenzilor de administrator la nevoie). Înlocuiți deploy cu orice nume.

# Creați utilizatorul (va stabili parola și va cere date — puteți apăsa Enter): adduser deploy # Adăugați în grupul sudo: usermod -aG sudo deploy # Verificați (sub root): su - deploy sudo whoami # trebuie să afișeze: root exit
În continuare conectați-vă la server deja sub acest utilizator: ssh deploy@203.0.113.10, iar comenzile de administrator rulați-le cu prefixul sudo.

05. Chei SSH și dezactivarea autentificării cu parolă

Autentificarea cu cheie este mai sigură decât parola: o parolă poate fi ghicită, o cheie — practic nu. Mai întâi creăm cheia pe propriul computer, o copiem pe server, verificăm autentificarea — și abia apoi dezactivăm parola.

Pasul 1. Creați cheia pe propriul computer (Windows PowerShell / macOS / Linux):

ssh-keygen -t ed25519 -C "my-laptop" # Enter la toate întrebările (cheia va fi salvată în ~/.ssh/id_ed25519)

Pasul 2. Copiați cheia publică pe server:

# macOS / Linux: ssh-copy-id deploy@203.0.113.10 # Windows (PowerShell): type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh deploy@203.0.113.10 "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

Pasul 3. Verificați autentificarea cu cheie într-o fereastră nouă — trebuie să vă permită accesul fără parolă:

ssh deploy@203.0.113.10
Nu executați Varianta B înainte de a verifica și confirma că autentificarea cu cheie funcționează (Pașii 1–3) și nu închideți sesiunea de lucru. Aceasta dezactivează autentificarea cu parolă pentru toți utilizatorii, inclusiv root. Fără o cheie funcțională veți pierde complet accesul la server — îl veți putea recupera doar prin consola hostingului. Nu aveți cheie — alegeți Varianta A.

Pasul 4. Consolidați accesul prin SSH. Setările le punem într-un fișier separat, configul principal nu îl atingem. Alegeți varianta în funcție de situație:

Varianta A — doar închideți root, păstrați parola. Nu este nevoie de cheie, nu veți pierde accesul:

echo 'PermitRootLogin no' | sudo tee /etc/ssh/sshd_config.d/00-hardening.conf >/dev/null sudo systemctl restart ssh

Varianta B — hardening complet. Dezactivați autentificarea cu parolă și lăsați root doar cu cheie. Executați doar după ce v-ați asigurat că autentificarea cu cheie funcționează:

sudo tee /etc/ssh/sshd_config.d/00-hardening.conf >/dev/null <<'EOF' PubkeyAuthentication yes PasswordAuthentication no PermitRootLogin prohibit-password KbdInteractiveAuthentication no EOF sudo systemctl restart ssh
În ambele variante root cu parolă este închis. PermitRootLogin no interzice complet root, prohibit-password — lasă accesul doar cu cheie (pentru administrare vă autentificați ca deploy și folosiți sudo). Dacă doriți să schimbați portul SSH — adăugați linia Port 2222, dar mai întâi deschideți noul port în firewall (secțiunea următoare) și verificați autentificarea, altfel vă veți bloca accesul.

06. Firewall de bază și autoprotecție

Închideți tot ce nu este necesar cu firewall-ul și activați fail2ban (blochează încercările de forțare a parolelor prin SSH). Mai întâi permiteți SSH, altfel după activarea UFW veți pierde accesul.

# Permite SSH (sau portul dvs., dacă l-ați schimbat) și web: sudo ufw allow OpenSSH sudo ufw allow 80,443/tcp # Activează firewall-ul: sudo ufw enable sudo ufw status verbose # fail2ban — protecția SSH împotriva forțării (profilul de bază este activ imediat): sudo systemctl enable --now fail2ban sudo fail2ban-client status sshd
Acesta este minimul. Setările funcționale fail2ban, lista de blocare ipsum, UFW extins și celelalte instrumente — în grupul „Instrumente de securitate” din ghid. Panoul Arcivéo Monitor va afișa clar statusul tuturor acestora.

07. Instalarea panoului HestiaCP (opțional)

HestiaCP — panou gratuit de administrare a găzduirii: instalează și configurează serverul web (nginx + apache), PHP, baza de date (MariaDB), poșta, DNS și certificatele SSL, oferind o interfață web pentru site-uri. Este util dacă nu doriți să configurați totul manual și intenționați să găzduiți site-uri (inclusiv panoul Arcivéo Monitor).

Instalați HestiaCP pe un server curat (o versiune recentă și suportată de Ubuntu/Debian, minimum ~1–2 GB RAM), înainte de a instala alte servere web și baze de date — altfel vor apărea conflicte. Instalarea durează 10–20 de minute și repornește serverul.
# Descărcați programul de instalare și porniți-l: wget https://raw.githubusercontent.com/hestiacp/hestiacp/release/install/hst-install.sh sudo bash hst-install.sh

Programul de instalare va cere adresa de e-mail și numele de gazdă, apoi va instala întreaga stivă. După repornire, panoul este disponibil la adresa https://YOUR_IP:8083 (numele de utilizator și parola le va afișa programul de instalare la final).

HestiaCP gestionează singur UFW și fail2ban — nu trebuie să le configurați separat, le va prelua automat. Cheile SSH și dezactivarea parolei (secțiunea anterioară) tot trebuie să le realizați.

08. Cerințe de sistem și ionCube

Panoul este o aplicație PHP pe un stack LAMP/LEMP tipic:

  • SO: Linux (se recomandă Ubuntu/Debian);
  • Server web: nginx sau Apache cu PHP-FPM;
  • PHP 8.0+ cu extensiile: pdo_mysql, openssl, curl, json, mbstring;
  • ionCube Loader — extensie PHP necesară pentru funcționarea panoului;
  • BD: MySQL 5.7+ sau MariaDB 10.3+;
  • HTTPS — obligatoriu (autentificarea și WebAuthn funcționează doar prin https);
  • sudo pentru utilizatorul serverului web (set restrâns — pasul 13).
# Verificați versiunea PHP și extensiile: php -v php -m | grep -iE 'pdo_mysql|openssl|curl|mbstring|ioncube'

Instalarea ionCube Loader (dacă nu este deja prezent). Pe un hosting cu panou (HestiaCP, cPanel) ionCube se activează bifând o casetă în setările PHP. Manual pe Ubuntu/Debian:

# Aflați versiunea PHP și directorul extensiilor: php -v EXTDIR=$(php -r 'echo ini_get("extension_dir");'); PHPVER=$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;') # Descărcați și dezarhivați loaderele (64-bit): cd /tmp wget -q https://downloads.ioncube.com/loader_downloads/ioncube_loaders_lin_x86-64.tar.gz tar xzf ioncube_loaders_lin_x86-64.tar.gz # Copiați loaderul pentru versiunea dumneavoastră de PHP în directorul extensiilor: sudo cp ioncube/ioncube_loader_lin_${PHPVER}.so "$EXTDIR"/ # Activați (CLI + PHP-FPM) și reporniți: echo "zend_extension=ioncube_loader_lin_${PHPVER}.so" | sudo tee /etc/php/${PHPVER}/mods-available/ioncube.ini sudo phpenmod ioncube sudo systemctl restart php${PHPVER}-fpm # Verificare — în ieșire va apărea linia "with the ionCube PHP Loader": php -v
Versiunea loaderului trebuie să coincidă cu versiunea PHP (de exemplu ioncube_loader_lin_8.1.so pentru PHP 8.1). Dacă folosiți mai multe versiuni de PHP — activați loaderul pentru fiecare.

09. Domeniu și DNS

Pentru a deschide panoul la o adresă de tipul monitor.example.com și a obține un SSL gratuit — aveți nevoie de un domeniu care indică spre serverul dumneavoastră. În panoul de gestionare DNS creați o înregistrare A:

Tip: A Nume: monitor (subdomeniu → monitor.example.com) sau @ (rădăcina domeniului → example.com) Valoare: 203.0.113.10 ← IP-ul serverului dumneavoastră TTL: 3600

După câteva minute verificați dacă domeniul indică spre server:

dig +short monitor.example.com # trebuie să returneze IP-ul dumneavoastră # sau, dacă dig lipsește: getent hosts monitor.example.com
Certificatul SSL Let's Encrypt se emite doar pentru un domeniu — DNS trebuie să indice spre server înainte de emiterea certificatului.

10. Creați site-ul și încărcați fișierele panoului

Apache: DocumentRoot — către rădăcina panoului, NU către public/. Stilurile (CSS/JS), sw.js, manifest.json se află în assets/ lângă public/ și sunt solicitate de la rădăcina site-ului. Fișierul .htaccess din rădăcină este front-controller-ul. Dacă sub Apache setați DocumentRoot către public/, panoul se va deschide fără stiluri. Pentru nginx pur — invers: rădăcina devine public/, iar assets/ sunt servite printr-o regulă separată (vezi blocul nginx mai jos).
Fișierele panoului (arhiva distribuției) se descarcă după cumpărare din contul my.arciveo.com„Descărcări”. Dezarhivați arhiva înainte de încărcare.

1) Creați directorul panoului și încărcați în el conținutul distribuției (astfel încât înăuntru să se afle public/, assets/, config.php etc.):

sudo mkdir -p /var/www/monitor # apoi încărcați fișierele distribuției în /var/www/monitor (FileZilla / WinSCP / scp)

2) Configurați serverul web. Apache: DocumentRoot — către rădăcina panoului (NU către /public); AllowOverride All este obligatoriu. Calea către socket-ul PHP-FPM este determinată automat. Blocul se inserează în terminal integral:

PHPSOCK=$(ls -1 /run/php/php*-fpm.sock 2>/dev/null | head -1) # auto-detectarea socket-ului PHP-FPM sudo tee /etc/apache2/sites-available/monitor.conf > /dev/null <<'EOF' <VirtualHost *:80> ServerName monitor.example.com DocumentRoot /var/www/monitor <Directory /var/www/monitor> AllowOverride All Require all granted </Directory> <FilesMatch \.php$> SetHandler "proxy:unix:__PHPSOCK__|fcgi://localhost" </FilesMatch> </VirtualHost> EOF sudo sed -i "s#__PHPSOCK__#${PHPSOCK}#" /etc/apache2/sites-available/monitor.conf sudo a2dissite 000-default.conf sudo a2ensite monitor.conf sudo apache2ctl configtest sudo systemctl reload apache2

nginx: nginx nu are .htaccess, de aceea rădăcina devine public/, iar assets/, sw.js, manifest.json (cu un nivel mai sus) sunt servite printr-o regulă separată:

PHPSOCK=$(ls -1 /run/php/php*-fpm.sock 2>/dev/null | head -1) # auto-detectarea socket-ului PHP-FPM sudo tee /etc/nginx/sites-available/monitor.conf > /dev/null <<'EOF' server { listen 80; server_name monitor.example.com; root /var/www/monitor/public; index index.php; # assets, service worker și manifest se află cu un nivel mai sus de public/ location ~ ^/(assets/|sw\.js|manifest\.json) { root /var/www/monitor; } location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:__PHPSOCK__; } } EOF sudo sed -i "s#__PHPSOCK__#${PHPSOCK}#" /etc/nginx/sites-available/monitor.conf sudo ln -s /etc/nginx/sites-available/monitor.conf /etc/nginx/sites-enabled/ sudo nginx -t && sudo systemctl reload nginx

Încărcarea fișierelor — SFTP/SCP (FileZilla, WinSCP) sau scp:

# Exemplu prin scp de pe computerul local: scp -r ./monitor/* deploy@203.0.113.10:/var/www/monitor/
Setați permisiunile fișierelor — este un pas obligatoriu. Dacă ați încărcat sub root sau prin SFTP, fișierele aparțin lui root, iar serverul web (www-data) nu le va putea citi — panoul se va deschide gol sau cu eroarea 403 (în jurnal: .htaccess unreadable / directory not executable). Comanda de mai jos rezolvă acest lucru:
# Normalizăm permisiunile întregului webroot: directorul creat de root este inaccesibil # serverului web (www-data) — fără aceasta panoul afișează o pagină goală sau 403. # Apache rulează sub www-data; dacă aveți alt utilizator web — înlocuiți-l. cd /var/www/monitor # Creăm folderele de lucru ÎNAINTE de chown — altfel directoarele noi rămân root:root # și la chmod 750 serverul web (www-data) nu va putea scrie în ele. sudo mkdir -p data/lynis data/logwatch tmp logs sudo chown -R www-data:www-data /var/www/monitor sudo find /var/www/monitor -type d -exec chmod 755 {} \; sudo find /var/www/monitor -type f -exec chmod 644 {} \; sudo chmod 640 /var/www/monitor/config.php sudo chmod 750 data tmp logs

3) Deschideți-vă încărcarea fișierelor prin SFTP. După comanda de mai sus toate fișierele aparțin lui www-data, în timp ce FileZilla / WinSCP se conectează cu utilizatorul dumneavoastră — încărcarea va eșua atunci cu SSH_FX_PERMISSION_DENIED (Permission denied). Autentificarea ca root pentru încărcare nu este o opțiune — accesul root a fost dezactivat la pasul 05. Alegeți una dintre cele două variante.

Varianta A — o ACL doar pentru utilizatorul dumneavoastră (recomandat). Dreptul de scriere îl primiți numai dumneavoastră; serverul web tot nu poate rescrie codul panoului:

sudo apt install -y acl # Drept de scriere pentru utilizatorul dumneavoastră pe tot directorul panoului: sudo setfacl -R -m u:deploy:rwX /var/www/monitor # Aceeași regulă ca implicită — pentru fișierele și folderele create ulterior: sudo setfacl -R -d -m u:deploy:rwX /var/www/monitor

Varianta B — prin grupul www-data. Mai simplă, dar dreptul de scriere asupra fișierelor panoului îl primește și serverul web: la o vulnerabilitate în PHP codul ar putea fi înlocuit. Ordinea comenzilor contează — config.php și folderele de lucru se închid la final:

sudo usermod -aG www-data deploy # Scriere pentru grup + setgid (bitul 2): fișierele încărcate prin SFTP rămân # în grupul www-data — altfel panoul nu le va putea rescrie. sudo find /var/www/monitor -type d -exec chmod 2775 {} \; sudo find /var/www/monitor -type f -exec chmod 664 {} \; sudo chmod 640 /var/www/monitor/config.php sudo chmod 2750 /var/www/monitor/data /var/www/monitor/tmp /var/www/monitor/logs
După varianta B reconectați-vă în FileZilla (Server → Deconectare, apoi autentificați-vă din nou) — grupul nou se aplică abia la o autentificare nouă, până atunci tot nu veți avea drepturi. Verificare: id deploy — în lista de grupuri trebuie să apară www-data; ls -ld /var/www/monitor — drepturi drwxrwsr-x, litera s în locul lui x înseamnă că setgid este activat.

11. Baza de date

Creați baza și utilizatorul, apoi importați schema. Blocul se lipește în terminal integral. monitor_db și monitor_user sunt nume pentru exemplu, puteți alege oricare doriți; rețineți numele bazei, al utilizatorului și parola — le veți scrie în config.php la pasul următor:

# 1. Baza de date. Parola se setează O SINGURĂ dată în DBPASS și se inserează în toate liniile. # Blocul se lipește în terminal INTEGRAL; sudo mysql intră ca root prin socket unix # (parola root nu e necesară). NU folosiți interactivul `sudo mysql -u root -p` # cu copy-paste — la lipire liniile SQL vor ajunge în cererea de parolă și se vor pierde. DBPASS='CHOOSE_A_PASSWORD' # ← modificați doar această linie sudo mysql <<SQL CREATE DATABASE IF NOT EXISTS monitor_db CHARACTER SET utf8mb4; CREATE USER IF NOT EXISTS 'monitor_user'@'localhost' IDENTIFIED BY '$DBPASS'; GRANT ALL ON monitor_db.* TO 'monitor_user'@'localhost'; FLUSH PRIVILEGES; SQL # Verificare (trebuie să afișeze monitor_db): mysql -u monitor_user -p"$DBPASS" -e "SHOW DATABASES;" # Aceeași parolă scrieți-o în config.php → DB_PASS.
Nu este nevoie să importați schema — panoul creează singur tabelele și contul admin la prima accesare în browser (din database/db.sql), dacă baza este goală. Importul manual al schemei este necesar doar dacă auto-inițializarea nu a funcționat.
Dacă ați folosit instalatorul din browser public/start_db.phpștergeți-l imediat după instalare: el permite recrearea bazei fără autentificare. Cât timp fișierul se află în rădăcina panoului sau în public/, panoul afișează un avertisment roșu.

12. Configurarea config.php

config.php din rădăcina panoului (/var/www/monitor/config.php) este singurul fișier pe care trebuie să îl editați manual. Toate setările panoului sunt definite în el prin constante define(). Deschideți-l în editor:

sudo nano /var/www/monitor/config.php

Puneți valorile dumneavoastră în locurile evidențiate; restul lăsați-l așa cum este:

// --- Baza de date (din pasul 11) --- define('DB_HOST', 'localhost'); // lăsați define('DB_NAME', 'db_name'); // ce ați creat la pasul 11 define('DB_USER', 'user'); // ce ați creat la pasul 11 define('DB_PASS', 'db_password'); // ce ați setat la pasul 11 define('DB_CHARSET', 'utf8mb4'); // lăsați // --- Aplicație --- define('APP_URL', 'https://monitor.example.com'); // adresa panoului, fără slash la final define('TIMEZONE', 'Europe/Bucharest'); // fusul dumneavoastră orar // --- Durata sesiunii --- define('SESSION_LIFETIME', 28800); // inactivitate până la reautentificare, sec (28800 = 8 h)

Ce se modifică:

  • DB_NAME, DB_USER, DB_PASS — exact același nume de bază, utilizator și parolă pe care le-ați setat la crearea BD în pasul 11 (dacă ați lăsat exemplele — monitor_db / monitor_user). DB_HOST și DB_CHARSET nu le atingeți.
  • APP_URL — adresa completă a panoului cu https://, fără slash la final și fără www. Trebuie să coincidă cu domeniul pe care activați licența (pasul 16), altfel cheia va fi respinsă.
  • TIMEZONE — fusul dumneavoastră orar (lista — timedatectl list-timezones). Afectează doar modul în care panoul afișează datele; asupra momentului rulării sarcinilor cron nu influențează (acolo se aplică fusul sistemului).
  • SESSION_LIFETIME — după câte secunde de inactivitate panoul va cere reautentificarea (implicit 8 ore). De ex. 3600 = 1 oră, 86400 = o zi.
  • Blocul de jurnalizare a erorilor (display_errors, log_errors, error_log) — lăsați-l implicit.

Salvați fișierul (Ctrl+O, Enter, apoi Ctrl+X) și reporniți PHP-FPM — altfel, din cauza OPcache, modificările nu se vor aplica:

sudo systemctl restart php*-fpm
config.php — fișier secret (conține parola BD). Se află în rădăcina panoului, care este chiar rădăcina web, dar este protejat: permisiuni 640 (setate la pasul 10) și interdicție explicită în .htaccess din rădăcină. Nu îl publicați în depozite publice și nu îl transmiteți la suport cu parola reală.
Analiza detaliată a tuturor parametrilor — în FAQ: „Fișierul config.php — toate setările panoului”.

13. Configurarea sudo pentru serverul web

PHP rulează sub utilizatorul serverului web, care nu are drepturi pentru comenzile de sistem. Accesul se acordă restrâns: sudo punctual pentru utilitare concrete și citirea jurnalelor prin grupuri (fără sudo). Compromiterea stratului web nu oferă root.

În exemple, www-data este utilizatorul standard al Apache. Dacă aveți altul (în unele panouri, PHP rulează sub un utilizator separat) — înlocuiți-l peste tot. Aflați-l: ps -o user= -C php-fpm | sort -u.

1. Creați /etc/sudoers.d/monitor prin sudo visudo -f /etc/sudoers.d/monitor și inserați (eliminați liniile modulelor neutilizate):

# UFW — stare și reguli (pagina „Firewall”) www-data ALL=(ALL) NOPASSWD: /usr/sbin/ufw status, /usr/sbin/ufw status verbose, /usr/sbin/ufw status numbered www-data ALL=(ALL) NOPASSWD: /usr/sbin/ufw allow [0-9]*, /usr/sbin/ufw deny [0-9]*, /usr/sbin/ufw --force delete [0-9]* # Fail2ban — stare, ban și unban (banned returnează banurile tuturor jail-urilor cu o singură comandă; # ban/unban sunt necesare butoanelor din panou) www-data ALL=(ALL) NOPASSWD: /usr/bin/fail2ban-client status, /usr/bin/fail2ban-client status *, /usr/bin/fail2ban-client banned, /usr/bin/fail2ban-client set * banip *, /usr/bin/fail2ban-client set * unbanip * # Actualizări de securitate (fișa „Actualizări”). Doar citire, dar exact de la root: # cache-ul apt (~70 MB) este accesibil doar pentru root, non-root îl reconstruiește la fiecare apel # (4.2 s CPU față de 0.01 s). Fără wildcard — exact această singură comandă, nu instalează nimic. www-data ALL=(ALL) NOPASSWD: /usr/bin/apt list --upgradable # IPset (harta atacurilor, dashboard) www-data ALL=(ALL) NOPASSWD: /usr/sbin/ipset list -t ipsum # CrowdSec www-data ALL=(ALL) NOPASSWD: /usr/bin/cscli decisions list *, /usr/bin/cscli alerts list *, /usr/bin/cscli bouncers list *, /usr/bin/cscli scenarios list * # Auditd — căutare de evenimente + citirea ultimelor linii din jurnal (cale exactă) www-data ALL=(ALL) NOPASSWD: /usr/sbin/ausearch -m * www-data ALL=(ALL) NOPASSWD: /usr/bin/tail -n 300 /var/log/audit/audit.log # Monit / ModSecurity / AppArmor / PSAD www-data ALL=(ALL) NOPASSWD: /usr/bin/monit status www-data ALL=(ALL) NOPASSWD: /usr/sbin/apache2ctl -M www-data ALL=(ALL) NOPASSWD: /usr/local/bin/monitor-modsec www-data ALL=(ALL) NOPASSWD: /usr/sbin/aa-status www-data ALL=(ALL) NOPASSWD: /usr/sbin/psad --Status # Porturi deschise (jurnalele nucleului/SSH/Falco se citesc FĂRĂ sudo — prin grupul # systemd-journal, vezi p.2; sudo pentru journalctl NU trebuie acordat și este nesigur) www-data ALL=(ALL) NOPASSWD: /usr/bin/ss -tuln, /usr/sbin/ss -tuln, /bin/ss -tuln # PostgreSQL (doar dacă îl folosiți) — script read-only fix, # creați-l conform FAQ „PostgreSQL nu se afișează”; fără el, ștergeți linia www-data ALL=(ALL) NOPASSWD: /usr/local/bin/monitor-pgstat
sudo chmod 440 /etc/sudoers.d/monitor sudo visudo -c # trebuie să fie "parsed OK"

2. Accesul la jurnale și la jurnalul systemd. Modulele citesc direct /var/log/fail2ban.log, auth.log, ufw.log, apache2/*, aide (pe Debian/Ubuntu, aceste jurnale sunt în grupul adm). Evenimentele nucleului, SSH și Falco se preiau din journald cu comanda journalctl fără sudo, prin grupul systemd-journal. Adăugați utilizatorul web în ambele grupuri și reporniți PHP-FPM:

sudo usermod -aG adm,systemd-journal www-data sudo systemctl restart php*-fpm # obligatoriu, altfel grupurile nu se aplică

3. Dacă ClamAV sau Suricata scriu jurnalele într-un alt grup decât adm (uneori root:root) — acordați accesul prin ACL:

sudo apt install acl sudo setfacl -R -m u:www-data:rX /var/log/clamav /var/log/suricata 2>/dev/null sudo setfacl -d -m u:www-data:rX /var/log/clamav /var/log/suricata 2>/dev/null

4. Învelișul ModSecurity. Jurnalul de audit al WAF (/var/log/apache2/modsec_audit.log) aparține lui root cu drepturile 640, iar utilizatorul web nu îl poate citi direct. Pagina ModSecurity preia modul motorului, evenimentele și lista regulilor active printr-un script read-only fix — chiar el este permis în sudoers prin linia de mai sus:

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
Fără fișierul /etc/modsecurity/modsecurity.conf, WAF-ul în sine nu funcționează: pachetul pune doar modsecurity.conf-recommended, iar motorul de reguli rămâne dezactivat — cum se activează, vezi FAQ → „Instalarea ModSecurity”.
Utilizatorul din toate liniile sudoers trebuie să coincidă cu utilizatorul pool-ului FPM: pe Apache/Debian obișnuit este www-data, în HestiaCP pool-ul site-ului rulează sub proprietarul site-ului (de exemplu, admin) — verificați grep -E '^user' /etc/php/*/fpm/pool.d/monitor.example.com.conf.

5. Dacă în fața Apache se află Nginx (HestiaCP, ISPmanager și alte panouri — acolo Nginx proxiază PHP către Apache, iar conținutul static îl servește el însuși). Directoarele de serviciu sunt protejate prin fișiere .htaccess, dar Nginx nu le citește: orice fișier static (.json, .txt, .log, .dat) îl va servi direct, ocolind Apache. În exterior se scurg cache-urile panoului și datele — de exemplu tmp/modsec_cache.json cu evenimentele WAF și IP-urile atacatorilor. Adăugați interdicția în configul site-ului Nginx:

location ^~ /data/ { deny all; } location ^~ /tmp/ { deny all; } location ^~ /logs/ { deny all; } location ^~ /includes/ { deny all; } location ^~ /cron/ { deny all; } location ^~ /database/ { deny all; } location = /config.php { deny all; }
Prefixul ^~ este obligatoriu: el este ales înaintea regulii regex pentru conținutul static din location /, altfel interdicția nu funcționează.
În HestiaCP puneți acest lucru într-un fișier separat /home/<user>/conf/web/<domain>/nginx.ssl.conf_deny (și nginx.conf_deny pentru HTTP) — configul site-ului include nginx.ssl.conf_*, iar la reconstrucție astfel de fișiere nu sunt suprascrise. Aplicați: sudo nginx -t && sudo systemctl reload nginx.
Verificare: curl -s -o /dev/null -w '%{http_code}\n' https://monitor.example.com/tmp/modsec_cache.json — trebuie să fie 403. Dacă Apache funcționează fără Nginx (ascultă el însuși pe 80/443), nu trebuie adăugat nimic — .htaccess este suficient.
Verificați căile către binare prin which (de exemplu which ufw cscli ausearch ss). Editați sudoers doar prin visudo. Lista tuturor bazelor de date MySQL se activează printr-un GRANT separat (FAQ → „Se vede o singură BD”).

14. Restricționarea accesului după IP

Restricționați accesul la monitor după adresa IP — chiar dacă URL-ul devine cunoscut, pagina de autentificare nu se va deschide. Se poate face la nivelul serverului web (exemplu pentru nginx mai jos) sau direct în panou („Setări” → „Restricționarea accesului după IP”). Dacă folosiți Apache, utilizați restricționarea din panou.

Dacă site-ul nginx este deja configurat conform pasului 10, nu adăugați un al doilea location / — introduceți liniile allow/deny în blocul deja existent. Două location / identice în același server { } sunt o eroare de configurare, iar nginx nu va reporni.
# În configul nginx (în interiorul server { }): # Calea ACME Let's Encrypt o păstrăm deschisă, ocolind restricția de IP — # ca emiterea și reînnoirea automată a SSL (pasul 15) să nu depindă de filtrul de IP. location ^~ /.well-known/acme-challenge/ { allow all; } location / { allow 203.0.113.10; # ← introduceți IP-ul dvs. allow 10.0.0.0/8; # rețea locală (dacă e necesar) deny all; try_files $uri $uri/ /index.php?$query_string; } # Reîncărcați nginx: sudo nginx -t && sudo systemctl reload nginx

15. Emiteți SSL (HTTPS)

Panoul funcționează doar prin HTTPS. Sesiunea de autentificare folosește un cookie securizat, iar WebAuthn (2FA) funcționează numai pe HTTPS. Prin http:// nu vă puteți autentifica.

Certificatul este gratuit (Let's Encrypt). DNS-ul domeniului trebuie să indice deja către server. Comanda depinde de serverul web:

# Apache: sudo certbot --apache -d monitor.example.com # nginx — DOAR dacă aveți exact nginx. Pe Apache NU rulați: # apt va instala nginx și va ocupa portul 80, conflict cu Apache. # sudo apt install python3-certbot-nginx # sudo certbot --nginx -d monitor.example.com # certbot va înscrie singur HTTPS în configurație și va configura reînnoirea automată
Ce va întreba certbot: e-mail → acordul cu Terms (Y) → transmiterea e-mailului către EFF (la alegerea dumneavoastră). Apoi va emite singur certificatul, va înscrie <VirtualHost *:443>, va configura redirecționarea http→https și reînnoirea automată.
DNS-ul trebuie să indice către server ÎNAINTE de a rula certbot (verificarea proprietății prin portul 80). Verificare: dig +short monitor.example.com → IP-ul serverului. Porturile 80/443 sunt deschise: sudo ufw allow 80,443/tcp.

După emitere: https://monitor.example.com se deschide cu lacăt, http:// redirecționează către https:// (APP_URL din config.php este deja setat la pasul 12).

16. Autentificare și configurare inițială

Deschideți https://monitor.example.com, autentificați-vă cu admin / useradmin și parcurgeți lista de verificare:

  1. Schimbați parola admin — secțiunea „Utilizatori” din meniu.
  2. Activați WebAuthn (2FA) — „Chei WebAuthn” → înregistrați o cheie/passkey (necesită HTTPS). Înregistrați imediat două: dacă pierdeți singura cheie, autentificarea cu ea va fi imposibilă. Detalii.
  3. Restricționați accesul după IP — „Setări” → „Restricționarea accesului după IP” (introduceți propriul IP înainte de activare, altfel vă blocați accesul).
  4. Introduceți licența — activați codul ARCIVEO-… din cont pe domeniul dumneavoastră și inserați cheia în „Setări” → „Licență”. Detalii.
  5. Configurați notificările — Telegram și/sau Email în „Setări”. Detalii.
  6. Ștergeți instalatorul public/start_db.php, dacă a rămas (pasul 11).

17. Instrumente de securitate (opțional)

Panoul funcționează deja. Instrumentele se instalează la alegere — instalați ce aveți nevoie, iar panoul afișează imediat starea. Comenzile de instalare pentru fiecare se află în ghid (secțiuni separate pe instrumente):

18. Cron și mentenanță

Se configurează o singură dată, tot opțional, dar recomandat. Comenzile detaliate — în ghid:

  1. Sarcini cron (rapoarte, actualizarea listelor, verificări);
  2. Copii de rezervă;
  3. Actualizarea și migrarea panoului;
  4. Recuperarea accesului — în caz de pierdere a cheii/parolei.
Ceva nu funcționează sau afișează „nu există date”? Consultați grupul „Diagnosticare” din ghid.
Arcivéo - Security Monitor © 2026