Linux•29 agosto 2026• 174 visualizzazioni

Proteggere un VPS Linux nel 2026: guida all'hardening di Debian e Ubuntu

Proteggere un VPS Linux nel 2026: guida all'hardening di Debian e Ubuntu

Proteggere un VPS Linux non significa installare UFW e Fail2ban e considerare il lavoro concluso. Un server esposto su Internet va difeso in profondità: sistema mantenuto, accessi amministrativi nominativi, autenticazione SSH robusta, porte strettamente necessarie, servizi eseguiti con i privilegi minimi, log utilizzabili, backup ripristinabili e una procedura di reazione in caso di compromissione.

Questa guida propone una base realistica per Debian e Ubuntu. Ogni modifica delicata è accompagnata da una verifica e, quando serve, da una precauzione contro l'esclusione dall'accesso remoto.

Alla fine dovreste poter rispondere con precisione a queste domande:

  • quale versione del sistema è installata e fino a quando è mantenuta?
  • quali servizi sono in ascolto su IPv4 e IPv6?
  • chi può connettersi via SSH, con quale metodo e da quale rete?
  • quali regole del firewall vengono davvero applicate?
  • le correzioni di sicurezza sono installate e i loro errori vengono segnalati?
  • i log sopravvivono a un riavvio e vengono copiati fuori dal VPS?
  • qual è l'ultimo backup ripristinato con successo?
  • che cosa farete se una chiave, un account o l'intero server risultano compromessi?

Metodo, perimetro e limiti

Le raccomandazioni sono state riscontrate il 31 agosto 2026 con le pubblicazioni dell'ANSSI francese sull'hardening di GNU/Linux, la documentazione ufficiale di Debian, Ubuntu Server, OpenSSH, systemd, il kernel Linux, Docker e restic. La guida ANSSI fornisce un quadro di hardening; i comandi e i comportamenti soggetti a modifiche sono stati verificati nella documentazione attuale dei progetti.

Versioni, date di supporto e comportamento degli strumenti cambiano. Prima di applicare questa base in produzione, eseguitela su un VPS di prova e verificate i valori datati di questo articolo sulle pagine ufficiali collegate nel testo.

Questa guida riguarda un VPS Debian o Ubuntu amministrato direttamente. Non sostituisce l'hardening specifico di Nginx, Apache, PHP, Docker, un database o un'applicazione, né un'architettura ad alta disponibilità, né un audit normativo o un test di intrusione, né le regole proprie di Kubernetes, Proxmox, un router, un server di posta o un hypervisor, né le misure adottate dal provider sotto il livello di virtualizzazione.

La sicurezza è una proprietà dell'insieme: provider, rete, sistema, applicazione, identità, dati, backup ed esercizio.

Versioni considerate ad agosto 2026

Debian 13 «trixie» è l'attuale versione stabile. Debian indica supporto completo fino al 9 agosto 2028, poi una fase LTS fino al 30 giugno 2030, con un insieme ridotto di architetture durante tale fase. Debian 12 è ormai sostituita da Debian 13: il supporto completo è terminato l'11 luglio 2026 e resta coperta dalla fase LTS fino al 30 giugno 2028, limitatamente ad alcune architetture. Consultate le pagine ufficiali di Debian 13 e Debian 12.

Ubuntu 22.04, 24.04 e 26.04 sono versioni LTS ancora mantenute ad agosto 2026. Canonical pubblica le date esatte nel suo ciclo di vita di Ubuntu.

SistemaSituazione al 31 agosto 2026Decisione consigliata
Debian 13stabile attualescelta Debian consigliata per una nuova installazione
Debian 12LTS, supporto più limitato secondo l'architetturapianificare la migrazione a Debian 13
Ubuntu 26.04 LTSLTS attualescelta Ubuntu consigliata dopo la verifica della compatibilità applicativa
Ubuntu 24.04 LTSmanutenzione standard fino al 2029ottima scelta per uno stack già qualificato
Ubuntu 22.04 LTSmanutenzione standard fino al 2027prevedere il passaggio di versione
versione fuori supportonessuna correzione ordinariamigrare; un firewall non compensa un sistema non mantenuto

Non giudicate la sicurezza di un sistema solo da uname -r. Debian e Ubuntu riportano le correzioni senza adottare necessariamente il numero di versione upstream più recente. Verificate una CVE nel Debian Security Tracker o nel tracciamento delle CVE di Ubuntu, con la distribuzione e il pacchetto realmente installati.

Modello di minaccia: che cosa questa guida vuole ridurre

Un VPS pubblico è esposto in particolare a scansioni automatiche e tentativi di autenticazione, allo sfruttamento di un servizio o di una dipendenza non corretti, al furto di una chiave SSH, di un token API o di un segreto applicativo, a un errore di firewall, di permessi o di pubblicazione Docker, all'escalation di privilegi dopo la compromissione di un'applicazione, alla cancellazione o cifratura dei dati e dei backup raggiungibili, alla rimozione dei log da parte di un aggressore divenuto amministratore e a un errore umano durante un aggiornamento o una modifica di rete.

Questa base non rende il VPS invulnerabile. Punta a ridurre la probabilità di intrusione, limitare l'impatto di un primo accesso, migliorare il rilevamento e consentire una ricostruzione controllata.

Tre livelli di maturità

LivelloMisure minimeUtilizzo
Baseinventario, aggiornamenti, account nominativo, chiave SSH, root e password SSH disattivati, firewall, backup remotoqualsiasi VPS esposto
Produzioneaggiornamenti monitorati, AppArmor, Fail2ban secondo il rischio, log persistenti e remoti, avvisi esterni, ripristino testatosito o servizio in produzione
Rafforzatoamministrazione via VPN o bastion, chiave FIDO2 o MFA, filtraggio in uscita studiato, auditd/AIDE, repository di backup append-only, configurazione dichiarativadati sensibili o requisiti stringenti

Non tutte le misure vanno applicate alla cieca. Disattivare l'inoltro IP, per esempio, rompe un router, una VPN o certe reti di container. L'hardening professionale parte dal contesto.

Prima di ogni modifica: non restare chiusi fuori

Prima di toccare SSH o il firewall:

  1. verificate che la console di emergenza del provider funzioni;
  2. tenete aperta la sessione SSH corrente;
  3. aprite una seconda finestra per provare ogni modifica;
  4. annotate l'indirizzo e la porta SSH effettivi;
  5. create uno snapshot precauzionale se la piattaforma lo consente;
  6. salvate i file che modificate;
  7. disattivate il vecchio accesso solo dopo aver convalidato il nuovo.

Uno snapshot preso prima della modifica agevola un ritorno operativo, ma non sostituisce un backup fuori dal VPS. Può risultare incoerente se un database scrive in quel momento e di norma resta amministrato dallo stesso account del provider.

1. Inventariare il sistema prima di irrobustirlo

Iniziate con una raccolta in sola lettura:

cat /etc/os-release
uname -a
hostnamectl
systemd-detect-virt

ip -brief address
ip route
ip -6 route

sudo ss -lntup
sudo systemctl --type=service --state=running --no-pager
sudo systemctl list-unit-files --state=enabled --no-pager

df -hT
df -ih
findmnt
timedatectl

ss -lntup elenca i socket in ascolto. Per vedere le connessioni TCP stabilite, comprese quelle in uscita:

sudo ss -tpn state established

Create una scheda operativa con:

ElementoValore da registrare
distribuzione e versioneoutput di /etc/os-release
kernel e architetturaoutput di uname -a
IPv4 e IPv6 pubbliciindirizzi realmente instradati
interfaccia principalenome, indirizzo, gateway
porte atteseper esempio TCP 22, 80 e 443
servizi attesiSSH, Nginx, l'applicazione, un agente di monitoraggio
amministratori autorizzatiaccount nominativi, chiavi e provenienza di rete
dati criticifile, database, segreti e configurazioni
RPOperdita di dati massima accettabile
RTOdurata di interruzione massima accettabile

Ogni porta senza proprietario né giustificazione va esaminata prima di chiuderla. Un servizio può restare in ascolto solo su 127.0.0.1, su un indirizzo privato, su tutte le interfacce IPv4 con 0.0.0.0 oppure su IPv6 con ::. Controllate entrambe le famiglie.

2. Usare account nominativi e privilegi minimi

Evitate l'amministrazione quotidiana con un account condiviso o direttamente come root. Create un account per amministratore, così che log e revoche restino attribuibili.

Esempio con adminops:

sudo adduser adminops
sudo usermod -aG sudo adminops

sudo groupadd --force ssh-admins
sudo usermod -aG ssh-admins adminops

id adminops
getent group ssh-admins

Su Debian e Ubuntu, i membri del gruppo sudo possono ottenere privilegi secondo la politica locale. Ubuntu spiega l'utilità di sudo per la tracciabilità nella sua documentazione sulla gestione degli utenti.

Dalla postazione dell'amministratore, generate una chiave moderna protetta da una passphrase:

ssh-keygen -t ed25519 -a 100 -C "adminops@organizzazione"
ssh-copy-id -i ~/.ssh/id_ed25519.pub adminops@INDIRIZZO_DEL_VPS

Ed25519 è la scelta consigliata nella documentazione OpenSSH di Ubuntu. L'opzione -a aumenta il numero di cicli della funzione di derivazione che protegge la chiave privata con la sua passphrase; non modifica l'algoritmo della chiave. La nostra guida per configurare una chiave SSH su un VPS Linux illustra la procedura su Windows, macOS e Linux.

Per un livello rafforzato, una chiave FIDO2 di tipo ed25519-sk richiede la presenza di un autenticatore hardware compatibile:

ssh-keygen -t ed25519-sk -C "adminops-fido2@organizzazione"

Mantenete un metodo di recupero distinto, protetto e testato. Un'unica chiave hardware senza procedura di riserva trasforma la sua perdita in un incidente di disponibilità.

Provate in una nuova finestra:

ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519 adminops@INDIRIZZO_DEL_VPS
sudo -v
id

Non proseguite finché l'accesso con chiave e sudo non funzionano.

Controllare gli account esistenti

getent passwd
awk -F: '($3 == 0) {print $1}' /etc/passwd
sudo lastlog
sudo passwd -S root

Di norma deve esistere un solo UID 0. Bloccate o rimuovete gli account divenuti inutili, dopo aver verificato file, attività pianificate, processi e dipendenze applicative.

3. Irrobustire OpenSSH senza interrompere l'accesso

Ubuntu accetta la configurazione principale in /etc/ssh/sshd_config e i frammenti in /etc/ssh/sshd_config.d/. La sua configurazione include normalmente quella cartella all'inizio del file principale. OpenSSH conserva il primo valore incontrato per la maggior parte delle direttive; un file chiamato 00-hardening.conf è quindi più prevedibile di uno tardivo, che potrebbe finire dopo un frammento creato da cloud-init. Questo comportamento è documentato da Ubuntu e nel manuale sshd_config di Debian.

Verificate anzitutto l'inclusione:

grep -nE '^[[:space:]]*Include' /etc/ssh/sshd_config
sudo sshd -T | sort

Salvate la configurazione:

sudo cp -a /etc/ssh/sshd_config /etc/ssh/sshd_config.before-hardening
sudo install -d -m 755 /etc/ssh/sshd_config.d
sudoedit /etc/ssh/sshd_config.d/00-hardening.conf

Aggiungete:

PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no
AuthenticationMethods publickey

AllowGroups ssh-admins
MaxAuthTries 3
LoginGraceTime 30
X11Forwarding no
PermitTunnel no

Prima di ricaricare:

sudo sshd -t
sudo sshd -T | grep -E '^(port|permitrootlogin|pubkeyauthentication|passwordauthentication|kbdinteractiveauthentication|authenticationmethods|allowgroups|maxauthtries|logingracetime|x11forwarding|permittunnel) '

Se esistono blocchi Match, controllate anche la configurazione applicata all'account e all'indirizzo di amministrazione:

sudo sshd -T \
  -C user=adminops,host="$(hostname -f)",addr=198.51.100.10 |
  grep -E '^(permitrootlogin|passwordauthentication|kbdinteractiveauthentication|authenticationmethods|allowgroups) '

L'indirizzo 198.51.100.10 appartiene a un intervallo riservato alla documentazione. Sostituitelo con l'indirizzo reale da cui si collegherà l'amministratore.

Se sshd -t non restituisce nulla, la sintassi è valida. Ricaricate senza chiudere la sessione corrente:

sudo systemctl reload ssh
sudo systemctl status ssh --no-pager
sudo journalctl -u ssh -n 50 --no-pager

Provate subito una nuova connessione con la chiave, poi sudo -v. Chiudete la vecchia sessione solo dopo questa prova.

Che cosa deve restare condizionato

  • AllowTcpForwarding no e AllowAgentForwarding no sono utili se non servono tunnel né rimbalzi SSH, ma ne impediscono l'uso;
  • limitare SSH a un indirizzo IP o a una VPN riduce molto l'esposizione, ma richiede una via di riserva;
  • cambiare la porta 22 riduce soprattutto il rumore dei bot; non sostituisce né una chiave, né un firewall, né le correzioni;
  • una MFA TOTP può integrare la chiave. La documentazione Ubuntu descrive la combinazione AuthenticationMethods publickey,keyboard-interactive nella sua guida TOTP/HOTP.

4. Installare e monitorare gli aggiornamenti di sicurezza

Un comando con -y è comodo in laboratorio, ma un primo hardening in produzione deve permettere di leggere le modifiche proposte:

sudo apt update
apt list --upgradable
sudo apt-get -s upgrade
sudo apt upgrade

sudo apt autoremove --dry-run

Eseguite apt autoremove solo dopo aver controllato l'elenco. Un aggiornamento di distribuzione, un kernel, un driver o un pacchetto applicativo può richiedere un riavvio e un test dell'applicazione.

Attivare le correzioni automatiche

Su Ubuntu Server unattended-upgrades è installato e gli aggiornamenti di sicurezza sono di norma attivi in modo predefinito. Non datelo per scontato: verificatelo. La documentazione Ubuntu sugli aggiornamenti automatici indica file, timer, origini consentite e log.

Su Debian, installate e attivate il meccanismo in modo esplicito, secondo la vostra politica:

sudo apt install unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades

systemctl list-timers 'apt-daily*' --all
sudo unattended-upgrade --dry-run --debug
sudo journalctl -u apt-daily-upgrade.service -n 100 --no-pager

Controllate in particolare:

grep -RhsE 'APT::Periodic::(Update-Package-Lists|Unattended-Upgrade)' \
  /etc/apt/apt.conf.d/

sudo sed -n '/Allowed-Origins/,/};/p' \
  /etc/apt/apt.conf.d/50unattended-upgrades

Un'origine di terze parti non è coperta automaticamente. Verificate quali repository forniscono i pacchetti:

grep -RhsE '^[[:space:]]*(deb |Types:|URIs:|Suites:|Signed-By:)' \
  /etc/apt/sources.list /etc/apt/sources.list.d 2>/dev/null

apt-cache policy

Su Debian 13 le note di rilascio propongono anche questa ricerca dei pacchetti installati che non provengono da Debian:

apt list '?narrow(?installed, ?not(?origin(Debian)))'

Un repository aggiunto per un solo pacchetto amplia la catena di fiducia e può fornire aggiornamenti anche ad altri pacchetti. Usate i repository ufficiali o del produttore, una chiave dedicata tramite Signed-By, e rimuovete le fonti non più necessarie. Evitate di eseguire curl ... | sh senza scaricare, verificare e leggere lo script.

Riavvii e avvisi

Su Ubuntu un riavvio consigliato viene in genere segnalato così:

if [ -f /var/run/reboot-required ]; then
  cat /var/run/reboot-required
  cat /var/run/reboot-required.pkgs 2>/dev/null
fi

L'automazione senza monitoraggio è incompleta. Segnalate almeno il fallimento del timer o del servizio di aggiornamento, l'età dell'ultima esecuzione riuscita, un riavvio richiesto da troppo tempo, un pacchetto bloccato o un'origine non coperta e un sistema vicino alla fine del supporto.

5. Configurare il firewall: scegliere un solo gestore

Un firewall non è uno strumento di inventario: individuate prima i flussi legittimi. Integra l'hardening dei servizi ma non lo sostituisce, come ricorda il manuale di sicurezza di Debian.

Scegliete un approccio principale:

ContestoScelta consigliata
Ubuntu, regole sempliciUFW
Debian, politica nativa e avanzatanftables
Docker Enginestudiare prima catene e limiti di Docker
infrastruttura con firewall del providerapplicare anche il filtraggio di rete, senza rinunciare al firewall locale

UFW è lo strumento di firewall predefinito documentato da Ubuntu. nftables è il framework predefinito e consigliato da Debian. Non sovrapponete UFW, un ruleset nftables manuale e altri gestori senza capirne l'ordine.

Opzione A: UFW su Ubuntu o per un'esigenza semplice

Rilevate la porta SSH effettiva:

sudo sshd -T | awk '$1 == "port" {print $2; exit}'

L'esempio seguente presuppone SSH sulla 22 e un server web. Adattate le porte prima dell'attivazione:

sudo apt install ufw

sudo ufw default deny incoming
sudo ufw default allow outgoing

sudo ufw allow 22/tcp comment 'SSH administration'
sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'

sudo ufw show added
sudo ufw enable
sudo ufw status verbose
sudo ufw status numbered

Tenete la sessione aperta e provate una nuova connessione SSH.

Se l'amministrazione proviene da un IPv4 fisso, create prima una regola restrittiva:

sudo ufw allow from 198.51.100.10 to any port 22 proto tcp \
  comment 'SSH dalla postazione di amministrazione'
sudo ufw status numbered

Dopo la prova da quell'indirizzo, eliminate la regola SSH aperta a tutti usando il suo numero:

sudo ufw delete NUMERO_DELLA_REGOLA

Ripetete la logica per IPv6 se l'amministratore lo usa. Non disattivate IPv6 solo per non scriverne le regole: un record AAAA o un'interfaccia IPv6 dimenticati possono creare un'esposizione diversa da quella provata in IPv4.

Il nostro tutorial per configurare UFW su un VPS Linux approfondisce la gestione delle regole.

Opzione B: nftables su un VPS Debian senza Docker

L'esempio seguente si adatta a un VPS web nuovo, non router, senza Docker e con SSH sulla 22. Sostituisce l'intero ruleset: non usatelo se un altro software gestisce già netfilter.

Salvate anzitutto lo stato attuale in un file che inizi esso stesso con un azzeramento del ruleset:

sudo sh -c '{
  printf "%s\n" "flush ruleset"
  nft list ruleset
} > /root/nftables.before-hardening.nft'
sudoedit /etc/nftables.conf

Contenuto:

#!/usr/sbin/nft -f

flush ruleset

define ssh_port = 22

table inet filter {
    chain input {
        type filter hook input priority filter; policy drop;

        iifname "lo" accept
        ct state invalid drop
        ct state established,related accept

        ip protocol icmp accept
        ip6 nexthdr ipv6-icmp accept

        tcp dport $ssh_port ct state new accept comment "SSH"
        tcp dport { 80, 443 } ct state new accept comment "Web"

        counter drop
    }

    chain forward {
        type filter hook forward priority filter; policy drop;
    }

    chain output {
        type filter hook output priority filter; policy accept;
    }
}

Lasciare passare l'ICMP e l'ICMPv6 utili evita di compromettere la scoperta dei vicini IPv6, la diagnostica e la scoperta della MTU. Non ricopiate una regola che blocca tutto l'ICMP senza comprendere queste funzioni.

Verificate la sintassi prima di applicare:

sudo nft -c -f /etc/nftables.conf
sudo nft -f /etc/nftables.conf
sudo nft list ruleset
sudo systemctl enable nftables

Provate una nuova sessione SSH e il servizio web. Per tornare indietro dalla console:

sudo nft -f /root/nftables.before-hardening.nft

Anche il file di ripristino contiene flush ruleset: caricarlo sostituisce quindi la politica corrente invece di aggiungere regole duplicate. Eseguite questo ritorno dalla console di emergenza se SSH è già interrotto.

Se il VPS instrada traffico, ospita una VPN, usa più interfacce o esegue Docker, progettate le catene forward e il NAT per quell'architettura. Una politica drop copiata senza adattamenti può interrompere il servizio.

Aggiungere un firewall di rete

Quando il provider offre un firewall a monte, usatelo come seconda barriera: SSH solo dagli indirizzi di amministrazione o dalla VPN, HTTP/HTTPS da Internet se il server è pubblico, database e pannelli di amministrazione mai aperti a tutti, regole IPv4 e IPv6 coerenti e console di emergenza testata.

Il filtraggio a monte può bloccare traffico prima che consumi risorse del VPS. Non vede però necessariamente le reti interne dei container e non protegge un servizio raggiungibile dal VPS stesso.

6. Caso critico: Docker e le regole di UFW o nftables

Docker modifica le regole di filtraggio e di NAT per pubblicare le porte dei container. La sua documentazione avverte che il traffico verso una porta pubblicata viene deviato prima delle catene INPUT e OUTPUT usate da UFW; una porta Docker può quindi restare raggiungibile nonostante una politica UFW che sembra negarla. Consultate la pagina ufficiale Packet filtering and firewalls.

Inventariate le pubblicazioni:

sudo docker ps --format 'table {{.Names}}\t{{.Ports}}'
sudo ss -lntup
sudo iptables -S DOCKER-USER 2>/dev/null

La differenza essenziale:

# Esposto su tutte le interfacce del VPS
ports:
  - "8080:80"

# Raggiungibile solo dal VPS, per esempio tramite Nginx
ports:
  - "127.0.0.1:8080:80"

Per un database, Redis, un pannello o un'applicazione dietro un reverse proxy, legate la porta a 127.0.0.1 o a un indirizzo privato quando l'accesso pubblico non serve.

Docker consiglia la catena DOCKER-USER per le politiche che devono precedere le proprie regole iptables. Sconsiglia di disattivare la sua gestione di iptables/ip6tables, perché ciò di norma compromette la rete dei container. La documentazione di installazione precisa inoltre che Docker Engine supporta iptables-nft e iptables-legacy, ma non un ruleset creato direttamente con nft come meccanismo di filtraggio di Docker. Non mescolate quindi il modello nftables precedente con Docker senza un'architettura testata. La nostra guida per installare Docker su un VPS Linux copre installazione e configurazione del demone.

Dopo ogni distribuzione di container, ripetete la scansione da una rete esterna. Il file Compose descrive l'intenzione; la rete osservabile descrive la realtà.

7. Ridurre servizi, pacchetti e privilegi

Elencate le unità attive e le porte:

sudo systemctl --type=service --state=running --no-pager
sudo systemctl list-unit-files --state=enabled --no-pager
sudo ss -lntup

Per ogni servizio chiedetevi: è indispensabile? deve avviarsi automaticamente? deve restare in ascolto su un'interfaccia pubblica? funziona con un account dedicato non privilegiato? di quali file, capability Linux e reti ha bisogno? il suo log e il suo stato sono sorvegliati?

Fermare e disattivare è più prudente che rimuovere subito:

sudo systemctl disable --now NOME_DEL_SERVIZIO
sudo systemctl status NOME_DEL_SERVIZIO --no-pager

Dopo un periodo di osservazione e una verifica delle dipendenze, rimuovete il pacchetto se la sua assenza è confermata.

Non eseguire l'applicazione come root

Un servizio applicativo deve usare un account di sistema dedicato, directory limitate e nessuna shell interattiva se non è richiesta. I database devono restare in ascolto su loopback o su un indirizzo privato, salvo esigenza esplicita e filtrata.

Con systemd, analizzate anzitutto il livello di isolamento:

sudo systemd-analyze security --no-pager NOME.service
sudo systemctl cat NOME.service

Il punteggio di systemd-analyze security misura soltanto le protezioni systemd note allo strumento. Un punteggio alto non dimostra una vulnerabilità e uno basso non convalida il codice dell'applicazione. Il manuale di systemd-analyze insiste su questo limite.

Per un'applicazione interna non JIT che scrive solo in due directory, un drop-in può assomigliare a questo:

[Service]
User=myapp
Group=myapp
NoNewPrivileges=yes
PrivateTmp=yes
PrivateDevices=yes
ProtectSystem=strict
ProtectHome=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectControlGroups=yes
LockPersonality=yes
CapabilityBoundingSet=
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
ReadWritePaths=/var/lib/myapp /var/log/myapp

Createlo con:

sudo systemctl edit NOME.service
sudo systemd-analyze verify NOME.service
sudo systemctl daemon-reload
sudo systemctl restart NOME.service
sudo systemctl status NOME.service --no-pager
sudo journalctl -u NOME.service -n 100 --no-pager

Applicate le opzioni una alla volta. MemoryDenyWriteExecute=yes, ProtectHome=yes, la restrizione delle famiglie di indirizzi o la rimozione delle capability possono compromettere un runtime JIT, un binario che carica moduli o un servizio che si aspetta un accesso particolare. Il riferimento completo è systemd.exec.

8. Mantenere e controllare AppArmor

AppArmor applica un controllo di accesso obbligatorio per programma. Su Ubuntu è installato e caricato in modo predefinito. Verificatene lo stato:

sudo aa-status
systemctl status apparmor --no-pager

La documentazione AppArmor di Ubuntu distingue in particolare la modalità enforce, che blocca le operazioni vietate e le registra, la modalità complain, utile per apprendere un profilo senza bloccare, e i processi confinati o privi di profilo.

Su Debian AppArmor è disponibile, ma la sua attivazione e la presenza di profili dipendono dall'immagine e dal kernel:

sudo apt install apparmor apparmor-utils
sudo systemctl enable --now apparmor
sudo aa-status

Non disattivate AppArmor per «riparare» un'applicazione. Analizzate i dinieghi:

sudo journalctl -k -g 'apparmor="DENIED"' --since today

Create o adattate un profilo in preproduzione, portate temporaneamente il profilo interessato in modalità di apprendimento se necessario, quindi tornate a enforce. Un profilo troppo permissivo o lasciato in complain non offre la protezione attesa.

9. Aggiungere Fail2ban quando il servizio lo giustifica

Fail2ban legge gli eventi di errore e aggiunge temporaneamente una regola di blocco. Riduce il rumore e alcuni attacchi ripetuti, ma non corregge né una password debole, né una falla software, né una credenziale rubata.

Installatelo:

sudo apt update
sudo apt install fail2ban
sudoedit /etc/fail2ban/jail.d/sshd.local

Configurazione per un sistema che usa il journal di systemd:

[sshd]
enabled = true
backend = systemd
maxretry = 5
findtime = 10m
bantime = 1h

Il backend systemd legge il journal e non deve ricevere un logpath. I parametri e le unità di tempo sono descritti nel manuale Debian jail.conf.

Convalidate prima dell'avvio:

sudo fail2ban-client -t
sudo systemctl enable --now fail2ban
sudo fail2ban-client ping
sudo fail2ban-client status
sudo fail2ban-client status sshd
sudo journalctl -u fail2ban -n 100 --no-pager

Una lista di eccezioni è ragionevole solo per un indirizzo davvero stabile e sotto controllo. Un intervallo troppo ampio aggira proprio il controllo appena aggiunto. Con Docker, verificate inoltre che l'azione scelta agisca nella catena effettivamente attraversata dal traffico.

La nostra guida per installare e configurare Fail2ban tratta i log recenti di Debian, la jail SSH, lo sblocco e i test dei filtri.

10. Irrobustire con prudenza alcuni parametri del kernel

I sysctl non vanno copiati a centinaia da una lista generica. Il kernel Linux avverte che alcune impostazioni possono rendere inutilizzabile un sistema e raccomanda di comprendere ogni modifica.

Iniziate rilevando i valori:

sysctl kernel.dmesg_restrict
sysctl kernel.kptr_restrict
sysctl fs.protected_hardlinks
sysctl fs.protected_symlinks
sysctl fs.protected_fifos
sysctl fs.protected_regular
sysctl net.ipv4.conf.all.accept_redirects
sysctl net.ipv6.conf.all.accept_redirects

Per un VPS host classico, non router, si può valutare questo frammento conservativo:

sudoedit /etc/sysctl.d/60-local-hardening.conf
# Limitare l'esposizione di informazioni del kernel
kernel.dmesg_restrict = 1
kernel.kptr_restrict = 2

# Irrobustire gli oggetti creati nelle directory temporanee condivise
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
fs.protected_fifos = 2
fs.protected_regular = 2

# Un VPS host di norma non deve accettare le redirezioni ICMP
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0

# Di norma non deve nemmeno inviare redirezioni IPv4
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0

Caricate e verificate:

sudo sysctl -p /etc/sysctl.d/60-local-hardening.conf
sudo sysctl --system

La documentazione del kernel descrive i sysctl IP e i sysctl dei file.

Questa guida non impone deliberatamente net.ipv4.ip_forward=0, perché Docker, WireGuard o un router possono dipenderne; né rp_filter=1, perché l'instradamento asimmetrico, alcune VPN e il policy routing richiedono uno studio; né la disattivazione di IPv6; né la disattivazione irreversibile dei moduli o di kexec; né un'impostazione BPF o io_uring senza un inventario di applicazioni e agenti.

11. Rendere i log persistenti e utilizzabili

I log locali servono alla diagnosi, ma un aggressore divenuto root può modificarli o cancellarli. La strategia deve unire conservazione locale limitata, orologio affidabile, invio remoto e avvisi.

Persistenza e limite di spazio di journald

Create un frammento:

sudo install -d -m 755 /etc/systemd/journald.conf.d
sudoedit /etc/systemd/journald.conf.d/60-persistent.conf

Esempio da adattare alla dimensione del disco:

[Journal]
Storage=persistent
Compress=yes
SystemMaxUse=500M
SystemKeepFree=1G
MaxRetentionSec=30day

Poi:

sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald
sudo journalctl --flush

sudo journalctl --disk-usage
sudo journalctl --verify
sudo journalctl -p warning..alert --since today

SystemMaxUse, SystemKeepFree e la persistenza sono documentati in journald.conf. Un limite fisso deve lasciare spazio sufficiente al sistema e all'applicazione.

Centralizzare le tracce fuori dal VPS

Per un server di produzione, inoltrate almeno le autenticazioni SSH e sudo, gli eventi del kernel e del firewall, i cambi di identità, i log del reverse proxy e dell'applicazione, oltre agli esiti di aggiornamenti automatici, backup e agenti di sicurezza.

Due soluzioni diffuse sono systemd-journal-upload verso systemd-journal-remote, oppure rsyslog verso un collector. systemd-journal-upload invia le voci del journal; il modulo omfwd di rsyslog supporta UDP, TCP o TLS e raccomanda TCP con TLS per un'installazione moderna.

Un'implementazione seria deve autenticare il collector tramite certificato, verificarne nome e autorità di certificazione, usare TLS anziché syslog in chiaro su UDP in Internet, mettere in coda gli eventi durante un'interruzione, impedire al VPS di origine di cancellare gli archivi del collector, avvisare se il flusso o l'heartbeat si interrompono e proteggere i log da accessi non autorizzati, poiché contengono spesso dati sensibili.

Sincronizzare l'ora

timedatectl status
timedatectl timesync-status 2>/dev/null || true
systemctl status systemd-timesyncd chrony --no-pager 2>/dev/null || true

Usate un solo meccanismo di sincronizzazione, configurato correttamente. Uno scostamento orario complica la correlazione degli eventi, i certificati, i token e talvolta l'autenticazione.

12. Verificare modifiche e integrità

Linux Audit

auditd raccoglie eventi prodotti dal sottosistema di audit del kernel. Debian fornisce gli strumenti per archiviare e consultare tali registrazioni, documentati nei manuali auditd di Debian 13.

sudo apt install auditd audispd-plugins
sudo systemctl enable --now auditd
sudoedit /etc/audit/rules.d/50-local.rules

Base minima:

-w /etc/passwd -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/gshadow -p wa -k identity
-w /etc/sudoers -p wa -k privilege
-w /etc/sudoers.d -p wa -k privilege
-w /etc/ssh/sshd_config -p wa -k ssh_config
-w /etc/ssh/sshd_config.d -p wa -k ssh_config

Caricate e verificate:

sudo augenrules --check
sudo augenrules --load
sudo auditctl -s
sudo auditctl -l

sudo ausearch -k ssh_config -ts today -i
sudo aureport --auth --summary

Adattate le regole ai file davvero critici. Un audit eccessivo riempie il disco e rende il segnale inutilizzabile. Configurate rotazione, avviso di saturazione e inoltro remoto.

Verifica dei pacchetti e AIDE

Per rilevare i file di pacchetto modificati:

sudo dpkg -V

Un output non indica automaticamente una compromissione: alcuni file di configurazione vengono modificati legittimamente. Confrontateli con la vostra gestione della configurazione e con le modifiche approvate.

AIDE costruisce una base di integrità:

sudo apt install aide
sudo aideinit
sudo aide --check

Inizializzate la base solo su un server ritenuto pulito e dopo l'hardening. Leggete l'output di aideinit per confermare quale base è attiva sulla vostra distribuzione. Copiate la base di riferimento, o almeno la sua impronta, in una posizione protetta fuori dal VPS; altrimenti un aggressore con root può modificare sia i file sia il loro riferimento.

Né auditd né AIDE sono un EDR completo. Aggiungono tracce e controlli di integrità, a condizione che i risultati vengano letti e protetti.

13. Proteggere file, chiavi e segreti

Cercate le anomalie senza correggerle automaticamente:

sudo find /etc -xdev -type f -perm -0002 -ls
sudo find / -xdev \( -perm -4000 -o -perm -2000 \) -type f -print

sudo find /root /home -path '*/.ssh/authorized_keys' -type f \
  -exec stat -c '%a %U:%G %n' {} \;

sudo find /etc/cron.d /etc/cron.daily /etc/cron.hourly \
  /etc/cron.monthly /etc/cron.weekly /var/spool/cron \
  -maxdepth 2 -type f -ls 2>/dev/null

systemctl list-timers --all --no-pager

Un permesso insolito non è necessariamente malevolo. Individuate pacchetto, proprietario e scopo prima di modificare qualcosa.

Regole di base: nessun segreto in Git, in un'immagine Docker, in un comando visibile nella cronologia o in un URL; file di segreti leggibili solo dall'account che ne ha bisogno; token distinti per servizio e per ambiente; privilegi minimi su DNS, backup, database e API; rotazione pianificata e immediata dopo un'esposizione; rimozione delle vecchie authorized_keys; chiavi private mai copiate in una documentazione o in un ticket.

Per i servizi systemd moderni, valutate le credenziali di systemd anziché variabili d'ambiente globali. Una variabile può restare visibile a processi privilegiati e finire in un output diagnostico.

14. Cifrare i servizi pubblici con TLS

HTTPS protegge il traffico tra client e server; non corregge un'applicazione vulnerabile. Per un sito Nginx o Apache, il record DNS A e, se esiste, il record AAAA devono puntare al server giusto; le porte TCP 80 e 443 devono essere aperte secondo la sfida ACME; il rinnovo deve essere automatizzato e testato; un avviso deve precedere la scadenza; e HSTS va attivato solo dopo aver convalidato stabilmente HTTPS sui nomi interessati.

Seguite la nostra guida per installare un certificato SSL Let's Encrypt con Certbot, poi verificate:

sudo certbot certificates
sudo certbot renew --dry-run
systemctl list-timers '*certbot*' --all

openssl s_client \
  -connect example.com:443 \
  -servername example.com \
  -verify_return_error </dev/null

Una redirezione da HTTP a HTTPS è utile per il browser, ma tenete la porta 80 raggiungibile se il rinnovo tramite HTTP-01 ne dipende. DNS-01 è necessario per un wildcard e può evitare quella dipendenza, al prezzo di un segreto API DNS da proteggere.

15. Predisporre un backup davvero ripristinabile

L'ANSSI ricorda che i backup sono indispensabili di fronte agli incidenti e raccomanda in particolare una politica 3-2-1: tre copie, su due supporti diversi, di cui una offline. Chiede inoltre di formalizzare la perdita di dati massima ammissibile e la durata di interruzione massima ammissibile, nel suo repertorio di misure e nella guida sulla salvaguardia dei sistemi informativi.

Distinguere archivio, snapshot e backup

MeccanismoUtile perLimite
archivio tar sullo stesso discocopia puntuale di filesparisce con il VPS o con il disco
snapshot del VPSritorno rapido prima di una modificastesso account del provider, coerenza applicativa da verificare
replica o sincronizzazionedisponibilità o copia rapidareplica anche cancellazioni e corruzioni
backup versionato fuori sederipresa dopo guasto, errore o compromissioneva cifrato, monitorato e ripristinato
copia offline o immutabileresistenza a cancellazione e ransomwarerichiede politica di conservazione e test

I nostri VPS offrono in opzione backup delocalizzati automatici: una copia completa del VPS, eseguita ogni giorno, archiviata in un datacenter europeo distinto, con ripristino in un clic e uno storico rotativo di cui scegliete la profondità. Dieci backup simultanei corrispondono quindi a dieci giorni di storico, e ogni nuova copia sostituisce la più vecchia. Questa opzione copre già la copia fuori dal server, la frequenza quotidiana e il ripristino rapido.

Non esime tuttavia dalle due precauzioni seguenti. Primo, la copia completa di un VPS in funzione non è necessariamente coerente per un database: continuate a produrre un dump subito prima, come descritto più avanti. Secondo, resta gestita dallo stesso account del provider del server; per lo scenario di compromissione, conservate anche una copia in un dominio amministrativo distinto, in append-only o offline a seconda del rischio. E in ogni caso provate il ripristino: uno storico di dieci giorni vale qualcosa solo dopo che avete verificato che un ripristino riavvia davvero l'applicazione.

Definire l'obiettivo prima dello strumento

DatoRPORTOConservazione
configurazione di sistema24 h4 h30 giorni
file dei clienti1 h2 h30 giorni e 12 mesi
database transazionale15 min1 hjournal e backup quotidiani
log di sicurezzasecondo la politicaconsultazione immediata90 giorni o requisito applicabile

Questi valori determinano frequenza e tecnologia. Un backup quotidiano non soddisfa un RPO di quindici minuti.

Esempio con restic verso una destinazione remota

restic cifra e deduplica i backup. Supporta più backend; l'esempio usa SFTP. Installate il pacchetto della distribuzione:

sudo apt update
sudo apt install restic

sudo install -d -m 700 /root/.config/restic
sudo touch /root/.config/restic/password
sudo chown root:root /root/.config/restic/password
sudo chmod 600 /root/.config/restic/password
sudoedit /root/.config/restic/password

sudo touch /etc/restic-vps.env
sudo chown root:root /etc/restic-vps.env
sudo chmod 600 /etc/restic-vps.env
sudoedit /etc/restic-vps.env

Contenuto di /etc/restic-vps.env:

RESTIC_REPOSITORY=sftp:backup@backup.example:/srv/restic/vps-01
RESTIC_PASSWORD_FILE=/root/.config/restic/password

La passphrase deve essere lunga, casuale, conservata in un gestore distinto e testata. Senza di essa il repository cifrato non è ripristinabile.

Inizializzate manualmente da una sessione root, dopo aver convalidato l'impronta SSH del server di backup:

sudo -i
set -a
. /etc/restic-vps.env
set +a

restic init
restic backup /etc /srv /var/www /var/backups/databases
restic snapshots
restic check
exit

Il backup della directory dati di un database attivo non è necessariamente coerente. Producete un dump oppure usate il metodo fisico e i journal consigliati dal motore.

Per MariaDB, quando è configurata l'autenticazione locale di root tramite socket:

sudo install -d -m 700 /var/backups/databases
sudo sh -c 'mariadb-dump --single-transaction --routines --events --triggers --all-databases | gzip -9 > "/var/backups/databases/mariadb-$(date -u +%F-%H%M%S).sql.gz"'

Per PostgreSQL:

sudo install -d -m 700 -o postgres -g postgres \
  /var/backups/databases/postgresql
sudo -u postgres sh -c 'pg_dumpall | gzip -9 > "/var/backups/databases/postgresql/all-$(date -u +%F-%H%M%S).sql.gz"'

Provate il ripristino su un database isolato. --single-transaction migliora la coerenza delle tabelle transazionali MariaDB/InnoDB, ma non è una garanzia universale per ogni motore e ogni operazione.

Automatizzare con un timer systemd

Create /etc/systemd/system/restic-backup.service:

[Unit]
Description=Backup restic del VPS
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
EnvironmentFile=/etc/restic-vps.env
ExecStart=/usr/bin/restic backup /etc /srv /var/www /var/backups/databases
Nice=10
IOSchedulingClass=best-effort
IOSchedulingPriority=7

Create /etc/systemd/system/restic-backup.timer:

[Unit]
Description=Backup restic quotidiano del VPS

[Timer]
OnCalendar=*-*-* 02:30:00
RandomizedDelaySec=30m
Persistent=true

[Install]
WantedBy=timers.target

Attivate e verificate:

sudo systemd-analyze verify \
  /etc/systemd/system/restic-backup.service \
  /etc/systemd/system/restic-backup.timer

sudo systemctl daemon-reload
sudo systemctl enable --now restic-backup.timer
sudo systemctl start restic-backup.service

sudo systemctl status restic-backup.service --no-pager
sudo journalctl -u restic-backup.service -n 100 --no-pager
systemctl list-timers restic-backup.timer --all

Il dump del database deve essere prodotto subito prima di questo servizio, da un'unità dedicata ordinata con Requires e After, oppure da un orchestratore di backup. Un vecchio dump salvato ogni notte dà solo l'illusione di essere aggiornato.

Separare scrittura e cancellazione

Un VPS compromesso non dovrebbe poter cancellare i vecchi backup. Quando il backend lo consente, date al VPS un accesso append-only. Eseguite la conservazione da una macchina di amministrazione distinta che possieda i diritti di cancellazione:

restic forget \
  --keep-daily 7 \
  --keep-weekly 4 \
  --keep-monthly 12 \
  --prune

restic check --read-data-subset=5%

La documentazione di restic su forget e prune precisa che prune può essere lungo, blocca il repository e va pianificato. Raccomanda inoltre una verifica dopo la pulizia. Per un repository append-only, studiate i rischi specifici delle politiche di conservazione e separate davvero il client di manutenzione.

Provare un ripristino

Almeno ogni trimestre, su una macchina isolata:

sudo -i
set -a
. /etc/restic-vps.env
set +a

restic snapshots
install -d -m 700 /mnt/restic-restore-test
restic restore latest --target /mnt/restic-restore-test
exit

Verificate poi presenza e permessi dei file, la decifratura con le credenziali documentate, il ripristino dei database in un motore di prova, l'avvio dell'applicazione, la coerenza funzionale, il tempo reale di ripristino rispetto all'RTO e la procedura di ricostruzione di un VPS vuoto.

Un backup «riuscito» significa che il processo è terminato. Un backup affidabile significa che è stato dimostrato un ripristino utile.

16. Monitorare il VPS dall'esterno

Il monitoraggio locale non può segnalare un VPS spento, isolato o completamente compromesso. Usate un servizio esterno per la disponibilità e un canale di avviso distinto dal server.

ControlloSegnale da sorvegliare
disponibilitàTCP/HTTPS, contenuto atteso, latenza
TLSdata di scadenza, catena e nome
sistemaCPU, memoria, swap, carico
archiviazionespazio, inode, crescita dei log
serviziunità systemd fallite, riavvii
retenuove porte, connessioni insolite
sicurezzaerrori SSH e sudo, dinieghi AppArmor, auditd
correzioniultima esecuzione, errore, riavvio richiesto
backupetà dell'ultimo snapshot, dimensione anomala, errore
orascostamento o perdita di sincronizzazione

Comandi di controllo quotidiano:

systemctl --failed --no-pager
df -hT
df -ih
free -h
uptime

sudo ss -lntup
sudo journalctl -p warning..alert --since '-24 hours'
sudo journalctl -u ssh --since '-24 hours'
sudo fail2ban-client status sshd 2>/dev/null || true
sudo aa-status 2>/dev/null || true

Le soglie devono rispecchiare il servizio. Un avviso all'80 % del disco è utile solo se arriva abbastanza presto rispetto alla velocità di crescita. Segnalate anche l'assenza di dati: un agente silenzioso può essersi guastato.

L'ANSSI definisce la supervisione di sicurezza come l'insieme dei mezzi che permettono di rilevare, qualificare e scegliere una reazione adeguata; la sua guida Gestire un progetto di supervisione colloca gli strumenti dentro questo processo.

17. Verificare il risultato invece di fidarsi della configurazione

Controlli locali

# Sistema e correzioni
cat /etc/os-release
apt list --upgradable
systemctl list-timers 'apt-daily*' --all

# Configurazione SSH effettiva
sudo sshd -t
sudo sshd -T | grep -E '^(port|permitrootlogin|passwordauthentication|kbdinteractiveauthentication|authenticationmethods|allowgroups) '

# Esposizione di rete
sudo ss -lntup
sudo ufw status verbose 2>/dev/null || true
sudo nft list ruleset 2>/dev/null || true

# Controlli di sicurezza
sudo aa-status 2>/dev/null || true
sudo fail2ban-client status 2>/dev/null || true
sudo auditctl -s 2>/dev/null || true

# Journal e servizi
sudo journalctl --verify
systemctl --failed --no-pager

# Backup
sudo systemctl status restic-backup.service --no-pager

Scansione esterna

Da una postazione che amministrate e soltanto contro il vostro VPS:

sudo nmap -Pn -sS -sV -p- INDIRIZZO_IPV4_DEL_VPS
sudo nmap -6 -Pn -sT -sV -p- INDIRIZZO_IPV6_DEL_VPS

Confrontate il risultato con l'elenco delle porte autorizzate. Il riferimento delle opzioni si trova nel manuale di Nmap.

Eseguite la scansione dopo il primo hardening, dopo l'installazione di Docker o di un pannello, dopo una modifica del firewall, dopo una migrazione di rete e regolarmente da Internet.

Tabella di collaudo

ProvaRisultato attesoProva da conservare
accesso SSH con chiaveriuscita con account nominativolog SSH anonimizzato
accesso SSH come rootrifiutoestratto della prova
password SSHrifiutocomando e risultato
sudoriuscita per l'amministratore autorizzatolog di sudo
sintassi SSHsshd -t senza erroridata e versione
porte esternesolo i flussi approvatirapporto Nmap per IPv4 e IPv6
aggiornamento automaticoprova a vuoto valida, timer attivolog
firewallpolitica e regole conformiesportazione UFW o nftables
AppArmorattivo, profili critici in enforceoutput di aa-status
backupesecuzione senza errorilog e snapshot restic
ripristinoapplicazione e dati leggibiliverbale datato
log remotievento ricevuto e con marca temporalericerca lato collector
console di emergenzaconnessione possibiledata dell'ultima prova

18. Che cosa fare in caso di sospetta compromissione

Sintomi come un picco di CPU, un processo sconosciuto o una connessione in uscita insolita giustificano una valutazione, ma da soli non provano un'intrusione. Al contrario, l'assenza di sintomi non prova l'integrità.

Prime azioni, da adattare alla gravità:

  1. usate una postazione fidata e aprite un registro dell'incidente;
  2. isolate il VPS con il firewall di rete quando ciò non distrugge le prove;
  3. evitate di riavviare o «ripulire» prima della raccolta se è prevista un'indagine;
  4. preservate i log remoti, lo stato dei processi, le connessioni, le attività e uno snapshot forense;
  5. revocate da un sistema sano le chiavi SSH, le password, i token, i certificati e gli accessi al provider esposti;
  6. proteggete i backup precedenti e impeditene la cancellazione;
  7. determinate il perimetro: altri VPS, repository Git, CI/CD, DNS, account e database;
  8. ricostruite da un'immagine e da una configurazione ritenute sane;
  9. ripristinate soltanto dati verificati;
  10. correggete la causa prima di tornare online e rafforzate la sorveglianza.

Uno snapshot del server sospetto serve a preservare o analizzare uno stato; non diventa automaticamente un punto di ripristino sano. Il CERT-FR raccomanda in particolare di conservare le prove, limitare la diffusione, mettere al sicuro i backup e sostituire un sistema compromesso con uno nuovo o reinstallato. Consultate I riflessi corretti in caso di intrusione.

Il NIST SP 800-61 revisione 3, pubblicato ad aprile 2025, integra la risposta agli incidenti nell'intera gestione del rischio: preparazione, rilevamento, risposta e ripristino non iniziano il giorno dell'attacco.

Calendario operativo consigliato

FrequenzaAzioni
continuadisponibilità esterna, metriche, avvisi di sicurezza, errori di backup
quotidianaaggiornamenti di sicurezza, backup, verifica dei servizi falliti
settimanalerevisione di avvisi, porte, spazio, account e modifiche
mensilerevisione di repository, pacchetti, chiavi, regole del firewall e versioni
trimestraleripristino completo testato, console di emergenza, esercitazione di incidente
semestralerevisione di architettura, privilegi, RPO/RTO ed esposizione esterna
a ogni modificabackup, convalida, scansione esterna, documentazione e piano di ritorno

Con più VPS, gestite questa base con Ansible, un repository versionato e una CI che verifichi la sintassi. I segreti devono restare fuori dal repository. Una configurazione dichiarativa non sostituisce le prove sull'ambiente reale, ma rende scostamenti e ritorni più controllabili.

Errori frequenti

  1. Chiudere SSH prima di aver provato la chiave. Tenete una sessione aperta e la console del provider.
  2. Aprire UFW per la porta 22 mentre SSH è in ascolto altrove. Verificate sshd -T.
  3. Dare a un frammento SSH un nome che lo carica tardi. Di solito vince il primo valore; controllate la configurazione effettiva.
  4. Dimenticare IPv6. Scansionate e filtrate IPv4 e IPv6 separatamente.
  5. Credere che UFW filtri Docker automaticamente. Le porte pubblicate richiedono un controllo specifico.
  6. Installare Fail2ban senza verificare la jail. Controllate status sshd e i log.
  7. Attivare un sysctl generico. Un'impostazione di rete può compromettere VPN, instradamento o container.
  8. Salvare sullo stesso disco. Un guasto o una compromissione porta via originale e copia.
  9. Non ripristinare mai. Un job verde non garantisce né la password, né la coerenza, né i tempi.
  10. Tenere tutti i log in locale. root può cancellarli; inoltrate gli eventi critici.
  11. Eseguire l'applicazione come root. Una falla applicativa diventa subito una compromissione di sistema.
  12. Confondere versione upstream e stato di una CVE. Consultate il tracker della distribuzione.

Domande frequenti

Cambiare la porta SSH mette in sicurezza il VPS?

Riduce il rumore delle scansioni opportunistiche e il volume dei log, ma non aggiunge alcuna barriera di autenticazione. Una chiave protetta, un account non root, la restrizione di rete e le correzioni vengono prima.

Fail2ban serve ancora se le password SSH sono disattivate?

Può ridurre il rumore e alcuni tentativi ripetuti. La sua importanza diminuisce se SSH è raggiungibile solo via VPN o da un elenco di indirizzi, ma non sostituisce nessuna di queste misure.

Serve un antivirus su Linux?

Dipende dal servizio. ClamAV può analizzare file caricati o la posta. Un agente EDR può fornire telemetria e risposta su un server sensibile. Nessun antivirus compensa un sistema non aggiornato, un'applicazione eseguita come root o segreti esposti.

UFW o nftables?

UFW si adatta a una politica semplice ed è lo strumento predefinito documentato da Ubuntu. nftables è il framework nativo consigliato da Debian e offre più controllo. Scegliete un unico proprietario del ruleset e tenete conto di Docker.

Si può disattivare IPv6?

Non è una misura generica di hardening. Filtrate e sorvegliate IPv6 come IPv4. Disattivare IPv6 può compromettere dipendenze e mascherare una scarsa comprensione della rete.

Basta uno snapshot del provider?

Uno snapshot è prezioso per un ritorno rapido, ma di norma resta nello stesso dominio amministrativo e la sua coerenza applicativa va verificata. Conservate anche un backup versionato fuori sede, con una copia offline o immutabile secondo il rischio. I nostri backup delocalizzati opzionali vanno oltre un semplice snapshot, poiché sono quotidiani e archiviati in un altro datacenter, ma restano gestiti dal vostro account cliente: contro il rischio di compromissione, conservate una copia in un dominio amministrativo distinto.

Come capire se il VPS è compromesso?

Non esiste un comando unico. Correlate connessioni, processi, account, chiavi, attività pianificate, log remoti, modifiche ai file, traffico e avvisi. In caso di dubbio serio, preservate le prove, revocate i segreti e ricostruite da una base sana.

Gli aggiornamenti automatici possono compromettere la produzione?

Ogni modifica comporta un rischio. Il rischio di non applicare una correzione è spesso maggiore, ma un'applicazione critica richiede preproduzione, finestre di manutenzione, blocchi mirati dove giustificati, monitoraggio e un piano di ritorno. Ubuntu precisa che unattended-upgrades non è uno strumento completo di gestione di parco macchine.

Questa guida rende il VPS conforme all'ANSSI o al CIS?

No. Si basa su principi e fonti riconosciuti, ma la conformità richiede un perimetro, un livello, prove, eccezioni e un audit. I benchmark vanno adattati al ruolo del server; applicarli automaticamente può interrompere funzioni legittime.

Checklist finale

Identità e SSH

  • un account nominativo per amministratore;
  • chiavi Ed25519 o FIDO2 protette;
  • sudo provato;
  • PermitRootLogin no effettivo;
  • password e keyboard-interactive disattivati se non usati;
  • gruppo SSH autorizzato esplicitamente;
  • configurazione convalidata con sshd -t e sshd -T;
  • console di emergenza testata.

Sistema e rete

  • distribuzione ancora mantenuta;
  • correzioni installate e automazione monitorata;
  • repository di terze parti inventariati;
  • porte IPv4 e IPv6 giustificate;
  • firewall locale attivo;
  • firewall di rete configurato se disponibile;
  • pubblicazioni Docker verificate da Internet;
  • servizi inutili disattivati.

Riduzione dell'impatto

  • applicazioni sotto account dedicati;
  • AppArmor attivo e dinieghi esaminati;
  • servizi systemd isolati secondo le loro esigenze;
  • segreti con privilegi minimi;
  • permessi e chiavi rivisti;
  • sysctl adattati al ruolo, senza copie alla cieca.

Rilevamento e ripresa

  • log persistenti con limite di spazio;
  • orologio sincronizzato;
  • eventi critici inviati fuori dal VPS;
  • auditd e AIDE se il rischio lo giustifica;
  • monitoraggio esterno e canale di avviso distinto;
  • backup cifrati, versionati e fuori sede;
  • diritti di cancellazione separati o archiviazione immutabile;
  • ripristino reale testato e cronometrato;
  • procedura di incidente e contatti disponibili offline.

Per approfondire

Questa guida è la base trasversale. Le procedure dettagliate si trovano nelle nostre guide dedicate: configurare una chiave SSH, configurare UFW, installare Fail2ban, installare Docker e installare un certificato Let's Encrypt con Certbot. Se arrivate da un hosting condiviso, la nostra guida per migrare un sito su un VPS descrive l'intero passaggio.

Fonti principali

Raccomandazioni generali

Debian e Ubuntu

Componenti