Perché conta
Un servizio SSH esposto su Internet viene trovato in pochi minuti e subisce brute force continui. Anche con SSH hardening ben fatto resta una superficie d’attacco: se domani esce una vulnerabilità pre-auth nel demone, sei esposto finché non patchi. L’idea del port knocking è ribaltare il problema: la porta 22 è chiusa per tutti, e si apre solo per l’IP di chi dimostra di conoscere un segreto.
È un controllo di riduzione della superficie, non un sostituto dell’autenticazione: lo scanner non vede nulla, quindi non ha nulla da attaccare. Nel linguaggio dello Zero Trust è un piccolo esempio di “dark service”: la risorsa non risponde finché il client non è autenticato.
Come funziona
Nel port knocking il client manda pacchetti (SYN) a una sequenza di porte chiuse, nell’ordine giusto. Il firewall registra i tentativi (non c’è nessun demone in ascolto) e, a sequenza completa, apre la porta per l’IP sorgente per un tempo limitato. La Single Packet Authorization (SPA) sostituisce la sequenza con un solo pacchetto UDP cifrato e autenticato, verificato da un demone che sniffa l’interfaccia.
sequenceDiagram
participant C as Client
participant F as Firewall (nftables)
participant S as sshd
C->>F: SYN :7000 (drop, set k1)
C->>F: SYN :8000 (drop, set k2)
C->>F: SYN :9000 (drop, set ssh_ok, 30s)
Note over F: IP del client in ssh_ok
C->>F: SYN :22
F->>S: accept (ct state new)
S-->>C: SSH handshake
Note over F: dopo 30s nuove connessioni di nuovo drop
Quanto vale la sequenza come segreto? Con $k$ porte scelte tra $65535$ possibili l’entropia è
$$H = k \cdot \log_2(65535) \approx 16k \ \text{bit}$$
Con $k=3$ sono circa 48 bit: fuori portata per un brute force online (ogni tentativo richiede 3 pacchetti e il firewall non dà nessun feedback). Il vero punto debole non è il guessing ma il replay: la sequenza viaggia in chiaro, e chi la osserva sul percorso (Wi-Fi pubblico, ISP, un router compromesso) la ripete dal proprio IP.
L’attacco
Il lato attaccante ha due strade. La prima è passiva: catturare il traffico verso il server e leggere la sequenza delle porte contattate.
|
|
Poi il replay dal proprio IP, che apre la porta 22 per l’attaccante (se condivide l’IP del client, ad esempio dietro lo stesso NAT, non serve nemmeno falsificare nulla):
|
|
Il knock classico ha altri limiti: la sequenza è fissa (nessun nonce), il tempo tra i colpi può essere perturbato, e un pacchetto SYN casuale non può essere autenticato perché non porta payload. Per questo la SPA mette il segreto dentro il pacchetto.
La difesa
Knock in nftables. Tre insiemi dinamici con timeout fanno da macchina a stati: ogni porta è accettata solo se l’IP è già nell’insieme dello stadio precedente.
|
|
Il timeout di 30 secondi vale solo per aprire la nuova connessione: quella già stabilita resta in piedi grazie
alla regola established,related, quindi la finestra utile per un attaccante è breve. Per i dettagli su
conntrack e sui set vedi stateful firewall con nftables.
SPA con fwknop. Il pacchetto contiene IP, porta richiesta, timestamp e un valore casuale, cifrato con
AES e autenticato con HMAC (RFC 2104). Il server rifiuta pacchetti con firma sbagliata e ripetizioni dello
stesso pacchetto, e non ha nessuna porta in ascolto: fwknopd legge i pacchetti con libpcap.
|
|
|
|
Vale per entrambe le tecniche: non è una difesa unica. Tienilo sopra a un SSH già indurito (solo chiavi, niente password), registra i tentativi sul SIEM e ricorda che un servizio nascosto non sparisce per chi ha già accesso alla rete interna: lì servono microsegmentazione e identità.
Lab
Con due container (o due VM) e nftables sul server:
- Carica il ruleset sopra e verifica che
nmap -p 22 <server>diafiltered. - Colpisci le porte in ordine con
nc -z, poi connettiti via SSH. Quanto dura la finestra? - Colpisci le porte nell’ordine sbagliato (9000, 8000, 7000): la porta 22 si apre? Perché?
- Da un terzo host, registra con
tcpdumpil knock e ripetilo. Che cosa dimostra?
Soluzione
nmapriportafiltered: la policydropnon risponde nemmeno con un RST, quindi lo scanner non distingue una porta chiusa da un host spento.- Per 30 secondi (
timeoutdissh_ok) si possono aprire nuove connessioni;nft list set inet filter ssh_okmostra l'IP e il tempo residuo. Le connessioni già stabilite non vengono chiuse. - No. La porta 9000 richiede l'IP in
k2, ek2si popola solo dopo un colpo valido su 8000 con l'IP ink1. L'ordine sbagliato non fa avanzare la macchina a stati. - Il replay funziona dal terzo host solo se ha l'IP sorgente giusto o se il server non lega il knock a nulla di più che l'IP: dimostra che la sequenza è un segreto riutilizzabile. Con fwknop lo stesso test fallisce, perché il pacchetto contiene un nonce e il server scarta i duplicati.
Conclusione
Port knocking e SPA riducono la superficie d’attacco, non la eliminano. Il knock con nftables è perfetto per un laboratorio e per capire la macchina a stati; in produzione la SPA di fwknop evita replay e forgery con costi operativi contenuti. In entrambi i casi il segreto che apre il firewall deve essere trattato come una credenziale: ruotarlo, non scriverlo negli script condivisi e monitorare chi lo usa.
Per approfondire: SSH hardening · Torna alla roadmap