vsFTPd, un serveur FTP sécurisé et simple

Introduction

Etant relativement jeune sous GNU/LINUX, j'ai d'abord cherché à m'appuyer sur une documentation solide, en cherchant à l'adapter pour Debian et à la rendre disponible au plus grand nombre. Cette documentation s'inspire donc pour toute ou partie de celle du site officiel http://vsftpd.beasts.org/ et notamment de plusieurs tutoriaux qu'il propose ftp://vsftpd.beasts.org/users/cevans/untar/vsftpd-2.0.3/EXAMPLE/.

Dans une traduction plus que subjective et dans un style qui est le mien, j'y regroupe plusieurs de ceux-ci dans un ensemble se voulant cohérent et synthétique, en y ajoutant des petits conseils et autres astuces glanés ça et là.

vsFTPd est un serveur FTP sous license GPL pour les systèmes UNIX. “vs”, mis pour “VerySecure” rappelle quelle a été l'orientation de son auteur Chris Evans, lors de la conception de cette application.

Privilégiant une architecture modulaire, dans le plus pur esprit d'UNIX, vsFTPd s'appuie sur des composants externes tels que PAM ou xinetd, même si l'utilisation de ce dernier a tendance a disparaître au bénéfice du mode standalone(introduit depuis la version 1.1.0).

Définitions:

  • PAM est un système de bibliothèques qui gèrent les tâches d'authentification des applications (services) sur le système.
  • xinetd est méta-daemon gèrant les services internet.

Ces caractéristiques remarquables font de vsFTPd un serveur FTP sécurisé, performant et stable, qui fait l'unanimité de sites tels que ftp://ftp.debian.org/ ou ftp://ftp.openbsd.org/ (la liste est loin d'être exhaustive) et des grands noms du libre.

Pour toujours plus d'éloges à propos de vsFTPd, je vous renvoie à la page officielle du projet.

Pré-requis

Alors bien évidemment (et il faudrait être idiot :p ), on installe vsFTPd:

# apt-get install vsftpd

Ceci étant, tout reste à faire.. et comme bien souvent sous UNIX, on va principalement se contenter de jouer avec les différents fichiers de configuration dans /etc/.

Serveur avec utilisateurs virtuels

Cette première configuration va être l'occasion pour nous, de mettre en évidence des concepts fondamentaux de vsFTPd. Ainsi, allons nous tenter de mettre en place un serveur FTP en mode standalone(autonome), en restreignant l'accès(grâce à PAM) aux utilisateurs virtuels d'une base de donnée.

Les utilisateurs virtuels ne disposent pas de véritables comptes sur la machine, mais d'un compte virtuel dans lequel ils sont emprisonnés(on dit aussi “chrootés”). C'est ainsi que de manière très limitée qu'ils pourront intéragir avec elle.

Encore une fois, cette configuration n'est qu'un exemple, choisi pour son aspect didactique. Pour d'autres scénarios, je vous renvoie encore une fois à la documentation officielle.

Dans ce qui suit, nous allons être amené à créer différents fichiers de configuration. Pour plus de commodité, nous les rangerons dans /etc/vsftpd/ . Créons par conséquent ce répertoire:

# mkdir /etc/vsftpd

Si ce n'est pas déjà fait, on prend soin de sauvegarder la configuration par défaut de vsFTPd (on sait jamais..):

# cp /etc/vsftpd.conf /etc/vsftpd.conf.default.bak
# cp /etc/pam.d/vsftpd /etc/pam.d/vsftpd.default.bak

Créons notre base de données d'utilisateurs virtuels

Le mécanisme d'authentification PAM utilise une base de données au format “Berkeley db”, un format très répandu. Nous allons donc la créer grâce cet outil:

# apt-get install libdb3-util

Pour créer ce fameux fichier au format “db”, créons un fichier texte login.txt où apparîtront alternativement par paire de lignes, le nom d'utilisateur et le mot de passe, comme ceci:

tom
foo
fred
bar

Les 2 utilisateurs sont donc ici ”'tom'” et ”'fred'” et leurs mots de passe respectifs ”'foo'” et ”'bar'”.

Attention, veillez à ce que votre fichier se termine bien par un retour à la ligne et respectez scrupuleusement le format “login puis passwd” sans ajouter le moindre commentaire!

puis convertissons-le au format “db”:

# db3_load -T -t hash -f login.txt /etc/vsftpd/login.db

voilà, on dispose maintenant d'une base de données au format “db”: /etc/vsftpd/login.db

et évidemment, on s'assure de ses permissions(si jamais y'avait des fouineurs :p ):

# chmod 600 /etc/vsftpd/login.db

Si vous voulez apprendre davantage sur comment maintenir votre base de données “Berkeley DB”: http://www.sleepycat.com/docs/utility/index.html

Créons un fichier PAM

Créons maintenant un fichier vsftpd.pam qui dira à PAM d'utiliser notre base de données pour authentifier les utilisateurs:

auth required /lib/security/pam_userdb.so db=/etc/vsftpd/login
account required /lib/security/pam_userdb.so db=/etc/vsftpd/login

Copions finalement ce fichier dans le dossier de configuration de PAM:

# cp vsftpd.pam /etc/pam.d/vsftpd

Ca y est, PAM dispose désormais de tous les éléments nécessaires pour assurer l'authentification des utilisateurs virtuels.

Un méta-utilisateur virtuel: l'utilisateur système

Tous les utilisateurs virtuels de notre base de données(tom, fred…) vont en réalité être représenté par UN même utilisateur(réel cette fois ci) système: l'utilisateur virtual(que l'on aurait très bien pu appeler autrement cela dit).

  • Ajoutons cet utilisateur à notre système, en définissant son groupe primaire à ftp(groupe que l'on va créer) et en le liant à son futur home ~virtual/, qu'il ne restera alors plus qu'à créer:
# groupadd ftp
# useradd -g ftp -d /home/ftp/virtual/ virtual

Si la commande “`groupadd`” ou “`useradd`” vous renvoie une erreur comme groupadd : le groupe ftp existe ou useradd : l'utilisateur virtual existe, ignorez-les purement et simplement: l'ordre dans lequel sont données les commandes contourne ces éventuels problèmes

  • Créons maintenant physiquement le répertoire ~virtual/ en prenant soin de lui procurer des permissions correctes:
  • le répertoire ne doit pas lui appartenir!
  • il ne doit pas pouvoir y écrire!(pour cet usage, on créera, un peu plus tard, un sous répertoire dédié: ~virtual/upload/)

# mkdir -p /home/ftp/virtual

# chown root.ftp ~virtual/
# chmod 2750 ~virtual/

Notez le setgid de ~virtual/, qui assure que tous les fichiers/dossiers créés dans ce répertoire appartiendront au même groupe que le répertoire lui même: ftp

Le voilà bien au chaud sous /home/ftp/virtual/ notre utilisateur virtual du groupe ftp.

On peut même lui filer un truc à manger tiens, histoire qu'il puisse télécharger quelque chose, par exemple:

# cp /etc/hosts ~virtual/

A la fin de ce tutoriel, pensez a supprimer ce fichier(~virtual/hosts) sans quoi vos utilisateurs virtuels risquent de se demander ce qu'il fait ici ;)

Créons notre fichier de configuration vsFTPd: vsftpd.conf

Créons le fichier vsftpd.conf :

# Ceci configure vsFTPd en mode "standalone"
listen=YES
# On désactive les connexions anonymes
# et on active les non-anonymes(c'est le cas des utilisateurs virtuels):
anonymous_enable=NO
local_enable=YES
# Pour des raisons de sécurité on interdit toute action d'écriture:
write_enable=NO
anon_upload_enable=NO
anon_mkdir_write_enable=NO
anon_other_write_enable=NO
# 'guest_enable' est très important: cela active les utilisateurs virtuels!
# 'guest_username' fait correspondre tous les utilisateurs virtuels à
# l'utilisateur 'virtual' que nous avons défini plus haut, et au home
# correspondant: '~virtual/'.
guest_enable=YES
guest_username=virtual
# On veut que les utilisateurs virtuels restent chez eux: '~virtual/'
# (attends, on leur a fait un toît, c'est pas pour rien!)
chroot_local_user=YES
# On défini le nombre maximum de sessions à 200(les nouveaux clients recevront
# un message du genre: "erreur: serveur occupé").
# On défini le nombre maximum de sessions par IP à 4
max_clients=200
max_per_ip=4
####################################
# Debian customization             #
# (ou adoptons la debian attitude) #
####################################
# Some of vsftpd's settings don't fit the Debian filesystem layout by
# default.  These settings are more Debian-friendly.
#
# This option should be the name of a directory which is empty.  Also, the
# directory should not be writable by the ftp user. This directory is used
# as a secure chroot() jail at times vsftpd does not require filesystem
# access.
secure_chroot_dir=/var/run/vsftpd
#
# This string is the name of the PAM service vsftpd will use.
pam_service_name=vsftpd
#
# This option specifies the location of the RSA certificate to use for SSL
# encrypted connections.
rsa_cert_file=/etc/ssl/certs/vsftpd.pem

Pour en apprendre davantage sur les différentes options du fichier vsftpd.conf et notemment connaître celles par défaut, consultez donc la page de manuel.

Copions-le dans /etc/:

# cp vsftpd.conf /etc/

Relancement du serveur

# /etc/init.d/vsftpd stop
# /etc/init.d/vsftpd start

Si votre configuration est bonne, la commande ne retourne rien. En revanche, dans le cas contraire, c'est ici que vous rencontrerez les éventuels messages d'erreurs.

Test

On choisit ci-dessous d'utiliser pour le test la commande ftp (car installée par défaut), mais si vous préférez un autre client: vous êtes libres!

Voici un exemple d'une session ftp sur notre serveur:

$ ftp localhost 21
Connected to localhost.localdomain.
220 (vsFTPd 2.0.3)
Name (localhost:to_): tom
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> pwd
257 "/"
ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
226 Transfer done (but failed to open directory).
ftp> size hosts
213 147
ftp> quit
221 Goodbye.

Le mot de passe entré était bien entendu ”'foo'” (cf. notre base de données).

Vous avez remarquez que la commande “ls” a échoué: failed to open directory. Ceci est tout à fait normal, car les utilisateurs virtuels ont en réalité les même permissions que les utilisateurs anonymes, pour lesquels vsFTPd applique une politique très restrictive. En effet, par défaut le serveur n'autorise que la lecture des répertoires dont les permissions sont définies sur ”'world_readable'”(lisible par le reste du monde). Or ce n'est pas le cas de notre répertoire ~virtual/ que nous avons pris soin de chmoder ainsi: 2750.

On pourrait remédier à ce problème en contrant cette politique dans /etc/vsftpd.conf par un anon_world_readable_only=NO, mais il serait beaucoup plus judicieux de pouvoir affiner les permissions de chacun des utilisateurs virtuels…

Gérer les permissions de chacun

  • Admettons que nous voulions définir 2 types d'utilisateurs virtuels:
    • un qui ne pourrait que se balader dans son home(commun à tous les utilisateurs virtuels i.e ~virtual/)et downloader tout ce qui s'y trouve(accès en lecture): tom
    • un autre qui pourrait en plus uploader(accès en lecture/écriture) dans un répertoire dédié, sans toutefois pouvoir supprimer des données: fred

Pour cela, nous allons utiliser une des fonctionnalités supplémentaires de vsFTPd(depuis la version 1.1.0): la configuration par utilisateur(ou la configuration per-user)

Activer la configuration per-user

La configuration 'per-user' est une option très puissante de vsFTPd puisqu'elle permet d'étendre l'usage de n'importe quelle option de la page de manuel à un utilisateur en particulier. Qui plus est, elle permet également de contrer la politique du vsftpd.conf qui joue alors le rôle d'une politique par défaut.

Pour l'activer, il suffit de rajouter la ligne suivante à notre fichier /etc/vsftpd.conf :

user_config_dir=/etc/vsftpd/vsftpd_user_conf

et de créer ce repertoire:

# mkdir /etc/vsftpd/vsftpd_user_conf/

C'est dans celui-ci que l'on va mettre les fichiers gérant les droits de chacun: un fichier par utilisateur!

N'oubliez pas que ce sont toujours les droits du système de fichiers qui prévalent sur ceux du serveur (ben oui, c'est logique, vsFTPd n'est jamais qu'un programme). Autrement dit, même si fred est autorisé du point de vue de vsFTPd à écrire, encore faut-il que l'utilisateur système virtual, qui le représente, ait le droit d'écriture sur le répertoire en question!

On oublie pas de re-démarrer le serveur ftp pour que cette option soit prise en compte:

# /etc/init.d/vsftpd reload

Donnons à tom son droit de lecture (download)

Comme nous l'avons vu plus haut, il suffit de contrer la politique par défaut de vsFTPd par un anon_world_readable_only=NO, mais pour tom uniquement cette fois! On le définit donc dans SON fichier à lui:

# echo "anon_world_readable_only=NO" > /etc/vsftpd/vsftpd_user_conf/tom

Vérifiez donc que ça marche: loguez-vous en tom et faites de nouveau un `ls`:

ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
-rw-r--r-- 1 0 0 263 Aug 23 23:18 hosts
226 Directory send OK.

Puis loguez-vous en fred et apercevez-vous que ça ne marche toujours pas pour lui…

Donnons à fred son droit de lecture/écriture(download/upload), dans un répertoire dédié

De la même manière:

# echo "anon_world_readable_only=NO" > /etc/vsftpd/vsftpd_user_conf/fred
# echo "write_enable=YES" >> /etc/vsftpd/vsftpd_user_conf/fred
# echo "anon_upload_enable=YES" >> /etc/vsftpd/vsftpd_user_conf/fred

Cependant, au vue des permissions de ~virtual/, si fred a les droits nécessaires du point de vue du serveur, virtual lui ne les aura pas du point de vue du système de fichiers !

Créons par conséquent un répertoire dédié dans lequel le méta-utilisateur virtuel virtual du groupe ftp aura la permission d'écrire:

# mkdir ~virtual/upload/
# chmod 770 ~virtual/upload/

Ayez-en le coeur net, loguez-vous en fred et vérifiez que vous pouvez uploader:

ftp> cd upload
250 Directory successfully changed.
ftp> send /etc/hostname hostname
local: /etc/hostname remote: hostname
200 PORT command successful. Consider using PASV.
150 Ok to send data.
226 File receive OK.
16 bytes sent in 0.00 secs (157.8 kB/s)

Loguez-vous en tom et constatez le contraire…

Essayez par la même d'effacer des fichiers avec la commande delete et constatez que vsFTPd vous l'interdit.

Quelques autres droits

Si l'on désire accorder en plus à fred le droit de créer un dossier:

# echo "anon_mkdir_write_enable=YES" >> /etc/vsftpd/vsftpd_user_conf/fred

ou même le droit de renommer, supprimer… :

# echo "anon_other_write_enable=YES" >> /etc/vsftpd/vsftpd_user_conf/fred

File dans ta chambre !

Jusqu'ici, tous nos utilisateurs virtuels vivaient sous le même toît et partageaient la même maison. tom ne faisait jamais son lit, rôtait tout fort et ne rangeait jamais ses chaussures !!! fred était à bout !

Dans ces conditions, et afin d'éviter le drame, nous n'avons d'autre choix que de leur construire une chambre et un placard chacun:

# cd ~virtual/
# mkdir -p {tom/,fred/}/upload
# chmod 2750 {tom/,fred/}
# chmod 770 {tom/,fred/}/upload/

Il suffit ensuite de rajouter l'option local_root=$USER dans le fichier de configuration de $USER (i.e: /etc/vsftpd/vsftpd_user_conf/$USER), et ce pour tous les utilsitateurs:

Vous aurez bien sûr compris que dans les faits, on remplace $USER par chacun des utilsateurs de notre base de données !

# echo "local_root=tom" >> /etc/vsftpd/vsftpd_user_conf/tom
# echo "local_root=fred" >> /etc/vsftpd/vsftpd_user_conf/fred

Automatisons cette tâche

Ce paragraphe est complètement facultatif, il n'apporte aucune fonctionnalité supplémentaire. Si vous voulez, vous pouvez très bien vous arrêtez là.

Ici, nous n'avons que deux utilisateurs à gérer, mais dans le cas d'une base de données plus importante, on peut automatiser cette tâche par ce script accountDB.sh:

#!/bin/bash
 
USER_CONFIG_DIR=/etc/vsftpd/vsftpd_user_conf/
 
if [ $# -eq 1 ]; then
    if [ -f $1 ]; then
        #pour tous les noms figurant dans la base de données:
        for user in ` db3_dump -p $1 | sed -n 's/^ //p' | sed -n '1,${p;n;}' `
          do
          #création des répertoires personnels pour les utilisatuers virtuels:
          if [ ! -d ~virtual/$user ]; then
              echo "$0: ajout du répertoire personnel ~virtual/$user pour l'utilisateur virtuel '$user'"
              mkdir -p ~virtual/$user/upload
              chmod 2750 ~virtual/$user/
              chmod 770 ~virtual/$user/upload/
          else
              echo "$0[warning]: ~virtual/$user: omission, ce répertoire existe déja."
          fi
          #chrootage des utilisateurs virtuels:
          if ! grep -q "^local_root=" $USER_CONFIG_DIR/$user 2>/dev/null; then
              echo "$0: on chroote '$user'"
              echo "local_root=$user" >> $USER_CONFIG_DIR/$user
          else
              echo "$0[warning]: $USER_CONFIG_DIR/$user: '$user' est déjà chrooté."
          fi
        done
    else
        echo "$0[erreur]: $1: la base de données est introuvable! "
    fi
else
    echo "$0[erreur]: usage: accountDB.sh base_de_donnees"
fi

Précisions quant au script:

  • Avant de le lancer, n'oubliez pas de le rendre exécutable :
    # chmod u+x accountDB.sh
  • Etant donné les permissions de /etc/vsftpd/login.db, il doit impérativement être exécuté avec les droits du super-utilisateur, par :
    # sh accountDB.sh /etc/vsftpd/login.db

Vous pouvez adapter ce script comme bon vous semble et ainsi automatiser entièrement votre configuration. Il vous suffit pour cela essentielement de remanier le corps de la boucle “for”.

Désinstallation

  • partielle:

Si vous souhaitez désinstaller le serveur vsftpd, mais garder vos fichiers de configurations(ce peut être une sage décision, surtout si vous avez passé du temps à configurer chaque utilisateur virtuel !):

# apt-get remove vsftpd
  • complète:

Cela dit, si vous souhaitez tout remettre à plat:

Attention: vous vous apprêtez à supprimer définitivement des données de votre disque dur!!! Si vous n'êtes pas sûr de vous, je vous conseille la désinstallation partielle!

# apt-get remove --purge vsftpd libdb3-util
# rm -rf /etc/vsftpd/
# rm /etc/vsftpd.conf.default.bak /etc/pam.d/vsftpd.default.bak

Vous pouvez même poussez le vice un peu plus loin, en supprimant l'utilisateur virtual et le groupe ftp de votre système:

# deluser virtual
# delgroup ftp

ainsi que tous les fichiers de son home: Là encore, réfléchissez bien avant de taper cette commande; vérifiez bien qu'aucun fichier important ne s'y trouve!!!

# rm -rf /home/ftp/virtual/

Conclusion

Ceci n'est qu'un aperçu très succint des possibilités de vsFTPd. J'essaierai au fur et à mesure de ma progression dans l'usage de ce programme, de compléter cet article. Revenez donc faire un tour prochainement…

Liens

La documentation sur vsFTPd n'étant pas très fournie, je vous re/donne divers liens qui vous permettrons de parfaire votre connaissance sur le sujet :

voili-voilou, bonne lecture ;)

 
reseau/vsftpd-un-serveur-ftp-securise-et-simple.txt · Dernière modification: 11/12/2010 17:37 par orgrim