Installazione completamente manuale: da un VPS appena acquistato fino a un pannello funzionante, passo per passo.
Preparazione del server, creazione del sito, database, config.php e SSL sono descritti qui.
I comandi per ogni strumento di sicurezza e per il cron sono nel
manuale delle FAQ, con i link lungo il percorso.
Regola fondamentale: quando modifica SSH o il firewall, non chiuda la connessione corrente finché non ha verificato quella nuova in una finestra separata. Se l'accesso viene comunque perso, quasi tutti i provider offrono una console di emergenza (VNC/Recovery) nel pannello di controllo.
01. Ho acquistato un VPS con Ubuntu/Debian — da dove iniziare
Dopo l'acquisto il provider di hosting invia: indirizzo IP, nome utente (di solito root) e password (o chiave SSH). Sono sufficienti per accedere. Sequenza delle operazioni (ogni passo è una sezione qui sotto):
Connettersi al server tramite SSH;
Aggiornare il sistema, impostare il nome host e il fuso orario;
Creare un utente normale con privilegi sudo (non lavorare come root);
Configurare l'accesso tramite chiave SSH e disabilitare l'accesso con password;
Abilitare il firewall e la protezione automatica;
(facoltativo) installare il pannello di controllo HestiaCP — server web, database, posta «pronti all'uso».
02. Prima connessione via SSH
SSH è un terminale sicuro verso il server. Inserisca il suo IP al posto di 203.0.113.10.
203.0.113.10 è un esempio, un indirizzo inesistente (riservato alla documentazione). Non lo inserisca così com'è: lo sostituisca con l'IP reale del suo server indicato nell'email dell'hoster. Altrimenti la connessione non funzionerà.
Windows 10/11: apra PowerShell o il «Terminale» e usi l'ssh integrato (oppure i client PuTTY / MobaXterm). macOS / Linux: apra il «Terminale».
# Accesso come root (la password è stata inviata dall'hoster):
ssh root@203.0.113.10
# Se l'hoster ha fornito un file chiave invece della password:
ssh -i percorso/della/chiave root@203.0.113.10
Alla prima connessione SSH chiederà dell'«authenticity of host»: digiti yes. La password durante la digitazione non viene mostrata (è normale). Se l'hoster ha fornito una password temporanea, la cambi con il comando passwd.
03. Aggiornamento del sistema e configurazione di base
Come prima cosa aggiorni tutti i pacchetti e imposti l'hostname e il fuso orario.
Elenco dei fusi orari — timedatectl list-timezones. Se al termine dell'aggiornamento compare la finestra blu «Daemons using outdated libraries», selezioni tutti i servizi (Spazio) e prema OK: è sicuro.
04. Creazione di un utente con sudo
Lavorare sempre come root non è sicuro. Crei un utente normale e gli conceda i privilegi sudo (esecuzione di comandi da amministratore quando necessario). Sostituisca deploy con un nome a piacere.
# Creare l'utente (imposterà la password e chiederà i dati — si può premere Enter):
adduser deploy
# Aggiungere al gruppo sudo:
usermod -aG sudo deploy
# Verificare (come root):
su - deploy
sudo whoami # deve restituire: root
exit
D'ora in poi acceda al server con questo utente: ssh deploy@203.0.113.10, ed esegua i comandi da amministratore con il prefisso sudo.
05. Chiavi SSH e disabilitazione dell'accesso con password
L'accesso con chiave è più sicuro della password: una password può essere indovinata, una chiave praticamente no. Prima creiamo la chiave sul proprio computer, la copiamo sul server, verifichiamo l'accesso e solo allora disabilitiamo la password.
Passo 1. Creare la chiave sul proprio computer (Windows PowerShell / macOS / Linux):
ssh-keygen -t ed25519 -C "my-laptop"
# Enter a tutte le domande (la chiave sarà salvata in ~/.ssh/id_ed25519)
Passo 3. Verificare l'accesso con chiave in una nuova finestra: deve consentire l'accesso senza password:
ssh deploy@203.0.113.10
Non eseguire la Variante B finché l'accesso con chiave non è stato verificato e non funziona (Passi 1–3), e non chiudere la sessione di lavoro. Disabilita l'accesso con password per tutti gli utenti, root incluso. Senza una chiave funzionante perderà completamente l'accesso al server, che potrà essere ripristinato solo tramite la console dell'hosting. Se non ha una chiave, scelga la Variante A.
Passo 4. Rendere più rigido l'accesso SSH. Mettiamo le impostazioni in un file separato, senza toccare la configurazione principale. Scelga la variante adatta alla situazione:
Variante A — chiudere solo root, mantenere la password. Non serve la chiave, non perderà l'accesso:
Variante B — hardening completo. Disabilitare l'accesso con password e mantenere root solo con chiave. Esegua solo dopo aver verificato che l'accesso con chiave funziona:
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
In entrambe le varianti l'accesso root con password è chiuso. PermitRootLogin no vieta root completamente, prohibit-password mantiene l'accesso solo con chiave (per l'amministrazione entri come deploy e usi sudo). Se desidera cambiare la porta SSH, aggiunga la riga Port 2222, ma prima apra la nuova porta nel firewall (sezione successiva) e verifichi l'accesso, altrimenti si bloccherà fuori.
06. Firewall di base e protezione automatica
Chiuda tutto il superfluo con il firewall e attivi fail2ban (blocca i tentativi di forzatura delle password via SSH). Prima di tutto autorizzi SSH, altrimenti dopo aver attivato UFW perderà l'accesso.
# Autorizzare SSH (o la sua porta, se modificata) e il web:
sudo ufw allow OpenSSH
sudo ufw allow 80,443/tcp
# Attiva il firewall:
sudo ufw enable
sudo ufw status verbose
# fail2ban — protezione SSH dalla forzatura (profilo di base attivo subito):
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd
Questo è il minimo. Le impostazioni operative di fail2ban, la blocklist ipsum, UFW avanzato e gli altri strumenti si trovano nel gruppo «Strumenti di sicurezza» della guida. Il pannello Arcivéo Monitor stesso mostrerà chiaramente lo stato di tutto ciò.
07. Installazione del pannello HestiaCP (opzionale)
HestiaCP — pannello di controllo hosting gratuito: installa e configura il server web (nginx + apache), PHP, il database (MariaDB), la posta, il DNS e i certificati SSL, e offre un'interfaccia web per i siti. Comodo se non vuole configurare tutto manualmente e prevede di ospitare siti (compreso lo stesso pannello Arcivéo Monitor).
Installi HestiaCP su un server pulito (Ubuntu/Debian recente e supportato, minimo ~1–2 GB RAM), prima di installare altri server web e database — altrimenti si verificheranno conflitti. L'installazione richiede 10–20 minuti e riavvia il server.
# Scaricare l'installer ed eseguirlo:
wget https://raw.githubusercontent.com/hestiacp/hestiacp/release/install/hst-install.sh
sudo bash hst-install.sh
L'installer chiederà l'email e il nome host, poi installerà l'intero stack. Dopo il riavvio, il pannello è accessibile all'indirizzo https://YOUR_IP:8083 (login e password verranno mostrati dall'installer al termine).
HestiaCP gestisce autonomamente UFW e fail2ban — non è necessario configurarli separatamente, li rileverà da sola. Configuri comunque le chiavi SSH e la disattivazione della password (sezione precedente).
08. Requisiti di sistema e ionCube
Il pannello è un'applicazione PHP su un tipico stack LAMP/LEMP:
SO: Linux (consigliati Ubuntu/Debian);
Server web: nginx o Apache con PHP-FPM;
PHP 8.0+ con le estensioni: pdo_mysql, openssl, curl, json, mbstring;
ionCube Loader — estensione PHP necessaria al funzionamento del pannello;
DB: MySQL 5.7+ o MariaDB 10.3+;
HTTPS — obbligatorio (accesso e WebAuthn funzionano solo via https);
sudo per l'utente del server web (set ristretto — passo 13).
# Verificare la versione di PHP e le estensioni:
php -v
php -m | grep -iE 'pdo_mysql|openssl|curl|mbstring|ioncube'
Installazione di ionCube Loader (se non è già presente). Su un hosting con pannello (HestiaCP, cPanel) ionCube si abilita con una casella nelle impostazioni PHP. Manualmente su Ubuntu/Debian:
# Scoprire la versione di PHP e la cartella delle estensioni:
php -v
EXTDIR=$(php -r 'echo ini_get("extension_dir");'); PHPVER=$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')
# Scaricare e decomprimere i loader (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
# Copiare il loader per la propria versione di PHP nella cartella delle estensioni:
sudo cp ioncube/ioncube_loader_lin_${PHPVER}.so "$EXTDIR"/
# Attivare (CLI + PHP-FPM) e riavviare:
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
# Verifica — nell'output comparirà la riga "with the ionCube PHP Loader":
php -v
La versione del loader deve coincidere con la versione di PHP (ad esempio ioncube_loader_lin_8.1.so per PHP 8.1). Se si usano più versioni di PHP, attivare il loader per ciascuna.
09. Dominio e DNS
Per aprire il pannello a un indirizzo come monitor.example.com e ottenere un SSL gratuito, serve un dominio che punti al Suo server. Nel pannello di gestione DNS crei un record A:
Tipo: A
Nome: monitor (sottodominio → monitor.example.com)
oppure @ (radice del dominio → example.com)
Valore: 203.0.113.10 ← IP del Suo server
TTL: 3600
Dopo qualche minuto verifichi che il dominio punti al server:
dig +short monitor.example.com # deve restituire il Suo IP
# oppure, se dig non è presente:
getent hosts monitor.example.com
Il certificato SSL di Let's Encrypt viene rilasciato solo per un dominio: il DNS deve puntare al server prima dell'emissione del certificato.
10. Creare il sito e caricare i file del pannello
Apache: DocumentRoot punta alla radice del pannello, NON a public/. Gli stili (CSS/JS), sw.js e manifest.json si trovano in assets/ accanto a public/ e vengono richiesti dalla radice del sito. Il .htaccess nella radice è il front controller. Se in Apache si imposta DocumentRoot su public/, il pannello si aprirà senza stili. Per nginx puro è il contrario: come radice si prende public/ e assets/ viene servito da una regola separata (vedi il blocco nginx più sotto).
I file del pannello (l'archivio della distribuzione) si scaricano dopo l'acquisto nell'area my.arciveo.com → «Download». Estragga l'archivio prima del caricamento.
1) Crei la cartella del pannello e vi carichi il contenuto della distribuzione (in modo che all'interno si trovino public/, assets/, config.php ecc.):
sudo mkdir -p /var/www/monitor
# poi caricare i file della distribuzione in /var/www/monitor (FileZilla / WinSCP / scp)
2) Configuri il web server.Apache: DocumentRoot alla radice del pannello (NON a /public); AllowOverride All è obbligatorio. Il percorso del socket PHP-FPM viene rilevato automaticamente. Il blocco va incollato nel terminale per intero:
PHPSOCK=$(ls -1 /run/php/php*-fpm.sock 2>/dev/null | head -1) # rilevamento automatico del socket 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 non ha il .htaccess, perciò come radice prendiamo public/ e serviamo assets/, sw.js, manifest.json (un livello più su) con una regola separata:
PHPSOCK=$(ls -1 /run/php/php*-fpm.sock 2>/dev/null | head -1) # rilevamento automatico del socket 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 e manifest si trovano un livello sopra 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
Caricamento dei file — SFTP/SCP (FileZilla, WinSCP) o scp:
# Esempio con scp dal computer locale:
scp -r ./monitor/* deploy@203.0.113.10:/var/www/monitor/
Imposti i permessi sui file: è un passaggio obbligatorio. Se ha caricato come root o via SFTP, i file appartengono a root e il web server (www-data) non potrà leggerli: il pannello si aprirà vuoto o con errore 403 (nel log: .htaccess unreadable / directory not executable). Il comando qui sotto risolve il problema:
# Normalizziamo i permessi dell'intera webroot: una cartella creata da root non è
# accessibile al web server (www-data): senza questo il pannello restituisce una pagina vuota o 403.
# Apache gira come www-data; se ha un altro utente web, lo sostituisca.
cd /var/www/monitor
# Le cartelle di lavoro le creiamo PRIMA di chown, altrimenti le nuove cartelle restano root:root
# e con chmod 750 il web server (www-data) non potrà scrivervi.
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) Si abra il caricamento dei file via SFTP. Dopo il comando qui sopra tutti i file appartengono a www-data, mentre FileZilla / WinSCP si collegano con il suo utente: il caricamento fallirà con SSH_FX_PERMISSION_DENIED (Permission denied). Accedere come root per caricare non è possibile: l'accesso root è stato disattivato al passo 05. Scelga una delle due varianti.
Variante A: una ACL solo per il suo utente (consigliata). Il permesso di scrittura lo riceve soltanto lei; il web server continua a non poter sovrascrivere il codice del pannello:
sudo apt install -y acl
# Permesso di scrittura per il suo utente sull'intera directory del pannello:
sudo setfacl -R -m u:deploy:rwX /var/www/monitor
# La stessa regola come predefinita: per file e cartelle creati in seguito:
sudo setfacl -R -d -m u:deploy:rwX /var/www/monitor
Variante B: tramite il gruppo www-data. Più semplice, ma il permesso di scrittura sui file del pannello lo ottiene anche il web server: con una vulnerabilità in PHP il codice potrebbe essere sostituito. L'ordine dei comandi è importante: config.php e le cartelle di lavoro vengono chiuse per ultime:
sudo usermod -aG www-data deploy
# Scrittura per il gruppo + setgid (il bit 2): i file caricati via SFTP restano
# nel gruppo www-data, altrimenti il pannello non potrà sovrascriverli.
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
Dopo la variante B si ricolleghi in FileZilla (Server → Disconnetti, poi acceda di nuovo): il nuovo gruppo ha effetto solo a un nuovo accesso, prima di allora i permessi continueranno a mancare. Verifica: id deploy, nell'elenco dei gruppi deve comparire www-data; ls -ld /var/www/monitor, permessi drwxrwsr-x, la lettera s al posto di x indica che setgid è attivo.
11. Database
Crei il database e l'utente, poi importi lo schema. Il blocco va incollato nel terminale per intero. monitor_db e monitor_user sono nomi di esempio, può usarne di propri; memorizzi il nome del database, l'utente e la password — li inserirà in config.php al passaggio successivo:
# 1. Database. La password si imposta UNA sola volta in DBPASS e viene sostituita in tutte le righe.
# Il blocco va incollato nel terminale PER INTERO; sudo mysql entra come root via socket unix
# (la password di root non serve). NON usi `sudo mysql -u root -p` interattivo
# con copia-incolla — durante l'incollaggio le righe SQL finiranno nella richiesta password e andranno perse.
DBPASS='CHOOSE_A_PASSWORD' # ← modifichi solo questa riga
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
# Verifica (deve mostrare monitor_db):
mysql -u monitor_user -p"$DBPASS" -e "SHOW DATABASES;"
# Inserisca la stessa password in config.php → DB_PASS.
Non è necessario importare lo schema — il pannello crea da sé le tabelle e l'account admin al primo accesso dal browser (da database/db.sql), se il database è vuoto. L'importazione manuale dello schema serve solo se l'inizializzazione automatica non è andata a buon fine.
Se ha usato l'installer da browser public/start_db.php — lo elimini subito dopo l'installazione: consente di ricreare il database senza autenticazione. Finché il file resta nella radice del pannello o in public/, il pannello mostra un avviso rosso.
12. Configurazione di config.php
config.php nella radice del pannello (/var/www/monitor/config.php) è l'unico file da modificare a mano. Tutte le impostazioni del pannello vi sono definite tramite costanti define(). Aprirlo nell'editor:
sudo nano /var/www/monitor/config.php
Inserisca i propri valori nei punti evidenziati; lasci il resto invariato:
// --- Database (dal passo 11) ---
define('DB_HOST', 'localhost'); // lasciare
define('DB_NAME', 'db_name'); // creato al passo 11
define('DB_USER', 'user'); // creato al passo 11
define('DB_PASS', 'db_password'); // impostato al passo 11
define('DB_CHARSET', 'utf8mb4'); // lasciare
// --- Applicazione ---
define('APP_URL', 'https://monitor.example.com'); // indirizzo del pannello, senza slash finale
define('TIMEZONE', 'Europe/Rome'); // il suo fuso orario
// --- Durata della sessione ---
define('SESSION_LIFETIME', 28800); // inattività prima del nuovo login, sec (28800 = 8 h)
Cosa modificare:
DB_NAME, DB_USER, DB_PASS — esattamente lo stesso nome del database, utente e password impostati alla creazione del DB nel passo 11 (se ha lasciato gli esempi — monitor_db / monitor_user). Non tocchi DB_HOST e DB_CHARSET.
APP_URL — indirizzo completo del pannello con https://, senza slash finale e senza www. Deve coincidere con il dominio su cui attiva la licenza (passo 16), altrimenti la chiave verrà rifiutata.
TIMEZONE — il suo fuso orario (elenco — timedatectl list-timezones). Influisce solo su come il pannello mostra le date; sull'orario di esecuzione dei processi cron non influisce (lì vale il fuso del sistema).
SESSION_LIFETIME — dopo quanti secondi di inattività il pannello richiederà di accedere di nuovo (predefinito 8 ore). Es. 3600 = 1 ora, 86400 = un giorno.
Il blocco di logging degli errori (display_errors, log_errors, error_log) — lo lasci ai valori predefiniti.
Salvi il file (Ctrl+O, Enter, poi Ctrl+X) e riavvii PHP-FPM — altrimenti, a causa di OPcache, le modifiche non verranno applicate:
sudo systemctl restart php*-fpm
config.php è un file segreto (contiene la password del DB). Si trova nella radice del pannello, che è anche la radice web, ma è protetto: permessi 640 (impostati nel passo 10) e divieto esplicito nel .htaccess radice. Non lo pubblichi in repository pubblici e non lo invii al supporto con la password reale.
PHP viene eseguito con l'utente del web server, che non ha i permessi per i comandi di sistema. L'accesso viene concesso in modo mirato: sudo puntuale su utilità specifiche e lettura dei log tramite gruppi (senza sudo). La compromissione dello strato web non dà accesso root.
Negli esempi www-data è l'utente standard di Apache. Se ne usa un altro (in alcuni pannelli PHP gira con un utente separato), sostituiscalo ovunque. Per scoprirlo: ps -o user= -C php-fpm | sort -u.
1. Crei /etc/sudoers.d/monitor con sudo visudo -f /etc/sudoers.d/monitor e incolli (rimuova le righe dei moduli non utilizzati):
# UFW — stato e regole (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 — stato, ban e sban (banned restituisce i ban di tutti i jail con un solo comando;
# ban/unban servono ai pulsanti del pannello)
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 *
# Aggiornamenti di sicurezza (scheda «Aggiornamenti»). Solo lettura, ma proprio da root:
# la cache apt (~70 MB) è accessibile solo a root, un non-root la ricostruisce a ogni chiamata
# (4,2 s di CPU contro 0,01 s). Senza wildcard — esattamente questo unico comando, non installa nulla.
www-data ALL=(ALL) NOPASSWD: /usr/bin/apt list --upgradable
# IPset (mappa degli attacchi, 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 — ricerca eventi + lettura delle ultime righe del registro (percorso esatto)
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
# Porte aperte (i log del kernel/SSH/Falco si leggono SENZA sudo — tramite il gruppo
# systemd-journal, vedi p.2; NON serve e non è sicuro dare sudo a journalctl)
www-data ALL=(ALL) NOPASSWD: /usr/bin/ss -tuln, /usr/sbin/ss -tuln, /bin/ss -tuln
# PostgreSQL (solo se lo usa) — script read-only fisso,
# da creare secondo la FAQ «PostgreSQL non viene visualizzato»; senza di esso rimuova la riga
www-data ALL=(ALL) NOPASSWD: /usr/local/bin/monitor-pgstat
2. Accesso ai log e al registro di systemd. I moduli leggono /var/log/fail2ban.log, auth.log, ufw.log, apache2/*, aide direttamente (su Debian/Ubuntu questi log appartengono al gruppo adm). Gli eventi del kernel, SSH e Falco vengono presi da journald con il comando journalctlsenza sudo, tramite il gruppo systemd-journal. Aggiunga l'utente web a entrambi i gruppi e riavvii PHP-FPM:
sudo usermod -aG adm,systemd-journal www-data
sudo systemctl restart php*-fpm # obbligatorio, altrimenti i gruppi non vengono applicati
3. Se ClamAV o Suricata scrivono i log non nel gruppo adm (a volte root:root), conceda l'accesso tramite ACL:
4. Wrapper ModSecurity. Il log di audit del WAF (/var/log/apache2/modsec_audit.log) appartiene a root con permessi 640, e l'utente web non può leggerlo direttamente. La pagina ModSecurity ricava la modalità del motore, gli eventi e l'elenco delle regole attive tramite uno script read-only fisso, che è appunto autorizzato in sudoers dalla riga sopra:
Senza il file /etc/modsecurity/modsecurity.conf il WAF stesso non funziona: il pacchetto installa solo modsecurity.conf-recommended e il motore delle regole resta disattivato — per come attivarlo, veda FAQ → «Installazione di ModSecurity».
L'utente in tutte le righe di sudoers deve coincidere con l'utente del pool FPM: su Apache/Debian standard è www-data, in HestiaCP il pool del sito gira con il proprietario del sito (ad esempio admin) — verifichi con grep -E '^user' /etc/php/*/fpm/pool.d/monitor.example.com.conf.
5. Se davanti ad Apache c'è Nginx (HestiaCP, ISPmanager e altri pannelli — lì Nginx fa da proxy per PHP verso Apache e serve i contenuti statici da solo). Le directory di servizio sono protette dai file .htaccess, ma Nginx non li legge: qualsiasi file statico (.json, .txt, .log, .dat) verrà servito direttamente, bypassando Apache. All'esterno trapeleranno le cache del pannello e dei dati — per esempio tmp/modsec_cache.json con gli eventi WAF e gli IP degli attaccanti. Aggiunga il divieto nella configurazione del sito Nginx:
Il prefisso ^~ è obbligatorio: viene scelto prima della regola regex per i contenuti statici dentro location /, altrimenti il divieto non ha effetto.
In HestiaCP metta questo in un file separato /home/<user>/conf/web/<domain>/nginx.ssl.conf_deny (e nginx.conf_deny per HTTP) — la configurazione del sito include nginx.ssl.conf_* e non sovrascrive questi file durante la ricompilazione. Per applicare: sudo nginx -t && sudo systemctl reload nginx.
Verifica: curl -s -o /dev/null -w '%{http_code}\n' https://monitor.example.com/tmp/modsec_cache.json — deve essere 403. Se Apache funziona senza Nginx (ascolta lui stesso sulle porte 80/443), non serve aggiungere nulla — basta .htaccess.
Verifichi i percorsi dei binari con which (ad esempio which ufw cscli ausearch ss). Modifichi sudoers solo tramite visudo. L'elenco di tutti i database MySQL si abilita con un GRANT separato (FAQ → «Si vede un solo DB»).
14. Limitazione dell'accesso per IP
Limiti l'accesso al monitor per indirizzo IP — anche se l'URL venisse scoperto, la pagina di accesso non si aprirà. È possibile farlo a livello di web server (esempio per nginx qui sotto) o nel pannello stesso («Impostazioni» → «Limitazione dell'accesso per IP»). Se usa Apache, utilizzi la limitazione dal pannello.
Se il sito nginx è già configurato secondo il passo 10, non aggiunga un secondolocation / — inserisca le righe allow/deny nel blocco già esistente. Due location / identici in uno stesso server { } sono un errore di configurazione, nginx non si riavvierà.
# Nella configurazione di nginx (dentro server { }):
# Manteniamo aperto il percorso ACME di Let's Encrypt aggirando la limitazione per IP —
# affinché il rilascio e il rinnovo automatico di SSL (passo 15) non dipendano dal filtro IP.
location ^~ /.well-known/acme-challenge/ { allow all; }
location / {
allow 203.0.113.10; # ← inserisca il suo IP
allow 10.0.0.0/8; # rete locale (se necessario)
deny all;
try_files $uri $uri/ /index.php?$query_string;
}
# Ricaricare nginx:
sudo nginx -t && sudo systemctl reload nginx
15. Emettere il certificato SSL (HTTPS)
Il pannello funziona solo in HTTPS. La sessione di accesso usa un cookie protetto e WebAuthn (2FA) funziona solo in HTTPS. Con http:// non è possibile accedere.
Il certificato è gratuito (Let's Encrypt). Il DNS del dominio deve già puntare al server. Il comando dipende dal server web:
# Apache:
sudo certbot --apache -d monitor.example.com
# nginx — SOLO se usa effettivamente nginx. Su Apache NON eseguire:
# apt installerà nginx e occuperà la porta 80, in conflitto con Apache.
# sudo apt install python3-certbot-nginx
# sudo certbot --nginx -d monitor.example.com
# certbot configura da solo l'HTTPS nel file di configurazione e imposta il rinnovo automatico
Cosa chiederà certbot: e-mail → accettazione dei Terms (Y) → invio dell'e-mail a EFF (a sua discrezione). Poi emetterà da solo il certificato, scriverà <VirtualHost *:443>, imposterà il redirect http→https e il rinnovo automatico.
Il DNS deve puntare al server PRIMA di eseguire certbot (verifica della proprietà tramite la porta 80). Verifica: dig +short monitor.example.com → IP del server. Porte 80/443 aperte: sudo ufw allow 80,443/tcp.
Dopo l'emissione: https://monitor.example.com si apre con il lucchetto, http:// reindirizza a https:// (APP_URL in config.php è già impostato nel passo 12).
16. Accesso e configurazione iniziale
Apra https://monitor.example.com, acceda con admin / useradmin e completi la checklist:
Cambiare la password di admin — sezione «Utenti» nel menu.
Abilitare WebAuthn (2FA) — «Chiavi WebAuthn» → registri una chiave/passkey (richiede HTTPS). Ne registri subito due: in caso di perdita dell'unica chiave l'accesso con essa sarà impossibile. Maggiori dettagli.
Limitare l'accesso per IP — «Impostazioni» → «Limitazione dell'accesso per IP» (inserisca il suo IP prima di abilitarla, altrimenti si bloccherà l'accesso).
Inserire la licenza — attivi il codice ARCIVEO-… dall'area personale sul suo dominio e incolli la chiave in «Impostazioni» → «Licenza». Maggiori dettagli.
Configurare le notifiche — Telegram e/o Email in «Impostazioni». Maggiori dettagli.
Rimuovere l'installerpublic/start_db.php, se è rimasto (passo 11).
17. Strumenti di sicurezza (opzionale)
Il pannello è già in funzione. Gli strumenti si installano a piacere: installa ciò che Le serve e il pannello ne mostrerà subito lo stato. I comandi di installazione di ciascuno sono nel manuale (sezioni dedicate per strumento):
Questa è una demo di Arcivéo Security Monitor solo in lettura: qualsiasi modifica è disattivata. Lo installi sul Suo server per gestire dati di sicurezza reali.