L'Internet Rapide et Permanent

Le protocole et les serveurs FTP

Vous disposez d'une connexion permanente et rapide… et maintenant, vous êtes perdu dans la technique…

Cette série « L'Internet Rapide et Permanent », que Christian Caleca nous a aimablement autorisé à reproduire, est là pour répondre à quelques-unes de ces questions. Cet article parlera du protocole FTP et du serveur FTP « Pure-ftpd ».

N'hésitez pas à commenter cet article ! Commentez Donner une note à l'article (5)

Article lu   fois.

L'auteur

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

1. Introduction

1-1. Pourquoi s'intéresser à FTP ?

Le protocole FTP est probablement le protocole applicatif le plus complexe, et aussi le moins utilisé au maximum de ses capacités. Il est même malheureusement bien souvent ignoré.

Il est intéressant d'étudier FTP au moins pour les raisons suivantes :

  • C'est le protocole le plus sûr pour faire du téléchargement de fichiers, même si cette opération peut aussi être réalisée avec HTTP ;
  • cependant, ce protocole peut poser problème lorsqu'on l'utilise à travers un filtre de paquets (pare-feu) en qualité de client, et encore plus en qualité de serveur, et il est toujours meilleur de comprendre le problème et de le résoudre que d'abandonner ;
  • si l'on souhaite placer un serveur FTP accessible à travers un pare-feu à filtre de paquets, en faisant du « port forwarding » sur le pare-feu, il devient impératif de bien comprendre le processus, faute de quoi, les transferts FTP resteront probablement bloqués à un moment où à un autre. C'est pourtant une solution bien pratique pour rendre accessible à distance certaines de nos données sans passer par un tiers « de confiance » (ou pas).

1-2. Que peut-on faire avec FTP ?

Parmi les applications les plus fréquentes :

  • téléchargement de fichiers depuis un serveur vers le client (Download),
  • téléchargement de fichiers depuis le client vers un serveur (Upload), par exemple pour la mise à jour des pages web personnelles.

Mais il est possible de faire d'autres choses encore :

  • bien que cette méthode soit de moins en moins utilisée, FTP peut servir à envoyer un document à imprimer sur une imprimante distante, l'imprimante faisant alors office de serveur,
  • un client FTP peut effectuer des transferts de fichiers entre deux serveurs distants. Bien que cette possibilité soit peu intéressante pour l'internaute moyen, ça reste une fonctionnalité importante pour les administrateurs de sites distants.

2. Utilisons FTP

De moins en moins d'internautes utilisent FTP, il en existe même qui ignorent jusqu'à son existence.

FTP reste pourtant un protocole de transfert de fichier puissant et efficace, parfaitement interopérable. Son seul « défaut » est qu'il nécessite d'en connaitre un peu le fonctionnement, puisqu'il faut un minimum configurer son client pour en profiter au mieux. La même remarque s'applique d'ailleurs à POP et IMAP, un « webmail » n'amenant à se poser aucune question, il n'y a rien à configurer (mais tellement moins efficace qu'un vrai MUA, surtout lorsque l'on dispose de plusieurs boites aux lettres).

Mais revenons à FTP. Du point de vue de l'utilisateur, il faut remarquer les modes de transfert de données actif et passif et leurs implications sur le paramétrage du pare-feu, c'est sans doute le point le plus important. Il est aussi important de savoir que FTP n'est par défaut pas sécurisé, que la connexion « normale » (utilisateur identifié), laisse passer en clair le nom d'utilisateur ainsi que le mot de passe, mais qu'il existe des extensions à FTP qui permettent le chiffrement.

Dans cette partie, nous verrons tous ces points en utilisant principalement le client FTP filezilla dont il existe une version pour la plupart des plate-formes.

2-1. Les bases de FTP

2-1-1. Le cas le plus « classique »

Un client (utilisateur FTP) va se servir de ce protocole, pour faire du transfert de fichiers (upload ou download) sur un serveur FTP.

Il existe une multitude de logiciels clients en mode graphique pour réaliser ces opérations. Passons sur les fonctions FTP implémentées dans les navigateurs web (Internet Explorer, Mozilla…), qui ne sont pas toujours très pratiques.

2-1-1-1. Clients Windows

Vous serez probablement surpris de constater le nombre impressionnant de clients FTP disponibles, le plus souvent en « shareware » (Windows oblige). Il en existe cependant au moins un sous licence GPL : Filezilla. En plus d'être sous licence GPL, ce logiciel est également localisé en français, ce qui ne gâte rien.

A noter également le module complémentaire de Firefox : FireFTP qui offre à ce navigateur de véritables fonctions de client FTP.

2-1-1-2. Clients GNU/Linux

Nous avons gftp , naturellement sous licence GPL, mais également le même FileZilla porté sur GNU/Linux et aussi Mac OS X. Bien entendu, le module FireFTP de Firefox reste d'actualité.

2-1-1-3. Autres possibilités

Il existe enfin des utilitaires FTP en ligne de commande, aussi bien sous Windows que sous Linux. Il sont certainement moins conviviaux, mais pas forcément moins puissants. L'outil en ligne de commande lftp est sans doute le plus abouti. Les utilisateurs de MS Windows devront s'en passer.

Dans la suite, nous utiliserons donc le client Filezilla :

Image non disponible

Les clients FTP graphiques ont tous plus ou moins la même présentation. Ici, nous nous sommes connectés au serveur mir1.ovh.net de façon anonyme. Nous aurons l'occasion de revenir sur ce mode de connexion.

La partie gauche représente l'arborescence locale et la partie droite, celle du serveur FTP.

2-1-1-4. Le principe de base

Le client ouvre une session FTP sur un serveur. Il existe une grande quantité de serveurs FTP publics. Un serveur FTP requiert une identification du client. Il existe souvent un compte « anonyme », qui donne accès en lecture seule dans la partie publique du serveur, mais il existe également des parties privées où les clients disposant d'un compte peuvent accéder en écriture sur certains répertoires de l'arborescence. C'est le cas, par exemple, pour les mises à jour de pages web personnelles.

Image non disponible

La première chose que l'on constate, c'est que, contrairement à d'autres protocoles comme HTTP, nous allons ici utiliser au moins deux canaux distincts :

  • L'un pour l'échange des commandes du protocole,
  • l'autre pour le transfert des données elle-mêmes. Il est possible d'ouvrir plusieurs canaux de données simultanément,si le serveur l'autorise, par exemple si l'on souhaite récupérer plusieurs fichiers sur un serveur.

Le client FTP (partie de droite), par l'intermédiaire de l'interface utilisateur, va cacher les diverses commandes du protocole FTP par des manipulations plus conviviales, en proposant à l'utilisateur une vision des choses similaire à un gestionnaire de fichiers. Avec des clics et des « glisser/déposer » l'utilisateur exploitera FTP sans en connaitre la multitude de commandes.

2-1-2. L'autre cas

Image non disponible

Un utilisateur pourra exploiter FTP pour transférer depuis son poste de travail des fichiers d'un serveur distant à un autre serveur distant, sans que les données ne transitent par sa machine, ce qui est fort intéressant si l'on travaille depuis une connexion à faible débit pour passer des données volumineuses d'une machine à une autre, ces dernières étant quant-à-elles connectées par des liens à haut débit. Cependant, cette opération ne sera possible que si les serveurs FTP l'acceptent (FXP), ce qui n'est pas souvent le cas, pour des raisons de sécurité et nous n'en parlerons pas d'avantage ici.

2-1-3. Modes Actif et Passif

Le meilleur moyen pour comprendre FTP n'est probablement pas la lecture des RFC mais plutôt l'expérimentation, du moins dans un premier temps. Nous allons donc mettre en œuvre FTP, voir comment les choses se passent et vérifier seulement après que c'est bien conforme à ce qui est dit dans les Livres.

Les manipulations sont faites depuis un poste client connecté à un LAN, lui-même connecté à l'Internet par une passerelle NAT GNU/Linux. Un sniffeur est placé sur le poste client lui-même, il aurait pu l'être sur la passerelle.

Il faut bien prendre le problème par un bout pour le décortiquer, même si pour l'instant, nous ne savons rien ou pas grand-chose de FTP. Nous sommes donc obligés de faire appel à un paramétrage du client, sans trop savoir pourquoi on va le faire comme ça. Nous y reviendrons par la suite.

Le protocole FTP supporte deux manières de fonctionner, à peine différentes, mais la différence est d'importance, surtout lorsque l'on doit traverser un pare-feu par filtrage de paquets. Ce sont les modes actif et passif.

Pour l'instant, contentons-nous de dire que si l'on doit passer un pare-feu, il vaut mieux utiliser le mode passif, car le mode actif risque de se solder rapidement par un échec. Ceci dit, le pare-feu utilisé ici est construit avec Iptables, qui sait parfaitement reconnaitre du FTP actif et le laisser passer sans encombre si nous lui en avons donné la consigne. Nous allons donc commencer par ce mode là.

Le résultat de la manipulation qui suit n'est plus tout jeune, les noms des hôtes et du fichier téléchargé ne sont plus d'actualité, mais le protocole, lui, n'a pas changé et l'exemple est toujours valide.

Nous avions créé une connexion au serveur ftp.oleane.fr, parcouru son arborescence, et téléchargé le fichier /pub/doc/rfc/rfc765.txt.

2-1-4. Ce que montre le sniffeur

2-1-4-1. Avertissement

L'étude qui va suivre est assez longue, voire laborieuse. Munissez-vous de temps, de friandises et de boissons, parce que nous allons rester coincés ici pendant un petit moment…

Pour vous éviter de faire plusieurs aller-retours sur la page, j'ai essayé d'organiser cette étude de façon la plus linéaire possible, c'est ce qui rend ce paragraphe très long. Allons-y.

2-1-4-2. Établissement de la connexion pour les commandes

 
Sélectionnez
No. Time     Source        Destination  Protocol Info
  1 0.000000 192.168.0.10  194.2.0.36   TCP      1175 > ftp [SYN]
  2 0.022327 194.2.0.36    192.168.0.10 TCP      ftp  > 1175 [SYN, ACK]
  3 0.022356 192.168.0.10  194.2.0.36   TCP      1175 > ftp [ACK]

Établissement d'une connexion TCP entre le client (192.168.0.10:1175) et le serveur (192.2.0.36:21). Le port 21 est le port standard d'écoute des commandes FTP. Nous trouvons ici le classique dialogue [SYN], [SYN,ACK], [ACK]. Etait-il nécessaire de le signaler ? FTP s'appuie bien entendu sur un mode connecté (TCP).

Pour savoir que le port nommé ftp est bien le port 21, il suffit d'aller regarder dans le détail de la trame 1 par exemple :

 
Sélectionnez
Frame 1 (62 bytes on wire, 62 bytes captured)
    ...
    Transmission Control Protocol, Src Port: 1175 (1175), Dst Port: ftp (21)
    Source port: 1175 (1175)
    Destination port: ftp (21)
    ...

Mais passons à la suite…

 
Sélectionnez
  4 0.055680 194.2.0.36    192.168.0.10 FTP      Response: 220 ProFTPD 1.2.0pre10 Server (ProFTPD)
                                                           [ftp.oleane.net]

Le serveur entame le dialogue propre au protocole FTP en se présentant. Chaque réponse commence par un nombre, optionnellement suivi d'un commentaire. La réponse 220 signifie : « Service disponible pour nouvel utilisateur ».
Vous aurez l'occasion de constater dans la suite à quel point les systèmes informatiques savent être civilisés. Le serveur se présente, par la même occasion.

 
Sélectionnez
  5 0.057744 192.168.0.10  194.2.0.36   FTP      Request: USER anonymous

Le client se présente aussi en indiquant son nom. Comme nous avons fait un accès anonyme, nous utilisons le nom conventionnel anonymous. Nous n'aurons droit qu'à un accès en lecture. Si nous avions disposé d'un compte d'utilisateur, nous aurions un identifiant personnel (nom d'utilisateur et mot de passe) qui nous permettrait éventuellement de disposer d'un droit d'accès en écriture dans un répertoire de l'arborescence.

 
Sélectionnez
  6 0.078527 194.2.0.36    192.168.0.10 TCP      ftp > 1175 [ACK]
  7 0.081892 194.2.0.36    192.168.0.10 FTP      Response: 331 Anonymous login ok, send your complete
                                                           e-mail address as password.

Le serveur accepte les accès anonymes. Ce n'est pas une obligation, certains serveurs ne le font pas. En général, en accès anonyme, l'adresse e-mail du client utilisateur est employée comme mot de passe, mais tout ce qui a vaguement une forme d'adresse e-mail est généralement accepté.

 
Sélectionnez
  8 0.084076 192.168.0.10  194.2.0.36   FTP      Request: PASS anon@localhost

La preuve, Filezilla envoie un laconique anon@localhost et tout va fonctionner quand même…
PASS est une commande FTP, c'est l'abréviation de Password.

 
Sélectionnez
  9 0.108851 194.2.0.36    192.168.0.10 FTP      Response: 230-Welcome, archive user
                                                           anonymous@ca-marseille-51-107.abo.wanadoo.fr!

La preuve… La réponse 230 veut dire : « Session ouverte ». Notons tout de même que le serveur a ici effectué une requête « reverse DNS » sur notre adresse IP, d'où la réponse anonymous@ca-marseille-51-107.abo.wanadoo.fr.

 
Sélectionnez
 11 0.109313 192.168.0.10  194.2.0.36   TCP      1175 >  ftp [ACK]
 12 0.109914 194.2.0.36    192.168.0.10 FTP      Response: 230-The local time is:
                                                           Sat Jan 11 10:32:57 2003
 13 0.110341 194.2.0.36    192.168.0.10 FTP      Response: 230-
 14 0.110365 192.168.0.10  194.2.0.36   TCP      1175 > ftp [ACK]
 15 0.131452 194.2.0.36    192.168.0.10 FTP      Response: 230-For informations about
                                                           this archive service,
                                                           or to report problems,

Le serveur nous donne son heure locale, qui peut être utile si l'on devait signaler un problème à l'administrateur du service.

 
Sélectionnez
 16 0.141903 192.168.0.10  194.2.0.36   FTP      Request: PWD

Le client envoie la commande PWD qui signifie : « Print Working Directory »

 
Sélectionnez
 17 0.172747 194.2.0.36    192.168.0.10 FTP      Response: 257 "/" is current directory.

Nous sommes à la racine de l'arborescence du serveur FTP. Le code 257 signifie « Chemin créé ».

2-1-4-2-1. Où en sommes-nous ?

Nous avons initié une connexion FTP avec le serveur. Nous nous sommes identifié comme un utilisateur anonyme et nous nous retrouvons dans la racine de l'arborescence du serveur FTP.
Nous avons vu quelques commandes FTP : USER, PASS, PWD et quelques codes de réponse. Jusqu'ici, c'était relativement simple, nous n'avons transmis que des commandes et des réponses à ces commandes. Maintenant, ça va commencer à se compliquer, parce que nous allons faire aussi transiter des données.

 
Sélectionnez
 18 0.176308 192.168.0.10  194.2.0.36   FTP      Request: PORT 192,168,0,10,4,152

Première commande curieuse : PORT 192.168.0.10,4,152, qui nécessite quelques explications.

  • PORT, c'est une commande. Le client signale qu'il voudrait utiliser un port particulier ;
  • 192.168.0.10, l'adresse du client et notons bien que nous voyons ici une adresse IP privée, non routable sur l'internet,
  • 4,152, c'est la notation d'un numéro de port, écrit à la mode des adresses IP, c'est-à-dire sous forme de deux octets, dont chaque octet est exprimé en valeur décimale. Dans la pratique, ceci veut dire que le port spécifié sera 4 x 256 + 152 = 1176

La suite va nous indiquer plus clairement à qui va servir ce port.

 
Sélectionnez
 19 0.198149 194.2.0.36    192.168.0.10 FTP      Response: 200 PORT command successful.

Le serveur répond qu'il est d'accord. 200 signifie : « Commande conclue ».

 
Sélectionnez
 20 0.200751 192.168.0.10  194.2.0.36   FTP      Request: TYPE A

La commande TYPE indique au serveur quel type de données sont attendues. Le type A signale que l'on attend du texte ASCII.

 
Sélectionnez
 21 0.223387 194.2.0.36    192.168.0.10 FTP      Response: 200 Type set to A.

Le serveur est toujours d'accord.

 
Sélectionnez
 22 0.225874 192.168.0.10  194.2.0.36   FTP      Request: LIST

La commande LIST qui signifie que le client attend la liste des objets présents dans le répertoire courant (l'équivalent de la commande DIR de MSDOS ou ls de UNIX).

Attention !!!
Ce qu'il va se passer maintenant réclame beaucoup d'attention. Rappelons-nous :

  • Que nous sommes en mode Actif,
  • Que le client a demandé l'usage du port 1176
 
Sélectionnez
23 0.247769 194.2.0.36    192.168.0.10 TCP      ftp-data > 1176 [SYN]
24 0.247826 192.168.0.10  194.2.0.36   TCP      1176 > ftp-data [SYN, ACK]
25 0.264940 194.2.0.36    192.168.0.10 TCP      ftp > 1175 [ACK]
26 0.267461 194.2.0.36    192.168.0.10 TCP      ftp-data > 1176 [ACK]

Le serveur FTP initie une nouvelle connexion FTP (trames 23,24 et 26). Mais vous avez bien vu, c'est le serveur qui initie la connexion, autrement dit, il agit comme un client TCP, et c'est le client FTP qui va agir comme un serveur TCP, c'est-à-dire qu'il va rester à l'écoute de son port 1176. Cette particularité est due au mode actif. Le client FTP est actif, parce qu'ici, ce sera lui le serveur (au sens TCP).

Mais comment… 192.168.0.10, c'est une adresse privée, comment le serveur FTP d'Oléane peut-il joindre une adresse privée, non routable par définition ?

Notre sniffeur se situe sur le poste client. Si nous l'avions placé sur le routeur NAT, nous aurions observé d'autres adresses, l'adresse publique du routeur à la place de 192.168.0.10. C'est sûrement un coup du Netfilter. Il est fort ce Netfilter…

Il est fort mais tout de même il faut l'aider. Netfilter sait faire du suivi de connexion, c'est-à-dire dans son jargon identifier des connexions RELATED (relatives à une connexion déjà existante). Il sait le faire avec de l'aide de modules spécifiques pour des protocoles où il est nécessaire d'analyser le dialogue au niveau de l'application.

Netfilter travaille normalement au niveau Internet (IP), des modules particuliers peuvent se charger automatiquement pour la gestion du transport (TCP/UDP) si le filtrage nécessite de s'intéresser aux ports utilisés. Quelques modules spéciaux peuvent permettre d'analyser le contenu au niveau Application, c'est ce qui nous intéresse ici avec les modules nf-conntrack-ftp et nf-nat-ftp, mais il faut charger explicitement ces modules « à la main » ou au moment de l'init. C'est ce qui a été fait sur le routeur NAT utilisé ici.

C'est le module nf-nat-ftp qui permet ici de remplacer à la volée l'adresse locale (privée) du client par celle publique de la passerelle, et d'effectuer l'opération inverse sur les réponses du serveur.

Si nous n'avons pas les moyens de disposer d'un tel outil sur le routeur NAT, le mode actif ne pourra fonctionner, nous devrons nous contenter du mode passif où le serveur FTP est aussi serveur sur les canaux de données.

2-1-4-2-2. Résumons nous

A ce stade, nous avons deux connexions TCP ouvertes :

  • 192.168.0.10:1175 → 194.2.0.36:21. Cette connexion sert à faire passer les commandes et les réponses à ces commandes, 194.2.0.36 est le serveur, au sens TCP, c'est lui qui écoute sur son port 21 ce que le client FTP lui raconte, c'est le canal de commande
  • 194.2.0.36:20 → 192.168.0.10:1176. Cette connexion va servir à faire passer les données. Ici, la liste du répertoire racine du serveur FTP vers le client FTP, qui agit comme un serveur TCP. Ce sera le canal de données.
 
Sélectionnez
 27 0.299444 194.2.0.36    192.168.0.10 FTP      Response: 150 Opening ASCII mode data
                                                            connection for file list.

Le serveur FTP répond 150, c'est-à-dire : « Statut de fichier vérifié, ouverture de canal de données en cours ».

 
Sélectionnez
 28 0.303502 194.2.0.36    192.168.0.10 FTP-DATA FTP Data: 75 bytes
 29 0.305993 194.2.0.36    192.168.0.10 FTP-DATA FTP Data: 699 bytes
 30 0.306052 192.168.0.10  194.2.0.36   TCP      1176 > ftp-data [ACK]
 31 0.306101 194.2.0.36    192.168.0.10 FTP      Response: 226-Transfer complete.

Normalement, c'est bien le catalogue de la racine du serveur FTP qui a été envoyée vers le client FTP. Nous pouvons le vérifier en regardant par exemple les données contenues dans la trame 29. Ce n'est pas très lisible, mais c'est bien ça. Je vous demande de me croire sur parole, inutile de charger encore d'avantage cette page déjà lourde. :

La réponse 226 signifie : « Fermeture du canal de données. Service terminé ».

 
Sélectionnez
 32 0.306117 192.168.0.10  194.2.0.36   TCP      1175 > ftp [ACK]
 33 0.306470 194.2.0.36    192.168.0.10 FTP      Response: 226 Quotas off
 34 0.307484 192.168.0.10  194.2.0.36   TCP      1176 > ftp-data [FIN, ACK]
 35 0.338378 194.2.0.36    192.168.0.10 TCP      ftp-data > 1176 [ACK]

Comme c'était prévu, 192.168.0.10:1176 met fin à la connexion TCP qui a servi de support au canal de données. C'est le client FTP qui met fin à cette connexion.

 
Sélectionnez
 36 0.457543 192.168.0.10  194.2.0.36   TCP      1175 > ftp [ACK]
 37 2.447889 192.168.0.10  194.2.0.36   FTP      Request: CWD pub

Nous sommes de nouveau sur le canal de commandes et le client FTP demande à changer de répertoire. CWD voulant dire : « Change Working Directory ». Nous allons dans le répertoire pub. Ce qui va maintenant suivre va ressembler à ce que nous venons de voir. Je vous laisse la totalité des trames pour deux raisons :

  • Nous permettre de vérifier que vous avez bien compris le mécanisme, parce que je ne vais pas tout répéter,
  • permettre d'observer un détail qui n'est pas sans importance…
 
Sélectionnez
 38 2.471233 194.2.0.36    192.168.0.10 FTP      Response: 250 CWD command successful.
 39 2.473782 192.168.0.10  194.2.0.36   FTP      Request: PWD
 40 2.499085 194.2.0.36    192.168.0.10 FTP      Response: 257 "/pub" is current directory.
 41 2.502415 192.168.0.10  194.2.0.36   FTP      Request: PORT 192,168,0,10,4,153
 42 2.524624 194.2.0.36    192.168.0.10 FTP      Response: 200 PORT command successful.
 43 2.527863 192.168.0.10  194.2.0.36   FTP      Request: TYPE A
 44 2.549182 194.2.0.36    192.168.0.10 FTP      Response: 200 Type set to A.
 45 2.551642 192.168.0.10  194.2.0.36   FTP      Request: LIST
 46 2.572805 194.2.0.36    192.168.0.10 TCP      ftp-data > 1177 [SYN]
 47 2.572856 192.168.0.10  194.2.0.36   TCP      1177 > ftp-data [SYN, ACK]
 48 2.585185 194.2.0.36    192.168.0.10 TCP      ftp > 1175 [ACK]
 49 2.593535 194.2.0.36    192.168.0.10 TCP      ftp-data > 1177 [ACK]

Selon le même mécanisme que celui vu plus haut, un nouveau canal de données est ouvert, mais le client FTP utilise un nouveau port : 1177, cette fois-ci. C'est un détail qui a son importance…

En effet, dans le cas où nous avons beaucoup de fichiers à transférer, nous allons utiliser beaucoup de ports successivement. Pour calculer des firewalls qui ne sont pas « statefull », ceci ne simplifiera pas les choses.

 
Sélectionnez
 50 2.595535 194.2.0.36    192.168.0.10 FTP      Response: 150 Opening ASCII mode data
                                                           connection for file list.
 51 2.625058 194.2.0.36    192.168.0.10 FTP-DATA FTP Data: 59 bytes
 52 2.627332 194.2.0.36    192.168.0.10 FTP-DATA FTP Data: 718 bytes
 53 2.627375 192.168.0.10  194.2.0.36   TCP      1177 > ftp-data [ACK]
 54 2.629615 194.2.0.36    192.168.0.10 FTP      Response: 226-Transfer complete.
 55 2.629654 192.168.0.10  194.2.0.36   TCP      1175 > ftp [ACK]
 56 2.630203 194.2.0.36    192.168.0.10 FTP      Response: 226 Quotas off
 57 2.652599 194.2.0.36    192.168.0.10 FTP-DATA FTP Data: 1229 bytes
 58 2.652668 192.168.0.10  194.2.0.36   TCP      1177 > ftp-data [ACK]
 59 2.654073 192.168.0.10  194.2.0.36   TCP      1177 > ftp-data [FIN, ACK]
 60 2.700163 194.2.0.36    192.168.0.10 TCP      ftp-data > 1177 [ACK]

Bien, nous n'allons pas poursuivre plus longtemps le cheminement dans les sous répertoires, d'autant qu'à chaque niveau, le catalogue devient de plus en plus volumineux.

 
Sélectionnez
 87 11.063406   192.168.0.10          194.2.0.36            FTP      Request: CWD rfc
...
 95 11.177496   192.168.0.10          194.2.0.36            FTP      Request: LIST
...

Et un grand saut plus loin :

 
Sélectionnez
413 29.719734 192.168.0.10  194.2.0.36   FTP      Request: PWD
414 29.741101 194.2.0.36    192.168.0.10 FTP      Response: 257 "/pub/doc/rfc"
                                                            is current directory.

Nous arrivons enfin dans le bon répertoire…

 
Sélectionnez
415 29.912570 192.168.0.10  194.2.0.36   TCP      1180 >; ftp [ACK]
416 30.584219 192.168.0.10  194.2.0.36   FTP      Request: TYPE A
417 30.605939 194.2.0.36    192.168.0.10 FTP      Response: 200 Type set to A.
418 30.609380 192.168.0.10  194.2.0.36   FTP      Request: PORT 192,168,0,10,4,157
419 30.635498 194.2.0.36    192.168.0.10 FTP      Response: 200 PORT command successful.
420 30.639387 192.168.0.10  194.2.0.36   FTP      Request: RETR rfc765.txt
421 30.660814 194.2.0.36    192.168.0.10 TCP      ftp-data > 1181 [SYN]
422 30.660867 192.168.0.10  194.2.0.36   TCP      1181 > ftp-data [SYN, ACK]
423 30.676003 194.2.0.36    192.168.0.10 TCP      ftp > 1180 [ACK]
424 30.683263 194.2.0.36    192.168.0.10 TCP      ftp-data > 1181 [ACK]
425 30.684698 194.2.0.36    192.168.0.10 FTP      Response: 150 Opening ASCII mode data
                                                            connection for rfc765.txt (146641 bytes).
426 30.685450 194.2.0.36    192.168.0.10 FTP-DATA FTP Data: 2 bytes
427 30.687400 194.2.0.36    192.168.0.10 FTP-DATA FTP Data: 716 bytes

Nous ouvrons encore un nouveau canal de données, nous en sommes maintenant au port 1181, données de type A toujours (ASCII) et utilisons la commande RETR (Retrieve) pour transférer le fichier rfc765.txt depuis le serveur FTP vers le client FTP.

Certains lecteurs à l'œil acéré auront remarqué que le port utilisé par le client FTP sur le canal de commande a changé depuis le début de la session. Pour une raison parasite, il y a eu une re-connexion au serveur à la fin de la transmission du catalogue de /pub/doc/rfc, re-connexion qui a entrainé l'ouverture d'un nouveau canal de commande, sans que le précédent ne soit fermé.

 
Sélectionnez
428 30.687446 192.168.0.10  194.2.0.36   TCP      1181 > ftp-data [ACK]
429 30.710881 194.2.0.36    192.168.0.10 FTP-DATA FTP Data: 1400 bytes
430 30.712372 194.2.0.36    192.168.0.10 FTP-DATA FTP Data: 1400 bytes
431 30.712414 192.168.0.10  194.2.0.36   TCP      1181 > ftp-data [ACK]
...

Les données commencent à venir, il y en a pour un moment. Nous nous retrouvons à la fin du fichier :

 
Sélectionnez
614 33.613493 192.168.0.10  194.2.0.36   TCP      1181 > ftp-data [FIN, ACK]
615 33.636771 194.2.0.36    192.168.0.10 TCP      ftp-data > 1181 [ACK]

Voilà, c'est fini. nous arrêtons la transaction avec le serveur FTP :

 
Sélectionnez
616 36.666211 192.168.0.10  194.2.0.36   TCP      1175 > ftp [FIN, ACK]
617 36.686973 194.2.0.36    192.168.0.10 TCP      ftp > 1175 [ACK]
618 36.689259 194.2.0.36    192.168.0.10 TCP      ftp > 1175 [FIN, ACK]
619 36.689275 192.168.0.10  194.2.0.36   TCP      1175 > ftp [ACK]
620 38.511841 192.168.0.10  194.2.0.36   TCP      1180 > ftp [FIN, ACK]
621 38.530529 194.2.0.36    192.168.0.10 TCP      ftp > 1180 [ACK]
622 38.533514 194.2.0.36    192.168.0.10 TCP      ftp > 1180 [FIN, ACK]
623 38.533552 192.168.0.10  194.2.0.36   TCP      1180 > ftp [ACK]

Toutes les connexions TCP encore ouvertes sont fermées, y compris le canal de commande initialement ouvert (port 1175).

2-1-5. Qu'avons-nous appris ?

Déjà beaucoup de choses :

  • nous avons mis en évidence la présence du canal de commande et du canal de données, placés sur des connexions TCP différentes,
  • nous avons, dans ce cas de FTP en mode actif, observé que, pour la création du canal de données, le client FTP :
    • indique au serveur un numéro de port ;
    • se met à l'écoute sur ce port (fonction « serveur TCP ») ;
    • le serveur FTP va quant à lui, utiliser le port 20 pour ce canal de données et agir en client TCP.Ce détail est extrêmement important. Il explique la raison pour laquelle le FTP actif ne fonctionne pas correctement sur des filtres de paquets qui interdisent tout paquet SYN depuis le Net vers la zone protégée. Nous avons vu en effet qu'ici, le serveur FTP initie une nouvelle connexion TCP sur le client FTP (ne nous mélangez pas les pédales entre FTP et TCP…).
      De plus, si le routeur fait du NAT, comme c'est souvent le cas, ça ne va pas être simple de savoir à qui s'adresse cette nouvelle connexion. N'oublions pas que nous regardons ici ce qu'il se passe derrière le NAT. Le serveur FTP, qui est sur le Net, n'a aucune connaissance de l'IP réelle de son client. Pour lui, son interlocuteur, c'est le routeur NAT lui-même, vu du côté Internet, ceci est le travail de Netfilter et des modules du kernel spécialisés dans le traitement de FTP, associés à une règle qui laisse entrer les nouvelles connexion identifiées comme RELATED ;
  • nous avons vu également quelques commandes FTP ainsi que quelques codes de réponses ;
  • enfin, nous avons vu un type de transfert, le type A, qui correspond à de l'ASCII. Mais tout fichier n'est pas forcément de l'ASCII. que va-t-il se passer si le fichier à transporter est, par exemple, une image jpg ?

Bien qu'à ce niveau, si vous êtes toujours là, vous pouvez commencer à lire ces fameuses rfc 765 avec quelques chances d'y comprendre quelque chose, vous sentez bien, n'est-ce pas, qu'il y aurait encore quelques manipulations intéressantes à faire…

2-2. Plus en profondeur

Ici, nous allons voir quelques points importants :

  • Le mode passif ;
  • le transfert de fichiers contenant autre chose que du texte ;
  • un transfert en upload.

2-2-1. Le mode Passif

La première chose à faire, lorsque l'on prend en main un client FTP, c'est de trouver à quel endroit l'on peut lui expliquer qu'il doit fonctionner en mode actif ou passif.

Nous n'allons pas nous lancer dans une étude détaillée de Filezilla qui nous mènerait trop loin. Disons simplement que la plupart des clients FTP proposent :

  • la possibilité d'une connexion « rapide » où l'on indique le nom du serveur et éventuellement ses nom d'utilisateur et mot de passe ;
  • la création d'une liste de sites FTP pour un usage répété ;
  • une configuration par défaut, qui est appliquée aux connexions rapides et sert de base à la configuration d'un site enregistré dans la liste ;
  • une configuration personnalisée pour chaque site FTP référencé dans la liste.

Nous nous bornerons pour l'instant à visiter la configuration par défaut de Filezilla (version 3.5.2 GNU/Linux), dans le menu Édition/Paramètres pour forcer le mode passif :

Image non disponible

Le mode passif est « recommandé » uniquement parce qu'il fonctionne plus facilement derrière un routeur NAT. En réalité, les serveurs FTP préfèrent le mode actif qui est pour eux moins consommateur de ressources.

Il serait intéressant de discuter des configurations particulières que l'on peut appliquer aux modes actif et passif, mais c'est peut-être encore un peu tôt.

Voyons ce que donne le même téléchargement, mais en mode passif :

 
Sélectionnez
No. Time     Source        Destination  Protocol Info
...

L'ouverture de session FTP est faite, la connexion de commandes est établie, le client envoie la première commande « PWD »

 
Sélectionnez
20 10.588511 192.168.0.10  194.2.0.36   FTP      Request: PWD
21 10.609876 194.2.0.36    192.168.0.10 FTP      Response: 257 « / » is current directory.

Jusqu'ici, tout était pareil, mais voyons la suite :

 
Sélectionnez
22 10.613105 192.168.0.10  194.2.0.36   FTP      Request: PASV

Cette nouvelle commande indique au serveur FTP que nous souhaitons fonctionner en mode passif.

 
Sélectionnez
23 10.661077 194.2.0.36    192.168.0.10 FTP      Response: 227 Entering Passive Mode (194,2,0,36,17,77).

Le serveur accepte (227 veut dire : « Passage en mode passif »), et indique un numéro de port, ici 17 x 256 + 77 = 4429

 
Sélectionnez
24 10.663545 192.168.0.10  194.2.0.36   FTP      Request: TYPE A
25 10.693712 194.2.0.36    192.168.0.10 FTP      Response: 200 Type set to A.
26 10.697611 192.168.0.10  194.2.0.36   FTP      Request: LIST
27 10.698306 192.168.0.10  194.2.0.36   TCP      1870 > 4429 [SYN]

Voyez ici comment la connexion TCP destinée à supporter le canal de données est créée. Ce n'est plus le serveur FTP qui, depuis son port 20 initie une connexion vers le client FTP, mais le client FTP qui ouvre une connexion TCP sur le port que lui a indiqué le serveur, à la suite de la commande PASV.

 
Sélectionnez
28 10.731631 194.2.0.36    192.168.0.10 TCP      ftp > 1869 [ACK]
29 10.736716 194.2.0.36    192.168.0.10 TCP      4429 > 1870 [SYN, ACK]
30 10.736751 192.168.0.10  194.2.0.36   TCP      1870 > 4429 [ACK]
31 10.757437 194.2.0.36    192.168.0.10 FTP      Response: 150 Opening ASCII mode data
                                                           connection for file list
32 10.761018 194.2.0.36    192.168.0.10 FTP-DATA FTP Data: 75 bytes
...

Le reste ne présente pas de nouveautés particulières. Notons qu'ici, c'est le serveur qui indique sur quel port il attend la prochaine connexion pour le transfert de données, et non plus le client FTP, comme nous l'avons vu en mode actif.

Ici, le suivi de connexion FTP n'est plus nécessaire sur la passerelle NAT/pare-feu.

2-2-1-1. Que pouvons-nous en conclure ?

Dans le mode passif, le client FTP est toujours client TCP. A charge pour le serveur FTP d'ouvrir de nouveaux ports sur lesquels il sera encore serveur TCP, pour le support des canaux de données. Le client FTP n'est jamais serveur TCP. Simplifie la vie pour le passage des filtres de paquets, mais alourdit la charge des serveurs FTP.

Chaque fois que ce sera possible, surtout si nous travaillons sur des « petits » serveurs FTP , utilisons plutôt le mode actif.

2-2-2. Le transfert non ASCII

C'est la deuxième chose qu'il faut savoir paramétrer sur son client FTP, parce qu'en principe, c'est lui qui décide. Nous avons bien vu que c'était lui qui envoyait la commande TYPE. Toujours sur Filezilla :

Image non disponible

Ce client FTP est vraiment très bien fait… Toujours dans le menu « Edition/paramètres », allons dans « Paramètres de transfert/ASCII/Binaire » et voyons. Par défaut, notre client est paramétré pour faire une détection automatique, en fonction de l'extension du fichier. Comme nous avons téléchargé un fichier txt, il a choisi automatiquement le mode ASCII. Nous pouvons forcer un mode. Bien entendu, si nous forçons le mode ASCII, les fichiers non ASCII arriveront corrompus. Il n'y a pas ici de mécanisme de type MIME pour faire de l'encodage base 64 par exemple.

Si nous devons forcer un mode, forçons le mode binaire, qui fonctionnera avec tout type de fichier, mais pas forcément de manière optimale.

2-2-2-1. Quelles différences ?

Juste un petit morceau de sniff :

 
Sélectionnez
No. Time      Source       Destination  Protocol Info
...
418 57.591410 192.168.0.10 194.2.0.36   FTP      Request: TYPE I

Le type demandé est maintenant I et non plus A

 
Sélectionnez
419 57.612530 194.2.0.36   192.168.0.10 FTP      Response: 200 Type set to I.
420 57.615147 192.168.0.10 194.2.0.36   FTP      Request: PASV
421 57.635511 194.2.0.36   192.168.0.10 FTP      Response: 227 Entering Passive Mode (194,2,0,36,18,136).
422 57.640090 192.168.0.10 194.2.0.36   FTP      Request: RETR rfc765.txt
423 57.640783 192.168.0.10 194.2.0.36   TCP      1111 > 4744 [SYN]
424 57.679211 194.2.0.36   192.168.0.10 TCP      4744 > 1111 [SYN, ACK]
425 57.679269 192.168.0.10 194.2.0.36   TCP      1111 > 4744 [ACK]
426 57.684695 194.2.0.36   192.168.0.10 TCP      ftp > 1105 [ACK]
427 57.699374 194.2.0.36   192.168.0.10 FTP      Response: 150 Opening BINARY mode data
                                                         connection for rfc765.txt (146641 bytes).

Le serveur répond qu'il ouvre le fichier en mode binaire et non plus ASCII

 
Sélectionnez
428 57.722806 194.2.0.36   192.168.0.10 FTP-DATA FTP Data: 1412 bytes
429 57.724012 194.2.0.36   192.168.0.10 FTP-DATA FTP Data: 1412 bytes
...

Les RFC 959 expliquent d'ailleurs la chose aux paragraphes 3.1.1.1 et 3.1.1.3

2-2-3. Où le serveur engueule le client

Encore un test hors d'age, mais qui reste intéressant. Un « upload » :

  • En utilisant un autre client FTP, ici, ce sera le client gFTP sous GNU/Linux
  • En utilisant un autre serveur FTP, ici, le serveur perso-ftp.wanadoo.fr.

En effet, chaque client FTP a ses petites habitudes et chaque serveur aussi…

Une fois de plus, nous allons étudier dans le détail cet échange.

 
Sélectionnez
 No. Time     Source         Destination    Protocol Info
  93 1.620013 192.168.0.254  193.252.18.14  TCP      32781 > ftp [SYN]
  94 1.650006 193.252.18.14  192.168.0.254  TCP      ftp > 32781 [SYN, ACK]
  95 1.650162 192.168.0.254  193.252.18.14  TCP      32781 > ftp [ACK]

Ouverture du canal de contrôle

 
Sélectionnez
  96 2.228519 193.252.18.14  192.168.0.254  FTP      Response: 220 pwp-ftp2 FTP server
                                                               (@(#)Version : 3-2-2  2002/08/21) ready.
  97 2.228698 192.168.0.254  193.252.18.14  TCP      32781 > ftp [ACK]
  98 2.229021 192.168.0.254  193.252.18.14  FTP      Request: USER dupond
  99 2.256639 193.252.18.14  192.168.0.254  TCP      ftp > 32781 [ACK]
 100 2.261983 193.252.18.14  192.168.0.254  FTP      Response: 331 PagePerso login ok, send your passwd.
 101 2.262205 192.168.0.254  193.252.18.14  FTP      Request: PASS dupont
 102 2.388503 193.252.18.14  192.168.0.254  TCP      ftp > 32781 [ACK]
 103 2.388952 193.252.18.14  192.168.0.254  FTP      Response: 230 User dupond logged in.
                                                                                Access restrictions apply.

Identification du client. Notons que le couple dupond/dupont circule en clair !

 
Sélectionnez
104 2.389150 192.168.0.254  193.252.18.14  FTP      Request: TYPE I
105 2.414035 193.252.18.14  192.168.0.254  FTP      Response: 200 Type set to I.

gFTP, quand on lui dit : « Mode binaire », il fait « mode binaire », même pour la récupération de la liste du répertoire.

 
Sélectionnez
106 2.414241 192.168.0.254  193.252.18.14  FTP      Request: PWD
107 2.433222 193.252.18.14  192.168.0.254  FTP      Response: 257 « /pub » is current directory.
108 2.438940 192.168.0.254  193.252.18.14  FTP      Request: PORT 192,168,0,254,128,14
109 2.462881 193.252.18.14  192.168.0.254  FTP      Response: 200 PORT command successful.
110 2.463200 192.168.0.254  193.252.18.14  FTP      Request: LIST -aL
111 2.582733 193.252.18.14  192.168.0.254  TCP      ftp > 32781 [ACK]

Mais il demande des détails. Les options « a » et « L » permettent d'obtenir les noms commençant par un point (entrées cachées) ainsi que la taille et les attributs de chaque entrée du répertoire.

 
Sélectionnez
 112 2.757014 193.252.18.14  192.168.0.254  TCP      ftp-data > 32782 [SYN]
 113 2.757157 192.168.0.254  193.252.18.14  TCP      32782 > ftp-data [SYN, ACK]
 114 2.774846 193.252.18.14  192.168.0.254  TCP      ftp-data > 32782 [ACK]

Ouverture du canal de données.

 
Sélectionnez
 115 2.775365 193.252.18.14  192.168.0.254  FTP      Response: 150 Opening BINARY mode data connection
                                                               for /bin/ls.
 116 2.808833 193.252.18.14  192.168.0.254  FTP-DATA FTP Data: 520 bytes
 117 2.808916 193.252.18.14  192.168.0.254  TCP      ftp-data > 32782 [FIN, ACK]
 118 2.808983 192.168.0.254  193.252.18.14  TCP      32782 > ftp-data [ACK]
 119 2.809821 192.168.0.254  193.252.18.14  TCP      32782 > ftp-data [FIN, ACK]
 120 2.822139 192.168.0.254  193.252.18.14  TCP      32781 > ftp [ACK]
 121 2.835875 193.252.18.14  192.168.0.254  TCP      ftp-data > 32782 [ACK]

Le canal de données est fermé d'un commun accord.

 
Sélectionnez
 122 2.844263 193.252.18.14  192.168.0.254  FTP      Response: 226-Transfer complete.
 123 2.844383 192.168.0.254  193.252.18.14  TCP      32781 > ftp [ACK]
 126 6.738405 192.168.0.254  193.252.18.14  FTP      Request: PORT 192,168,0,254,128,15
 127 6.760458 193.252.18.14  192.168.0.254  FTP      Response: 200 PORT command successful.
 128 6.760606 192.168.0.254  193.252.18.14  TCP      32781 > ftp [ACK]
 129 6.760844 192.168.0.254  193.252.18.14  FTP      Request: STOR /pub/ie6_proxy_1.gif

Le client va envoyer son fichier.

 
Sélectionnez
 130 6.886677 193.252.18.14  192.168.0.254  TCP      ftp > 32781 [ACK]
 131 6.923111 193.252.18.14  192.168.0.254  TCP      ftp-data > 32783 [SYN]
 132 6.923242 192.168.0.254  193.252.18.14  TCP      32783 > ftp-data [SYN, ACK]
 133 6.947755 193.252.18.14  192.168.0.254  TCP      ftp-data > 32783 [ACK]

Un nouveau canal de données est ouvert.

 
Sélectionnez
 134 6.948206 193.252.18.14  192.168.0.254  FTP      Response: 150 Opening BINARY mode data connection
                                                               for /pub/ie6_proxy_1.gif.
 135 6.959283 192.168.0.254  193.252.18.14  FTP-DATA FTP Data: 1412 bytes
 136 6.960470 192.168.0.254  193.252.18.14  FTP-DATA FTP Data: 1412 bytes
 137 6.982307 192.168.0.254  193.252.18.14  TCP      32781 > ftp [ACK]

Et le transfert démarre.

 
Sélectionnez
 138 6.986320 193.252.18.14  192.168.0.254  TCP      ftp-data > 32783 [ACK]
 139 6.987578 192.168.0.254  193.252.18.14  FTP-DATA FTP Data: 1412 bytes
 140 6.988767 192.168.0.254  193.252.18.14  FTP-DATA FTP Data: 1412 bytes
 141 6.999923 193.252.18.14  192.168.0.254  TCP      ftp-data > 32783 [ACK]
 142 7.001176 192.168.0.254  193.252.18.14  FTP-DATA FTP Data: 1412 bytes
 143 7.002388 192.168.0.254  193.252.18.14  FTP-DATA FTP Data: 1412 bytes
 144 7.123111 193.252.18.14  192.168.0.254  TCP      ftp-data > 32783 [ACK]
 145 7.124365 192.168.0.254  193.252.18.14  FTP-DATA FTP Data: 1412 bytes
 146 7.125555 192.168.0.254  193.252.18.14  FTP-DATA FTP Data: 1412 bytes
 147 7.126746 192.168.0.254  193.252.18.14  FTP-DATA FTP Data: 1412 bytes
 148 7.314251 193.252.18.14  192.168.0.254  TCP      ftp-data > 32783 [ACK]
 149 7.315529 192.168.0.254  193.252.18.14  FTP-DATA FTP Data: 1412 bytes
 150 7.315885 192.168.0.254  193.252.18.14  FTP-DATA FTP Data: 372 bytes
 151 7.315950 192.168.0.254  193.252.18.14  TCP      32783 > ftp-data [FIN, ACK]
 152 7.502913 193.252.18.14  192.168.0.254  TCP      ftp-data > 32783 [ACK]
 153 7.680958 193.252.18.14  192.168.0.254  TCP      ftp-data > 32783 [ACK]
 154 7.713910 193.252.18.14  192.168.0.254  TCP      ftp-data > 32783 [ACK]
 155 7.714014 193.252.18.14  192.168.0.254  FTP      Response: 226 Transfer complete.
 156 7.714093 193.252.18.14  192.168.0.254  TCP      ftp-data > 32783 [FIN, ACK]
 157 7.714166 192.168.0.254  193.252.18.14  TCP      32781 > ftp [ACK]
 158 7.714232 192.168.0.254  193.252.18.14  TCP      32783 > ftp-data [ACK]

Le transfert est terminé, le canal de données est fermé.

 
Sélectionnez
159 7.714542 192.168.0.254  193.252.18.14  FTP      Request: SITE CHMOD 744 /pub/ie6_proxy_1.gif
160 7.765540 193.252.18.14  192.168.0.254  FTP      Response: 200 CHMOD command successful.
161 7.802347 192.168.0.254  193.252.18.14  TCP      32781 > ftp [ACK]

Le monde Unix…
Le client gFTP demande au serveur de changer les attributs du fichier. 744, ce qui signifie que le propriétaire a tous les droits et que les autres ne peuvent que lire.

 
Sélectionnez
 162 8.334702 192.168.0.254  193.252.18.14  FTP      Request: PORT 192,168,0,254,128,16
 163 8.355047 193.252.18.14  192.168.0.254  FTP      Response: 200 PORT command successful.
 164 8.355196 192.168.0.254  193.252.18.14  TCP      32781 > ftp [ACK]
 165 8.355366 192.168.0.254  193.252.18.14  FTP      Request: LIST -aL
 166 8.435637 193.252.18.14  192.168.0.254  TCP      ftp-data > 32784 [SYN]
 167 8.435767 192.168.0.254  193.252.18.14  TCP      32784 > ftp-data [SYN, ACK]
 168 8.457199 193.252.18.14  192.168.0.254  TCP      ftp-data > 32784 [ACK]
 169 8.457363 193.252.18.14  192.168.0.254  FTP      Response: 150 Opening BINARY mode data connection
                                                               for /bin/ls.
 170 8.464111 193.252.18.14  192.168.0.254  FTP-DATA FTP Data: 591 bytes
 171 8.464194 193.252.18.14  192.168.0.254  TCP      ftp-data > 32784 [FIN, ACK]
 172 8.464262 192.168.0.254  193.252.18.14  TCP      32784 > ftp-data [ACK]
 173 8.465013 192.168.0.254  193.252.18.14  TCP      32784 > ftp-data [FIN, ACK]
 174 8.492369 192.168.0.254  193.252.18.14  TCP      32781 > ftp [ACK]
 175 8.494386 193.252.18.14  192.168.0.254  TCP      ftp-data > 32784 [ACK]
 176 8.511638 193.252.18.14  192.168.0.254  FTP      Response: 226-Transfer complete.

Rien de bien nouveau, le client rafraichit la liste des entrées du répertoire courant.

 
Sélectionnez
177  8.511763 192.168.0.254  193.252.18.14  TCP      32781 > ftp [ACK]
178 14.584417 192.168.0.254  193.252.18.14  TCP      32781 > ftp [FIN, ACK]
179 14.603193 193.252.18.14  192.168.0.254  TCP      ftp > 32781 [ACK]

Le client ferme alors le canal de contrôle, sans autre forme de procès…

 
Sélectionnez
180 14.603616 193.252.18.14  192.168.0.254  FTP      Response: 221 You could at least say goodbye.

Et se fait jeter par le serveur qui, habitué à la politesse, est choqué de ne pas lire une formule du genre « au revoir et merci

 
Sélectionnez
181 14.603731 192.168.0.254  193.252.18.14  TCP      32781 > ftp [RST]

Mais le client répond en gros « va te faire f… » [RST] indiquant au serveur qu'il parle devant une porte fermée, affichant ouvertement sa grossièreté.

2-2-4. Ca y est ? Nous avons tout vu ?

Non. FTP sait encore faire d'autres choses que nous n'avons pas vues ici, mais nous avons pu observer l'essentiel :

  • Le transfert binaire ou ASCII. C'est une notion qu'il faut connaître si l'on ne veut pas risquer de perdre beaucoup de temps. Si l'on peut transférer n'importe quoi en mode binaire sans trop de risques, il n'en va pas de même si l'on essaye de transférer en mode ASCII un fichier qui n'est pas du texte.
  • Les modes Actif et Passif. La notion est elle aussi essentielle, surtout s'il y a un pare-feu à filtrage de paquets non configuré pour autoriser le mode actif, c'est-à-dire le mode où le client FTP se retrouve serveur TCP sur le canal de données.
  • Nous avons vu avec suffisamment de précision le mécanisme des canaux de commandes et de données, en modes actif et passif, pour pouvoir configurer avec quelques espoir de réussite un firewall du genre GNU/Linux avec Netfilter.

Nous n'avons pas vu en revanche :

  • Comment utiliser FTP pour faire de l'impression distante,
  • comment utiliser FTP à travers un serveur PROXY ou un proxy SOCKS, mais ces problèmes ne sont pas spécifiquement du ressort de FTP et ne peuvent se rencontrer qu'en entreprise.
  • Enfin, nous n'avons pas vu certains modes de transfert que FTP sait faire, relatifs à la compression des données et à la reprise en cas d'incident, mais pour utiliser ces possibilités, encore faut-il disposer d'un client qui sache les gérer.
  • Finalement, nous n'avons pas fait non plus de transfert de fichier de serveur à serveur avec un client distant. Pour mener à bien cette tâche, il vous faudra :
    • Un client FTP qui sache faire ce genre d'opérations (gftp en mode graphique, lftp en ligne de commande). Sous Windows, je n'en ai trouvé qu'un : FlashFXP, qui n'est pas libre ;
    • des serveurs FTP qui acceptent ce genre d'opérations.

Si vous voulez en savoir d'avantage sur FTP, vous n'avez plus d'autre choix que de lire les RFC 959.

3. Jouons avec Pure-ftpd

Après nous être intéressés à FTP du côté du client, nous allons le faire du côté du serveur. Disposer chez soi d'un petit serveur FTP peut rendre quelques services.

Bien entendu, il n'est pas question de mettre en place un vrai serveur public au bout d'une connexion ADSL, même de bonne qualité. Le A du DSL indiquant clairement que le débit de notre serveur sera forcément lamentable, comparé à un serveur hébergé chez un fournisseur de services. Mais la location d'un serveur dédié chez un fournisseur de service représente un certain budget.

Cependant, pouvoir disposer d'un accès à des données personnelles où que l'on se trouve, même si l'on a oublié sa clé USB peut présenter un réel intérêt.

Nous aurons ainsi l'occasion de nous intéresser au paramétrage d'un serveur FTP, à son accès en modes passif ou actif, qu'il soit placé sur la machine faisant aussi office de routeur NAT ou même derrière le NAT. Nous aurons même l'occasion de tester ce serveur en accès IPv6.

Enfin, nous aborderons FTPES, qui ajoute la cryptographie à notre système, apportant par là un peu de confidentialité si le besoin s'en fait sentir (rappelons nous que les dupond/dupont vus plus haut ne sont pas discrets).

Pure-FTPD sera l'heureux élu pour nos manipulations.

3-1. Installation de base

Jouons un peu avec ce serveur FTP. Ce sera l'occasion de voir plus en détails les commandes du protocole. Pour les besoins de cette manipulation, une machine virtuelle fera l'affaire. Lorsque nous aurons fait le tour du problème, nous pourrons placer notre serveur où ce sera le plus judicieux.

L'hôte virtuel a pour adresse IP 192.168.10.76 et fonctionne avec une Debian squeeze. Pour tout dire, il s'agit d'un DomU Xen, hébergé sur Une Debian squeeze « xénifiée ».

Ce réseau est accessible par le réseau 192.168.0.0/24 où se trouve le poste de travail (Ubuntu 10.10, en attendant de passer à Arch Linux).

Il n'y a pas ici de NAT, ni d'un côté ni de l'autre, il y a juste un tunnel OpenVpn entre les deux réseaux IP, si vous voulez tout savoir.

Voici la vraie installation :

Image non disponible

Mais qui fonctionnellement peut se résumer ainsi :

Image non disponible

Nous avons donc fonctionnellement deux réseaux IP 192.168.10.0/24 et 192.168.0.0/24 simplement routés entre eux. Le tunnel peut être omis, mais si nous voulons le détail d'un tcptraceroute :

 
Sélectionnez
Tracing the path to 192.168.10.76 on TCP port 21 (ftp), 30 hops max
 1  192.168.0.254  0.168 ms  0.143 ms  0.185 ms
 2  192.168.25.3  47.686 ms  46.795 ms  46.018 ms
 3  192.168.10.76 [open]  45.906 ms  47.400 ms  50.886 ms

3-1-1. Installation

C'est simple :

 
Sélectionnez
aptitude install pure-ftpd

Qui installe aussi pure-ftpd-common. Il y a d'autres versions de ce serveur :

 
Sélectionnez
# aptitude search pure-ftpd
p   mysqmail-pure-ftpd-logger      - real-time logging system in MySQL - Pure-FTPd traffic-logger
i   pure-ftpd                      - Secure and efficient FTP server
i A pure-ftpd-common               - Pure-FTPd FTP server (Common Files)
p   pure-ftpd-ldap                 - Secure and efficient FTP server with LDAP user authentication
p   pure-ftpd-mysql                - Secure and efficient FTP server with MySQL user authentication
p   pure-ftpd-postgresql           - Secure and efficient FTP server with PostgreSQL user authentication

Nous n'allons pas monter une usine à gaz et les identifications des utilisateurs fournies par le paquet pure-ftpd nous suffisent largement. Les logs dans un simple fichier texte suffiront également.

L'installation se termine par le démarrage du serveur en mode « standalone » avec la ligne de commande :

 
Sélectionnez
Starting ftp server: Running: /usr/sbin/pure-ftpd -l pam -8 UTF-8 -E -O clf:/var/log/pure-ftpd/transfer.log -u 1000 -B 

3-1-1-1. Quelques mots à propos de pure-ftpd

Ce serveur, dans sa version « vanilla » n'est pas prévu pour s'appuyer sur un fichier de configuration. Cette dernière se fait par une liste d'arguments, ce qui explique cette ligne de commande un peu incantatoire. Le mainteneur du paquet Debian a toutefois jugé nécessaire, pour rester dans l'harmonie Debian, de créer un « wrapper » qui lit un tas de fichiers situés dans /etc/pure-ftpd/ ainsi qu'un fichier /etc/default/pure-ftpd-common. Ce « wrapper » ne fait que construire la ligne de commande nécessaire au démarrage de pure-ftpd.

Comme nous n'utiliserons pas ce serveur de façon intensive, nous le ferons fonctionner plutôt à travers le super-serveur inetd. Pour cette raison, nous ne nous intéresserons pas plus que ça à la particularité Debian.

Analysons tout de même la ligne de commande construite par défaut lors de l'installation :

  • -l pam indique que l'authentification des utilisateurs se fait à travers PAM. Peut-être choisirons-nous quelque chose de plus simple ;
  • -8 UTF-8 n'est pas documentée mais elle semble vouloir indiquer que l'on souhaite utiliser UTF-8 ;
  • -E interdit les connexions anonymes ;
  • -O clf:/var/log/pure-ftpd/transfer.log permet d'indiquer où et avec quel format le serveur va consigner les transferts de fichiers effectués. Ici, dans un format similaire à celui d'Apache ;
  • -u 1000 interdit aux utilisateurs dont l'uid est inférieure à 1000 de se connecter au serveur, autrement dit, les comptes « système » ;
  • -B démarre le serveur en tâche de fond (sera inutile pour nous).

Pure-ftpd propose plusieurs méthodes d'identification des utilisateurs. PAM en est une, mais si nous souhaitons isoler les comptes FTP des comptes locaux, mieux vaut utiliser une logique d'utilisateurs virtuels. Sans aller jusqu'à une base SQL ou un annuaire LDAP, notre serveur propose une méthode « maison », gérée avec un outil pure-pw que nous utiliserons.

Apriori, nous ne souhaitons pas créer de zone publique (connexions anonymes).

Il pourra être nécessaire d'étudier quelques techniques pour préserver cette pauvre bande passante : Nombre limité de connexions simultanées, nombre limité d'utilisateurs simultanés, limitation du débit des transferts…

Nous savons que par défaut FTP laisse passer en clair les identifiants des utilisateurs. Peut-être faudra-t-il envisager de mettre en œuvre TLS.

Nous mettrons en place un filtrage de paquets (Netfilter) sur le serveur virtuel, il faudra l'adapter pour que FTP fonctionne correctement.

3-1-1-2. Mode opératoire

Dans un premier temps, nous allons désactiver le démarrage en mode « daemonized ». Pour les essais, nous ferons démarrer le serveur dans un shell et lorsque nous aurons arrêté une configuration convenable, nous configurerons inetd pour qu'il prenne en charge notre serveur FTP.

3-1-2. Recherche d'une configuration

3-1-2-1. L'authentification

Le support des utilisateurs virtuels se fait par un fichier de structure assez similaire au /etc/passwd. Il est maintenu par la commande pure-pw.

Comme ces utilisateurs sont virtuels, ils n'ont aucune existence sur le système. il est nécessaire de créer un compte système que le serveur pourra emprunter pour effectuer les opérations de lecture et d'écriture pour le compte de ces utilisateurs virtuels. Un seul compte utilisateur suffit, si l'on veut rester simple, chaque utilisateur virtuel disposant de son propre espace, dans lequel il est emprisonné (chroot).

3-1-2-1-1. Préparation du système

Commençons par arrêter le serveur « standalone » :

 
Sélectionnez
# /etc/init.d/pure-ftpd stop

Puis modifions /etc/default/pure-ftpd-common comme suit :

 
Sélectionnez
STANDALONE_OR_INETD=inetd

De cette manière, le script init ne cherchera plus à démarrer pure-ftpd comme un service.

Nous allons maintenant créer un groupe ftpgroup :

 
Sélectionnez
# groupadd ftpgroup

Nous créons un utilisateur ftpuser qui appartient à ce groupe, qui n'a pas de répertoire par défaut, qui n'a pas de shell et qui n'a pas non plus de mot de passe :

 
Sélectionnez
# useradd -g ftpgroup -d /dev/null -s /bin/false ftpuser

Nous créons un répertoire qui contiendra les répertoires des utilisateurs virtuels :

 
Sélectionnez
# mkdir /home/ftpusers
3-1-2-1-2. Création d'un compte virtuel

Avec la commande pure-pw créons un compte test :

 
Sélectionnez
# pure-pw useradd test -u ftpuser -d /home/ftpusers/test

Cette commande nécessitera d'entrer un mot de passe pour notre utilisateur test. Nous pouvons vérifier :

 
Sélectionnez
# pure-pw show test

Login              : test
Password           : $1$GrGl3h50$VHP8e646FLXfk7qUUnA7G1
UID                : 1001 (ftpuser)
GID                : 1001 (ftpgroup)
Directory          : /home/ftpusers/test/./
Full name          : 
Download bandwidth : 0 Kb (unlimited)
Upload   bandwidth : 0 Kb (unlimited)
Max files          : 0 (unlimited)
Max size           : 0 Mb (unlimited)
Ratio              : 0:0 (unlimited:unlimited)
Allowed local  IPs : 
Denied  local  IPs : 
Allowed client IPs : 
Denied  client IPs : 
Time restrictions  : 0000-0000 (unlimited)
Max sim sessions   : 0 (unlimited)

Tout ceci laisse entendre qu'il est possible de configurer finement chaque compte virtuel. Il sera intéressant de lire le manuel de pure-pw… Le mot de passe est chiffré, mieux vaut donc ne pas l'oublier, ou alors il faudra en générer un nouveau (pure-pw permet de le faire); cet utilisateur empruntera bien le compte système ftpuser pour ses opérations de lecture/écriture, son répertoire de base sera bien /home/ftpusers/, le ./ qui suit signifie qu'il sera prisonnier de son répertoire, ce que nous ne manquerons pas de vérifier.

Ce n'est pas tout. Pure-pw a créé (par défaut) un fichier /etc/pure-ftpd/pureftpd.passwd, mais pure-ftpd n'utilisara pas directement ce fichier pour l'authentification. Pour des raisons de rapidité, il faut créer un fichier formaté spécialement, toujours avec la commande pure-pw :

 
Sélectionnez
# pure-pw mkdb

qui crée, toujours par défaut, un fichier /etc/pure-ftpd/pureftpd.pdb.

3-1-2-1-3. Premier test

Nous démarrons le serveur avec les options suivantes :

 
Sélectionnez
# pure-ftpd -j -l puredb:/etc/pure-ftpd/pureftpd.pdb
  • -j fera que le répertoire de l'utilisateur sera automatiquement créé s'il n'existe pas déjà ;
  • -l indique le mode d'authentification (puredb) et le fichier à consulter.

Nous pouvons dans une autre console, observer deux choses :

 
Sélectionnez
# ps aux | grep pure
root     23658  0.0  0.3  24888  1668 pts/0    S+   18:44   0:00 pure-ftpd (SERVER) 

et :

 
Sélectionnez
# netstat -laputen | grep pure
tcp     0    0 0.0.0.0:21    0.0.0.0:*       LISTEN      0          71232       23658/pure-ftpd (SE
tcp6    0    0 :::21         :::*            LISTEN      0          71234       23658/pure-ftpd (SE

Nous avons un serveur qui tourne (c'est tant mieux), sous l'identité root (oups ?) et qu'il écoute sur toutes les interfaces, aussi bien en IPv4 qu'en IPv6.

Avec notre FileZilla nous nous connections au serveur 192.168.10.76 avec comme identifiant test et son mot de passe et nous voyons dans le liste du haut :

 
Sélectionnez
Statut :        Connexion à 192.168.10.76:21...
Statut :        Connexion établie, attente du message d'accueil...
Réponse :       220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
Réponse :       220-You are user number 1 of 50 allowed.
Réponse :       220-Local time is now 18:30. Server port: 21.
Réponse :       220-IPv6 connections are also welcome on this server.
Réponse :       220 You will be disconnected after 15 minutes of inactivity.
Commande :      USER test
Réponse :       331 User test OK. Password required
Commande :      PASS ********
Réponse :       230-User test has group access to:  ftpgroup  
Réponse :       230 OK. Current directory is /
Commande :      OPTS UTF8 ON
Réponse :       200 OK, UTF-8 enabled
Statut :        Connecté
Statut :        Récupération du contenu du dossier...
Commande :      PWD
Réponse :       257 "/" is your current location
Statut :        Succès de la lecture du contenu du dossier

Tout s'est bien passé. Sur le serveur, le dossier a été créé (par ftpuser) :

 
Sélectionnez
# ls -l /home/ftpusers/
total 4
drwxr-xr-x 2 ftpuser ftpgroup 4096  1 janv. 18:30 test

Si nous essayons de remonter dans l'arborescence (..), nous avons :

 
Sélectionnez
Statut :        Récupération du contenu du dossier...
Commande :      CDUP
Réponse :       250 OK. Current directory is /
Commande :      PWD
Réponse :       257 "/" is your current location
Statut :        Succès de la lecture du contenu du dossier

CDUP (Change Directory UP) pour aller vers le répertoire parent a bien été exécutée, mais test est resté prisonnier de son répertoire.

Tant que notre client est connecté, revoyons un peu :

 
Sélectionnez
# ps aux | grep pure
root     23658  0.0  0.3  24888  1672 pts/0    S+   18:44   0:00 pure-ftpd (SERVER)                                
ftpuser  23666  0.0  0.2  37540  1480 pts/0    S+   18:49   0:00 pure-ftpd (IDLE)                                  
root     23667  0.0  0.1  37512  1000 pts/0    S+   18:49   0:00 pure-ftpd (PRIV)

et :

 
Sélectionnez
# netstat -laputen | grep pure
tcp     0   0 0.0.0.0:21           0.0.0.0:*               LISTEN      0    71232     23658/pure-ftpd (SE
tcp     0   0 192.168.10.76:21     192.168.0.16:34924      ESTABLISHED 0    71309     23666/pure-ftpd (ID
tcp6    0   0 :::21                :::*                    LISTEN      0    71234     23658/pure-ftpd (SE

Nous avons un nouveau service qui tourne sous l'identité ftpuser, en mode IDLE parce que nous ne faisons rien de particulier en ce moment et un troisième service (PRIV).

Le service IDLE a bien établi une connexion en IPv4 entre le client (192.168.0.16:34924) et le serveur (192.168.10.76:21). Autrement dit, les échanges entre client et serveur vont se faire sous l'identité ftpuser (ouf !).

Tout ceci est plutôt encourageant.

3-2. Affinons la configuration

3-2-1. Pas de FTP anonyme

Pure-ftpd accepte par défaut les connexions anonymes, si un utilisateur nommé ftp existe, avec son répertoire /home/ftp. Si ces conditions ne sont pas remplies, il n'y aura pas d'accès anonyme possible. Cependant, mieux vaut signaler explicitement que l'on n'en veut pas, avec le paramètre -E.

3-2-2. Protéger la bande passante

Depuis l'avènement de l'internet à « haut débit » (1998 à peu près), le débit « upload » a toujours été inférieur au débit « download », considérant que l'internaute est un consommateur et pas un acteur (ce qui est hélas trop souvent vrai). Il nous faut nous contenter en moyenne de 100 Ko/s en upload, et il faut bien voir que notre upload sera le débit maximal de notre serveur FTP qui ne sera donc pas une bête de course. Qui plus est, si le serveur doit fonctionner alors qu'il y a des clients actifs sur notre réseau local, il faudra partager cette bande passante dérisoire.

Si nous voulons faire simple, nous pouvons limiter le débit du serveur avec le paramètre -T. Cette option peut limiter les débits «up » et « down ». Les limites sont données en Ko/s, séparés par un :. Par exemple, -T :60 ne limitera pas l'upload sur le serveur, mais limitera le download à 60 Ko/s.

Ce paramètre s'applique à tous les utilisateurs. Nous avons suggéré qu'il est possible de faire plus fin en définissant des limites à chaque utilisateur, avec la commande pure-pw.

Le lecteur attentif aura pu constater que, par défaut, le serveur accepte 50 clients simultanés. Il est sans doute judicieux de limiter ce nombre, avec le paramètre -c. De même qu'il est possible de limiter le nombre de connexions simultanées par client (paramètre -C).

Au final, notre ligne de commende pourrait être de la forme :

 
Sélectionnez
# pure-ftpd -j -l puredb:/etc/pure-ftpd/pureftpd.pdb -E -T :30 -c 3 -C 2

3-2-3. Les logs

Par défaut, pure-ftpd va envoyer ses logs sur le syslog. Si l'on souhaite récupérer ces logs dans un fichier séparé, il faudra donc configurer notre système de logs.

Il existe cependant le paramètre -O (déjà vu plus haut) qui permet de créer un fichier propre aux transferts. Par exemple -O clf:/var/log/pure-ftpd/transfer.log comme fait par défaut dans l'installation Debian. Dans ce cas, les transferts seront consignés dans ce fichier. Le reste des informations que pure-ftpd pourrait envoyer seront à rechercher dans les messages du syslog.

3-2-4. TLS

Pure-ftpd sait faire du FTPES (FTP over explicit TLS/SSL). Dans cette configuration, les connexions sont chiffrées par TLS, ce qui évite entre autres le passage de l'authentification en clair.

Le système est simple (et peu souple). Il faut créer un certificat x509 qui doit obligatoirement s'appeler pure-ftpd.pem et se trouver dans /etc/ssl/private/. Pour le construire, il faut bien sûr avoir installé openssl et utiliser la commande suivante :

 
Sélectionnez
# openssl req -x509 -nodes -days 7300 -newkey rsa:2048 -keyout /etc/ssl/private/pure-ftpd.pem -out /etc/ssl/private/pure-ftpd.pem 

Ce certificat autosigné sera donc valide 7300 jours, c'est peut-être beaucoup…

 
Sélectionnez
Generating a 2048 bit RSA private key
....................................................................+++
..................................................................................................................+++
writing new private key to '/etc/ssl/private/pure-ftpd.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:FR
State or Province Name (full name) [Some-State]:BdR
Locality Name (eg, city) []:Marseille
Organization Name (eg, company) [Internet Widgits Pty Ltd]:IRP
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:ftp.nain-t.net
Email Address []:irp@nain-t.net

Il faudra aussi :

 
Sélectionnez
# chmod 600 /etc/ssl/private/pure-ftpd.pem

Enfin, le paramètre -Y spécifiera l'utilisation de TLS. Pour la suite des manipulations, nous adopterons -Y 1 qui laisse le choix au client d'utiliser ou non TLS. -Y 2 n'autorisera pas les connexions sans TLS.

3-2-4-1. Test

Pour tester TSL, mieux vaut créer dans le gestionnaire de sites de FileZilla :

Image non disponible

FTPES est donc un mode de transfert FTP explicitement sécurisé. Ce mode introduit des commandes supplémentaires qui dont définies dans les RFC 2228 : This document defines extensions to the FTP specification STD 9, RFC 959, “FILE TRANSFER PROTOCOL (FTP)” (October 1985). These extensions provide strong authentication, integrity, and confidentiality on both the control and data channels with the introduction of new optional commands, replies, and file transfer encodings.

La connexion suivant ce mode fera apparaitre :

Image non disponible

Si nous acceptons ce certificat, la connexion s'établit et dans la fenêtre du protocole nous observons :

 
Sélectionnez
Statut :        Connexion à 192.168.10.76:21...
Statut :        Connexion établie, attente du message d'accueil...
Réponse :       220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
Réponse :       220-You are user number 1 of 3 allowed.
Réponse :       220-Local time is now 17:32. Server port: 21.
Réponse :       220-This is a private system - No anonymous login
Réponse :       220-IPv6 connections are also welcome on this server.
Réponse :       220 You will be disconnected after 15 minutes of inactivity.
Commande :      AUTH TLS
Réponse :       234 AUTH TLS OK.
Statut :        Initialisation TLS...
Statut :        Vérification du certificat...
Commande :      USER test
Statut :        Connexion TLS/SSL établie.
Réponse :       331 User test OK. Password required
Commande :      PASS ********
Réponse :       230-Your bandwidth usage is restricted
Réponse :       230-User test has group access to:  ftpgroup  
Réponse :       230 OK. Current directory is /
Commande :      SYST
...

Le client FileZilla réclame une authentification TLS, qui lui est accordée, et la connexion TLS est établie avant le passage du mot de passe. Nous pouvons d'ailleurs vérifier avec notre wireshark habituel :

 
Sélectionnez
No.     Time        Source                Destination           Protocol Info
      1 0.000000    192.168.0.16          192.168.10.76         TCP      41198 > ftp [SYN] Seq=0 Win=5840 Len=0 MSS=1460 TSV=348647 TSER=0 WS=7
      2 0.045419    192.168.10.76         192.168.0.16          TCP      ftp > 41198 [SYN, ACK] Seq=0 Ack=1 Win=5792 Len=0 MSS=1368 TSV=106073221 TSER=348647 WS=5
      3 0.045442    192.168.0.16          192.168.10.76         TCP      41198 > ftp [ACK] Seq=1 Ack=1 Win=5888 Len=0 TSV=348651 TSER=106073221
      4 0.101193    192.168.10.76         192.168.0.16          FTP      Response: 220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
      5 0.101210    192.168.0.16          192.168.10.76         TCP      41198 > ftp [ACK] Seq=1 Ack=320 Win=6912 Len=0 TSV=348657 TSER=106073234
      6 0.101333    192.168.0.16          192.168.10.76         FTP      Request: AUTH TLS
      7 0.148394    192.168.10.76         192.168.0.16          TCP      ftp > 41198 [ACK] Seq=320 Ack=11 Win=5792 Len=0 TSV=106073246 TSER=348657
      8 0.150079    192.168.10.76         192.168.0.16          FTP      Response: 234 AUTH TLS OK.
      9 0.150989    192.168.0.16          192.168.10.76         FTP      Request: \026\003\002\000O\001\000\000K\003\002O\005\322\335\335d\2319U4\303[8\311\264\223\304\320\025\030\244\357\271d\202\330\361\373Rg)@\000\000$\0003\000E\0009\000\210\000\026\0002\000D\0008\000\207\000\023\000f\000/\000A\0005\000\204\000
     10 0.215860    192.168.10.76         192.168.0.16          FTP      Response: \026\003\001\000J\002\000\000F\003\001O\005\322\335H\315\246\005\351[\346.\263\033\301`\030\216"7\324gba|\021\350\307*+\201\267 \3648Y\335\257\204,.\334\253C\232x\f\217\265\2351.T0Vo\370\235\206\267I\333\231yY\0003\000\026\003\001\004V\v\000\004R\000\004O\000\004L0\202\004H0\202\0030\240\003\002\001\002\002\t\000\237s\0326\002\241\304y0
     11 0.218216    192.168.10.76         192.168.0.16          FTP      Response: \033\343:2 \374f\226%\360E\031\322j\240#\316\303\244\252\337\260\001\221\247U\363\224\223\030\302q\005HG\200\367\0166\2640\016\341\337M\2550\004\211$N\245\376E\227\302PK\332\270\006\250zL\211&-\346\263\264\022\377i\221\201\315\202\032z\253B\356y\233i\317IjU\337d\031'\016{\020G\022\246\351Y\317\210\276u\35395hC\001\000\001\323\345\000\021.\032l\332\214\3600x\025\255\300\327\374\342\343+\275\332\005\234\220!\376`\255\210\370\021"\243\301P\261gF#L\253\341\3465\313>\265FV\200Qs\365\253\274s\356D,X'
     12 0.218229    192.168.0.16          192.168.10.76         TCP      41198 > ftp [ACK] Seq=95 Ack=2071 Win=12544 Len=0 TSV=348669 TSER=106073260
     13 0.226760    192.168.0.16          192.168.10.76         FTP      Request: \026\003\001\000\206\020\000\000\202\000\200\b\322Xk\344O\275\330\251\032\257?\241\251\243!\361\250\001z9\342\342\205\346\241\0356\347V?\v\a\242\277\266+\027\242`}\300W\231\240\234&\357\v\3113\001v/&\211\023aRP
     14 0.226773    192.168.0.16          192.168.10.76         FTP      Request: \024\003\001\000\001\001
     15 0.227819    192.168.0.16          192.168.10.76         FTP      Request: \026\003\001\0000H\232_k%t\232=,\324\251\026\035\277\262F\224C\005\270>\355\225h\234R\221\177\266z\317\233W\310p\261\255\036\275l\367\212#\3378\323\271\027
     16 0.276986    192.168.10.76         192.168.0.16          TCP      ftp > 41198 [ACK] Seq=2071 Ack=240 Win=6880 Len=0 TSV=106073279 TSER=348670
     17 0.279681    192.168.10.76         192.168.0.16          FTP      Response: \024\003\001\000\001\001\026\003\001\0000\350%k\216\327\226|N\au\203o\272\033\333V\233b\2226Eg\002\332o\302`\206\230\032\tUKrR\217$u\254z9c\357\002\233K\f=
     18 0.281552    192.168.0.16          192.168.10.76         FTP      Request: \027\003\001\000\260\332\316[\341R`5\332\233\vU\365\275\033\306a.h\251A\0310\a\201\347rI<)b\312-0.r\361\200\266\255\254\276\367\323\a\332xe\365\331\206\334U\301\300#q:\342>\2525\243j\274J\336\220\022@\221b\373\240\202-C?,~\003VE\334\242
     19 0.331704    192.168.10.76         192.168.0.16          FTP      Response: \027\003\001\000@o\a+\303\333)l+XZ\260\260\243|)/f\304Kv\262S`\274\273\304\200\316\215u\264\tR\000\231\240\021v
     20 0.331923    192.168.0.16          192.168.10.76         FTP      Request: \027\003\001\001\020\2518:\203K:y\343:\t\016R\002?+_\340F F\005lO\267*\252\274\202p\325\2746Q$3\310\335\252\261\v\371\037\313\344e\207\027\3633\2244\334\021I\205gHVn\315*\bj\331\0230\203\314\200i\231\314u'-\315\321\271F#\336\243\353\242GT:\vy\235\251\032\216\324\202\026\t[\361\217/\020\a\376]\252\247\306\240\205\225\215K\350<\274\307K\301M\333\024/nn\342,\}k\247\360m\271\245G\372\216\222\021\336\264\251c\b\326\020\t\237\346\366u\217\257\305\201\034[{\\202\376H!w\332>\351\301
     21 0.389619    192.168.10.76         192.168.0.16          FTP      Response: \027\003\001\000@B\314\337\266\312\225\027\f\220U\265fx\244\026\330Y\307\240\213n\251\272\300\002\372\307\232I\355\360T\317\301{,\320\265\006\225T\002'h\000\220\361k\270\337.\330\276\2309F\203)\366\336\246e\310]
     22 0.391778    192.168.10.76         192.168.0.16          FTP      Response: \027\003\001\000P\023\326\265\242\326V\0005\360\235g\003\323\331x\3370\376\335\036\234S-,\342\310y\224\262/!Pv\232\250|\350\3538ue\341\257\006-i\232o\v\260\265\177\372\322n\265$2\235\a,\320\245\024\005I\306\335?\366t\250\324u\221\326\200\354x\231
     23 0.393748    192.168.10.76         192.168.0.16          FTP      Response: \027\003\001\000@\244\377\364\215\375\212\346\241\306\257\224\326\307\321\346\242n\271!K?^\244\220i]\276\312\\340\316N(\017 G\220j\177\004M\334D\177\267\324\027\312\t\203\351\036\344c\240M\314\300\364Tt&\341\245
     24 0.394575    192.168.0.16          192.168.10.76         TCP      41198 > ftp [ACK] Seq=751 Ack=2422 Win=12544 Len=0 TSV=348686 TSER=106073307
     25 0.394665    192.168.0.16          192.168.10.76         FTP      Request: \027\003\001\000@\315>k\375\375*\357\035\262^~\224\311M\322\332\270uW\307\035\356P\b\256\317\313\000\b\215}\322\273?\300kN\f\244h\376g(O\334VeU\322\310\262\236O\323\027\374g\323M):\254\265\177
     26 0.444358    192.168.10.76         192.168.0.16          FTP      Response: \027\003\001\0000-\216#1H\234\266\355\244\036\311\f?\320\237x\226\246\005\330p\252(\035\223\2420\243S\316\372\b~'[\325r\302\361\322\254\034\002\243\215\361\300\377
     27 0.444560    192.168.0.16          192.168.10.76         FTP      Request: \027\003\001\000\240\3166\351\033\372a\271\025\177,\213\255\020\206\000Z\344\334\243\2631\035\236o]\365\222`\233V
     28 0.493829    192.168.10.76         192.168.0.16          FTP      Response: \027\003\001\0000\212y\017\v\245\237\252O\246\zh*0\364\037\233\241`%a\261\321I\f}9z\354-QMH\236K\222#\336I\326H\212~/\227\026X
     29 0.493986    192.168.0.16          192.168.10.76         FTP      Request: \027\003\001\000\340\024d,D\244;\250\236{\326\217h-H+\240\206eA\307\375u\027\311\216\232\363\202\243\246\377\343\371\263\003Z\033Fj\326\363X]\272\265\241=;\257|\226\350\351P\320\215Q-\200]\004\256q\2206?\350\370ca\257\246'{\223j\v\003\300\311\274\033\217\025\346k\216\353$\251V\327\355\240\262\261Q\236\377H\341\370\022\312\3333\340\212LI\000\212\354\370 H\373\342\035\2756\336&?\372k\232:\231\266\372qQ\206"N\345qzv2\344bR\342\375\242E\226$
     30 0.544508    192.168.10.76         192.168.0.16          FTP      Response: \027\003\001\000P\004u\357\003\344\262\232\252\3209vZL\024\222\016\260\270>5\016\256\271Z\274\251\376p\344FU\236-\263\211\210u\301\035\206C\361_-\237\225\351]\271FR\017\027\222\201\032\225@\317\351tN@\252\337]hH\266\243\312\360\340:k\3600
     31 0.577128    192.168.0.16          192.168.10.76         TCP      41198 > ftp [ACK] Seq=1214 Ack=2613 Win=12544 Len=0 TSV=348705 TSER=106073345

A partir du moment où Response: 234 AUTH TLS OK, tous les échanges FTP sont chiffrés.

Il faut s'en souvenir… Dans le cas d'un mode passif, la Commande : PORT 192,168,0,16,159,10 va être chiffrée. Si ça ne pose pas de problème au client FTP qui sait le déchiffrer, le conntrack de Netfilter risque d'avoir plus de mal s'il est sollicité.

3-3. FTP et Netfilter

Mettons en place un pare-feu sur l'hôte du serveur FTP. Ce n'est pas une nécessité absolue si un autre pare-feu se trouve en amont, mais ce sera l'occasion de mieux comprendre le suivi de connexion en FTP et de comprendre aussi pourquoi ce suivi ne peut être réalisé si les transferts sont chiffrés (FTPES).

3-3-1. SSH sinon rien

Au départ, sur l'hôte du serveur (une seule interface eth0), nous posons ceci :

 
Sélectionnez
# iptables-save
# Generated by iptables-save v1.4.8 on Mon Jan 23 11:26:11 2012
*filter
:INPUT DROP [1:76]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [1:76]
-A INPUT -i eth0 -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -i lo -j ACCEPT
COMMIT

Par défaut, rien ne peut entrer par aucune interface. Il est quand même judicieux de laisser passer SSH (port 22) et de laisser tout entrer sur lo (du moins pour ce qui nous intéresse ici).

3-3-2. FTP et son suivi de connexion

Dans de telles conditions, FTP ne peut bien entendu pas fonctionner. Nous allons ajouter ces deux règles :

 
Sélectionnez
iptables -A INPUT -p tcp --dport 21 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT

ceci afin de laisser entrer les connexions des clients FTP sur le port 21

 
Sélectionnez
iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

ceci afin d'avoir des chances de laisser passer les connexions DATA relatives aux commandes FTP lancées par le client. Mais le suivi de connexions sur FTP est, nous l'avons vu, assez particulier pour nécessiter le chargement d'un module spécialisé :

 
Sélectionnez
modprobe nf-conntrack-ftp

Autrefois, ce module s'appelait ip-conntrack-ftp. Ce nom est aujourd'hui (30/01/2012) devenu un alias et donc toujours utilisable, mais autant adopter l'appellation actuelle.

Il n'y a pas ici de NAT puisque nous sommes toujours dans le cas de deux réseaux locaux routés entre eux. Au final, nous avons :

 
Sélectionnez
# iptables-save
# Generated by iptables-save v1.4.8 on Mon Jan 23 11:42:34 2012
*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [1:76]
-A INPUT -i eth0 -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m tcp --dport 21 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
COMMIT

Et, en ce qui concerne les modules de suivi :

 
Sélectionnez
# lsmod | grep conntrack
nf_conntrack_ipv4       9833  2 
nf_defrag_ipv4          1139  1 nf_conntrack_ipv4
xt_conntrack            2407  1 
x_tables               12845  4 xt_state,xt_tcpudp,xt_conntrack,ip_tables
nf_conntrack_ftp        5505  0 
nf_conntrack           46311  4 nf_conntrack_ipv4,xt_state,xt_conntrack,nf_conntrack_ftp

3-3-3. Essais FTP

Essayons maintenant une connexion FTP active :

 
Sélectionnez
Statut :        Connexion à 192.168.10.76:21...
Statut :        Connexion établie, attente du message d'accueil...
Réponse :       220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
Réponse :       220-You are user number 1 of 3 allowed.
Réponse :       220-Local time is now 11:48. Server port: 21.
Réponse :       220-This is a private system - No anonymous login
Réponse :       220-IPv6 connections are also welcome on this server.
Réponse :       220 You will be disconnected after 15 minutes of inactivity.
Commande :      USER test
Réponse :       331 User test OK. Password required
Commande :      PASS ********
Réponse :       230-Your bandwidth usage is restricted
Réponse :       230-User test has group access to:  ftpgroup  
Réponse :       230 OK. Current directory is /
Commande :      SYST
Réponse :       215 UNIX Type: L8
Commande :      FEAT
Réponse :       211-Extensions supported:
Réponse :        EPRT
Réponse :        IDLE
Réponse :        MDTM
Réponse :        SIZE
Réponse :        REST STREAM
Réponse :        MLST type*;size*;sizd*;modify*;UNIX.mode*;UNIX.uid*;UNIX.gid*;unique*;
Réponse :        MLSD
Réponse :        AUTH TLS
Réponse :        PBSZ
Réponse :        PROT
Réponse :        UTF8
Réponse :        TVFS
Réponse :        ESTA
Réponse :        PASV
Réponse :        EPSV
Réponse :        SPSV
Réponse :        ESTP
Réponse :       211 End.
Commande :      OPTS UTF8 ON
Réponse :       200 OK, UTF-8 enabled
Statut :        Connecté
Statut :        Récupération du contenu du dossier...
Commande :      PWD
Réponse :       257 "/" is your current location
Commande :      TYPE I
Réponse :       200 TYPE is now 8-bit binary
Commande :      PORT 192,168,0,16,171,235
Réponse :       200 PORT command successful
Commande :      MLSD
Réponse :       150 Connecting to port 44011
Réponse :       226-Options: -a -l 
Réponse :       226 8 matches total
Statut :        Succès de la lecture du contenu du dossier

Ça marche. Essayons maintenant en mode passif :

 
Sélectionnez
Statut :        Connexion à 192.168.10.76:21...
Statut :        Connexion établie, attente du message d'accueil...
Réponse :       220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
Réponse :       220-You are user number 1 of 3 allowed.
Réponse :       220-Local time is now 11:51. Server port: 21.
Réponse :       220-This is a private system - No anonymous login
Réponse :       220-IPv6 connections are also welcome on this server.
Réponse :       220 You will be disconnected after 15 minutes of inactivity.
Commande :      USER test
Réponse :       331 User test OK. Password required
Commande :      PASS ********
Réponse :       230-Your bandwidth usage is restricted
Réponse :       230-User test has group access to:  ftpgroup  
Réponse :       230 OK. Current directory is /
Commande :      OPTS UTF8 ON
Réponse :       200 OK, UTF-8 enabled
Statut :        Connecté
Statut :        Récupération du contenu du dossier...
Commande :      PWD
Réponse :       257 "/" is your current location
Statut :        Succès de la lecture du contenu du dossier

Ça fonctionne aussi. Pas vraiment étonnant, le conntrack de Netfilter fait son travail, grâce à la ligne :

 
Sélectionnez
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

3-3-4. Essais FTPES

Essayons en FTPES mode actif :

 
Sélectionnez
Statut :        Connexion à 192.168.10.76:21...
Statut :        Connexion établie, attente du message d'accueil...
Réponse :       220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
Réponse :       220-You are user number 1 of 3 allowed.
Réponse :       220-Local time is now 11:58. Server port: 21.
Réponse :       220-This is a private system - No anonymous login
Réponse :       220-IPv6 connections are also welcome on this server.
Réponse :       220 You will be disconnected after 15 minutes of inactivity.
Commande :      AUTH TLS
Réponse :       234 AUTH TLS OK.
Statut :        Initialisation TLS...
Statut :        Vérification du certificat...
Commande :      USER test
Statut :        Connexion TLS/SSL établie.
Réponse :       331 User test OK. Password required
Commande :      PASS ********
Réponse :       230-Your bandwidth usage is restricted
Réponse :       230-User test has group access to:  ftpgroup  
Réponse :       230 OK. Current directory is /
Commande :      SYST
Réponse :       215 UNIX Type: L8
Commande :      FEAT
Réponse :       211-Extensions supported:
Réponse :        EPRT
Réponse :        IDLE
Réponse :        MDTM
Réponse :        SIZE
Réponse :        REST STREAM
Réponse :        MLST type*;size*;sizd*;modify*;UNIX.mode*;UNIX.uid*;UNIX.gid*;unique*;
Réponse :        MLSD
Réponse :        AUTH TLS
Réponse :        PBSZ
Réponse :        PROT
Réponse :        UTF8
Réponse :        TVFS
Réponse :        ESTA
Réponse :        PASV
Réponse :        EPSV
Réponse :        SPSV
Réponse :        ESTP
Réponse :       211 End.
Commande :      OPTS UTF8 ON
Réponse :       200 OK, UTF-8 enabled
Commande :      PBSZ 0
Réponse :       200 PBSZ=0
Commande :      PROT P
Réponse :       200 Data protection level set to "private"
Statut :        Connecté
Statut :        Récupération du contenu du dossier...
Commande :      PWD
Réponse :       257 "/" is your current location
Commande :      TYPE I
Réponse :       200 TYPE is now 8-bit binary
Commande :      PORT 192,168,0,16,136,97
Réponse :       200 PORT command successful
Commande :      MLSD
Réponse :       150 Connecting to port 34913
Réponse :       226-Options: -a -l 
Réponse :       226 7 matches total
Statut :        Succès de la lecture du contenu du dossier

Pas de soucis. Mais en mode passif :

 
Sélectionnez
Statut :        Connexion à 192.168.10.76:21...
Statut :        Connexion établie, attente du message d'accueil...
Réponse :       220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
Réponse :       220-You are user number 1 of 3 allowed.
Réponse :       220-Local time is now 12:00. Server port: 21.
Réponse :       220-This is a private system - No anonymous login
Réponse :       220-IPv6 connections are also welcome on this server.
Réponse :       220 You will be disconnected after 15 minutes of inactivity.
Commande :      AUTH TLS
Réponse :       234 AUTH TLS OK.
Statut :        Initialisation TLS...
Statut :        Vérification du certificat...
Commande :      USER test
Statut :        Connexion TLS/SSL établie.
Réponse :       331 User test OK. Password required
Commande :      PASS ********
Réponse :       230-Your bandwidth usage is restricted
Réponse :       230-User test has group access to:  ftpgroup  
Réponse :       230 OK. Current directory is /
Commande :      SYST
Réponse :       215 UNIX Type: L8
Commande :      FEAT
Réponse :       211-Extensions supported:
Réponse :        EPRT
Réponse :        IDLE
Réponse :        MDTM
Réponse :        SIZE
Réponse :        REST STREAM
Réponse :        MLST type*;size*;sizd*;modify*;UNIX.mode*;UNIX.uid*;UNIX.gid*;unique*;
Réponse :        MLSD
Réponse :        AUTH TLS
Réponse :        PBSZ
Réponse :        PROT
Réponse :        UTF8
Réponse :        TVFS
Réponse :        ESTA
Réponse :        PASV
Réponse :        EPSV
Réponse :        SPSV
Réponse :        ESTP
Réponse :       211 End.
Commande :      OPTS UTF8 ON
Réponse :       200 OK, UTF-8 enabled
Commande :      PBSZ 0
Réponse :       200 PBSZ=0
Commande :      PROT P
Réponse :       200 Data protection level set to "private"
Statut :        Connecté
Statut :        Récupération du contenu du dossier...
Commande :      PWD
Réponse :       257 "/" is your current location
Commande :      TYPE I
Réponse :       200 TYPE is now 8-bit binary
Commande :      PASV
Réponse :       227 Entering Passive Mode (192,168,10,76,252,141)
Commande :      MLSD
Erreur :        Délai d'attente expiré
Erreur :        Échec lors de la récupération du contenu du dossier

Ici, ça coince au moment d'utiliser un canal de DATA. Conntrack n'a pas pu voir passer les informations relatives au port passif et n'a pas pu gérer le RELATED à cause du chiffrement.

A ma connaissance il n'y a pas de solution du côté de Netfilter. Il existe cependant une solution de contournement que nous allons voir maintenant.

3-3-5. FTPES en mode passif

Si l'on souhaite que le serveur fonctionne en FTPES passif, il faut abandonner le suivi de connexion, indiquer au serveur une plage de ports à ouvrir en mode passif et de laisser entrer les paquets NEW par ces ports. Ceci ne présente pas un très gros danger dans la mesure où :

  • nous n'aurons pas beaucoup de connexions DATA simultanées, il n'est donc pas nécessaire d'ouvrir une grande plage ;
  • ces ports seront normalement fermés en dehors d'une connexion DATA qui en utiliserait.

3-3-5-1. Spécifier les ports

Nous avons une configuration -c3 -C2 ce qui laisse entendre deux connexions DATA par client, avec deux clients simultanés. Nous ne devrions pas avoir besoin de plus de 4 ports, nous allons en prévoir 10 avec le paramètre -p 65525:65535 qui indique assez clairement que le serveur choisira un port disponible sur la plage [65525,65535], ce qui nous donne une ligne de commande :

 
Sélectionnez
pure-ftpd -j -lpuredb:/etc/pure-ftpd/pureftpd.pdb -E -T:30 -c3 -C2 -Y1 -p 65525:65535

3-3-5-2. Ouvrir les ports concernés

Il faut le dire à Netfilter :

 
Sélectionnez
iptables -A INPUT -p tcp --dport 65525:65535 -m state --state NEW,ESTABLISHED -j ACCEPT

3-3-5-3. Vérification

Connexion en FTPES mode passif :

 
Sélectionnez
Statut :        Connexion à 192.168.10.76:21...
Statut :        Connexion établie, attente du message d'accueil...
Réponse :       220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
Réponse :       220-You are user number 1 of 3 allowed.
Réponse :       220-Local time is now 15:13. Server port: 21.
Réponse :       220-This is a private system - No anonymous login
Réponse :       220-IPv6 connections are also welcome on this server.
Réponse :       220 You will be disconnected after 15 minutes of inactivity.
Commande :      USER test
Réponse :       331 User test OK. Password required
Commande :      PASS ********
Réponse :       230-Your bandwidth usage is restricted
Réponse :       230-User test has group access to:  ftpgroup  
Réponse :       230 OK. Current directory is /
Commande :      OPTS UTF8 ON
Réponse :       200 OK, UTF-8 enabled
Statut :        Connecté
Statut :        Récupération du contenu du dossier...
Commande :      PWD
Réponse :       257 "/" is your current location
Commande :      TYPE I
Réponse :       200 TYPE is now 8-bit binary
Commande :      PASV
Réponse :       227 Entering Passive Mode (192,168,10,76,102,168)
Commande :      MLSD
Réponse :       150 Accepted data connection
Réponse :       226-Options: -a -l 
Réponse :       226 7 matches total
Statut :        Succès de la lecture du contenu du dossier
Statut :        Déconnecté du serveur
Statut :        Connexion à 192.168.10.76:21...
Statut :        Connexion établie, attente du message d'accueil...
Réponse :       220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
Réponse :       220-You are user number 1 of 3 allowed.
Réponse :       220-Local time is now 15:22. Server port: 21.
Réponse :       220-This is a private system - No anonymous login
Réponse :       220-IPv6 connections are also welcome on this server.
Réponse :       220 You will be disconnected after 15 minutes of inactivity.
Commande :      AUTH TLS
Réponse :       234 AUTH TLS OK.
Statut :        Initialisation TLS...
Statut :        Vérification du certificat...
Commande :      USER test
Statut :        Connexion TLS/SSL établie.
Réponse :       331 User test OK. Password required
Commande :      PASS ********
Réponse :       230-Your bandwidth usage is restricted
Réponse :       230-User test has group access to:  ftpgroup  
Réponse :       230 OK. Current directory is /
Commande :      SYST
Réponse :       215 UNIX Type: L8
Commande :      FEAT
Réponse :       211-Extensions supported:
Réponse :        EPRT
Réponse :        IDLE
Réponse :        MDTM
Réponse :        SIZE
Réponse :        REST STREAM
Réponse :        MLST type*;size*;sizd*;modify*;UNIX.mode*;UNIX.uid*;UNIX.gid*;unique*;
Réponse :        MLSD
Réponse :        AUTH TLS
Réponse :        PBSZ
Réponse :        PROT
Réponse :        UTF8
Réponse :        TVFS
Réponse :        ESTA
Réponse :        PASV
Réponse :        EPSV
Réponse :        SPSV
Réponse :        ESTP
Réponse :       211 End.
Commande :      OPTS UTF8 ON
Réponse :       200 OK, UTF-8 enabled
Commande :      PBSZ 0
Réponse :       200 PBSZ=0
Commande :      PROT P
Réponse :       200 Data protection level set to "private"
Statut :        Connecté
Statut :        Récupération du contenu du dossier...
Commande :      PWD
Réponse :       257 "/" is your current location
Commande :      TYPE I
Réponse :       200 TYPE is now 8-bit binary
Commande :      PASV
Réponse :       227 Entering Passive Mode (192,168,10,76,196,229)
Commande :      MLSD
Erreur :        Délai d'attente expiré
Erreur :        Échec lors de la récupération du contenu du dossier
Statut :        Connexion à 192.168.10.76:21...
Statut :        Connexion établie, attente du message d'accueil...
Réponse :       220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
Réponse :       220-You are user number 1 of 3 allowed.
Réponse :       220-Local time is now 15:54. Server port: 21.
Réponse :       220-This is a private system - No anonymous login
Réponse :       220-IPv6 connections are also welcome on this server.
Réponse :       220 You will be disconnected after 15 minutes of inactivity.
Commande :      AUTH TLS
Réponse :       234 AUTH TLS OK.
Statut :        Initialisation TLS...
Statut :        Vérification du certificat...
Commande :      USER test
Statut :        Connexion TLS/SSL établie.
Réponse :       331 User test OK. Password required
Commande :      PASS ********
Réponse :       230-Your bandwidth usage is restricted
Réponse :       230-User test has group access to:  ftpgroup  
Réponse :       230 OK. Current directory is /
Commande :      OPTS UTF8 ON
Réponse :       200 OK, UTF-8 enabled
Commande :      PBSZ 0
Réponse :       200 PBSZ=0
Commande :      PROT P
Réponse :       200 Data protection level set to "private"
Statut :        Connecté
Statut :        Récupération du contenu du dossier...
Commande :      PWD
Réponse :       257 "/" is your current location
Commande :      TYPE I
Réponse :       200 TYPE is now 8-bit binary
Commande :      PASV
Réponse :       227 Entering Passive Mode (192,168,10,76,255,248) Donc le port 65528
Commande :      MLSD
Réponse :       150 Accepted data connection
Réponse :       226-Options: -a -l 
Réponse :       226 7 matches total
Statut :        Succès de la lecture du contenu du dossier

Ça fonctionne sans surprise, mais sans le conntrack.

3-4. Mise en « production »

Puisque nous avons résolu à peu près tous les problèmes, nous pouvons envisager de fixer tout ceci pour que le fonctionnement perdure après redémarrage de la machine. Nous sommes toujours ici dans la configuration simplifiée :

Image non disponible

3-4-1. Netfilter

Nous devons nous assurer que les règles Iptables seront restaurées. Une solution pas vilaine consiste à sauvegarder les règles en place :

 
Sélectionnez
mkdir /etc/iptables
iptables-save > /etc/iptables/rules

Et de les recharger lorsque l'interface eth0 est activée. Nous devons aussi charger le module nf-conntrack-ftp. Tout ceci peut être fait avec un script placé dans /etc/network/if-up.d/ (Sur Debian et dérivées) :

 
Sélectionnez
# cat /etc/network/if-up.d/netfilter
#! /bin/sh
if [ "$IFACE" = eth0 ]; then
    /sbin/modprobe nf-conntrack-ftp
    /sbin/iptables-restore < /etc/iptables/rules
fi

Ne pas oublier de rendre ce script exécutable et éventuellement l'améliorer pour par exemple s'assurer que tout s'est bien passé.

3-4-2. Inetd

Il nous faut ajouter dans le fichier /etc/inetd.conf la ligne suivante :

 
Sélectionnez
ftp  stream tcp nowait root /usr/sbin/pure-ftpd -j -lpuredb:/etc/pure-ftpd/pureftpd.pdb -E -T:30 -c3 -C2 -Y1 -p 65525:65535

Puis demander à inetd de recharger sa configuration.

Tout devrait fonctionner, du moins en IPv4.

3-4-2-1. Et IPv6 ?

Pure-ftpd sait le faire, c'est clairement indiqué dans sa documentation et nous aurions pu le tester lorsqu'il était démarré « à la main » dans un shell.

Ici cependant, ça ne fonctionnera pas, non pas à cause du Pure-ftpd mais du service inetd qui par défaut ne fonctionne qu'en IPv4. Cependant, la version fournie avec squeeze supporte IPv6 si on le lui demande poliment.

La méthode polie étant d'ajouter cette ligne dans inetd.conf :

 
Sélectionnez
ftp  stream tcp6 nowait root /usr/sbin/pure-ftpd -j -lpuredb:/etc/pure-ftpd/pureftpd.pdb -E -T:30 -c3 -C2 -Y1 -p 65525:65535

3-4-3. Et depuis le Net ?

Jusqu'ici, nous avons travaillé sur des nœuds situés sur des réseaux privés, routés entre eux. Une sorte de gros réseau local donc. Mais si les nœuds doivent se joindre par l'internet, il y aura de nouveaux problèmes à régler.

Probablement que dans tous les cas, les clients seront placés derrière un routeur NAT muni d'un pare-feu…

3-4-3-1. FTP sur la passerelle

Si le serveur est placé sur la passerelle elle-même, il n'y aura pas de problèmes supplémentaires du côté du serveur, il faudra juste adapter les règles IPtables de la passerelle comme nous l'avons vu plus haut.

3-4-3-2. FTP dans le LAN

Si le serveur est placé derrière le routeur NAT, deux cas de figure seront alors possibles :

3-4-3-2-1. IPv6

La passerelle se comporte en routeur NAT en IPv4 et en simple pont en IPv6. Dans ce cas, l'hôte du serveur FTP peut disposer d'une adresse IPv6 publique et il n'y a toujours pas de problèmes.

Notons que nous avons étudié le filtrage en IPv4 seulement. Il serait décent d'en faire autant en IPv6 dans un tel cas.

Malheureusement, IPv6 est loin d'être déployé chez tous les fournisseurs d'accès (à l'heure où ces lignes sont écrites), ce qui rend la solution moins intéressante.

3-4-3-2-2. IPv4

Il va falloir faire de la redirection de port (DNAT) sur la passerelle. Pas de problèmes pour le canal de contrôle (port 21), mais c'est une autre affaire pour les canaux de DATA. La page suivante va détailler ce cas de figure.

3-5. Derrière un routeur NAT

3-5-1. Architecture du montage

Notre architecture devient un peu plus compliquée puisque :

  • le client FTP est derrière un routeur NAT ;
  • le serveur lui aussi se trouve derrière un routeur NAT.

Ce qui nous donne :

Image non disponible

3-5-2. Côté client

Sur la passerelle du client (GNU/Linux avec iptables), nous avons chargé les modules nf-conntrack-ftp et nf-nat-ftp, nécessaires pour que le client puisse utiliser le mode actif.

Notons que dans un cas de figure comme celui-ci, si nous comptons sur le suivi de connexion pour résoudre nos problèmes de connexions RELATED, celui-ci sera mis en œuvre :

  • pour le mode passif côté serveur ;
  • pour le mode actif côté client.

En nous souvenant de ce qui a déjà été vu à propos du suivi de connexion en FTPES, nous pouvons prévoir une impasse…

3-5-3. Côté serveur

Dans cette configuration, l'adresse IP(v4) du serveur sera une adresse privée. Or de l'extérieur, la seule adresse accessible sera l'IP publique attribuée par le fournisseur d'accès.

La première idée qui vient à l'esprit est donc de rediriger en DNAT le port 21 du routeur sur l'adresse IP du serveur.

 
Sélectionnez
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 21 -j DNAT --to-destination 192.168.10.76
Image non disponible

Pouvons-nous prévoir le comportement ? Une requête arrivant sur xxx.yyy.zzz.ttt port 21 va être redirigée sur notre serveur. Il répondra à la requête. Côté canal de contrôle, il ne devrait pas y avoir de problèmes.

3-5-4. Mode actif

Dans ce mode, où le client FTP devient serveur pour les DATA, le serveur ne devrait pas poser de problèmes, s'il reçoit l'adresse IP publique du routeur NAT du client. S'il y a un problème, il faudra donc chercher à le résoudre du côté du client, mais avec les modules de suivi de connexion du protocole FTP de Netfilter, nous avons nos chances.

3-5-4-1. Essai en FTP

Si nous utilisons le mode actif, le client enverra son adresse et un port pour que pure-ftpd puisse ouvrir une connexion TCP et ça devrait fonctionner. Vérifions dans le compte-rendu de FileZilla :

 
Sélectionnez
Statut :        Connexion à 82.243.80.13:21...
...
Commande :      OPTS UTF8 ON
Réponse :       200 OK, UTF-8 enabled
Statut :        Connecté
Statut :        Récupération du contenu du dossier...
Commande :      PWD
Réponse :       257 "/" is your current location
Commande :      TYPE I
Réponse :       200 TYPE is now 8-bit binary
Commande :      PORT 192,168,0,16,204,129
Réponse :       200 PORT command successful
Commande :      MLSD
Réponse :       150 Connecting to port 52353
Réponse :       226-Options: -a -l 
Réponse :       226 7 matches total
Statut :        Succès de la lecture du contenu du dossier

Le client, en mode actif envoie son adresse IP privée et pourtant, tout fonctionne. Miracle ? Comment la passerelle côté serveur peut-elle interpréter une adresse IP privée qu'il ne sait pas router ?

Sniffons sur la passerelle du serveur (Tshark, la version en ligne de commande de Wireshark est notre ami)…

 
Sélectionnez
...
     19 0.386311    82.229.41.132         82.243.80.13          FTP      Request: TYPE I
     20 0.386608    82.243.80.13          82.229.41.132         FTP      Response: 200 TYPE is now 8-bit binary
     21 0.435339    82.229.41.132         82.243.80.13          FTP      Request: PORT 82,229,41,132,143,22
     22 0.435765    82.243.80.13          82.229.41.132         FTP      Response: 200 PORT command successful
...
     25 0.522738    82.243.80.13          82.229.41.132         FTP      Response: 150 Connecting to port 36630

Ce que l'on voit passer ici n'est plus l'adresse IP privée du client, mais l'adresse publique de sa passerelle.

Il est fort ce netfilter…

Il est fort, certes, mais i ne fait pas de miracles. Les modules nf-conntrack-ftp et surtout nf-nat-ftp dans le cas présent peuvent analyser et modifier le contenu des datagrammes FTP parce qu'ils ne sont pas chiffrés.

3-5-4-2. Essai en FTPES

Est-ce bien la peine ? Netfilter ne pourra pas faire son travail sur du FTP chiffré. Essayez si vous ne me croyez pas. Vous obtiendrez dans le FileZilla un message du type :

 
Sélectionnez
Commande :      PORT 192,168,0,16,186,176
Réponse :       500 I won't open a connection to 192.168.0.16 (only to 82.229.41.132)

82.229.41.132, c'est ici l'adresse publique du routeur du client.

Même message que si les modules nf-conntrack-ftp et nf-nat-ftp n'étaient pas chargés sur le routeur NAT du client, soit dit en passant.

Existe-t-il un contournement ? Rien de propre. Sauf si j'ai raté quelque chose, nous devrons nous passer du mode actif en FTPES dans cette topologie.

3-5-5. Le mode passif

Nous avons déjà vu ce qu'il se passe côté serveur. Sur le routeur NAT du serveur, il faudra donc aussi rediriger les ports que nous avons spécifié dans la configuration de pure-ftpd :

 
Sélectionnez
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 65525:65535 -j DNAT --to-destination 192.168.10.76

Cette solution sera acceptable dans la mesure où il n'y a qu'un seul serveur FTP derrière le NAT.

3-5-5-1. Essai en FTP

Ici, nous risquons de rencontrer un problème du fait que dans ce mode, le serveur va présenter son adresse IP qui est ici privée donc, non routée. FileZilla sait contourner cette erreur, mais nous allons lui dire de ne pas le faire :

Image non disponible

Ce qui nous permettra de mettre en évidence cette erreur :

 
Sélectionnez
Commande :      PASV
Réponse :       227 Entering Passive Mode (192,168,10,76,255,251)
Statut :        Le serveur a envoyé une réponse passive avec une adresse non routable. Échec du mode passif.
Erreur :        Échec lors de la récupération du contenu du dossier

Comment corriger cette erreur ? Il y a deux façons de faire, dont une que nous avons déjà rencontrée côté client pour le mode actif :

3-5-5-1-1. Netfilter, au secours !

En chargeant les modules nf-conntrack-ftp et nf-nat-ftp, nous avons nos chances :

 
Sélectionnez
Commande :      PASV
Réponse :       227 Entering Passive Mode (82,243,80,13,255,245)
Commande :      MLSD
Réponse :       150 Accepted data connection
Réponse :       226-Options: -a -l 
Réponse :       226 6 matches total
Statut :        Succès de la lecture du contenu du dossier

Et ça fonctionne. Le conntrack corrige à la volée. C'est bien, surtout si le routeur NAT du serveur récupère une adresse IP publique qui change dans le temps, mais il est clair qu'en mode FTPES, ceci ne fonctionnera plus.

3-5-5-1-2. Dans pure-ftpd

Il est parfaitement possible de demander à pure-ftpd d'exposer l'adresse IP publique de sa passerelle, lorsqu'il travaille en mode passif. Cette solution ne sera acceptable que si cette passerelle dispose d'une adresse IP publique fixe, bien entendu.

Nous modifions la ligne de commande comme suit (elle commence à devenir vraiment longue) dans /etc/inetd.conf :

 
Sélectionnez
ftp  stream tcp4 nowait root /usr/sbin/pure-ftpd -j -lpuredb:/etc/pure-ftpd/pureftpd.pdb -E -T:30 -c3 -C2 -Y1 -p 65525:65535 -P 82.243.80.13

Cette opération va perturber le fonctionnement du suivi de connexions FTP de Netfilter, aussi bien sur le serveur lui-même que sur son routeur NAT. Sur le routeur, ce n'est pas important puisque les ports réservés au mode passif sont déjà explicitement redirigés.

Sur le serveur lui-même, en revanche nous avons actuellement :

 
Sélectionnez
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -i eth1 -p tcp -m tcp --dport 22 -j ACCEPT 
-A INPUT -i lo -j ACCEPT 
-A INPUT -p tcp -m tcp --dport 21 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT 
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT 

Il nous faut maintenant ouvrir explicitement les ports 65525 à 65535 à cause du suivi de connexion rendu inopérant :

 
Sélectionnez
iptables -A INPUT -i eth1 -p tcp --dport 65525:65535 -j ACCEPT

Nous rechargeons la configuration de inetd et nous essayons :

 
Sélectionnez
Commande :      PASV
Réponse :       227 Entering Passive Mode (82,243,80,13,255,248)
Commande :      MLSD
Réponse :       150 Accepted data connection
Réponse :       226-Options: -a -l 
Réponse :       226 6 matches total
Statut :        Succès de la lecture du contenu du dossier

Tout va bien.

3-5-5-2. Essai en FTPES

Avec les modifications apportées aux règles iptables du côté du serveur, le suivi de connexion n'est plus nécessaire. Du côté du client, en mode passif, il n'y a pas besoin de suivi de connexion spécifique à FTP. Nous pouvons nous attendre à ce que tout fonctionne correctement :

 
Sélectionnez
Commande :      AUTH TLS
Réponse :       234 AUTH TLS OK.
...
Commande :      PASV
Réponse :       227 Entering Passive Mode (82,243,80,13,255,245)
Commande :      MLSD
Réponse :       150 Accepted data connection
Réponse :       226-Options: -a -l 
Réponse :       226 6 matches total
Statut :        Succès de la lecture du contenu du dossier

Pas de mauvaise surprise.

3-5-6. Bilan

Si nous donnons la priorité à l'usage du FTPES qui offre le chiffrement de la connexion, dans une telle topologie où le serveur comme les clients se trouvent derrière des routeurs NAT, la seule solution est de faire du FTP passif.

Bien entendu, en IPv6 tout devient plus simple puisqu'il n'y a plus de NAT nulle part. Un jour peut-être ?

En attendant résumons les configurations des divers protagonistes :

3-5-6-1. Serveur FTP

  • Les lignes de commande dans inetd (IPv4 et IPv6) :
     
    Sélectionnez
    ftp  stream tcp4 nowait root /usr/sbin/pure-ftpd -j -lpuredb:/etc/pure-ftpd/pureftpd.pdb -E -T:30 -c3 -C2 -Y1 -p 65525:65535 -P 82.243.80.13
    ftp  stream tcp6 nowait root /usr/sbin/pure-ftpd -j -lpuredb:/etc/pure-ftpd/pureftpd.pdb -E -T:30 -c3 -C2 -Y1 -p 65525:65535
  • les règles Iptables :
     
    Sélectionnez
    # iptables-save
    
    # Generated by iptables-save v1.4.8 on Sun Jan 29 11:46:57 2012
    *nat
    :PREROUTING ACCEPT [1255:400710]
    :POSTROUTING ACCEPT [715:52251]
    :OUTPUT ACCEPT [715:52251]
    COMMIT
    # Completed on Sun Jan 29 11:46:57 2012
    # Generated by iptables-save v1.4.8 on Sun Jan 29 11:46:57 2012
    *filter
    :INPUT DROP [400:95800]
    :FORWARD ACCEPT [0:0]
    :OUTPUT ACCEPT [884:74191]
    -A INPUT -i eth0 -p tcp -m tcp --dport 22 -j ACCEPT 
    -A INPUT -i lo -j ACCEPT 
    -A INPUT -p tcp -m tcp --dport 21 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT 
    -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT 
    -A INPUT -i eth0 -p tcp -m tcp --dport 65525:65535 -j ACCEPT 
    COMMIT
    Le suivi de connexion est resté en place pour permettre la connexion en mode FTP actif (sans chiffrement) ;
  • les modules chargés pour le suivi de connexion FTP :
 
Sélectionnez
# lsmod | grep ftp

nf_conntrack_ftp        5505  0 
nf_conntrack           46311  6 iptable_nat,nf_nat,nf_conntrack_ipv4,xt_state,xt_conntrack,nf_conntrack_ftp

3-5-6-2. Routeur NAT du FTP

  • les règles Iptables relatives au fonctionnement du FTP :
     
    Sélectionnez
    # iptables-save
    
    # Generated by iptables-save v1.4.8 on Sun Jan 29 11:56:26 2012
    *nat
    :PREROUTING ACCEPT [3838277:231166320]
    :POSTROUTING ACCEPT [916200:55004844]
    :OUTPUT ACCEPT [47781:3326346]
    ...
    -A PREROUTING -i eth0 -p tcp -m tcp --dport 21 -j DNAT --to-destination 192.168.10.76 
    -A PREROUTING -i eth0 -p tcp -m tcp --dport 65525:65535 -j DNAT --to-destination 192.168.10.76 
    -A POSTROUTING -o eth0 -j MASQUERADE 
    COMMIT
    ...
  • les modules de suivi de connexion ne sont pas nécessaires pour ce qui nous intéresse ici, compte tenu des règles Iptables mises en place. Il peut cependant être utile de les charger si par ailleurs des clients du même réseau souhaitent faire du FTP actif sur l'internet :
 
Sélectionnez
# lsmod | grep ftp

nf_nat_ftp              1999  0 
nf_conntrack_ftp        5505  1 nf_nat_ftp
nf_nat                 13276  3 nf_nat_ftp,ipt_MASQUERADE,iptable_nat
nf_conntrack           46327  7 nf_nat_ftp,nf_conntrack_ftp,ipt_MASQUERADE,iptable_nat,nf_nat,nf_conntrack_ipv4,xt_state

3-5-6-3. Routeur NAT des clients

Il n'y a rien de spécial, à part optionnellement charger les modules de suivi de connexion nf-conntrack-ftp et nf-nat-ftp pour autoriser le FTP actif, aussi bien sur notre serveur que sur d'autres, situés quelque part sur l'internet.

Nous supposons que par ailleurs, Iptables configure correctement la passerelle pour autoriser les connexions RELATED et ESTABLISHED venant de l'internet dans le routage NAT.

3-5-6-4. Rappel important

Souvenons-nous que les modules de suivi de connexion nf-conntrack-ftp et nf-nat-ftp sont dans l'incapacité totale de faire leur travail en présence d'un flux chiffré (FTPES). La conséquence principale est que même si le serveur FTP est installé directement sur une passerelle et peut donc être atteint sans DNAT, le client derrière un routeur NAT n'aura pas de possibilité d'y accéder en FTPES actif.

3-5-6-5. Une autre piste

Une solution intéressante, mais qui sort du cadre de cette étude sur FTP consiste à établir un tunnel chiffré, par exemple entre la passerelle du réseau contenant le serveur FTP et le poste du client :

Image non disponible

Dans ce cas, le tunnel étant lui-même chiffré, rien n'interdirait d'abandonner FTPES au profit de FTP, ce qui simplifierait le problème. Dans une telle topologie, le client pourrait même à travers son tunnel accéder à tous les nœuds de son réseau privé. Une solution comme openvpn supporte très bien de passer un routeur NAT, encore faudra-t-il que les pare-feux laissent passer le tunnel. Mais tout ceci est une autre histoire.

4. Remerciements Developpez

Vous pouvez retrouver l'article original ici : L'Internet Rapide et Permanent. Christian Caleca a aimablement autorisé l'équipe « Réseaux » de Developpez.com à reprendre son article. Retrouvez tous les articles de Christian Caleca sur cette page.

Nos remerciements à Claude Leloup pour sa relecture orthographique.

N'hésitez pas à commenter cet article ! Commentez Donner une note à l'article (5)

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2012 Christian Caleca. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.