FTP : Impossible de récupérer le contenu du dossier

Bonjour,

J’ai configuré un dédié sous wheezy pour qu’il fasse serveur FTP.
J’ai installé le paquet vsftpd.
J’ai configuré vsftpd pour que
-> les connexions anonymes soient interdites.
-> Le port utilisé soit 1337
-> Les users connectés soient chrootés

Une fois configuré, lorsque je me connecte avec FileZilla, voici le message d’erreur :

Statut :	Résolution de l'adresse de web.XXXXX.fr
Statut :	Connexion à XXXXXXXXXXXXXXXXX:1337...
Erreur :	Délai d'attente expiré
Erreur :	Impossible d'établir une connexion au serveur
Statut :	Résolution de l'adresse de web.XXXXXXXXXXx.fr
Statut :	Connexion à XXXXXXXXXXXXXx:1337...
Statut :	Connexion établie, attente du message d'accueil...
Réponse :	220 Vous êtes bien connecté en FTP sur le serveur XXXXXXXXXXXXX.fr
Commande :	USER musique
Réponse :	331 Please specify the password.
Commande :	PASS ***********
Réponse :	230 Login successful.
Commande :	SYST
Réponse :	215 UNIX Type: L8
Commande :	FEAT
Réponse :	211-Features:
Réponse :	 EPRT
Réponse :	 EPSV
Réponse :	 MDTM
Réponse :	 PASV
Réponse :	 REST STREAM
Réponse :	 SIZE
Réponse :	 TVFS
Réponse :	 UTF8
Réponse :	211 End
Commande :	OPTS UTF8 ON
Réponse :	200 Always in UTF8 mode.
Statut :	Connecté
Statut :	Récupération du contenu du dossier...
Commande :	PWD
Réponse :	257 "/home/musique"
Commande :	TYPE I
Réponse :	200 Switching to Binary mode.
Commande :	PASV
Réponse :	227 Entering Passive Mode (XXXXXXXXXXXXXXXX,203,244).
Commande :	LIST
Erreur :	Délai d'attente expiré
Erreur :	Impossible de récupérer le contenu du dossier

Côté log de vsftp, rien du tout.

Je vous joins ma config (/etc/vsftpd.conf)

listen=YES
listen_port=1337
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
anon_upload_enable=NO
anon_mkdir_write_enable=NO
dirmessage_enable=YES
use_localtime=YES
xferlog_enable=YES
connect_from_port_20=NO
xferlog_file=/var/log/vsftpd.log
xferlog_std_format=YES
idle_session_timeout=300
data_connection_timeout=120
nopriv_user=ftpsecure
ascii_upload_enable=YES
ascii_download_enable=YES
ftpd_banner=Vous êtes bien connecté en FTP sur le serveur XXXXXXXXXXXX.fr
chroot_local_user=YES
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd.chroot_list
secure_chroot_dir=/var/run/vsftpd/empty
pam_service_name=vsftpd
rsa_cert_file=/etc/ssl/private/vsftpd.pem

Mes règles de parefeu concernant le FTP :

# FTP Out
iptables -t filter -A OUTPUT -p tcp --dport 1337 -j ACCEPT
# FTP In
iptables -t filter -A INPUT -p tcp --dport 1337 -j ACCEPT
iptables -t filter -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

Quid des politiques par défaut des chaînes iptables ? Je suppose que celle d’OUTPUT est à ACCEPT sinon tu ne recevrais même pas les réponses du serveur. Si celle d’INPUT est à DROP, tes règles iptables bloquent la connexion de données nécessaire au listage de répertoire ou au transfert de fichier. Cette connexion se fait sur un port dynamique différent du port de la connexion de commande. Pour l’autoriser, il y a deux méthodes.

Méthode 1, utilisable seulement pour les connexions FTP en clair (sans chiffrement TLS/SSL) : charger le module de suivi de connexion pour FTP nf_conntrack_ftp en lui indiquant le port de commande FTP à surveiller si ce n’est pas le port standard 21 : dans ton cas, 1337. Cela marquera à la volée le premier paquet de la connexion de données comme RELATED quel que soit le port utilisé.

  • Chargement manuel :

(je laisse aussi le port 21 pour les éventuelles connexions sortantes effectuées par la machine)

  • Chargement automatique au démarrage : ajouter la ligne suivante dans /etc/modules :
  • Configuration de modprobe pour ajouter implicitement l’option ports sans avoir besoin de la mentionner dans les cas ci-dessus : créer un fichier /etc/modprobe.d/nf_conntrack_ftp.conf avec le contenu suivant :

Méthode 2, utilisable même avec du FTP chiffré : définir une plage de ports passifs dans vsftpd.conf et autoriser cette plage de ports en entrée avec une règle iptables. Toute la plage est autorisée en permanence.

Observations :

  • Ta règle dans OUTPUT ne sert à rien pour faire fonctionner un serveur FTP, elle ne peut servir qu’à la machine pour se connecter à un autre serveur sur le port 1337.
  • Utiliser un autre port que 21 pour du FTP est une mauvaise idée car il y a plein de firewalls et NAT un peu partout qui font la même chose que la méthode 1 et s’attendent à ce que le FTP soit sur le port 21.

Merci pour ta réponse, que je vais étudier avec le plus grand soin.

J’ai remis les ports originaux (20 et 21), puisque tu dis que c’est préférable. L’initiative du changement de port n’était qu’un soucis de sécurité (chgt du port ssh, interdiction de l’accès par le root,…)

J’avoue avoir une méconnaissance totale des connexions passives et actives en FTP… Pour moi c’était comme le ssh : j’ouvre en entrée un port X dans la configuration du parefeu au niveau du serveur, et lorsque je me connecte avec mon client, je précise le port X.

Donc, pour l’instant ça n’est toujours pas fonctionnel, car je n’ai pas établi/compris cette histoire de plage de ports passifs. Je m’en vais étudier ça (d’autant plus qu’une fois la configuration en FTP fonctionnelle, je veux passer tout de suite en FTP sécurisé).

A poursuivre donc.

Il ne faut pas autoriser les connexions entrantes vers le port 20. Ce port n’est pas ouvert en écoute comme le port 21 mais utilisé comme port source pour les connexions de données sortantes du serveur (entrantes pour le client), en mode actif. Je n’ai pas parlé du mode FTP actif car il est moins utilisé que le mode passif, notamment par les clients FTP graphiques usuels, et plus délicat à géré par le pare-feu côté client puisqu’il implique des connexions entrantes pour le client alors que le mode passif n’implique que des connexions sortantes.

Dans ce cas le module de suivi de connexion FTP de netfilter ne fonctionnera pas car il ne pourra pas décoder le contenu chiffré de la connexion de commande, et la restriction sur l’utilisation du port 21 est caduque. Il faudra définir des plages de ports passifs dans vsftpd et autoriser ces ports dans les règles iptables.

  • Mode actif : autoriser la plage de ports passifs en destination (–dport début:fin) en entrée (INPUT).
  • Mode actif : autoriser le port source 20 (–sport 20) en sortie (OUTPUT).

Une alternative au FTP sécurisé, compliqué à gérer par les pare-feux, est d’utiliser SFTP, le transfert de fichiers par SSH.

Bon, ça commence à venir, en glânant le web, on trouve des réponses… souvent erronées, donc il faut faire le tri.

Voici mes règles parefeu concernant le FTP :

[code]# FTP Out
iptables -t filter -A OUTPUT -p tcp --dport 20 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 21 -j ACCEPT

FTP In

iptables -t filter -A INPUT -p tcp --dport 21 -j ACCEPT
iptables -t filter -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

Accepter les connexions passives

iptables -A INPUT -p tcp -m tcp --sport 40000:40200 --dport 40000:40200 -m conntrack --ctstate ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp -m tcp --sport 40000:40200 --dport 40000:40200 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
[/code]

Et j’ai donc configuré en conséquence vsftp.conf:

listen=YES
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
anon_upload_enable=NO
anon_mkdir_write_enable=NO
dirmessage_enable=YES
use_localtime=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_file=/var/log/vsftpd.log
xferlog_std_format=YES
idle_session_timeout=300
data_connection_timeout=120
#Autorisation des connexions passives:
pasv_enable=YES
#Définition de la plage de ports passifs :
pasv_min=40000
pasv_max=40200
nopriv_user=ftpsecure
ascii_upload_enable=YES
ascii_download_enable=YES
ftpd_banner=Vous êtes bien connecté en FTP sur le serveur XXXX.fr
chroot_local_user=YES
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd.chroot_list
secure_chroot_dir=/var/run/vsftpd/empty
pam_service_name=vsftpd
#rsa_cert_file=/etc/ssl/private/vsftpd.pem

Et là, je n’arrive même plus à me connecter :

[quote]Résolution de l’adresse de XXXXXXXXX.fr
Statut : Connexion à XXXXXXXXXXXX:21…
Statut : Échec de la tentative de connexion avec “ECONNREFUSED - Connection refused by server”.
Erreur : Impossible d’établir une connexion au serveur[/quote]

Je n’ai rien compris encore au conntrack, mais si je suis ta méthode 2, je n’en ai pas besoin.

Le problème doit maintenant venir de vsftpd, puisque le service ne veut pas démarrer…

Si vsftpd ne démarre pas, cela explique le message d’erreur “connexion refusée” car rien n’écoute sur le port 21. Vérifie ses options. En tout cas ce n’est a priori pas un problème de blocage par iptables.

Concernant tes nouvelles règles :

  • Pour autoriser les connexion de données FTP actives en sortie, il faut autoriser le port source 20 (–sport) et non destination.
  • En mode passif, les clients ne se connectent pas à partir de la plage de ports 40000:40200 mais vers ces ports, les options --sport dans INPUT et --dport dans OUTPUT n’ont pas lieu d’être.
  • La règle INPUT pour les connexions de données FTP devrait avoir l’état NEW. L’état ESTABLISHED est inutile puisqu’une règle précédente accepte déjà tous les paquets entrants ayant cet état.
  • Le RELATED dans la règle OUTPUT des connexions passives n’a pas lieu d’être car seul le premier paquet entrant d’une connexion de données est susceptible d’avoir cet état (si FTP en clair et module de suivi chargé).
    Récapitulatif :

[code]# règles générales de suivi de connexion
iptables -t filter -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -t filter -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

FTP serveur

connexions de commande

iptables -t filter -A INPUT -p tcp --dport 21 -m state --state NEW -j ACCEPT

connexions de données actives

iptables -t filter -A OUTPUT -p tcp --sport 20 -m state --state NEW -j ACCEPT

connexions de données passives

iptables -t filter -A INPUT -p tcp --dport 40000:40200 -m state --state NEW -j ACCEPT[/code]