====== 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 à [[http://archlinux.org|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 : {{ :205ftp:topo-vraie.png?720 |Topologie réelle}} Mais qui fonctionnellement peut se résumer ainsi : {{ :205ftp:topo-simple.png?360 |Topologie simplifiée}} 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 : 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 ===== Installation ===== C'est simple : aptitude install pure-ftpd Qui installe aussi ''pure-ftpd-common''. Il y a d'autres versions de ce serveur : # 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 : 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 ==== 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. ==== 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. ===== Recherche d'une configuration ===== ==== 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). === Préparation du système === Commençons par arrêter le serveur « standalone » : # /etc/init.d/pure-ftpd stop Puis modifions ''/etc/default/pure-ftpd-common'' comme suit : 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'' : # 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 : # useradd -g ftpgroup -d /dev/null -s /bin/false ftpuser Nous créons un répertoire qui contiendra les répertoires des utilisateurs virtuels : # mkdir /home/ftpusers === Création d'un compte virtuel === Avec la commande ''pure-pw'' créons un compte ''test'' : # 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 :
# 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'' : # pure-pw mkdb qui crée, toujours par défaut, un fichier ''/etc/pure-ftpd/pureftpd.pdb''. === Premier test === Nous démarrons le serveur avec les options suivantes : # 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 : # ps aux | grep pure root 23658 0.0 0.3 24888 1668 pts/0 S+ 18:44 0:00 pure-ftpd (SERVER) et : # 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 :
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) : # 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 :
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 : # 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 : # 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.