Licence d'Informatique - Projet tutoré

MUXFTP : un serveur FTP virtuel

Résumé :

Le protocole FTP est couramment utilisé pour effectuer des transferts de fichiers dans des réseaux IP (Internet ou LAN). Son mode de fonctionnement est tel que chaque transfert de fichier utilise une connexion TCP différente ; ce qui permet d'effectuer un transfert d'un serveur à un autre sans passer par le client. Le serveur FTP virtuel est une variante sur ce thème ; le but est d'implanter un serveur FTP qui servira de proxy pour un ou plusieurs serveurs FTP normaux. L'originalité du proxy sera de permettre des "montages" ou "liens symboliques" à travers l'arborescence virtuelle ; par exemple, sur le serveur virtuel, le répertoire /pub pourrait être redirigé vers le serveur helios dans son répertoire /pub ; le répertoire /debian pourrait être redirigé vers le répertoire du même nom sur le serveur naibed ; et le répertoire /incoming sur le serveur porky dans le répertoire /new. Le second intérêt du serveur virtuel est de permettre des connexions directes entre le client et le véritable serveur, sans que les données n'aient à transiter par le proxy. Bien sûr, outre l'écriture du serveur (impliquant la compréhension du protocole FTP et l'utilisation de sockets en C ou dans un autre langage adapté), le projet comporte la rédaction d'une documentation permettant de faire fonctionner le serveur et éventuellement d'y apporter des modifications, ainsi que la réalisation d'un package Debian afin de permettre une installation facile.

Mots clefs :

FTP - SERVEUR - DEBIAN - DPKG - LINUX - RETR - PASV - PORT - SOCKET - TCP - API - DEMON - PROXY - PYTHON

Connaissances requises :

Intérêt

La manipulation de sockets constitue à la fois une difficulté et un intérêt importants. Les concepts réseau ne sont pas très difficiles à appréhender, et pour quelqu'un qui dispose déjà de quelques notions, ce projet est l'occasion de les conforter concrètement. Le protocole FTP est original ; à la fois simple (format des commandes, données transférées sans en-têtes particulières...) et compliqué (utilisation de deux connexions séparées pour les commandes et les données). Sa complexité nous permet justement les transferts serveur/serveur ou serveur/client par l'intermédiaire d'un proxy, sans charger le client ou le proxy. En résumé, ce projet permet d'aborder la programmation réseau, en utilisant des protocoles très courants ; de plus, l'utilité du proxy FTP est bien réelle, car il permettrait de créer un serveur FTP "virtuel" de très grande taille, constitué en réalité de plusieurs serveurs "normaux" et d'un proxy.

Description détaillée :

Le protocole FTP est assez ancien (il fait partie des premiers protocoles définis sur TCP/IP, et fêtera donc bientôt ses 30 ans), et il est encore utilisé tous les jours dans de nombreuses applications (téléchargement de programmes, de sources ; accès non crypté à des données personnelles ; mise à jour de sites Web...). Son principe est assez simple : le client établit une connexion dite de commande avec le serveur. Après une éventuelle phase d'authentification très simple, le client peut se promener dans les répertoires du serveur, comme on le ferait avec la commande shell cd. Lorsque le client souhaite lister le contenu d'un répertoire, ou bien transférer un fichier du serveur vers chez lui ou inversement, il établit une seconde connexion, dite de données. Chaque répertoire listé, ou chaque fichier transféré, nécessite une nouvelle connexion.

Cette connexion supplémentaire peut sembler lourde et inutile, mais elle constitue toute la force du protocole. En effet, le côté qui établit cette deuxième connexion demande son adresse à l'autre partie ; c'est-à-dire que si c'est le serveur qui établit la deuxième connexion (mode par défaut, dit actif), il demande au client sur quelle adresse IP et quel port TCP le contacter ; si c'est le client qui établit la connexion (mode passif, utilisé pour passer certains firewalls), le serveur lui dit sur quelle adresse IP et port TCP le contacter. Ce qui veut dire que lorsque le client annonce "me contacter sur telle adresse, tel port", le serveur FTP virtuel (le proxy) va contacter un "vrai" serveur FTP pour lui relayer cette information, afin que ce soit le vrai serveur qui se connecte directement au client ; inversement, lorsque c'est au serveur d'annoncer où se connecter, le proxy demande l'adresse et le port au vrai serveur et annonce ces informations au client.

Un petit schéma pour rendre tout ceci encore plus incompréhensible :

                                         DATA pour LIST
                  /--------------------------------------------------------\
                  |                                                        |
                  v    CWD /pub, LIST, cwd /debian       CWD /pub, LIST    v
                [client]<----------------------\      /--------->[serveur 1]
                  ^          cd /new, STOR     |     /
                  |                            v    /    CWD /debian
                  |                         [proxy]*------------>[serveur 2]
                  |                                 \
                  \                                  \   CWD /new, STOR
                   \                                  \--------->[serveur 3]
                    \                                                    ^
                     \           DATA pour STOR                          |
                      \--------------------------------------------------/

Heureusement, il est très facile d'utiliser un outil comme netcat pour simuler le comportement d'un serveur ou d'un client FTP, afin de mieux comprendre le principe de fonctionnement et de réaliser des tests.

Il doit exister un moyen de définir les "montages" ou "liens" dans l'arborescence du serveur. Plusieurs solutions sont possibles ; voici 3 exemples :

A priori, l'écriture du proxy nécessite de gérer la plupart des commandes du protocole FTP, mais toutes les commandes manipulant l'état du serveur (changement de répertoire courant, principalement) doivent être exécutées sur un serveur distant. Il faut donc éventuellement conserver plusieurs connexions ouvertes, et maintenir un état ; il va sans dire qu'il est fortement recommandé de réfléchir longuement sur papier avant de pondre un code qui ferait n'importe quoi.

Le projet peut être développé en C ou C++, mais ce n'est pas obligatoire. L'inconvénient de ces langages est qu'il n'y a pas de bibliothèque standard bien adaptée à la manipulation de threads et de sockets ; il faut utiliser des appels système d'assez bas niveau, gérer correctement les erreurs et les signaux... En Java ou en Python, le développement est beaucoup plus facile. Le Python n'est pas enseigné à Marne-La-Vallée (pour l'instant), mais si des élèves souhaitent utiliser ce langage (qui présente de nombreux avantages sur le Java, surtout pour un projet "léger"), il est relativement simple à prendre en main.

Travail à effectuer :

Des améliorations pourront être proposées ; par exemple afin de faire du load-balancing sur plusieurs serveurs offrant les mêmes contenus, ou bien pour calculer à partir de l'adresse IP du client le miroir le plus proche de lui. Ces améliorations sont tout à fait facultatives ; il est bien plus important d'avoir un projet qui marche avec les fonctionalités de base, qu'un projet qui ne marche pas avec des fonctionalités étendues...