Protezione di SSH con iptables

Esempi pratici di iptables per proteggere l'accesso SSH.

iptables è un'utility a riga di comando e l'interfaccia standard per gestire il firewall Netfilter integrato nel kernel Linux. Permette di creare e modificare regole che controllano come i pacchetti di rete vengono filtrati e instradati. Per lavorare con iptables sono necessari i privilegi di root.

Concetti fondamentali

Una regola è composta da un criterio di corrispondenza, un'azione target e un contatore di pacchetti. Quando un pacchetto in arrivo soddisfa il criterio, l'azione viene applicata e il contatore si incrementa. Le regole vengono valutate in ordine — la sequenza è importante.

  • Criterio — un'espressione logica che esamina le proprietà del pacchetto e della connessione per stabilire se la regola si applica. Più criteri vengono combinati con un AND logico.
  • Azione (target) — cosa fare con un pacchetto quando corrisponde al criterio: accettarlo, scartarlo, passarlo a un'altra chain e così via.
  • Contatore — tiene traccia di quanti pacchetti hanno soddisfatto la regola e della loro dimensione totale in byte.

Una chain è un elenco ordinato di regole. Le chain esistono in due varianti:

  • Chain predefinite — create automaticamente all'inizializzazione di una tabella. Ognuna ha una policy di default che si applica a qualsiasi pacchetto non abbinato da altre regole. I nomi delle chain predefinite sono sempre in maiuscolo: PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING.
  • Chain definite dall'utente — create manualmente, limitate alla propria tabella. Si consiglia di usare nomi in minuscolo per evitare confusione con le chain predefinite e i target.

Una tabella è un insieme di chain raggruppate per scopo. I nomi delle tabelle sono in minuscolo. Si specifica una tabella con il flag -t nome_tabella — se omesso, iptables utilizza filter come default.

1. Limitazione delle connessioni (protezione contro il brute force)

Per proteggersi dagli attacchi di forza bruta sulle password, puoi limitare il numero di nuove connessioni SSH da un singolo IP — ad esempio, 2 tentativi al minuto — e scartare tutto ciò che supera questa soglia.

## Crea la chain sshguard
/sbin/iptables -N sshguard

# Opzionale: registra i tentativi bloccati nel log
#/sbin/iptables -A sshguard -m state --state NEW -m recent --name SSH --rcheck --seconds 60 --hitcount 2 -j LOG --log-prefix "SSH-shield: "

# Scarta le connessioni che superano il limite di frequenza
/sbin/iptables -A sshguard -m state --state NEW -m recent --name SSH --update --seconds 60 --hitcount 2 -j DROP

# Accetta e registra l'IP se è sotto il limite
/sbin/iptables -A sshguard -m state --state NEW -m recent --name SSH --set -j ACCEPT
/sbin/iptables -A sshguard -j ACCEPT

## Instrada tutto il traffico SSH attraverso sshguard
/sbin/iptables -A INPUT -p tcp --dport 22 -j sshguard

Queste regole si basano sul modulo kernel recent, che gestisce liste dinamiche di indirizzi IP. Ecco cosa fa ciascuna opzione:

  • --name name — il nome della lista IP con cui lavorare (il default è DEFAULT)
  • --rcheck — verifica se l'IP del mittente è nella lista; restituisce false se non trovato
  • --update — come --rcheck, ma aggiorna anche il timestamp se l'IP viene trovato
  • --hitcount hits — restituisce true quando il conteggio dei pacchetti da un dato IP raggiunge o supera il valore specificato; usato con --rcheck o --update
  • --seconds seconds — definisce per quanto tempo un IP rimane nella lista dopo essere stato aggiunto
  • --set — aggiunge l'IP del mittente alla lista, o aggiorna la voce se già presente
  • --remove — rimuove un IP dalla lista; restituisce false se non trovato

Importante

Usare --update invece di --rcheck significa che ogni nuovo tentativo di connessione azzera il timer. Se qualcuno continua a tentare senza aspettare, il suo cooldown di 60 secondi ricomincia ogni volta da capo.

2. Apertura e chiusura dinamica della porta (port knocking)

Invece di lasciare SSH esposto continuamente, puoi nasconderlo dietro una sequenza di knock. La porta si apre solo per l'IP che invia il knock corretto — e si richiude su richiesta.

Per aprire l'accesso SSH, connettiti prima alla porta 1500 — tramite telnet:

telnet myserver 1500

o direttamente dal browser:

http://192.168.0.100:1500

Per chiuderla di nuovo, batti sulla porta 1499.

iptables -N sshguard

# Consenti la connessione se l'IP è già nella lista
iptables -A sshguard -m state --state NEW -m recent --rcheck --name SSH -j ACCEPT

# Consenti i pacchetti per connessioni già stabilite
iptables -A sshguard -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A sshguard -j DROP

# Apertura: aggiungi l'IP alla lista quando viene colpita la porta 1500
#iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 1500 -j LOG --log-prefix "SSH-open: "
iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 1500 -m recent --name SSH --set -j DROP

# Chiusura: rimuovi l'IP dalla lista quando viene colpita la porta 1499
iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 1499 -m recent --name SSH --remove -j DROP

## Instrada il traffico SSH attraverso sshguard
iptables -A INPUT -p tcp --dport 22 -j sshguard

L'accesso viene concesso solo all'IP che ha eseguito il knock.

3. Accesso SSH a tempo

Questo approccio ti permette di aprire SSH per un IP specifico per un intervallo di tempo fisso — utile quando hai bisogno di accesso temporaneo senza lasciare una porta permanentemente esposta.

## Crea e svuota la chain sshguard
iptables -N sshguard
iptables -F sshguard

# Consenti la connessione se l'IP è nella lista e l'ultima attività è entro 30 ore (108000 secondi)
iptables -A sshguard -m state --state NEW -m recent --update --seconds 108000 --name SSH -j ACCEPT

# Consenti i pacchetti per connessioni già stabilite
iptables -A sshguard -m state --state ESTABLISHED,RELATED -j ACCEPT

# Scarta tutto il resto
iptables -A sshguard -j DROP

## Registra l'IP quando viene colpita la porta 222
iptables -A INPUT -m state --state NEW -p tcp --dport 222 -m recent --name SSH --set

## Instrada il traffico SSH attraverso sshguard
iptables -A INPUT -p tcp --dport 22 -j sshguard

Per ottenere l'accesso, connettiti prima alla porta 222:

ssh user@server.name -p 222

Dopodiché, il tuo IP avrà accesso SSH per la durata specificata. Ogni connessione SSH successiva rinnova il timer. Se preferisci non estendere la finestra a ogni connessione, sostituisci --update --seconds 108000 con --rcheck.

L'accesso viene concesso solo all'IP che ha eseguito la connessione iniziale.

Per vedere quali IP hanno attualmente accesso SSH:

cat /proc/net/ipt_recent/SSH

Aiuto

Hai domande o ti serve una mano? Scrivici tramite il sistema di ticket — siamo sempre qui per aiutarti!

Hai bisogno di aiuto?I nostri ingegneri ti aiuteranno gratuitamente con qualsiasi domanda in pochi minutiContattaci