Questa guida raccoglie i comandi Ubuntu essenziali per amministrare un web server Linux in produzione. Tutti i comandi sono testati su Ubuntu 22.04 LTS, 24.04 LTS e 26.04 LTS — le tre release LTS attualmente supportate. L’articolo copre ogni area operativa: accesso SSH, gestione file, pacchetti, servizi systemd, web server, database, firewall, rete, sicurezza e monitoraggio.
Rispetto alla versione precedente di questa pagina (2018), il contenuto è stato riscritto integralmente. Comandi deprecati come ifconfig, netstat, iptables e apt-get sono stati sostituiti con le alternative moderne: ip, ss, nftables/ufw e apt. In fondo all’articolo è disponibile una tabella riepilogativa completa delle sostituzioni.
Prerequisiti e versioni Ubuntu di riferimento
I comandi di questa guida richiedono accesso SSH a un server Ubuntu con privilegi sudo. La guida fa riferimento alle tre release LTS attualmente supportate da Canonical.
Versioni LTS supportate
| Versione | Nome | Kernel | Supporto standard | Ubuntu Pro |
|---|---|---|---|---|
| 22.04 LTS | Jammy Jellyfish | 5.15 | Aprile 2027 | Aprile 2032 |
| 24.04 LTS | Noble Numbat | 6.8 | Aprile 2029 | Aprile 2034 |
| 26.04 LTS | — | 7.0 | Aprile 2031 | Aprile 2036 |
Per verificare la versione installata sul server:
# Versione distribuzione
lsb_release -a
# Alternativa (funziona su tutte le distro)
cat /etc/os-release
# Versione kernel
uname -r
Differenze rilevanti tra 22.04, 24.04 e 26.04
Le tre LTS condividono la stessa base Debian/Ubuntu, ma alcune differenze impattano l’amministrazione quotidiana:
- SSH socket activation — su 24.04+ il servizio SSH usa systemd socket activation (
ssh.socket). Dopo modifiche asshd_configservesystemctl restart ssh.socket, nonssh.service - APT v3 — Ubuntu 26.04 include APT v3 con un risolutore di dipendenze migliorato e output più leggibile
- sudo-rs — Ubuntu 26.04 sostituisce il sudo tradizionale (C) con sudo-rs (Rust). I comandi restano identici, cambia solo l’implementazione per maggiore sicurezza della memoria
- Btrfs con zstd — su 24.04+ il filesystem Btrfs con compressione zstd è un’opzione di installazione predefinita, con vantaggi di spazio e I/O
- systemd v259 — Ubuntu 26.04 include systemd 259, l’ultima versione che supporta i legacy System V init script
Accesso SSH e gestione delle chiavi
SSH è il punto di ingresso per qualsiasi operazione su un server remoto. La configurazione corretta delle chiavi e del demone SSH è il primo passo per la sicurezza del server.
Generare chiavi ed25519
Le chiavi Ed25519 sono lo standard attuale. Offrono la stessa sicurezza di RSA 4096-bit con chiavi più corte e operazioni crittografiche più veloci. DSA è stato rimosso da OpenSSH 10.0+, ECDSA è accettabile ma Ed25519 è preferibile.
# Generare una chiave Ed25519
ssh-keygen -t ed25519 -C "[email protected]"
# Copiare la chiave pubblica sul server remoto
ssh-copy-id -i ~/.ssh/id_ed25519.pub [email protected]
# Verificare le chiavi disponibili
ls -la ~/.ssh/
Nota: se il server di destinazione ha OpenSSH molto vecchio (< 6.5) e non supporta Ed25519, usare RSA 4096: ssh-keygen -t rsa -b 4096.
Configurare sshd per la produzione
Il file di configurazione del demone SSH è /etc/ssh/sshd_config. Le direttive fondamentali per un server in produzione:
# /etc/ssh/sshd_config — direttive di sicurezza
Port 22
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
MaxAuthTries 3
ClientAliveInterval 300
ClientAliveCountMax 2
X11Forwarding no
AllowUsers deploy admin
Dopo ogni modifica, testare la configurazione prima di riavviare:
# Validare la configurazione (non riavvia il servizio)
sudo sshd -t
# Riavviare il servizio SSH
# Ubuntu 22.04:
sudo systemctl restart ssh
# Ubuntu 24.04+ (socket activation):
sudo systemctl restart ssh.socket
Socket activation su Ubuntu 24.04+
Da Ubuntu 24.04 il servizio SSH utilizza systemd socket activation: il processo sshd non resta in ascolto permanente, ma viene avviato da systemd solo quando arriva una connessione sulla porta configurata. Questo riduce il consumo di memoria di circa 3 MiB per istanza.
# Verificare se il server usa socket activation
systemctl status ssh.socket
# Verificare lo stato del servizio SSH
systemctl status ssh.service
# Dopo modifiche a sshd_config, riavviare il socket
sudo systemctl restart ssh.socket
Nota: su Ubuntu 24.04+, riavviare ssh.service non applica le modifiche alla configurazione. Riavviare sempre ssh.socket.
Navigazione del filesystem e struttura delle directory
Struttura delle directory di un server Ubuntu
La gerarchia del filesystem Linux segue lo standard FHS (Filesystem Hierarchy Standard). Su un web server, le directory più rilevanti sono:
| Directory | Contenuto | Rilevanza web server |
|---|---|---|
/etc/nginx/ | Configurazione Nginx | Server block, parametri globali |
/etc/apache2/ | Configurazione Apache | Virtual host, moduli |
/etc/php/ | Configurazione PHP (per versione) | php.ini, pool FPM |
/etc/mysql/ | Configurazione MySQL/MariaDB | my.cnf, tuning |
/etc/letsencrypt/ | Certificati SSL (Certbot) | Certificati, chiavi private |
/var/www/ | Document root dei siti | File dei siti web |
/var/log/ | Log di sistema e applicazioni | nginx/access.log, error.log |
/var/lib/mysql/ | Dati MySQL/MariaDB | Database files |
/tmp/ | File temporanei | Cache, sessioni PHP |
/home/ | Home directory utenti | Deploy user, chiavi SSH |
/root/ | Home dell’utente root | Script di manutenzione |
/opt/ | Software opzionale | Applicazioni custom |
/usr/local/bin/ | Binari installati localmente | Script, tool custom |
Comandi di navigazione e gestione file
# Mostrare la directory corrente
pwd
# Elencare file con dettagli (permessi, owner, dimensione)
ls -lah
# Spostarsi nella directory di configurazione Nginx
cd /etc/nginx/sites-available/
# Creare una struttura di directory per un nuovo sito
mkdir -p /var/www/example.com/{public_html,logs,backups}
# Copiare un file di configurazione come template
cp /etc/nginx/sites-available/default /etc/nginx/sites-available/example.com
# Spostare/rinominare un file
mv old-config.conf new-config.conf
# Eliminare file e directory (usare con cautela)
rm file.txt
rm -rf /var/www/old-site/
# Creare un link simbolico (es. abilitare un sito Nginx)
ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
# Cercare file per nome
find /var/log/ -name "*.log" -mtime -7
# Cercare testo nei file di configurazione
grep -r "server_name" /etc/nginx/sites-enabled/
# Visualizzare la struttura ad albero di una directory
tree /etc/nginx/ -L 2
# Visualizzare le ultime righe di un file di log
tail -f /var/log/nginx/error.log
Tool moderni: fd-find, ripgrep, bat, eza
I tool GNU classici (find, grep, cat, ls) funzionano su qualsiasi sistema, ma esistono alternative moderne scritte in Rust che offrono prestazioni superiori e output più leggibile. Su un server di produzione dove si eseguono ricerche frequenti nei log o nelle configurazioni, la differenza è tangibile.
# Installare i tool moderni
sudo apt install fd-find ripgrep bat eza
| Tool classico | Alternativa moderna | Vantaggi |
|---|---|---|
find | fdfind (fd-find) | Sintassi più semplice, rispetta .gitignore, 5-10x più veloce |
grep | rg (ripgrep) | 10x più veloce, rispetta .gitignore, output con contesto |
cat | batcat (bat) | Syntax highlighting, numeri di riga, integrazione Git |
ls | eza | Colori, icone, integrazione Git, output ad albero |
# fd: cercare file .conf nella configurazione Nginx
fdfind -e conf /etc/nginx/
# ripgrep: cercare "proxy_pass" in tutti i file di configurazione
rg "proxy_pass" /etc/nginx/
# bat: visualizzare un file con syntax highlighting
batcat /etc/nginx/nginx.conf
# eza: elencare file con dettagli e albero
eza -la --tree --level=2 /etc/nginx/
Nota: su Ubuntu i binari si chiamano fdfind e batcat per evitare conflitti con pacchetti preesistenti. Per usare i nomi brevi: alias fd=fdfind e alias bat=batcat nel proprio ~/.bashrc.
Gestione utenti e permessi
Creare e configurare utenti di servizio
Su un web server è buona pratica non operare come root. Si crea un utente di deploy con privilegi sudo e si aggiunge al gruppo www-data per gestire i file del sito.
# Creare un utente di deploy
sudo adduser deploy
# Aggiungere l'utente al gruppo sudo
sudo usermod -aG sudo deploy
# Aggiungere l'utente al gruppo www-data (per gestire file web)
sudo usermod -aG www-data deploy
# Verificare i gruppi dell'utente
id deploy
groups deploy
# Cambiare password di un utente
sudo passwd deploy
# Elencare tutti gli utenti del sistema
cut -d: -f1 /etc/passwd
# Elencare solo gli utenti con shell di login
grep -E '/bin/(bash|sh|zsh)' /etc/passwd
Permessi file: chmod, chown e ACL
I permessi file sui contenuti web seguono una regola consolidata: directory a 755 (rwxr-xr-x) e file a 644 (rw-r–r–), con owner www-data:www-data per i file serviti dal web server.
# Impostare owner su tutti i file di un sito
sudo chown -R www-data:www-data /var/www/example.com/
# Permessi standard per directory web
sudo find /var/www/example.com/ -type d -exec chmod 755 {} \;
# Permessi standard per file web
sudo find /var/www/example.com/ -type f -exec chmod 644 {} \;
# Rendere eseguibili gli script
chmod +x /var/www/example.com/deploy.sh
# Verificare i permessi
ls -la /var/www/example.com/
Per scenari più complessi (più utenti che devono scrivere nella stessa directory), le ACL (Access Control List) offrono granularità superiore rispetto ai permessi Unix tradizionali:
# Concedere accesso in scrittura all'utente deploy sulla directory web
sudo setfacl -R -m u:deploy:rwx /var/www/example.com/
# ACL di default per i nuovi file creati nella directory
sudo setfacl -R -d -m u:deploy:rwx /var/www/example.com/
# Visualizzare le ACL
getfacl /var/www/example.com/
sudo e sudo-rs su Ubuntu 26.04
Ubuntu 26.04 introduce sudo-rs, una reimplementazione di sudo scritta in Rust. L’obiettivo è eliminare intere categorie di vulnerabilità legate alla gestione della memoria in C. Dal punto di vista operativo non cambia nulla: i comandi, la configurazione in /etc/sudoers e il comportamento sono identici.
# Verificare quale versione di sudo è installata
sudo --version
# Modificare la configurazione sudo (usare SEMPRE visudo)
sudo visudo
# Aggiungere un utente al gruppo sudo
sudo usermod -aG sudo username
Gestione pacchetti: apt, snap e dpkg
apt vs apt-get: cosa usare
Il comando apt è il frontend raccomandato per l’uso interattivo a terminale dalla versione 16.04 in poi. apt-get resta disponibile e preferibile negli script di automazione per la sua stabilità di output.
| Operazione | apt (interattivo) | apt-get (script) |
|---|---|---|
| Aggiornare lista pacchetti | apt update | apt-get update |
| Aggiornare tutti i pacchetti | apt upgrade | apt-get upgrade |
| Aggiornamento completo (con rimozioni) | apt full-upgrade | apt-get dist-upgrade |
| Installare un pacchetto | apt install pkg | apt-get install pkg |
| Rimuovere un pacchetto | apt remove pkg | apt-get remove pkg |
| Rimuovere con configurazioni | apt purge pkg | apt-get purge pkg |
| Rimuovere dipendenze orfane | apt autoremove | apt-get autoremove |
| Cercare un pacchetto | apt search keyword | apt-cache search keyword |
| Mostrare info pacchetto | apt show pkg | apt-cache show pkg |
| Elencare pacchetti installati | apt list --installed | dpkg --list |
Operazioni comuni con apt
# Aggiornamento completo del sistema
sudo apt update && sudo apt upgrade -y
# Installare un pacchetto
sudo apt install nginx
# Rimuovere un pacchetto mantenendo le configurazioni
sudo apt remove nginx
# Rimuovere un pacchetto con tutte le configurazioni
sudo apt purge nginx
# Rimuovere dipendenze non più necessarie
sudo apt autoremove
# Pulire la cache dei pacchetti scaricati
sudo apt clean
# Bloccare un pacchetto a una versione specifica (impedire aggiornamenti)
sudo apt-mark hold nginx
# Sbloccare il pacchetto
sudo apt-mark unhold nginx
# Elencare i pacchetti bloccati
apt-mark showhold
# Avanzamento di versione Ubuntu
sudo do-release-upgrade
Snap: coesistenza e gestione
Snap è il sistema di pacchetti containerizzati di Canonical. Su un web server, i pacchetti snap più comuni sono Certbot (il metodo di installazione raccomandato) e LXD. I pacchetti snap si aggiornano automaticamente.
# Elencare i pacchetti snap installati
snap list
# Installare un pacchetto snap
sudo snap install certbot --classic
# Aggiornare tutti i pacchetti snap
sudo snap refresh
# Rimuovere un pacchetto snap
sudo snap remove certbot
# Visualizzare lo spazio occupato dai pacchetti snap
du -sh /var/lib/snapd/snaps/
dpkg: operazioni a basso livello
dpkg è il gestore di pacchetti a basso livello che opera direttamente sui file .deb. Si usa quando apt non è sufficiente — ad esempio per installare un pacchetto scaricato manualmente o per diagnosticare problemi di dipendenze.
# Installare un pacchetto .deb scaricato
sudo dpkg -i package.deb
# Risolvere eventuali dipendenze mancanti dopo dpkg -i
sudo apt install -f
# Elencare tutti i pacchetti installati
dpkg --list
# Cercare un pacchetto specifico
dpkg --list | grep nginx
# Mostrare i file installati da un pacchetto
dpkg -L nginx
# Trovare a quale pacchetto appartiene un file
dpkg -S /usr/sbin/nginx
systemd: gestione dei servizi e dei log
systemd è il sistema di init e gestore dei servizi su tutte le versioni di Ubuntu dalla 15.04. Il vecchio comando service funziona ancora come wrapper, ma systemctl è il modo canonico per gestire i servizi.
Comandi systemctl essenziali
| Azione | Comando | Esempio |
|---|---|---|
| Avviare un servizio | systemctl start | sudo systemctl start nginx |
| Fermare un servizio | systemctl stop | sudo systemctl stop nginx |
| Riavviare un servizio | systemctl restart | sudo systemctl restart nginx |
| Ricaricare la configurazione (senza downtime) | systemctl reload | sudo systemctl reload nginx |
| Abilitare all’avvio | systemctl enable | sudo systemctl enable nginx |
| Disabilitare all’avvio | systemctl disable | sudo systemctl disable nginx |
| Verificare lo stato | systemctl status | systemctl status nginx |
| Elencare tutti i servizi attivi | systemctl list-units --type=service | — |
| Elencare i servizi che hanno fallito | systemctl --failed | — |
| Ricaricare i file unit dopo modifiche | systemctl daemon-reload | sudo systemctl daemon-reload |
Creare e modificare unit file
Un unit file systemd definisce come gestire un servizio. È utile per applicazioni custom — ad esempio un’applicazione Node.js, un processo Python o un reverse proxy personalizzato.
# /etc/systemd/system/myapp.service
[Unit]
Description=My Node.js Application
After=network.target
[Service]
Type=simple
User=deploy
WorkingDirectory=/var/www/myapp
ExecStart=/usr/bin/node /var/www/myapp/server.js
Restart=on-failure
RestartSec=5
Environment=NODE_ENV=production
[Install]
WantedBy=multi-user.target
# Dopo aver creato o modificato un unit file
sudo systemctl daemon-reload
# Abilitare e avviare il servizio
sudo systemctl enable --now myapp
# Verificare lo stato
systemctl status myapp
journalctl: analisi dei log di sistema
journalctl è il tool per consultare i log gestiti da systemd. Sostituisce la navigazione manuale dei file in /var/log/ per tutti i servizi gestiti da systemd.
# Log di un servizio specifico
journalctl -u nginx
# Log in tempo reale (come tail -f)
journalctl -u nginx -f
# Log dell'ultima ora
journalctl -u nginx --since "1 hour ago"
# Log di oggi
journalctl -u nginx --since today
# Log tra due date specifiche
journalctl -u nginx --since "2026-03-01" --until "2026-03-31"
# Solo errori e livelli superiori
journalctl -u nginx -p err
# Log del boot corrente
journalctl -b
# Spazio occupato dai log di journald
journalctl --disk-usage
# Pulire i log più vecchi di 7 giorni
sudo journalctl --vacuum-time=7d
Web server: Nginx e Apache
Nginx e Apache sono i due web server dominanti su Linux. Nginx è oggi il più diffuso per la gestione di siti ad alto traffico grazie al suo modello event-driven. Apache resta rilevante per la compatibilità con .htaccess e moduli specifici. Per un confronto approfondito delle architetture, vedi Apache vs Nginx: quale web server scegliere.
Installazione e configurazione di base
# Installare Nginx
sudo apt update && sudo apt install nginx
# Installare Apache (alternativa)
sudo apt update && sudo apt install apache2
# Verificare la versione installata
nginx -v
apache2 -v
I file di configurazione si trovano in posizioni diverse:
| Elemento | Nginx | Apache |
|---|---|---|
| Config principale | /etc/nginx/nginx.conf | /etc/apache2/apache2.conf |
| Siti disponibili | /etc/nginx/sites-available/ | /etc/apache2/sites-available/ |
| Siti abilitati | /etc/nginx/sites-enabled/ | /etc/apache2/sites-enabled/ |
| Log accesso | /var/log/nginx/access.log | /var/log/apache2/access.log |
| Log errori | /var/log/nginx/error.log | /var/log/apache2/error.log |
| Document root default | /var/www/html/ | /var/www/html/ |
Gestione con systemctl
# Nginx: avviare, fermare, riavviare, ricaricare
sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginx
sudo systemctl reload nginx
sudo systemctl enable nginx
# Apache: stessi comandi, servizio diverso
sudo systemctl start apache2
sudo systemctl stop apache2
sudo systemctl restart apache2
sudo systemctl reload apache2
sudo systemctl enable apache2
# Verificare lo stato
systemctl status nginx
systemctl status apache2
Nota: preferire sempre reload a restart in produzione. Il reload ricarica la configurazione senza interrompere le connessioni attive. Usare restart solo quando strettamente necessario (ad esempio dopo l’aggiornamento del binario).
Test della configurazione e reload
Testare sempre la configurazione prima di applicarla. Un errore di sintassi nel file di configurazione può impedire il riavvio del web server, causando un downtime.
# Nginx: testare la configurazione
sudo nginx -t
# Nginx: mostrare la configurazione completa (inclusi tutti gli include)
sudo nginx -T
# Apache: testare la configurazione
sudo apache2ctl -t
# Apache: mostrare i virtual host configurati
sudo apache2ctl -S
# Workflow corretto: test + reload
sudo nginx -t && sudo systemctl reload nginx
sudo apache2ctl -t && sudo systemctl reload apache2
Virtual host e server block
Per aggiungere un nuovo sito, creare il file di configurazione in sites-available e abilitarlo con un link simbolico in sites-enabled.
# Nginx: creare un server block per un nuovo sito
sudo nano /etc/nginx/sites-available/example.com
# Abilitare il sito (link simbolico)
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
# Disabilitare un sito
sudo rm /etc/nginx/sites-enabled/example.com
# Testare e ricaricare
sudo nginx -t && sudo systemctl reload nginx
# Apache: abilitare/disabilitare siti e moduli
sudo a2ensite example.com.conf
sudo a2dissite example.com.conf
sudo a2enmod rewrite
sudo a2enmod ssl
sudo a2dismod autoindex
# Ricaricare dopo le modifiche
sudo systemctl reload apache2
Per approfondire l’analisi dei log del web server, vedi come leggere i log del web server.
PHP-FPM: configurazione e tuning
PHP-FPM (FastCGI Process Manager) è il metodo standard per eseguire PHP con Nginx e la scelta consigliata anche con Apache (tramite mod_proxy_fcgi). Gestisce pool di processi PHP indipendenti per ogni sito.
Installare più versioni PHP in parallelo
Il PPA di Ondřej Surý permette di installare e mantenere più versioni PHP sulla stessa macchina — utile per gestire siti con requisiti diversi.
# Aggiungere il PPA di Ondřej Surý
sudo add-apt-repository ppa:ondrej/php
sudo apt update
# Installare PHP 8.3 con le estensioni comuni per WordPress
sudo apt install php8.3-fpm php8.3-mysql php8.3-curl php8.3-gd \
php8.3-mbstring php8.3-xml php8.3-zip php8.3-intl php8.3-opcache
# Installare una seconda versione (es. 8.1)
sudo apt install php8.1-fpm
# Verificare le versioni PHP installate
php -v
php8.1 -v
php8.3 -v
# Elencare i moduli PHP attivi
php -m
Pool PHP-FPM per sito
Ogni sito può avere un proprio pool PHP-FPM con risorse dedicate. I file di configurazione dei pool si trovano in /etc/php/8.3/fpm/pool.d/.
# Copiare il pool di default come template
sudo cp /etc/php/8.3/fpm/pool.d/www.conf /etc/php/8.3/fpm/pool.d/example.com.conf
# Testare la configurazione PHP-FPM
sudo php-fpm8.3 -t
# Riavviare PHP-FPM dopo le modifiche
sudo systemctl restart php8.3-fpm
# Verificare lo stato
systemctl status php8.3-fpm
# Verificare i processi PHP-FPM attivi
ps aux | grep php-fpm
Parametri di tuning critici
I parametri del pool PHP-FPM determinano quanti processi PHP possono girare contemporaneamente. Un tuning errato è la causa più comune di errori 502/504 e consumo eccessivo di RAM.
# /etc/php/8.3/fpm/pool.d/example.com.conf — parametri chiave
[example.com]
user = www-data
group = www-data
listen = /run/php/php8.3-fpm-example.com.sock
listen.owner = www-data
listen.group = www-data
; Process manager: static, dynamic o ondemand
pm = dynamic
; Numero massimo di processi child
; Formula: RAM disponibile per PHP / RAM per processo (~40-60 MB per WordPress)
pm.max_children = 20
; Processi avviati all'avvio
pm.start_servers = 5
; Processi spare minimi e massimi
pm.min_spare_servers = 3
pm.max_spare_servers = 10
; Richieste prima del riciclo del processo (previene memory leak)
pm.max_requests = 500
Per un server con 4 GB di RAM totali, di cui ~2 GB disponibili per PHP (il resto è occupato da Nginx, MySQL, sistema), con processi WordPress da ~50 MB ciascuno: pm.max_children = 2048 / 50 ≈ 40. Monitorare l’utilizzo effettivo con ps --no-headers -o rss -C php-fpm8.3 | awk '{sum+=$1} END {print sum/1024 " MB"}'.
Per la configurazione di OPcache (complementare a PHP-FPM), consultare la guida dedicata.
Database MySQL e MariaDB da terminale
MySQL e MariaDB sono i database più usati con WordPress e i CMS PHP. MariaDB è un fork di MySQL, compatibile a livello di protocollo e comandi. Le operazioni da terminale sono sostanzialmente identiche.
Operazioni di amministrazione
# Accedere alla console MySQL
sudo mysql
# oppure con credenziali specifiche
mysql -u root -p
# Verificare la versione
mysql -V
# Creare un database
CREATE DATABASE example_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
# Creare un utente con accesso limitato
CREATE USER 'example_user'@'localhost' IDENTIFIED BY 'password_sicura';
GRANT ALL PRIVILEGES ON example_db.* TO 'example_user'@'localhost';
FLUSH PRIVILEGES;
# Elencare i database
SHOW DATABASES;
# Elencare gli utenti
SELECT User, Host FROM mysql.user;
# Verificare lo stato del server
systemctl status mysql
# oppure
systemctl status mariadb
Backup e restore con mysqldump
# Backup completo di un singolo database
mysqldump -u root -p example_db > /var/backups/example_db_$(date +%Y%m%d).sql
# Backup compresso (risparmia 80-90% di spazio)
mysqldump -u root -p example_db | gzip > /var/backups/example_db_$(date +%Y%m%d).sql.gz
# Backup di tutti i database
mysqldump -u root -p --all-databases > /var/backups/all_databases.sql
# Restore di un database
mysql -u root -p example_db < /var/backups/example_db_20260331.sql
# Restore da file compresso
gunzip < /var/backups/example_db_20260331.sql.gz | mysql -u root -p example_db
# Verificare l'integrità delle tabelle
mysqlcheck -u root -p --check example_db
Monitoraggio query lente
Il slow query log è uno strumento diagnostico fondamentale per identificare query non ottimizzate che rallentano il sito.
# Verificare se il slow query log è attivo
mysql -u root -p -e "SHOW VARIABLES LIKE 'slow_query_log%';"
# Abilitare il slow query log (nel file di configurazione)
# /etc/mysql/mysql.conf.d/mysqld.cnf
slow_query_log = 1
slow_query_log_file = /var/log/mysql/mysql-slow.log
long_query_time = 1
# Riavviare MySQL dopo la modifica
sudo systemctl restart mysql
# Visualizzare i processi attivi (query in esecuzione)
mysql -u root -p -e "SHOW PROCESSLIST;"
# Analizzare il log delle query lente
sudo mysqldumpslow /var/log/mysql/mysql-slow.log
# Le 10 query più lente
sudo mysqldumpslow -s t -t 10 /var/log/mysql/mysql-slow.log
Per strategie di caching che riducono il carico sul database, vedi le guide su Memcached e Redis.
Certificati SSL/TLS con Certbot
Certbot è il client ACME più diffuso per ottenere certificati SSL/TLS gratuiti da Let's Encrypt. Il metodo di installazione raccomandato è via snap. Per una guida completa su configurazione SSL, cipher suite e hardening HTTPS, vedi Certificati SSL con Certbot su Nginx e Ubuntu.
Installare Certbot e ottenere certificati
# Installare Certbot via snap
sudo snap install --classic certbot
# Creare il link simbolico per l'accesso globale
sudo ln -s /snap/bin/certbot /usr/bin/certbot
# Ottenere un certificato per Nginx (configurazione automatica)
sudo certbot --nginx -d example.com -d www.example.com
# Ottenere un certificato per Apache
sudo certbot --apache -d example.com -d www.example.com
# Ottenere solo il certificato (senza modificare la configurazione del web server)
sudo certbot certonly --webroot -w /var/www/example.com/public_html -d example.com
Rinnovo automatico e troubleshooting
# Verificare il timer di rinnovo automatico
systemctl status snap.certbot.renew.timer
# Simulare il rinnovo (dry run) senza modificare nulla
sudo certbot renew --dry-run
# Rinnovare manualmente tutti i certificati in scadenza
sudo certbot renew
# Elencare tutti i certificati gestiti da Certbot
sudo certbot certificates
# Verificare il certificato di un dominio dall'esterno
openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates
Certificati wildcard con DNS challenge
I certificati wildcard (*.example.com) richiedono la validazione DNS. Il processo richiede l'accesso alla gestione DNS del dominio per creare un record TXT temporaneo.
# Richiedere un certificato wildcard
sudo certbot certonly --manual --preferred-challenges dns \
-d "example.com" -d "*.example.com"
# Certbot chiederà di creare un record DNS TXT del tipo:
# _acme-challenge.example.com TXT "valore_generato"
# Revocare un certificato
sudo certbot revoke --cert-name example.com
# Eliminare un certificato
sudo certbot delete --cert-name example.com
Firewall: UFW e nftables
UFW (Uncomplicated Firewall) è il frontend semplificato per la gestione del firewall su Ubuntu. Dal 20.10 il backend è nftables (non più iptables). Per la maggior parte delle configurazioni di un web server, UFW è sufficiente. L'accesso diretto a nftables serve per regole avanzate che UFW non supporta.
Configurare UFW per un web server
# Verificare lo stato del firewall
sudo ufw status verbose
# Regole base per un web server
sudo ufw default deny incoming
sudo ufw default allow outgoing
# Permettere SSH (prima di abilitare UFW!)
sudo ufw allow ssh
# Permettere HTTP e HTTPS
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# In alternativa, usare i profili applicazione
sudo ufw allow 'Nginx Full'
# oppure
sudo ufw allow 'Apache Full'
# Abilitare il firewall
sudo ufw enable
# Verificare le regole attive
sudo ufw status numbered
Nota: abilitare sempre la regola SSH prima di attivare UFW. Attivare il firewall senza la regola SSH blocca l'accesso al server.
Regole avanzate: rate limiting e whitelist
# Rate limiting su SSH (blocca dopo 6 tentativi in 30 secondi)
sudo ufw limit ssh
# Permettere SSH solo da un IP specifico
sudo ufw allow from 203.0.113.50 to any port 22
# Permettere accesso MySQL solo da localhost
sudo ufw allow from 127.0.0.1 to any port 3306
# Bloccare un IP specifico
sudo ufw deny from 198.51.100.0/24
# Eliminare una regola per numero
sudo ufw status numbered
sudo ufw delete 3
# Resettare tutte le regole
sudo ufw reset
# Elencare i profili applicazione disponibili
sudo ufw app list
nftables: il backend di UFW
nftables è il framework di filtraggio dei pacchetti che ha sostituito iptables nel kernel Linux. UFW lo usa come backend in modo trasparente. L'accesso diretto a nftables è necessario quando servono regole complesse (es. rate limiting per IP con contatori, filtraggio a livello di conntrack, regole per protocolli specifici).
# Visualizzare il ruleset nftables completo
sudo nft list ruleset
# Visualizzare le tabelle
sudo nft list tables
# Visualizzare una catena specifica
sudo nft list chain inet filter input
# Il file di configurazione persistente
cat /etc/nftables.conf
# Ricaricare la configurazione nftables
sudo systemctl restart nftables
Nota: se si usa UFW, non modificare le regole nftables direttamente. I due sistemi possono confliggere. Usare nftables diretto solo se si è scelto di non usare UFW.
Rete: ip, ss, netplan
I comandi di rete tradizionali (ifconfig, netstat, route, arp) del pacchetto net-tools sono deprecati e non installati di default da Ubuntu 22.04. I sostituti moderni fanno parte del pacchetto iproute2 (preinstallato) e offrono output più dettagliato e consistente.
ip addr, ip route, ip link: sostituire ifconfig
| Vecchio comando (net-tools) | Comando moderno (iproute2) | Descrizione |
|---|---|---|
ifconfig | ip addr show (o ip a) | Mostrare indirizzi IP delle interfacce |
ifconfig eth0 up | ip link set eth0 up | Attivare un'interfaccia |
ifconfig eth0 down | ip link set eth0 down | Disattivare un'interfaccia |
route | ip route show (o ip r) | Mostrare la tabella di routing |
route add | ip route add | Aggiungere una rotta |
arp -a | ip neigh show | Mostrare la tabella ARP (neighbor) |
# Mostrare tutti gli indirizzi IP
ip addr show
# Mostrare solo le interfacce attive
ip link show up
# Mostrare solo gli indirizzi IPv4
ip -4 addr show
# Mostrare la tabella di routing
ip route show
# Mostrare il gateway predefinito
ip route show default
# Mostrare le statistiche delle interfacce
ip -s link show
# Risolvere un hostname
dig example.com +short
host example.com
ss: sostituire netstat
ss (socket statistics) sostituisce netstat con prestazioni migliori — interroga direttamente il kernel invece di parsare /proc. I flag sono in gran parte compatibili.
| netstat (deprecato) | ss (moderno) | Descrizione |
|---|---|---|
netstat -tulnp | ss -tulnp | Porte in ascolto (TCP/UDP) con PID |
netstat -an | ss -an | Tutte le connessioni, formato numerico |
netstat -s | ss -s | Statistiche riassuntive |
netstat -tn | ss -tn | Connessioni TCP attive |
# Porte TCP in ascolto con processo associato
sudo ss -tulnp
# Connessioni attive sulla porta 443 (HTTPS)
ss -tn state established '( dport = :443 or sport = :443 )'
# Contare le connessioni per stato
ss -s
# Connessioni per IP (sostituisce le pipe con netstat dell'articolo originale)
ss -tn state established | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -rn | head -20
# Verificare cosa è in ascolto sulla porta 80
sudo ss -tulnp | grep :80
Netplan: configurazione di rete su Ubuntu
Netplan è il sistema di configurazione di rete predefinito su Ubuntu dalla versione 18.04. I file di configurazione sono in formato YAML nella directory /etc/netplan/. Netplan genera le configurazioni per il backend (NetworkManager su desktop, systemd-networkd su server).
# Visualizzare la configurazione Netplan attiva
cat /etc/netplan/*.yaml
# Esempio: configurazione IP statico per un server
# /etc/netplan/01-static.yaml
network:
version: 2
renderer: networkd
ethernets:
eth0:
addresses:
- 203.0.113.10/24
routes:
- to: default
via: 203.0.113.1
nameservers:
addresses:
- 1.1.1.1
- 8.8.8.8
# Applicare le modifiche Netplan
sudo netplan apply
# Testare le modifiche con rollback automatico dopo 120 secondi
sudo netplan try
# Generare la configurazione senza applicarla (debug)
sudo netplan generate
Sicurezza del server
La sicurezza di un web server richiede un approccio a più livelli: firewall (trattato nella sezione precedente), controllo degli accessi con AppArmor, protezione dai brute force con Fail2ban, e una serie di pratiche di hardening.
AppArmor: profili e gestione
AppArmor è il sistema MAC (Mandatory Access Control) di Ubuntu. Limita ciò che ogni applicazione può fare sul sistema — file accessibili, porte utilizzabili, operazioni permesse — indipendentemente dai permessi Unix dell'utente che la esegue.
# Verificare lo stato di AppArmor
sudo aa-status
# Elencare i profili e il loro stato (enforce/complain/unconfined)
sudo aa-status --json | python3 -m json.tool
# Mettere un profilo in modalità enforce (blocca le violazioni)
sudo aa-enforce /etc/apparmor.d/usr.sbin.nginx
# Mettere un profilo in modalità complain (logga ma non blocca)
sudo aa-complain /etc/apparmor.d/usr.sbin.nginx
# Ricaricare tutti i profili
sudo systemctl reload apparmor
# Verificare i log di violazione
sudo dmesg | grep apparmor
Fail2ban: protezione dai brute force
Fail2ban monitora i log di sistema e blocca automaticamente gli IP che eseguono troppi tentativi falliti di autenticazione. Fondamentale per proteggere SSH e le pagine di login delle applicazioni web.
# Installare Fail2ban
sudo apt install fail2ban
# Creare una configurazione locale (non modificare jail.conf)
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
# Configurazione base per SSH e Nginx
# /etc/fail2ban/jail.local
[sshd]
enabled = true
port = ssh
filter = sshd
maxretry = 3
bantime = 3600
findtime = 600
[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
maxretry = 5
bantime = 3600
# Avviare e abilitare Fail2ban
sudo systemctl enable --now fail2ban
# Verificare lo stato dei jail attivi
sudo fail2ban-client status
# Stato di un jail specifico (es. sshd)
sudo fail2ban-client status sshd
# Bannare manualmente un IP
sudo fail2ban-client set sshd banip 198.51.100.50
# Sbannare un IP
sudo fail2ban-client set sshd unbanip 198.51.100.50
# Verificare i log di Fail2ban
sudo tail -f /var/log/fail2ban.log
Hardening checklist essenziale
Un elenco di operazioni di hardening da verificare su ogni server in produzione:
# 1. Aggiornamenti automatici di sicurezza
sudo apt install unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades
# 2. Verificare che SSH non permetta login root
grep "^PermitRootLogin" /etc/ssh/sshd_config
# 3. Verificare che SSH non permetta login con password
grep "^PasswordAuthentication" /etc/ssh/sshd_config
# 4. Verificare i servizi in ascolto (ridurre la superficie di attacco)
sudo ss -tulnp
# 5. Disabilitare servizi non necessari
sudo systemctl disable --now service_name
# 6. Verificare gli utenti con accesso sudo
getent group sudo
# 7. Verificare i login recenti
last -20
lastb -20
# 8. Verificare i tentativi di accesso SSH falliti
journalctl -u ssh --since "24 hours ago" | grep "Failed password"
Monitoraggio risorse e prestazioni
Il monitoraggio delle risorse è essenziale per diagnosticare problemi di prestazioni e pianificare la capacità del server. I comandi seguenti coprono CPU, memoria, disco e I/O.
CPU, memoria e disco: top, htop, btop
# top: monitor di base (preinstallato)
top
# htop: monitor interattivo con interfaccia migliorata
sudo apt install htop
htop
# btop: monitor moderno con grafici e UI avanzata
sudo apt install btop
btop
# Uptime e carico medio del sistema
uptime
# Utenti connessi e loro attività
w
In top/htop, i valori chiave da monitorare su un web server sono: load average (non deve superare il numero di core CPU), %wa (I/O wait — indica colli di bottiglia disco), e la memoria usata dai processi php-fpm, mysql e nginx.
free, df, du: analisi dello spazio
# Memoria RAM e swap (formato leggibile)
free -h
# Spazio disco su tutte le partizioni
df -h
# Spazio occupato dalle directory in /var (dove crescono log e database)
sudo du -sh /var/log/ /var/lib/mysql/ /var/www/ /var/backups/
# Le 10 directory più grandi nella root
sudo du -sh /* 2>/dev/null | sort -rh | head -10
# Spazio occupato dai log
sudo du -sh /var/log/*.log /var/log/**/*.log 2>/dev/null | sort -rh | head -10
# ncdu: analisi interattiva dello spazio disco
sudo apt install ncdu
sudo ncdu /var/
iotop e vmstat: diagnostica avanzata
Quando il server è lento ma CPU e RAM non sono saturi, il collo di bottiglia è spesso l'I/O del disco. iotop identifica i processi che generano più I/O, vmstat fornisce un quadro d'insieme delle risorse di sistema.
# iotop: monitor I/O in tempo reale (richiede root)
sudo apt install iotop
sudo iotop -oP
# vmstat: statistiche di sistema ogni secondo
vmstat 1
# Colonne vmstat rilevanti:
# r = processi in coda CPU
# b = processi bloccati su I/O
# si/so = swap in/out (valori > 0 indicano insufficienza RAM)
# wa = % tempo CPU in attesa di I/O
# iostat: statistiche I/O per dispositivo
sudo apt install sysstat
iostat -xz 1
# Verificare la percentuale di utilizzo del disco
iostat -xz 1 | grep -E "Device|sda|nvme"
Cron job e automazione
L'automazione delle attività ricorrenti — backup, pulizia log, rinnovo certificati, aggiornamenti — è fondamentale per ridurre il carico operativo e minimizzare gli errori umani.
Crontab: sintassi e gestione
# Visualizzare il crontab dell'utente corrente
crontab -l
# Modificare il crontab
crontab -e
# Visualizzare il crontab di root
sudo crontab -l
# Sintassi crontab:
# minuto ora giorno_mese mese giorno_settimana comando
# * * * * * comando
# Esempi pratici per un web server:
# Backup database ogni giorno alle 3:00
0 3 * * * mysqldump -u root example_db | gzip > /var/backups/db_$(date +\%Y\%m\%d).sql.gz
# Pulizia log compressi più vecchi di 30 giorni
0 4 * * 0 find /var/log/ -name "*.gz" -mtime +30 -delete
# Pulizia cache ogni 6 ore
0 */6 * * * rm -rf /var/www/example.com/cache/page/*
# Verifica spazio disco ogni ora (notifica se sopra 90%)
0 * * * * df -h / | awk 'NR==2 {if ($5+0 > 90) print "Disco al "$5}' | mail -s "Allarme disco" [email protected]
Systemd timer: alternativa a cron
I timer systemd sono un'alternativa moderna a cron con vantaggi significativi: logging integrato in journald, dipendenze tra servizi, e gestione unificata tramite systemctl. Certbot su Ubuntu 24.04+ usa un timer systemd (non cron) per il rinnovo automatico dei certificati.
# Elencare tutti i timer attivi
systemctl list-timers --all
# Esempio: creare un timer per il backup del database
# /etc/systemd/system/db-backup.service
[Unit]
Description=Database backup
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup-db.sh
# /etc/systemd/system/db-backup.timer
[Unit]
Description=Run database backup daily
[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true
[Install]
WantedBy=timers.target
# Abilitare e avviare il timer
sudo systemctl daemon-reload
sudo systemctl enable --now db-backup.timer
# Verificare quando il timer scatterà
systemctl list-timers db-backup.timer
# Eseguire manualmente il servizio (per test)
sudo systemctl start db-backup.service
# Verificare i log dell'ultima esecuzione
journalctl -u db-backup.service
Container: Docker e Podman
Docker è lo standard de facto per la containerizzazione di applicazioni web. Podman è l'alternativa di Red Hat che non richiede un demone root. Su Ubuntu, entrambi sono disponibili e i comandi sono in gran parte intercambiabili.
Docker: comandi essenziali per web server
# Installare Docker (metodo ufficiale)
sudo apt install docker.io docker-compose-v2
# Aggiungere l'utente al gruppo docker (evita sudo per ogni comando)
sudo usermod -aG docker $USER
# Elencare i container in esecuzione
docker ps
# Elencare tutti i container (anche fermati)
docker ps -a
# Avviare uno stack web con Docker Compose
docker compose up -d
# Fermare lo stack
docker compose down
# Visualizzare i log di un container
docker logs -f container_name
# Accedere alla shell di un container
docker exec -it container_name bash
# Verificare risorse utilizzate dai container
docker stats
# Pulire immagini, container e volumi non utilizzati
docker system prune -a
Podman: alternativa rootless
Podman esegue container senza un demone in background e senza privilegi root — un vantaggio significativo per la sicurezza. I comandi sono compatibili con Docker.
# Installare Podman
sudo apt install podman
# I comandi sono identici a Docker
podman ps
podman run -d --name nginx -p 80:80 nginx
podman logs nginx
podman exec -it nginx bash
podman stop nginx
# Podman Compose (equivalente di Docker Compose)
sudo apt install podman-compose
podman-compose up -d
Tabella comandi deprecati e sostituti moderni
Riepilogo completo dei comandi deprecati e le alternative moderne da utilizzare su Ubuntu 22.04+.
| Comando deprecato | Sostituto moderno | Pacchetto | Deprecato da |
|---|---|---|---|
ifconfig | ip addr / ip link | iproute2 | Ubuntu 18.04 |
netstat | ss | iproute2 | Ubuntu 22.04 |
route | ip route | iproute2 | Ubuntu 18.04 |
arp | ip neigh | iproute2 | Ubuntu 18.04 |
iptables | nft / ufw | nftables | Ubuntu 20.10 |
service X restart | systemctl restart X | systemd | Ubuntu 15.04 |
apt-get (interattivo) | apt | apt | Ubuntu 16.04 |
apt-get dist-upgrade | apt full-upgrade | apt | Ubuntu 16.04 |
ifupdown (/etc/network/interfaces) | Netplan (/etc/netplan/*.yaml) | netplan.io | Ubuntu 18.04 |
sudo (C) | sudo-rs (Rust) | sudo-rs | Ubuntu 26.04 |
scp | rsync / sftp | openssh-client | OpenSSH 9.0 |
egrep / fgrep | grep -E / grep -F | grep | GNU grep 3.8 |
find (per ricerche veloci) | fdfind | fd-find | Alternativa |
grep (per codebase) | rg | ripgrep | Alternativa |
cat (per lettura file) | batcat | bat | Alternativa |
ls | eza | eza | Alternativa |
top / htop | btop | btop | Alternativa |
neofetch | fastfetch | fastfetch | 2024 (discontinued) |
Nota: le ultime righe della tabella (fd-find, ripgrep, bat, eza, btop) non sono deprecazioni ufficiali ma alternative moderne con prestazioni superiori. I tool classici (find, grep, cat, ls, top) restano pienamente funzionanti e preinstallati.
Risorse e documentazione ufficiale
- Ubuntu Manpages — documentazione ufficiale di tutti i comandi Ubuntu
- Ubuntu Server Guide — guida ufficiale all'amministrazione di Ubuntu Server
- systemd Documentation — reference completo per systemctl, journalctl, unit file
- Nginx Documentation — documentazione ufficiale di Nginx
- Apache HTTP Server Documentation — documentazione ufficiale di Apache
- nftables Wiki — reference per la sintassi e le funzionalità di nftables
- Netplan Reference — documentazione YAML per la configurazione di rete
- Certbot Documentation — guida ufficiale per Let's Encrypt/Certbot
Articoli correlati
Autore
Mi chiamo Giovanni Sacheli e dal 2009 aiuto le aziende a farsi trovare online. Sono specializzato in SEO tecnica e PPC, competenze che applico quotidianamente nella mia agenzia, Searcus Swiss Sagl. Mi piace sviluppare strumenti a supporto del mio lavoro, ho creato SEOdata.app e cluster.army e co-scritto il libro SEO Audit Avanzato. Curo maniacalmente questo blog per colleghi e appassionati, dove mi "appunto" quello che imparo. Sono un NERD anni '80, motociclista e orgoglioso papà di due bambini.
Link:
Giovanni Sacheli
SEO Audit Avanzato
Searcus Swiss Sagl
SEOdata.app
cluster.army