DNS, firewall, VPN, proxy, subnet e tutti gli altri motivi per cui "non funziona la rete". Spoiler: è quasi sempre il DNS.
"Hai provato a spegnere e riaccendere il router?" — il 70% delle volte funziona. Il 30% rimanente è questa guida.
http://localhost:9191. Dove ha senso, trovi il link al pannello giusto. → netforge.it
Lo stack di rete che tutti citano in ogni colloquio e che quasi nessuno usa davvero nella vita quotidiana. Ma serve capirlo almeno una volta.
Spedire un pacchetto di dati in rete funziona come spedire una lettera raccomandata: hai il contenuto (applicazione), imbustato in una busta (trasporto con mittente e destinatario), messa dentro un furgone del corriere (rete/IP) che viaggia su strade fisiche (link/fisico). Ogni strato conosce solo il suo compito e si fida che quelli sopra e sotto facciano il loro. Quando la rete non funziona, stai cercando dove si è fermato il furgone.
Transmission Control Protocol. Connection-oriented: prima stringe la mano (3-way handshake), poi manda dati, poi chiude educatamente.
Garantisce: ordine dei pacchetti, ritrasmissione in caso di perdita, controllo di flusso.
Quando usarlo: HTTP/S, SSH, database, email — tutto ciò dove un pacchetto perso è un problema.
Client → Server: SYN # "ciao, ci sei?"
Server → Client: SYN-ACK # "sì, ci sono"
Client → Server: ACK # "ok, parliamo"
# ora il canale è aperto e si scambiano dati
User Datagram Protocol. Connectionless: spara e dimentica. Nessun handshake, nessuna conferma, nessun controllo di ordine.
Vantaggi: bassa latenza, nessun overhead di connessione.
Quando usarlo: DNS, streaming video, VoIP, giochi online, WireGuard VPN — tutto ciò dove un pacchetto perso è meno grave di arrivare in ritardo.
Quella parte dove tutti fanno finta di capire le subnet mask e poi usano un calcolatore online. Noi anche.
32 bit, 4 ottetti, ~4 miliardi di indirizzi. Finiti nel 2011. Si va avanti con NAT e IPv6 (quando qualcuno si decide a deployarlo).
192.168.1.100
│ │ │ └── host nell'host range
│ │ └───── terzo ottetto
│ └────────── secondo ottetto
└─────────────── primo ottetto
# Ogni ottetto: 0-255 (8 bit)
# 192.168.1.100 = 11000000.10101000.00000001.01100100
128 bit, notazione esadecimale, praticamente infiniti indirizzi. Deployato lentamente da 30 anni. Il tuo router probabilmente lo supporta. Il tuo collega probabilmente non lo ha mai configurato.
2001:0db8:85a3:0000:0000:8a2e:0370:7334
# compresso (zero omissibili):
2001:db8:85a3::8a2e:370:7334
# loopback (= 127.0.0.1 in IPv4):
::1
# link-local (assegnato automaticamente):
fe80::1
CIDR (Classless Inter-Domain Routing) esprime la subnet come indirizzo/prefisso. Il prefisso indica quanti bit sono fissi (rete), i restanti sono per gli host.
| CIDR | Subnet Mask | Host utilizzabili | Uso tipico |
|---|---|---|---|
/8 | 255.0.0.0 | 16.777.214 | Reti enormi (tipo 10.0.0.0/8) |
/16 | 255.255.0.0 | 65.534 | Reti aziendali medie (172.16.0.0/16) |
/24 | 255.255.255.0 | 254 | Rete di casa/ufficio tipica. La sai a memoria. |
/25 | 255.255.255.128 | 126 | Dimezzare un /24 |
/28 | 255.255.255.240 | 14 | VLAN piccola, DMZ |
/30 | 255.255.255.252 | 2 | Link point-to-point |
/32 | 255.255.255.255 | 1 (host singolo) | Route statica a host specifico |
| Range | CIDR | Uso |
|---|---|---|
10.0.0.0 – 10.255.255.255 | 10.0.0.0/8 | Reti enterprise, cloud VPC |
172.16.0.0 – 172.31.255.255 | 172.16.0.0/12 | Meno comune, Docker di default usa questo |
192.168.0.0 – 192.168.255.255 | 192.168.0.0/16 | Casa, ufficio piccolo. Il tuo router è probabilmente 192.168.1.1 |
127.0.0.0/8 | loopback | 127.0.0.1 = localhost. Non esce dalla macchina. |
169.254.0.0/16 | link-local APIPA | Quando il DHCP non risponde e Windows si inventa un indirizzo da solo. Segnale di guaio. |
Il Domain Name System. La rubrica telefonica di internet. E il primo sospettato in ogni indagine di rete.
Il DNS esiste perché gli esseri umani ricordano "google.com" ma non "142.250.180.46". Traduce nomi in IP. Sembra semplice. In pratica è distribuito, gerarchico, con cache multiple, TTL variabili, record di 15 tipi diversi e configurazioni che si propagano lentamente nel mondo. Ogni volta che "la rete non funziona", il DNS è il primo indiziato. Anche quando non è colpa sua.
Se la risposta è in cache del resolver o del browser, i passi 2-6 saltano. Il TTL decide quanto a lungo vive la cache. Cambi un record DNS e poi aspetti che si propaghi: questa è la vita.
| Tipo | Cosa fa | Esempio |
|---|---|---|
| A | Nome → IPv4 | esempio.it → 93.184.216.34 |
| AAAA | Nome → IPv6 | esempio.it → 2606:2800::1 |
| CNAME | Alias → altro nome (non IP direttamente) | www → esempio.it (no CNAME su apex!) |
| MX | Server email per il dominio | @ MX 10 mail.esempio.it |
| TXT | Testo libero. Usato per SPF, DKIM, DMARC, verifiche | v=spf1 include:... ~all |
| NS | Nameserver autorevole per il dominio | ns1.registrar.com |
| PTR | Reverse DNS: IP → nome (per email e logging) | 34.216.184.93.in-addr.arpa → esempio.it |
| SRV | Service record: porta e protocollo per un servizio | _sip._tcp 10 0 5060 server.it |
| CAA | Quale CA può emettere certificati per il dominio | 0 issue "letsencrypt.org" |
# Query base: A record
dig esempio.it
dig esempio.it A
# Query specifica per tipo
dig esempio.it MX
dig esempio.it TXT
dig esempio.it NS
# Chiedi a un resolver specifico (bypass della cache locale)
dig @8.8.8.8 esempio.it # Google
dig @1.1.1.1 esempio.it # Cloudflare
dig @9.9.9.9 esempio.it # Quad9
# Reverse DNS (PTR)
dig -x 93.184.216.34
# Traccia l'intera risoluzione gerarchica
dig +trace esempio.it
# Solo la risposta, niente rumore
dig +short esempio.it
93.184.216.34
# Su Windows: nslookup (meno potente ma c'è)
nslookup esempio.it 8.8.8.8
| Resolver | IP | Pro | Contro |
|---|---|---|---|
| Cloudflare | 1.1.1.1 / 1.0.0.1 | Velocissimo, privacy-focused, DoH/DoT | Cloudflare vede le query |
8.8.8.8 / 8.8.4.4 | Affidabile, buona cache, globale | Google vede le query. Google vede tutto. | |
| Quad9 | 9.9.9.9 | Blocca domini malware, privacy, svizzero | Meno cache rispetto agli altri due |
| AdGuard DNS | 94.140.14.14 | Blocca pubblicità e tracker a livello DNS | Può rompere cose (sì, anche quelle legittime) |
| Proprio (Pi-hole) | tuo IP locale | Controllo totale, blocklist custom, log | Manutenzione tua, se cade la rete va giù |
Il buttafuori della rete. Decide chi entra, chi esce e chi viene segnato su un log che nessuno leggerà mai.
Guarda IP sorgente/destinazione, porta e protocollo. Veloce, stateless. Il tipo di regola che scrivi con iptables/nftables.
Ricorda le connessioni aperte. Sa che un pacchetto in arrivo fa parte di una sessione già autorizzata. Quello che fa il tuo router di casa senza che tu lo sappia.
Ispeziona il payload: blocca HTTP ma permette HTTPS, filtra per User-Agent. Costoso computazionalmente. Tipico delle enterprise.
nftables ha sostituito iptables nelle distro moderne (Debian 10+, Ubuntu 20.04+, RHEL 8+). Sintassi più pulita, performance migliori, un singolo tool invece di iptables/ip6tables/arptables.
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
# Loopback: sempre permesso
iifname lo accept
# Connessioni già stabilite: lasciale passare
ct state established,related accept
# ICMP: ping e path MTU (non bloccare tutto o ti rompi cose)
icmp type echo-request accept
icmpv6 type { echo-request, nd-neighbor-solicit, nd-router-advert } accept
# SSH: solo da IP specifico (modifica con il tuo)
ip saddr 10.0.0.0/8 tcp dport 22 accept
# Web pubblico
tcp dport { 80, 443 } accept
# Log e drop di tutto il resto
log prefix "[nft drop] " drop
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
# Mostra tutte le regole
nft list ruleset
# Applica configurazione
nft -f /etc/nftables.conf
# Abilita al boot
systemctl enable nftables
# Aggiungi regola al volo (temporanea)
nft add rule inet filter input tcp dport 8080 accept
# Svuota tutto (attento: espone il server)
nft flush ruleset
UFW (Uncomplicated Firewall) è il frontend semplice di iptables/nftables. Ubuntu lo include di default. Per server dove non hai voglia di scrivere nftables da zero.
# Abilita ufw (policy default: deny in, allow out)
ufw enable
# Permetti servizi
ufw allow ssh # porta 22
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow from 10.0.0.0/8 to any port 5432 # PostgreSQL solo da rete interna
# Blocca
ufw deny from 1.2.3.4
# Stato e regole
ufw status verbose
ufw status numbered
# Rimuovi regola per numero
ufw delete 3
# Reset completo (torna a tutto aperto)
ufw reset
iptables-save o config nftables nell'Analizzatore e ottieni spiegazioni in italiano regola per regola. Il Costruttore genera regole iptables/nftables con form visuale. Il Convertitore fa conversione bidirezionale iptables↔nftables. L'Audit Sicurezza esegue 19 check automatici con score. Lo Simulatore testa un pacchetto ipotetico attraverso le catene. I Template hanno 9 configurazioni pronte (web server, gateway, Docker, VPN, mail).
# Lista regole
Get-NetFirewallRule | Where-Object Enabled -eq True | Select DisplayName,Direction,Action
# Aggiungi regola in ingresso
New-NetFirewallRule -DisplayName "Allow 8080" -Direction Inbound -Protocol TCP -LocalPort 8080 -Action Allow
# Via netsh (vecchio stile ma ovunque)
netsh advfirewall firewall add rule name="Allow 8080" dir=in action=allow protocol=TCP localport=8080
# Disabilita completamente (non farlo in produzione)
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False
Virtual Private Network. Tunnel cifrato tra due punti. Non ti rende anonimo, non ti protegge da tutto, ma è essenziale per collegare reti e proteggere traffico su reti non fidate.
Collega due reti come se fossero la stessa LAN. Router A ↔ Router B. Tutti gli host dietro vedono quelli dell'altro lato. Classica VPN aziendale tra sedi.
Un dispositivo (laptop, telefono) si connette alla rete aziendale da remoto. Lavoro da casa. Il classico "sono in VPN" dei tuoi colleghi.
WireGuard è il protocollo VPN moderno. ~4.000 righe di codice (vs ~100.000 di OpenVPN). Kernel module su Linux, velocissimo, basato su ChaCha20/Poly1305/Curve25519. Configurazione sorprendentemente semplice.
# Installa
apt install wireguard
# Genera coppia di chiavi (server)
wg genkey | tee /etc/wireguard/server_private.key | wg pubkey > /etc/wireguard/server_public.key
chmod 600 /etc/wireguard/server_private.key
# /etc/wireguard/wg0.conf — SERVER
[Interface]
PrivateKey = <contenuto di server_private.key>
Address = 10.10.0.1/24
ListenPort = 51820
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
[Peer] # un peer per ogni client
PublicKey = <public key del client>
AllowedIPs = 10.10.0.2/32
# Abilita IP forwarding
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf && sysctl -p
# Avvia
systemctl enable --now wg-quick@wg0
wg show
[Interface]
PrivateKey = <client private key>
Address = 10.10.0.2/24
DNS = 10.10.0.1 # opzionale: usa il DNS del server
[Peer]
PublicKey = <server public key>
Endpoint = server.esempio.it:51820
AllowedIPs = 0.0.0.0/0 # tutto il traffico via VPN (full tunnel)
# AllowedIPs = 10.10.0.0/24 # solo traffico verso la VPN (split tunnel)
PersistentKeepalive = 25 # mantieni vivo attraverso NAT
Esiste dal 2001. TLS-based, UDP o TCP, più complesso di WireGuard ma onnipresente in aziende e appliance. Se hai una VPN aziendale legacy o un router consumer, probabilmente è OpenVPN.
| WireGuard | OpenVPN | |
|---|---|---|
| Codice | ~4k righe | ~100k righe |
| Performance | Eccellente | Buona |
| Configurazione | Semplice | Complessa (PKI, certificati) |
| Protocollo | Solo UDP | UDP o TCP (TCP su 443 bypass firewall) |
| Audit | Più semplice da auditare | Più storia, più audit disponibili |
| Quando usarlo | Nuovo deployment, performance critica | Compatibilità con sistemi legacy, TCP su 443 |
L'intermediario. Chi fa il proxy forward, chi fa il reverse, chi fa entrambe le cose e non lo sa.
Il client parla col proxy, il proxy parla con internet. Il server vede l'IP del proxy, non del client. Usato per: filtering, caching, bypass restrizioni, anonimizzazione parziale.
Esempi: Squid, Privoxy, SOCKS5
Sta davanti ai server. Il client parla col proxy, il proxy smista verso i backend. Il client non sa quanti server ci sono dietro. Usato per: load balancing, SSL termination, caching, WAF.
Esempi: nginx, Caddy, HAProxy, Traefik
Il caso d'uso più comune: nginx davanti a un'applicazione che gira su localhost:3000, espone HTTPS pubblico, gestisce SSL, aggiunge header di sicurezza.
server {
listen 80;
server_name app.esempio.it;
# Redirect HTTP → HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name app.esempio.it;
ssl_certificate /etc/letsencrypt/live/app.esempio.it/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/app.esempio.it/privkey.pem;
# Header di sicurezza (non saltare questi)
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header Strict-Transport-Security "max-age=31536000" always;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade; # per WebSocket
proxy_set_header Connection "upgrade";
}
}
Caddy gestisce i certificati Let's Encrypt da solo. Zero configurazione SSL. Per chi non vuole pensarci.
app.esempio.it {
reverse_proxy localhost:3000
}
# Sì, è tutto. Caddy prende il certificato da solo.
# Non ti serve nient'altro per HTTPS in produzione.
# La prima volta che lo vedi ti sembra troppo facile.
Un SOCKS proxy (v4 o v5) lavora a layer più basso di un HTTP proxy: può gestire qualsiasi tipo di traffico TCP (e UDP con SOCKS5), non solo HTTP. Usato da browser, torrent, SSH tunneling.
# Apri tunnel SOCKS5 sulla porta locale 1080
ssh -D 1080 -N -f user@server-remoto.it
# -D: SOCKS dynamic port forwarding
# -N: non eseguire comandi, solo il tunnel
# -f: vai in background
# Poi configura il browser per usare SOCKS5 127.0.0.1:1080
# Tutto il traffico del browser passa attraverso il server remoto
# Oppure usa curl con il proxy
curl --socks5 127.0.0.1:1080 https://ifconfig.me
1.2.3.4 # IP del server remoto, non tuo
Come i pacchetti trovano la strada. E come fai sembrare che 200 dispositivi abbiano un unico IP pubblico.
Ogni host ha una routing table: per ogni destinazione, quale gateway usare e tramite quale interfaccia. I pacchetti vengono instradati hop-by-hop.
# Linux: visualizza routing table
ip route show
default via 192.168.1.1 dev eth0 proto dhcp # default gateway
192.168.1.0/24 dev eth0 proto kernel scope link # rete locale
10.10.0.0/24 dev wg0 proto kernel scope link # rete VPN
# Aggiungi route statica
ip route add 10.20.0.0/24 via 192.168.1.254
ip route add 10.20.0.0/24 via 192.168.1.254 dev eth0
# Rimuovi route
ip route del 10.20.0.0/24
# Cambia default gateway
ip route replace default via 192.168.1.2
# Windows
route print
route add 10.20.0.0 mask 255.255.255.0 192.168.1.254
# Traccia il percorso verso una destinazione
traceroute 8.8.8.8 # Linux/Mac
tracert 8.8.8.8 # Windows
mtr 8.8.8.8 # Linux: traceroute continuo con statistiche
Il NAT permette a tanti host con IP privati di uscire su internet usando un singolo IP pubblico. Il router traccia le connessioni e smista le risposte al mittente corretto.
Il NAT è come un ufficio con un unico numero di telefono esterno. Quando un dipendente chiama fuori, il centralino usa il numero unico e tiene traccia di "questa risposta va al sig. Rossi interno 42". Dall'esterno sembrate tutti lo stesso numero.
# Abilita IP forwarding
sysctl -w net.ipv4.ip_forward=1
# NAT masquerade con iptables (interfaccia pubblica = eth0)
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
iptables -A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
# Port forwarding: porta 80 esterna → server interno 192.168.1.10:80
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.10:80
# Con nftables (più moderno)
nft add rule ip nat postrouting oifname "eth0" masquerade
nft add rule ip nat prerouting iifname "eth0" tcp dport 80 dnat to 192.168.1.10
Quella cosa che fa diventare HTTP in HTTPS e che scade sempre di venerdì alle 23:50.
Il browser vuole parlare con la banca in modo sicuro. La banca presenta un certificato firmato da una CA (Certificate Authority) che il browser già si fida. Il browser verifica la firma, genera una chiave di sessione usando crittografia asimmetrica, e da lì in poi tutto il traffico è cifrato con quella chiave simmetrica. Nessuno nel mezzo può leggere cosa stai scrivendo. A meno che non abbiano installato il loro certificato root nel tuo browser, ma questa è un'altra storia (ciao, aziende con proxy SSL inspection).
# Installa certbot
apt install certbot python3-certbot-nginx
# Ottieni certificato e configura nginx automaticamente
certbot --nginx -d esempio.it -d www.esempio.it
# Solo certificato (configuri nginx a mano)
certbot certonly --nginx -d esempio.it
# Rinnovo manuale (di solito è automatico via timer systemd)
certbot renew --dry-run # testa il rinnovo senza farlo
certbot renew
# I certificati finiscono in:
/etc/letsencrypt/live/esempio.it/fullchain.pem
/etc/letsencrypt/live/esempio.it/privkey.pem
# Scadenza: verifica
openssl x509 -in /etc/letsencrypt/live/esempio.it/fullchain.pem -noout -dates
# Controlla certificato di un sito live
openssl s_client -connect esempio.it:443 -servername esempio.it < /dev/null
echo | openssl s_client -connect esempio.it:443 2>/dev/null | openssl x509 -noout -dates -subject
# Genera chiave privata e CSR (Certificate Signing Request)
openssl genrsa -out server.key 4096
openssl req -new -key server.key -out server.csr
# Genera certificato self-signed (test locale)
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
# Verifica che chiave e certificato combacino
openssl x509 -noout -modulus -in cert.pem | md5sum
openssl rsa -noout -modulus -in key.pem | md5sum
# Se i md5 coincidono: fanno coppia
# Controlla chain completa
openssl verify -CAfile chain.pem cert.pem
TLS 1.3 (2018) è più veloce (1-RTT handshake), più sicuro (rimossi cipher deboli), e obbligatorio per qualsiasi deployment nuovo. nginx e Apache lo abilitano di default.
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
L'arsenale. Quelli che usi ogni volta che "non funziona la rete" e devi capire dove si è fermato il pacchetto.
Scopre host attivi, porte aperte, servizi in ascolto, versioni software, sistema operativo. Indispensabile. Usalo solo su reti che hai il diritto di scansionare.
# Scan base: host attivi in una subnet
nmap -sn 192.168.1.0/24
# Porte TCP più comuni su un host
nmap 192.168.1.100
# Scan completo tutte le porte TCP
nmap -p- 192.168.1.100
# Con rilevamento versione servizi e OS
nmap -sV -O 192.168.1.100
# Script NSE per vulnerabilità comuni
nmap --script vuln 192.168.1.100
# Scan veloce (-T4) con output verboso
nmap -T4 -v 192.168.1.0/24
# UDP scan (lento ma necessario per DNS/SNMP/etc)
nmap -sU -p 53,123,161 192.168.1.100
# Output su file (tutti i formati)
nmap -oA scan_result 192.168.1.0/24
# Tutto il traffico su eth0
tcpdump -i eth0
# Filtra per host
tcpdump -i eth0 host 8.8.8.8
# Filtra per porta
tcpdump -i eth0 port 443
# HTTP su qualsiasi porta con payload leggibile
tcpdump -i eth0 -A port 80
# Cattura su file, poi analizza con Wireshark
tcpdump -i eth0 -w cattura.pcap
tcpdump -r cattura.pcap
# Filtro composito: TCP dalla 192.168.1.10 verso porta 443
tcpdump -i eth0 'src 192.168.1.10 and tcp dst port 443'
# Wireshark: interfaccia grafica, apri il .pcap
# oppure cattura live: File → Capture → interfaccia
# Porte in ascolto (il comando che usi ogni 5 minuti)
ss -tlnp
# -t: TCP -l: listening -n: numerici -p: processo
# Tutte le connessioni stabilite
ss -tnp
# UDP in ascolto
ss -ulnp
# Filtra per porta
ss -tlnp sport = :443
# Chi usa la porta 3000?
ss -tlnp | grep :3000
lsof -i :3000 # alternativa, mostra anche il processo
fuser 3000/tcp # solo il PID
# Equivalente Windows
netstat -ano | findstr :3000
Get-NetTCPConnection -LocalPort 3000
# Ping base
ping -c 4 8.8.8.8 # layer 3: IP raggiungibile?
ping -c 4 google.com # anche DNS funziona?
# MTR: traceroute continuo con statistiche latenza/loss
mtr 8.8.8.8
mtr --report 8.8.8.8 # output non interattivo
# curl: testa HTTP/HTTPS
curl -I https://esempio.it # solo headers
curl -v https://esempio.it # verbose: mostra TLS handshake
curl -o /dev/null -w "%{http_code}\n" https://esempio.it # solo status code
curl -L https://esempio.it # segui redirect
curl --resolve esempio.it:443:1.2.3.4 https://esempio.it # forza IP specifico
# Test connettività TCP a una porta (senza curl)
nc -zv 192.168.1.10 5432 # PostgreSQL raggiungibile?
nc -zv -w 3 1.2.3.4 22 # SSH raggiungibile con timeout 3s?
Gli attacchi che esistono, come funzionano e perché hardening base non è opzionale. Sì, anche per quel server di test che "usiamo solo internamente".
L'attaccante si posiziona tra client e server, intercettando o modificando il traffico. Possibile su reti non cifrate o con ARP poisoning su LAN.
Difesa: TLS ovunque, HSTS, certificate pinning, DNSSEC. Su LAN: Dynamic ARP Inspection sugli switch gestiti.
Distributed Denial of Service: migliaia di source che saturano banda o risorse. Difficile da mitigare senza infrastruttura dedicata (Cloudflare, AWS Shield).
Difesa base: rate limiting, SYN cookies, blackhole routing per IP sorgenti, anycast. Per siti piccoli: CDN davanti.
L'attaccante manda ARP reply false sulla LAN per associare il suo MAC a un IP legittimo. Intercetta il traffico di quella coppia IP-MAC.
Difesa: static ARP entries per host critici, Dynamic ARP Inspection, segmentazione con VLAN.
Qualcuno sta mappando le porte aperte sulla tua rete. Di per sé non è un attacco, è ricognizione. Ma se vedi nmap sul tuo server da un IP sconosciuto, qualcuno sta pianificando qualcosa.
Difesa: fail2ban, port knocking, nascondere versioni dei servizi (server_tokens off), minimizzare le porte esposte.
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
banaction = nftables-multiport # o iptables-multiport
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
[nginx-http-auth]
enabled = true
port = http,https
logpath = %(nginx_error_log)s
[nginx-botsearch]
enabled = true
port = http,https
logpath = %(nginx_access_log)s
maxretry = 2
fail2ban-client status
fail2ban-client status sshd
fail2ban-client set sshd unbanip 1.2.3.4 # sblocca (te stesso)
"Non funziona la rete." Respira. Segui l'ordine. È quasi sempre il DNS.
Segui lo stack dal basso verso l'alto:
Layer 1 fisico: il cavo è connesso? Il LED di rete è acceso? Il WiFi è associato all'AP?
Layer 3 IP: hai un IP? ip addr show. Se vedi 169.254.x.x → DHCP non risponde.
Gateway: ping 192.168.1.1 (o il tuo gateway). Se non risponde, problema di rete locale.
DNS: ping 8.8.8.8. Se funziona → internet c'è ma DNS è rotto. dig google.com @8.8.8.8 per confermare.
Applicazione: curl -v https://esempio.it. Se DNS e ping funzionano ma HTTP no → firewall, TLS, servizio down.
1. Il DNS risolve? dig +short esempio.it. Se non risponde: record DNS mancante o resolver down.
2. L'IP è corretto? Confronta l'IP del DNS con quello del server. Propagazione DNS: puoi controllare su dnschecker.org.
3. La porta è aperta? nc -zv IP_SERVER 443. Se connection refused: nginx/apache non gira o non ascolta su quella porta.
4. Il firewall blocca? Sul server: nft list ruleset o ufw status. Cerca rule DROP sulla porta 80/443.
5. Il certificato è scaduto? echo | openssl s_client -connect esempio.it:443 2>/dev/null | openssl x509 -noout -dates. Se scaduto: certbot renew.
6. nginx/apache gira? systemctl status nginx. Controlla journalctl -u nginx -n 50 per errori.
Se hai console/KVM remoto: accedi dalla console, correggi le regole firewall, riapri SSH.
Se il server è cloud (AWS/GCP/Azure/Hetzner): accedi alla console web del provider → Recovery Mode o Serial Console.
Con ufw: ufw allow ssh && ufw reload dalla console.
Con nftables: nft flush ruleset svuota tutto (ti ri-espone ma almeno rientri).
Prevenzione: prima di abilitare un firewall su un server remoto, apri sempre due sessioni SSH. Se la seconda funziona, procedi.
WireGuard: wg show sul server. Controlla "latest handshake": se è 0 o molto vecchio, il tunnel non è attivo.
IP forwarding: sysctl net.ipv4.ip_forward deve essere 1. Se è 0: sysctl -w net.ipv4.ip_forward=1.
NAT masquerade: verifica che le regole PostUp di WireGuard abbiano aggiunto la regola NAT. iptables -t nat -L POSTROUTING.
AllowedIPs client: 0.0.0.0/0 per full tunnel, oppure le subnet specifiche per split tunnel. Se manca la subnet che ti serve, non passa.
DNS via VPN: se AllowedIPs include tutto ma DNS ancora va all'ISP, aggiungi DNS = 10.10.0.1 nel config client.
Rinnovo immediato: certbot renew --force-renewal && systemctl reload nginx.
Perché non si è rinnovato automaticamente? Controlla il timer: systemctl status certbot.timer. Controlla i log: journalctl -u certbot.
Porta 80 bloccata? Certbot challenge HTTP-01 usa la porta 80. Se è bloccata dal firewall o da redirect aggressivi, il rinnovo fallisce silenziosamente.
Prevenzione: aggiungi un monitoring sulla scadenza. Un semplice cron che manda email 30 giorni prima: echo | openssl s_client -connect esempio.it:443 2>/dev/null | openssl x509 -noout -checkend 2592000.
Test velocità resolver: dig @8.8.8.8 google.com, dig @1.1.1.1 google.com — confronta i tempi nella riga "Query time".
Cache locale avvelenata: su Linux: systemd-resolve --flush-caches. Su macOS: sudo dscacheutil -flushcache. Su Windows: ipconfig /flushdns.
TTL basso: se stai cambiando record DNS di frequente, abbassa il TTL PRIMA (es. a 300s), aspetta che si propaghi, poi fai le modifiche. Dopo rialza il TTL.
Pi-hole o resolver locale down: se usi un resolver locale e si ferma, tutta la rete perde il DNS. Configura sempre un resolver secondario come fallback.
Tutto quello che devi ricordare. Stampa, incolla sul muro, ignora fino a quando serve davvero.