SSD Nodes Learn 🎉 VPS dès $5.50/mois
Guides Matt ConnorPar Matt Connor · Mis à jour le 2026-08-21

FTP passif : le pare-feu bloque l’affichage des dossiers

La connexion FTP réussit, puis le listing reste bloqué : ouvrez la plage de ports passifs du canal de données et appliquez la règle au pare-feu.

Pourquoi la connexion FTP fonctionne mais pas l’affichage du contenu du répertoire

Le mode passif FTP échoue derrière un pare-feu, car FTP utilise deux connexions TCP et non une seule. La connexion au port 21 transporte l’authentification et les commandes. Le nom d’utilisateur et le mot de passe sont donc acceptés, et le pare-feu semble correctement configuré. La première ls doit ensuite établir une seconde connexion sur un autre port. Aucune règle du pare-feu ne l’autorise, et le client attend jusqu’à l’expiration du délai.

La solution consiste à définir une plage fixe de ports pour ces connexions de données, puis à autoriser cette même plage dans le pare-feu. Un serveur situé derrière un NAT (network address translation) nécessite un paramètre supplémentaire pour annoncer la bonne adresse. Les helpers de suivi des connexions s’en chargeaient auparavant automatiquement. Ce n’est plus le cas, et il est important d’en comprendre la raison avant de reprendre une ancienne procédure.

Le canal de contrôle et le canal de données

Le FTP (File Transfer Protocol) est défini dans la RFC 959 et est antérieur au NAT et au pare-feu stateful. Une session ouvre une connexion de contrôle vers le port TCP 21 et la conserve pendant toute la session. Les commandes sont transmises en texte brut. Les réponses comportent un code à trois chiffres et une ligne de texte. Cette connexion ne transporte jamais le contenu des fichiers.

Chaque élément de données utilise sa propre connexion TCP : une pour une liste de répertoire (LIST), une pour chaque téléchargement (RETR) et une pour chaque envoi (STOR). La connexion est ouverte, utilisée une seule fois, puis fermée. L’authentification s’effectue entièrement sur le canal de contrôle. Un chemin de données défaillant se manifeste donc toujours de la même manière : la connexion est établie, puis le client se bloque. Si le client affiche une réponse 230, puis s’arrête pendant la génération de la liste, le problème concerne le canal de données et non les identifiants.

Mode actif : le serveur se reconnecte au client

En mode actif, le client choisit un port, se met à l’écoute sur ce port et indique au serveur où se connecter :

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

Les quatre premiers nombres correspondent à l’adresse IP du client. Les deux derniers indiquent le port, encodé sur 2 octets : 195 * 256 + 80 = 50000. Le serveur ouvre ensuite la connexion de données depuis son propre port 20 vers le port 50000 du client.

Du point de vue du client, cette connexion est entrante et non sollicitée. Le pare-feu du client la bloque donc. Si le client se trouve derrière un routeur domestique, l’adresse indiquée dans la commande PORT est une adresse privée que le serveur ne peut pas joindre. C’est le mode actif qui a valu au FTP sa réputation de protocole difficile à faire fonctionner.

Mode passif : le client ouvre les deux connexions

Le mode passif inverse la connexion de données. Le client envoie PASV et le serveur répond avec sa propre adresse et son propre port :

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

L’encodage est identique. Le client se connecte donc à 203.0.113.10 sur le port 50000. Le client ouvre alors les deux connexions. C’est pourquoi le mode passif fonctionne derrière le NAT côté client et pourquoi tous les clients actuels le demandent en premier.

Le problème a été déplacé, pas supprimé. La connexion entrante non sollicitée arrive désormais sur votre serveur, sur un port élevé qui change à chaque transfert. Ce pare-feu vous appartient, donc le problème vous appartient désormais.

EPSV (mode passif étendu, RFC 2428) repose sur le même principe, avec une réponse plus simple :

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

Elle ne contient aucune adresse. Le client réutilise l’adresse qu’il utilise déjà pour la connexion de contrôle. C’est ce qui permet au mode passif de fonctionner avec IPv6 et élimine toute une catégorie de problèmes liés au NAT. Le manuel de curl indique que curl essaie normalement EPSV avant PASV. Le port est toujours choisi au moment de l’exécution. EPSV ne change donc rien à vos règles de pare-feu.

Pourquoi une règle de pare-feu classique ne peut pas autoriser le canal de données

Le numéro de port n’existe pas encore lorsque vous écrivez la règle. Le serveur le choisit pour chaque transfert. Avec sa configuration par défaut, vsftpd documente pasv_min_port et pasv_max_port comme 0, c’est-à-dire « utiliser n’importe quel port ». La connexion de données peut donc arriver sur n’importe quel port supérieur à 1023. sudo ufw allow 21/tcp autorise le canal de contrôle, et rien d’autre. C’est exactement la configuration qui permet une connexion réussie, mais empêche l’affichage du contenu des répertoires. Si la notion de service à l’écoute sur un port fixe reste floue, consultez le fonctionnement des ports et des sockets en écoute sous Linux.

Un pare-feu stateful suit bien l’état des connexions, et le noyau peut autoriser une nouvelle connexion comme RELATED d’une connexion existante. Avec FTP, cela nécessite qu’un composant lise le flux de contrôle et récupère le port dans une ligne 227 ou PORT. Rien ne le fait par défaut.

Pourquoi le helper de suivi des connexions FTP n’est plus la solution

Le module du noyau nf_conntrack_ftp est celui indiqué par les anciens guides. Il lit le canal de contrôle en clair, trouve le port annoncé et enregistre une attente. La connexion de données est ainsi autorisée sans règle faisant référence à son port. Quatre éléments ont changé depuis la rédaction de ces guides.

L’attribution automatique des helpers est désactivée. Le noyau documente le sysctl nf_conntrack_helper avec la valeur « 0 - disabled (default) » et précise : « If disabled it is required to set up iptables rules to assign helpers to connections. » Charger le module ne suffit donc pas.

Sur les noyaux actuels, ce commutateur a disparu. Exécutez sysctl net.netfilter.nf_conntrack_helper. Une réponse sysctl: cannot stat /proc/sys/net/netfilter/nf_conntrack_helper: No such file or directory signifie que le noyau ne dispose plus d’une attribution automatique des helpers à activer. Si une valeur numérique est renvoyée, le commutateur existe encore et sa valeur par défaut est 0.

Les interfaces de configuration du pare-feu l’ont également rendu obsolète. man ufw-framework sur Ubuntu 24.04 indique à propos de la ligne IPT_MODULES dans /etc/default/ufw : « Unconditional loading of connection tracking modules (nf_conntrack_*) in this manner is deprecated », et précise que les règles de helper « must be managed in via the RULES FILES ». firewalld documente AutomaticHelpers dans firewalld.conf comme suit : « Deprecated. This option is ignored and no longer used. » Attacher un helper nécessite désormais d’écrire manuellement une règle explicite avec la cible CT. C’est plus complexe que la correction ci-dessous et cela cesse de fonctionner dès que vous activez TLS. iptables et nftables sur Ubuntu explique où ces règles sont réellement définies.

TLS met fin au débat. Un helper fonctionne en lisant le canal de contrôle sous forme de texte. Si ce canal est chiffré, le helper ne voit que du texte chiffré et ne peut pas trouver le port. Il n’existe aucune correction à ce problème, et il ne devrait pas y en avoir : un équipement intermédiaire capable de lire votre canal de contrôle est un équipement intermédiaire qui a lu votre mot de passe.

Déclarer une plage de ports passifs sur le serveur

Chaque serveur FTP peut être configuré pour choisir ses ports passifs dans une plage définie par vos soins. Les noms des options varient. Consultez donc la documentation du serveur que vous utilisez réellement.

vsftpd, dans /etc/vsftpd.conf :

pasv_enable=YES
pasv_min_port=30000
pasv_max_port=30099

pasv_enable utilise déjà YES par défaut. Les deux options de port utilisent 0 par défaut, ce qui correspond au comportement « utiliser n’importe quel port » décrit plus haut. Appliquez la configuration avec sudo systemctl restart vsftpd, puis vérifiez que le service a redémarré avec systemctl status vsftpd. vsftpd refuse de démarrer lorsqu’il ne peut pas analyser une ligne de configuration, au lieu de l’ignorer. Si le redémarrage échoue, consultez journalctl -u vsftpd -n 20 pour trouver la ligne 500 OOPS: qui indique l’option que vous venez de saisir.

ProFTPD, dans proftpd.conf :

PassivePorts 30000 30099

La documentation de ProFTPD ne définit aucune valeur par défaut ici : sans cette directive, le kernel choisit le port. Elle indique également que, lorsqu’aucun port de votre plage n’est disponible, le serveur utilise un port attribué par le kernel et consigne un message. Une plage trop petite provoque donc des échecs intermittents au lieu d’un échec explicite, ce qui est beaucoup plus difficile à diagnostiquer. Utilisez des ports non privilégiés, à partir de 1024.

Pure-FTPd utilise l’option -p first:last, documentée dans man pure-ftpd comme suit : « utiliser uniquement les ports compris entre le premier et le dernier port inclus pour les téléchargements en mode passif », ce qui « rend pure-ftpd plus compatible avec les packet filters ». Les paquets distribués intègrent généralement cette option dans un fichier de configuration. Consultez donc la documentation de votre distribution pour connaître le nom du fichier au lieu de le deviner.

De combien de ports avez-vous besoin ? D’un port par connexion de données active. Un port TCP fermé reste dans TIME_WAIT pendant quelques minutes avant de pouvoir être réutilisé. Prévoyez donc plusieurs fois le nombre correspondant à votre pic d’activité prévu. Une centaine de ports suffit confortablement pour quelques utilisateurs. Un serveur public très sollicité en nécessite beaucoup plus.

Où placer cette plage ? Exécutez d’abord sysctl net.ipv4.ip_local_port_range. Sur une installation Ubuntu standard, la commande affiche 32768 60999, c’est-à-dire les ports que le kernel attribue aux connexions sortantes. Une plage passive située dans cette fenêtre peut entrer en conflit avec une connexion sortante qui utilise déjà le port. Placez donc la plage en dessous. 30000 à 30099 sont disponibles sur une installation par défaut. Vérifiez la configuration de votre propre serveur au lieu de vous fier à cette valeur.

Ouvrir la même plage dans le pare-feu

ufw utilise deux-points pour écrire une plage. Sa page de manuel précise qu’une plage ou une liste « peut également servir à spécifier plusieurs ports, auquel cas le protocole est obligatoire » :

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

ufw status verbose doit maintenant afficher les deux entrées. La même commande sans /tcp est rejetée avec une erreur vous demandant d’indiquer tcp ou udp, car ufw ne devine pas le protocole. syntaxe des règles ufw sur un VPS couvre le reste.

firewalld utilise un tiret pour écrire la plage et nécessite un rechargement :

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 ouvre 21/tcp et demande l’helper ftp, qui est défini par la définition de service fournie. Cette commande n’ouvre pas votre plage de ports passifs. À elle seule, elle vous laisse donc exactement dans la situation de départ. zones et services firewalld sur un VPS présente le fonctionnement global.

Avec nftables directement, dans votre chaîne input :

tcp dport { 21, 30000-30099 } accept

Il faut également tenir compte d’un autre pare-feu : la plupart des fournisseurs exécutent un pare-feu réseau dans le panneau de contrôle, en dehors du système d’exploitation. Si les règles du serveur semblent correctes, mais que les paquets n’arrivent toujours pas, ouvrez-y également la même plage.

Indiquer l’adresse publique du serveur derrière un NAT

Exécutez ip -4 addr show sur le serveur. Si l’adresse de l’interface est celle à laquelle les clients se connectent, ignorez cette section. Si l’interface possède une adresse privée (10.x, 172.16 à 172.31.x, 192.168.x) et que la plate-forme lui associe une adresse publique, le serveur ne connaît pas sa propre adresse publique. La documentation de vsftpd indique que la valeur par défaut de pasv_address est « l’adresse est extraite du socket connecté entrant ». La réponse 227 contient donc l’adresse privée, et le client est redirigé vers une adresse qu’il ne peut pas atteindre.

FileZilla nomme précisément ce problème :

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

FileZilla le corrige et poursuit le transfert. Beaucoup d’autres clients ne le font pas. Ils se connectent à 10.0.0.5 et restent bloqués.

curl masque également le problème, ce qui est important si vous l’utilisez pour vos tests. Sa documentation indique que --ftp-skip-pasv-ip « est activé par défaut (ajouté dans 7.74.0) ». curl ignore donc l’adresse contenue dans la réponse 227 et réutilise l’adresse de la connexion de contrôle. Un transfert qui fonctionne avec curl peut tout de même échouer dans un client graphique pour cette seule raison.

Définissez explicitement l’adresse. vsftpd utilise pasv_address=203.0.113.10, ainsi que pasv_addr_resolve=YES (valeur par défaut : NO) si vous préférez indiquer un nom d’hôte. ProFTPD utilise MasqueradeAddress, qui accepte une adresse, un nom DNS ou un nom d’interface. Pure-FTPd utilise -P, prévu notamment lorsque « le serveur se trouve derrière un équipement de masquerading (NAT) ». EPSV évite entièrement le problème, car sa réponse ne contient aucun champ d’adresse. Vous ne pouvez toutefois pas compter dessus, car c’est le client qui décide quelle commande envoyer.

Ce que TLS change

FTPS est le protocole FTP sur TLS (Transport Layer Security). Le client se connecte au port 21 comme d’habitude, envoie AUTH TLS pour sécuriser le canal de contrôle, puis envoie PROT P pour chiffrer également le canal de données. FTP en clair transmet le mot de passe sur le réseau sous forme de texte lisible. Si vous devez conserver FTP, utilisez FTPS. vsftpd est fourni avec ssl_enable défini par défaut sur NO.

Deux conséquences en découlent. Aucun helper de suivi des connexions ne peut fonctionner. C’est le même point que précédemment, vu sous un autre angle. De plus, sudo tcpdump -nAi any 'tcp port 21' n’affichera plus la réponse 227. Pour connaître l’adresse et le port annoncés par le serveur, consultez plutôt le journal du serveur que le trafic réseau.

Tester la modification depuis l’extérieur

Exécutez ces commandes depuis une autre machine. Un test effectué depuis le serveur lui-même contourne le pare-feu que vous essayez de corriger.

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

ss doit indiquer que le daemon FTP écoute sur le port 21. Aucun processus n’écoute dans la plage passive lorsque le serveur est inactif, car ces sockets sont créées pour un transfert puis fermées à la fin de celui-ci.

--disable-epsv force curl à utiliser le chemin PASV, celui qui révèle le problème d’adresse. La trace affiche la réponse du serveur, puis l’adresse et le port auxquels curl se connecte :

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

117 * 256 + 52 = 30004, ce qui se trouve dans la plage déclarée. La présence d’une adresse privée sur cette ligne signifie que pasv_address n’est pas défini. Un port situé en dehors de votre plage signifie que le serveur n’a jamais chargé la modification de configuration. Vérifiez donc que vous avez modifié le fichier utilisé par le service en cours d’exécution.

nc répond directement à la question concernant le pare-feu. Un Connection refused immédiat signifie que le paquet a atteint le serveur et n’a trouvé aucun processus en écoute. C’est le résultat attendu pour un port passif inactif : votre règle fonctionne. Un blocage jusqu’à ce que nc abandonne signifie qu’un élément a silencieusement supprimé le paquet. Il s’agit d’un pare-feu, soit celui du serveur, soit celui configuré dans le panneau de votre fournisseur. Cette distinction est la même que celle décrite dans connexion SSH refusée ou expirée, et elle s’applique à tous les ports.

Faut-il encore utiliser FTP ?

Pour les nouveaux projets, non. SFTP (protocole de transfert de fichiers SSH) fonctionne dans une seule connexion SSH sur le port 22. Il n’y a pas de second canal, pas de plage de ports passifs, pas de configuration NAT et pas de démon supplémentaire à sécuriser, car OpenSSH fournit déjà cette fonction. sftp user@example.com fonctionne sur un serveur où aucun service de transfert de fichiers n’a été configuré. Pour donner des fichiers à quelqu’un, sans rien d’autre, sshd_config utilise ForceCommand internal-sftp avec ChrootDirectory. Ce répertoire doit appartenir à root et ne doit pas être inscriptible par l’utilisateur. Sinon, sshd refuse la session et journalise une ligne bad ownership or modes for chroot directory.

FTP reste nécessaire lorsque l’autre partie ne peut pas changer. Les scanners et les imprimantes multifonctions sont livrés avec un firmware qui ne prend en charge que FTP. Les équipements de laboratoire et les équipements industriels utilisent souvent une image figée que personne ne fera recertifier. Les partenaires commerciaux publient un point de dépôt FTPS et n’ajouteront pas un protocole pour un seul fournisseur. Dans chacun de ces cas, la plage de ports passifs et la règle de pare-feu correspondante constituent l’essentiel de la configuration. Il faut alors utiliser FTPS plutôt que FTP en clair. La conception à deux canaux date de 1985 et fonctionne aujourd’hui dans un environnement qu’elle n’avait pas anticipé. Cette histoire est racontée dans l’histoire des protocoles de transfert de fichiers.

FAQ

Pourquoi FTP s’authentifie-t-il, mais le listing du répertoire reste-t-il bloqué ?

L’authentification utilise uniquement la connexion de contrôle sur le port 21, que votre pare-feu autorise. Le listing du répertoire nécessite une deuxième connexion TCP sur un autre port, et cette connexion est bloquée. Déclarez une plage de ports passifs sur le serveur FTP, ouvrez la même plage dans le pare-feu, puis le listing s’effectuera correctement. Un listing bloqué indique un problème de canal de données, jamais un problème de mot de passe.

Quels ports dois-je ouvrir pour le mode passif FTP ?

Le port 21 pour le canal de contrôle, ainsi que la plage configurée pour les connexions de données passives. Il n’existe pas de plage standard, puisque c’est vous qui la choisissez. Une plage comme 30000 à 30099 convient : dimensionnez-la selon le nombre maximal de transferts simultanés et évitez la plage de ports sortants du kernel, que vous pouvez lire avec sysctl net.ipv4.ip_local_port_range. Si votre fournisseur propose un pare-feu réseau dans son panneau de contrôle, ouvrez également cette plage à cet endroit.

Ai-je encore besoin de nf_conntrack_ftp ?

Non, et vous ne pouvez pas compter dessus avec un kernel actuel. L’affectation automatique des helpers est désactivée par défaut. Sur les kernels récents, le switch net.netfilter.nf_conntrack_helper a été supprimé, et sysctl indique donc que le fichier n’existe pas. Le manuel d’ufw considère le chargement inconditionnel de ces modules comme obsolète, et firewalld ignore complètement AutomaticHelpers. Un helper doit également lire le canal de contrôle en texte brut. Il cesse donc de fonctionner dès que vous activez FTPS. Déclarez plutôt une plage de ports passifs.

Pourquoi mon client FTP indique-t-il que la réponse passive contient une adresse non routable ?

Le serveur a répondu à PASV avec l’adresse qu’il voit sur sa propre interface, et cette adresse est privée. Cela se produit lorsque la plateforme associe une adresse publique à une adresse privée. Définissez explicitement l’adresse publique : pasv_address dans vsftpd, MasqueradeAddress dans ProFTPD ou -P dans Pure-FTPd. FileZilla contourne ce problème en réutilisant l’adresse à laquelle il s’est déjà connecté et journalise « Using server address instead ». C’est pourquoi certains clients tolèrent cette mauvaise configuration alors que d’autres restent bloqués.

Dois-je utiliser FTPS ou SFTP ?

Utilisez SFTP pour tout ce que vous contrôlez aux deux extrémités : une seule connexion SSH sur le port 22, aucun canal de données à ouvrir, et le service est déjà disponible. FTPS est du FTP sur TLS. Il conserve donc la conception à deux canaux et tous les problèmes de pare-feu qui en découlent. Choisissez-le lorsque l’autre partie ne prend en charge aucun autre protocole. N’utilisez pas FTP en clair sur Internet, car le mot de passe circule sur le réseau en texte lisible.