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 :
Mais qui fonctionnellement peut se résumer ainsi :
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
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
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.
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.
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).
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
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
.
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 dossierTout 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.