SSD Nodes Learn 🎉 VPS da $5.50/mese
Guide Matt ConnorDi Matt Connor · Aggiornato 2026-08-21

FTP passivo: perché il firewall blocca l'elenco file

Il login FTP riesce, ma l'elenco resta in attesa: configura un intervallo fisso di porte passive e autorizzalo nella regola del firewall.

Perché FTP accetta il login ma si blocca durante l'elenco delle directory

La modalità passiva di FTP non funziona attraverso un firewall perché FTP usa due connessioni TCP, non una sola. La connessione alla porta 21 trasporta il login e i comandi, quindi il nome utente e la password vengono accettati e il firewall sembra configurato correttamente. Il primo ls richiede quindi una seconda connessione su una porta diversa. Il firewall non consente questa connessione, quindi il client resta in attesa fino alla scadenza del timeout.

La soluzione consiste nel definire un intervallo fisso di porte per queste connessioni dati e nell'aggiungere una regola del firewall che consenta lo stesso intervallo. Un server dietro NAT (network address translation) richiede un'ulteriore impostazione per pubblicizzare l'indirizzo corretto. In passato gli helper per il connection tracking svolgevano automaticamente questa funzione. Oggi non lo fanno più. È importante capire il motivo prima di copiare una guida obsoleta.

Il canale di controllo e il canale dati

FTP (file transfer protocol) è definito nella RFC 959 ed è precedente sia al NAT sia al firewall stateful. Una sessione apre una connessione di controllo sulla porta TCP 21 e la mantiene attiva per tutta la sessione. I comandi vengono inviati in testo non cifrato. Le risposte sono costituite da un codice a tre cifre e da una riga di testo. Questa connessione non trasporta mai il contenuto dei file.

Ogni trasferimento di dati usa una connessione TCP distinta: una per un elenco di directory (LIST), una per ogni download (RETR) e una per ogni upload (STOR). La connessione viene aperta, usata una sola volta e chiusa. L'autenticazione avviene interamente sul canale di controllo, quindi un percorso dati non funzionante produce sempre lo stesso comportamento: accesso riuscito, quindi blocco. Se il client visualizza una risposta 230 e poi si blocca durante l'elenco, il problema riguarda il canale dati, non le credenziali.

Modalità attiva: il server si riconnette al client

In modalità attiva, il client sceglie una porta, resta in ascolto su quella porta e comunica al server la porta a cui connettersi:

PORT 192,168,1,50,195,80

I primi quattro numeri sono l'indirizzo IP del client. Gli ultimi due rappresentano la porta, codificata come due byte: 195 * 256 + 80 = 50000. Il server apre quindi la connessione dati dalla propria porta 20 verso la porta 50000 del client.

Dal punto di vista del client, questa connessione è in ingresso e non richiesta, quindi il firewall del client la blocca. Se il client si trova dietro un router domestico, l'indirizzo indicato nel comando PORT è un indirizzo privato che il server non può raggiungere. È in modalità attiva che FTP si è guadagnato la reputazione di protocollo che spesso non funziona.

Modalità passiva: il client apre entrambe le connessioni

La modalità passiva inverte la connessione dati. Il client invia PASV e il server risponde con un indirizzo e una propria porta:

227 Entering Passive Mode (203,0,113,10,195,80)

La codifica è la stessa, quindi il client si connette a 203.0.113.10 sulla porta 50000. Il client apre ora entrambe le connessioni. Per questo la modalità passiva funziona attraverso il NAT lato client e per questo tutti i client attuali la richiedono per prima.

Il problema si è spostato, non è scomparso. La connessione in ingresso non richiesta arriva ora al server, su una porta alta che cambia a ogni trasferimento. Quel firewall è sotto il tuo controllo, quindi ora il problema riguarda il tuo firewall.

EPSV (modalità passiva estesa, RFC 2428) segue lo stesso principio, ma usa una risposta più semplice:

229 Entering Extended Passive Mode (|||50000|)

La risposta non contiene alcun indirizzo. Il client riutilizza l'indirizzo già usato per la connessione di controllo. Questo permette il funzionamento su IPv6 ed elimina un'intera classe di problemi legati al NAT. Il manuale di curl indica che curl prova normalmente prima EPSV e poi PASV. La porta viene comunque scelta a runtime, quindi EPSV non modifica le regole del firewall.

Perché una normale regola del firewall non può consentire il canale dati

Il problema è che il numero di porta non esiste ancora quando si scrive la regola. Il server lo sceglie per ogni trasferimento. Con i valori predefiniti, vsftpd documenta pasv_min_port e pasv_max_port come 0, cioè «usa qualsiasi porta»: la connessione dati può quindi arrivare su qualsiasi porta superiore a 1023. sudo ufw allow 21/tcp consente il canale di controllo e nient’altro. È esattamente questa configurazione a produrre un login funzionante e un elenco delle directory che non viene caricato. Se il concetto di un servizio in ascolto su una porta fissa non è ancora chiaro, come funzionano le porte e i socket in ascolto su Linux fornisce il contesto necessario.

Un firewall stateful tiene traccia delle connessioni e il kernel può accettare una nuova connessione come RELATED a una connessione esistente. Per FTP, però, è necessario che un componente legga il flusso di controllo ed estragga la porta da una riga 227 o PORT. Per impostazione predefinita, non lo fa alcun componente.

Perché l'helper di tracking delle connessioni FTP non è più la soluzione

Il modulo del kernel nf_conntrack_ftp è quello indicato dalle guide meno recenti. Legge il canale di controllo in chiaro, individua la porta annunciata e registra un'aspettativa, così la connessione dati viene autorizzata senza alcuna regola che ne specifichi la porta. Da quando sono state scritte quelle guide, sono cambiate quattro cose.

L'assegnazione automatica degli helper è disabilitata. La documentazione del kernel indica il sysctl nf_conntrack_helper come "0 - disabled (default)" e aggiunge: "If disabled it is required to set up iptables rules to assign helpers to connections." Caricare il modulo, da solo, non produce alcun effetto.

Nei kernel attuali l'opzione è stata rimossa. Eseguire sysctl net.netfilter.nf_conntrack_helper. Una risposta sysctl: cannot stat /proc/sys/net/netfilter/nf_conntrack_helper: No such file or directory indica che il kernel non dispone più dell'assegnazione automatica degli helper da riattivare. Se viene restituito un numero, l'opzione è ancora presente e il valore predefinito è 0.

Anche i frontend del firewall l'hanno dichiarata deprecata. man ufw-framework su Ubuntu 24.04 definisce la riga IPT_MODULES in /etc/default/ufw come segue: "Unconditional loading of connection tracking modules (nf_conntrack_*) in this manner is deprecated" e aggiunge che le regole degli helper "must be managed in via the RULES FILES". firewalld documenta AutomaticHelpers in firewalld.conf come "Deprecated. This option is ignored and no longer used." Per associare ora un helper è necessario scrivere manualmente una regola esplicita con il target CT. È più complesso della correzione descritta di seguito e smette di funzionare non appena si abilita TLS. iptables e nftables su Ubuntu spiega dove si trovano effettivamente queste regole.

TLS rende la soluzione impraticabile. Un helper funziona leggendo il canale di controllo come testo. Quando il canale viene cifrato, l'helper vede testo cifrato e non può individuare la porta. Non esiste una correzione per questo comportamento, e non dovrebbe esistere: un dispositivo intermedio in grado di leggere il canale di controllo è un dispositivo intermedio che ha letto la password.

Dichiarare un intervallo di porte passive sul server

Ogni server FTP può essere configurato per scegliere le porte passive da un intervallo definito dall'amministratore. I nomi delle opzioni cambiano, quindi consultare la documentazione del server effettivamente in uso.

vsftpd, in /etc/vsftpd.conf:

pasv_enable=YES
pasv_min_port=30000
pasv_max_port=30099

pasv_enable ha già come valore predefinito YES. Le due opzioni delle porte hanno come valore predefinito 0, cioè il comportamento «usa qualsiasi porta» descritto sopra. Applicare la modifica con sudo systemctl restart vsftpd, quindi verificare che il servizio sia nuovamente attivo con systemctl status vsftpd. vsftpd non ignora una riga di configurazione che non riesce ad analizzare: rifiuta invece di avviarsi. Se il riavvio non riesce, leggere journalctl -u vsftpd -n 20 per trovare la riga 500 OOPS: che identifica l'opzione appena inserita.

ProFTPD, in proftpd.conf:

PassivePorts 30000 30099

ProFTPD non documenta alcun valore predefinito per questa impostazione: senza la direttiva, la porta viene scelta dal kernel. La documentazione specifica inoltre che, quando nessuna porta dell'intervallo è libera, il server ripiega su una porta assegnata dal kernel e registra un messaggio nel log. Un intervallo troppo piccolo causa quindi errori intermittenti invece di un errore immediato e chiaro, rendendo la diagnosi molto più difficile. Usare porte non privilegiate, a partire da 1024.

Pure-FTPd usa il flag -p first:last, documentato in man pure-ftpd come «Usa innanzitutto, per i download in modalità passiva, soltanto le porte comprese nell'intervallo da first a last», il che «rende pure-ftpd più compatibile con i filtri dei pacchetti». Le build distribuite tramite pacchetti racchiudono solitamente questo flag in un file di configurazione; consultare quindi la documentazione della propria distribuzione per conoscere il nome del file, senza fare supposizioni.

Quante porte servono? Una per ogni connessione dati attiva. Dopo la chiusura, una porta TCP rimane nello stato TIME_WAIT per un paio di minuti prima di poter essere riutilizzata, quindi è opportuno prevedere un numero di porte diverse volte superiore al picco previsto. Un centinaio di porte è sufficiente per alcuni utenti; un server pubblico con traffico elevato ne richiede molte di più.

Dove collocare l'intervallo? Eseguire prima sysctl net.ipv4.ip_local_port_range. Su un'installazione Ubuntu standard l'output è 32768 60999, cioè l'intervallo di porte che il kernel assegna alle connessioni in uscita. Un intervallo di porte passive all'interno di questa finestra può entrare in conflitto con una connessione in uscita che utilizza già la porta, quindi è consigliabile mantenere l'intervallo al di sotto di essa. Da 30000 a 30099 l'intervallo è libero su un'installazione predefinita. Verificare comunque il sistema in uso invece di affidarsi a quel valore.

Aprire lo stesso intervallo nel firewall

ufw definisce un intervallo con i due punti e il relativo manuale specifica che un intervallo o un elenco «può essere usato anche per specificare più porte; in questo caso il protocollo è obbligatorio»:

sudo ufw allow 21/tcp
sudo ufw allow 30000:30099/tcp
sudo ufw status verbose

ufw status verbose dovrebbe ora elencare entrambe le regole. Lo stesso comando senza /tcp viene rifiutato con un errore che richiede di specificare tcp o udp, perché ufw non sceglie il protocollo in modo automatico. sintassi delle regole ufw su un VPS illustra gli altri casi.

firewalld definisce l’intervallo con un trattino e richiede un reload:

sudo firewall-cmd --permanent --add-service=ftp
sudo firewall-cmd --permanent --add-port=30000-30099/tcp
sudo firewall-cmd --reload
sudo firewall-cmd --list-all

--add-service=ftp apre 21/tcp e richiede l’helper ftp indicato dalla definizione del servizio fornita con il prodotto. Non apre l’intervallo per le connessioni passive, quindi da solo lascia la situazione invariata. zone e servizi firewalld su un VPS fornisce il quadro completo.

nftables in forma diretta, nella catena input:

tcp dport { 21, 30000-30099 } accept

Occorre considerare anche un altro firewall: la maggior parte dei provider gestisce un firewall di rete nel pannello di controllo, esterno al sistema operativo. Se le regole sul server sono corrette ma i pacchetti continuano a non arrivare, aprire lo stesso intervallo anche in quel firewall.

Indicare al server il proprio indirizzo pubblico quando si trova dietro NAT

Eseguire ip -4 addr show sul server. Se l'indirizzo dell'interfaccia è quello a cui si connettono i client, saltare questa sezione. Se l'interfaccia ha un indirizzo privato (10.x, da 172.16 a 172.31.x, 192.168.x) e la piattaforma vi associa un indirizzo pubblico, il server non conosce il proprio indirizzo pubblico. La documentazione di vsftpd indica che il valore predefinito di pasv_address è «the address is taken from the incoming connected socket», quindi la risposta 227 contiene l'indirizzo privato e il client viene indirizzato verso una destinazione che non può raggiungere.

FileZilla indica questa situazione con il messaggio seguente:

Server sent passive reply with unroutable address. Using server address instead.

FileZilla corregge il problema e prosegue. Molti altri client non lo fanno. Si connettono a 10.0.0.5 e rimangono in attesa.

Anche curl nasconde il problema, aspetto rilevante se lo si usa per i test. Il manuale indica che --ftp-skip-pasv-ip «is enabled by default (added in 7.74.0)», quindi curl ignora l'indirizzo nella risposta 227 e riutilizza quello della connessione di controllo. Un trasferimento che funziona con curl può comunque non riuscire in un client grafico per questo unico motivo.

Impostare esplicitamente l'indirizzo. vsftpd accetta pasv_address=203.0.113.10, oltre a pasv_addr_resolve=YES (valore predefinito NO) se si preferisce specificare un hostname. ProFTPD accetta MasqueradeAddress, che può contenere un indirizzo, un nome DNS o il nome di un'interfaccia. Pure-FTPd accetta -P, documentato per il caso in cui «the server is behind a masquerading (NAT) box». EPSV evita completamente il problema, perché la risposta non contiene alcun campo indirizzo; tuttavia non si può fare affidamento su questo comportamento, poiché è il client a decidere quale comando inviare.

Cosa cambia con TLS

FTPS è FTP su TLS (Transport Layer Security). Il client si connette alla porta 21 come di consueto, invia AUTH TLS per proteggere il canale di controllo, quindi invia PROT P per cifrare anche il canale dati. FTP in chiaro trasmette la password sulla rete come testo leggibile; se devi continuare a usare FTP, esegui FTPS. vsftpd viene fornito con ssl_enable impostato su NO.

Ne conseguono due aspetti. Nessun helper per il connection tracking può funzionare: è lo stesso problema descritto sopra, visto dall'altro lato. Inoltre, sudo tcpdump -nAi any 'tcp port 21' non mostrerà più la risposta 227; quando devi sapere quale indirizzo e quale porta ha annunciato il server, consulta il log del server invece del traffico di rete.

Test della modifica dall'esterno

Eseguire questi comandi da un'altra macchina. Eseguire i test direttamente dal server bypassa il firewall che si sta cercando di correggere.

sudo ss -ltnp | grep :21
curl -v --disable-epsv --user ftpuser:secret ftp://example.com/
nc -vz example.com 30000

ss dovrebbe mostrare il demone FTP in ascolto sulla porta 21. Quando il server è inattivo, nessun processo resta in ascolto sull'intervallo passivo, perché questi socket vengono creati per un trasferimento e chiusi al termine.

--disable-epsv forza curl a usare il percorso PASV, che è quello che espone il problema dell'indirizzo. Il trace stampa la risposta del server, quindi l'indirizzo e la porta a cui curl si connette:

< 227 Entering Passive Mode (203,0,113,10,117,52)

117 * 256 + 52 = 30004, all'interno dell'intervallo dichiarato. Un indirizzo privato su quella riga indica che pasv_address non è impostata. Una porta esterna all'intervallo indica che il server non ha mai letto la modifica alla configurazione; verificare quindi di aver modificato il file utilizzato dal servizio in esecuzione.

nc risponde direttamente alla domanda sul firewall. Un Connection refused immediato indica che il pacchetto ha raggiunto il server, ma non ha trovato alcun processo in ascolto: è il risultato corretto per una porta passiva inattiva e significa che la regola funziona. Un'attesa fino a quando nc rinuncia indica che qualcosa ha eliminato il pacchetto senza risposta. Si tratta di un firewall, quello del server oppure quello configurato nel pannello del provider. La distinzione è la stessa descritta in connessione SSH rifiutata o scaduta e si applica a ogni porta.

È ancora opportuno usare FTP?

Per i nuovi progetti, no. SFTP (SSH file transfer protocol) opera all'interno di un'unica connessione SSH sulla porta 22. Non esistono un secondo canale, un intervallo passivo, una configurazione NAT o un demone aggiuntivo da proteggere, perché queste funzioni sono già fornite da OpenSSH. sftp user@example.com funziona su un server in cui non è mai stato configurato alcun servizio di trasferimento file. Per fornire a qualcuno soltanto dei file, e nient'altro, sshd_config utilizza ForceCommand internal-sftp insieme a ChrootDirectory. La directory deve essere di proprietà di root e non deve essere scrivibile dall'utente; in caso contrario, sshd rifiuta la sessione e registra una riga bad ownership or modes for chroot directory.

FTP rimane utile quando l'altra estremità non può essere modificata. Scanner e stampanti multifunzione vengono distribuiti con firmware che supporta soltanto FTP. Le apparecchiature di laboratorio e industriali spesso utilizzano un'immagine fissa che nessuno certificherà nuovamente. I partner commerciali pubblicano un'area di scambio FTPS e non aggiungeranno un protocollo per un singolo fornitore. In tutti questi casi, l'intervallo passivo e la regola firewall corrispondente costituiscono l'intero lavoro, e la versione da usare è FTPS, non FTP in chiaro. Il design a due canali è una decisione del 1985 che oggi opera in un mondo non previsto all'epoca, una storia descritta in la storia dei protocolli di trasferimento file.

FAQ

Perché FTP esegue il login ma il listing della directory resta bloccato?

Il login usa soltanto la connessione di controllo sulla porta 21, consentita dal firewall. Il listing della directory richiede una seconda connessione TCP su un'altra porta, che viene bloccata. Dichiarare un intervallo di porte passive sul server FTP e aprire lo stesso intervallo nel firewall consente di completare il listing. Un listing bloccato indica un problema del canale dati, non della password.

Quali porte devo aprire per la modalità passiva di FTP?

La porta 21 per il canale di controllo, più l'intervallo configurato per le connessioni dati passive. Non esiste un intervallo standard, perché lo scegli tu. Un intervallo come 30000-30099 è adatto: dimensionarlo in base al numero massimo di trasferimenti simultanei e mantenerlo separato dall'intervallo di porte in uscita del kernel, che puoi leggere con sysctl net.ipv4.ip_local_port_range. Se il provider gestisce un firewall di rete nel proprio pannello di controllo, aprire lo stesso intervallo anche lì.

Ho ancora bisogno di nf_conntrack_ftp?

No, e con un kernel attuale non puoi farci affidamento. L'assegnazione automatica degli helper è disabilitata per impostazione predefinita e, nei kernel recenti, l'opzione net.netfilter.nf_conntrack_helper è stata rimossa; per questo sysctl segnala che il file non esiste. Il manuale di ufw considera deprecato il caricamento incondizionato di questi moduli e firewalld ignora completamente AutomaticHelpers. Inoltre, un helper deve leggere il canale di controllo come testo in chiaro, quindi smette di funzionare non appena abiliti FTPS. Dichiara invece un intervallo di porte passive.

Perché il client FTP segnala che la risposta passiva contiene un indirizzo non instradabile?

Il server ha risposto a PASV con l'indirizzo rilevato sulla propria interfaccia, ma quell'indirizzo è privato. Questo accade quando la piattaforma associa un indirizzo pubblico a uno privato. Imposta esplicitamente l'indirizzo pubblico: pasv_address in vsftpd, MasqueradeAddress in ProFTPD oppure -P in Pure-FTPd. FileZilla aggira il problema riutilizzando l'indirizzo a cui si era già connesso e registra "Using server address instead"; per questo alcuni client superano la configurazione errata mentre altri restano bloccati.

Devo usare FTPS o SFTP?

SFTP per tutto ciò che controlli su entrambe le estremità: usa una sola connessione SSH sulla porta 22, non richiede l'apertura di un canale dati ed è già in esecuzione. FTPS è FTP su TLS, quindi conserva il modello a due canali e tutti i problemi di firewall associati. Sceglilo quando l'altra estremità non supporta altro. Non usare FTP in chiaro su Internet, perché la password attraversa la rete come testo leggibile.