De plus en plus le protocole FTP est critiqué pour son manque de sécurtié, comparé à d'autres protocoles de transfert sécurisés, tel scp. Personnellement je l'aprécie parce qu'il reste encore parfois (de moins en moins souvent c'est vrai) la seule possibilité de protocole de transfert chez certains hébergeurs, mais surtout pour la possibilité de gérer des utilisateurs virtuels (plutôt que de créer un compte système pour chaque utilisateur). J'ai toujours utilisé pureftpd, séduit par ce serveur légé, très configurable,disponible de base dans les répos Fedora, et de plus je pouvais m'appuyer sur l'excellent tutoriel de drpixel même si Fedora par défaut propose le serveur vsftpd lors de son installation. Récemment j'ai eu à configurer un serveur FTP sous CentOS 5.0, qui propose aussi vsftpd par défaut, et qui n'a pas dans ses dépôts de base pureftpd. J'ai vite trouvé un dépôt tiers le proposant, mais je me suis dis que c'etais plutôt une occasion de découvrir vsftpd, et j'ai immédiatement apprécié la aussi sa souplesse, sa légereté, et le fait qu'il propose une configuration très fine pour chaque utilisateur, bref, je l'ai adopté. L'intérêt de vsftpd est aussi son système d'authentification par PAM.
Ainsi vous pouvez utiliser tous les types de stockage d'utilisateurs
que PAM permet. Il sera par exemple très simple de les stocker dans une
base mysql.
Je décris donc dans ce billet l'installation et la configuration de vsftpd, utilisant des utilisateurs virtuels, s'identifiant avec PAM. Jai choisis comme stockage pour les utilisateurs une petite base au format berkeley. Pour chacun de ces utilisateurs, je ferais en sorte que chaque paramètre de configuration puisse être personnalisé. J'ai testé ces manipulations sous Fedora 7 et CentOS 5.0. Je me suis inspiré de cet article pour rédiger ce billet.
Installation
Il vous faut tout d'abord installer vsftpd. Il est possible d'installer le package vsftpd avec yum, mais il est préférable d'utiliser le groupe FTP Server fourni par yum. Pour dire vrai je ne sait pas la réelle différence puisque le seul package proposé dans ce groupe est vsftpd, mais cela pourrait changer, et c'est peut-être cela qui permet d'avoir le user FTP et le groupe FTP automatiquement. Donc nous tapons en root :
# yum groupinstall "FTP Server"
Une fois l'installation faite, pour que le serveur démarre automatiquement au démarrage (attention il faut être dans l'environnement root, donc su - ) :
# chkconfig On
Pour démarrer , redémarrer et stopper le service, ce sera respectivement (toujours en su -) :
# service vsftpd start
# service vsftpd restart
# service vsftpd stop
Normalement votre système doit déja avoir un utilisateur ftp et un groupe ftp. Si ce n'est pas le cas, créez les avec groupadd et useradd.
Configuration
Le fichier de configuration de vsftpd se trouve dans le répertoire /etc/vsftpd et se nomme : vsftpd.conf
Rendons nous d'abord dans le dossier pour y faire du ménage, en root :
# cd /etc/vsftpd
La première chose à faire est de sauvegarder le fichier de configuration original (je repars d'un fichier vide ensuite) :
# mv vsftpd.conf vsftpd.conf.default
Nous créons ensuite un dossier qui contiendra les configuration spécifiques à chaque utilisateur :
# mkdir vsftpd_user_conf
Enfin il est temps que je dise deux mots sur deux fichiers présents dans ce répertoire :
ftpusers et user_list
En fait ces deux fichiers ont la même vocation : interdire des utilisateurs. En effet il contiennent tous les deux une liste d'utilisateurs pour lesquels le server ftp refusera toute connexion. Pourquoi deux fichiers (au contenu identique) ? Le premier (ftpusers) est utilisé via PAM dans la configuration par défaut faite sur Fedora et CentOS. A la connexion d'un utilisateur, PAM vient lire ce fichier et si le login est dans ce fichier, la connexion est refusée. Le second (user_list) est utilisé directement par vsftpd. Il peut avoir deux usages : soit seuls les utilisateurs contenus dans ce fichier ont le droit de se connecter, soit au contraire, si un utilisateur se connectant fait partie de ce fichier, il sera alors refusé. La seconde solution correspond à la même que celle utilisée via PAM. Je me fiche d'avoir une liste d'utilisateurs autorisés, puisque je les gererais avec ma liste d'utilisateurs virtuels. Il est donc inutile d'avoir ces deux système d'interdiction. Mon choix pourrait être de suivre la configuration par défaut faite par CentOS et Fedora, c'est à dire utiliser PAM (dans la configuration par défaut d'ailleurs, le fichier user_list n'est pas utilisé), et donc supprimé le fichier user_list alors inutile. Et pourtant ce n'est pas la solution que j'ai retenue. En effet il y a une petite différence dans la façon de rejeter les utilisateurs. Imaginons que "root" fasse partie des deux fichiers (ce qui est le cas en fait). Si root se connecte, le système PAM ne va pas réagir, et le mot de passe sera demandé. A partir de la, même si ce dernier est correct, PAM va refuser la connexion car "root" est présent dans le fichier ftpusers. Vsftpd ca lui réagir différemment. Lorsque le login sera demandé, et que l'utilisateur tapera "root", si celui-ci est das le fichier "user_list", il coupe directement la connexion, sans même demander le mot de passe. C'est une subtilité, mais je préfère ce comportement. Je vais donc utiliser le fichier user_list plutot que ftpusers. On supprime donc ce dernier :
# rm ftpusers
Nous verrons plus loin la configuration de PAM pour ne plus qu'il aille chercher dans ce fichier. A vous de rentrer les logins que vous ne souhaitez pas voir se connecter dans user_list en plus ce ceux par défaut. Cela sera pratique pour désactiver un utilisateur virtuel, plutôt que de supprimer puis recrééer son compte.
Venons en maintenant au fichier de configuration à proprement parlé :
# vi vsftpd.conf
Vous êtes dans un fichier vide, puisque nous avons renommé celui par défaut. Vous trouverez tous les paramêtres possible du fichier de config dans la page de man (man vsftpd.conf) où à cette adresse.
Je vous donne directement mon fichier de configuration, que je pense assez documenté. Si vous avez des questions ou des suggestions,n'hésitez pas à en faire part dans les commentaires :
# http://vsftpd.beasts.org/vsftpd_conf.html ou "man vsftpd.conf"
# Port d'ecoute
listen_port=21
# Banniere de bienvenue
ftpd_banner=Bienvenue sur le FTP ANETT
# Fichier de config PAM
pam_service_name=vsftpd
# Mode "standalone"
listen=YES
# Je ne veux pas de connexion anonymes
anonymous_enable=NO
# On autorise les connexion des utilisateurs locaux. C'est indispensable
# pour que les utilisateurs virtuels (mappes sur un utilisateur local)
# puissent se connecter (les "vrai" utilisateurs locaux sont ensuite desactives
# avec le fichier user_list
local_enable=YES
# Fichier de users
userlist_file=/etc/vsftpd/user_list
# Chargement de la liste userlist_file
userlist_enable=YES
# On refuse les utilisateur de la liste
userlist_enable=YES
# trop restrictif, un utilisateur virtuel pourra ainsi telecharger un fichier meme s'il n'est pas world readable
anon_world_readable_only=NO
# Refus des commandes influant sur le systeme de fichier (STOR, DELE, RNFR, RNTO, MKD, RMD, APPE and SITE)
write_enable=NO
# Refus des droits d'ecriture pour les anonyme (et donc utilisateurs virtuels) par défaut
# les autorisations seront donnees au cas par cas :
# pas d'upload
anon_upload_enable=NO
# pas de creation de repertoire
anon_mkdir_write_enable=NO
# pas de creation, suppression, renommage de repertoire ...
anon_other_write_enable=NO
# On autorise la connexion "guest" (qui veut dire "non invite"),
# puis on map ce guest sur le compte reel "ftp"
guest_enable=YES
guest_username=ftp
# chroot des utilisateurs
chroot_local_user=YES
# Nombre maximum de connexion simultannees
max_clients=50
# Nombre maxeimum de connexion venant de la meme IP
max_per_ip=4
# Dossier de configuration specifique de sutilisateurs
user_config_dir=/etc/vsftpd/vsftpd_user_conf
# On active le log
xferlog_enable=YES
Voila pour la configuration. Pour faire un petit résumé court :
- On écoute sur le port 21
- On est en standalone
- On refuse les utilisateurs anonymes
- On accepte les utilisateurs système et les utilsiateurs virtuels
- Les utilisateurs virtuels sont mappés sur le user "ftp"
- Les utilisateurs n'ont aucun droit d'écriture par défaut
- Ils sont chrootés dans /var/ftp
- vsftpd_user_conf ser ale dossier pour les config d'utilisateurs virtuels
- user_list contiendra la liste des utilisateurs refusés (pour lesquels on ne demandera même pas le mot de passe
Pensez à ouvrir les ports 20 et 21 de votre pare-feu, voir de faire une redirection de port si vous êtes derrière un routeur. Si vous avez changé les valeurs de ces ports dans le fichier de configuration, modifier vos pare-feu et routage en conséquence. De plus pour plus de sécurité, on réduit les droits sur le fichier de configuration :
# chmod 600 /etc/vsftpd/vsftpd.conf
Utilisateurs virtuels
Il est temps maintenant de créer la base contenant nos utilisateurs virtuels. Comme je l'ai dis celle-ci sera au format berkeley. Nous partirons d'un fichier texte simple, comprenant les logins et les mots de passe, puis nous utiliserons une commande pour transformer ce fichier en format db. Le format du fichier est simplissime, un mot par ligne, et on écrit dans l'ordre le login, le pass, le login, le pass etc ... Je vais créer une base contenant deux utilisateurs :
- titi dont le mot de passe est passtiti
- toto dont le mot de passe est passtoto
Rendez vous dans /etc/vsftpd et en root créez un fichier nommé login.txt :
# cd /etc/vsftpd/
# vi login.txt
Et voici le ce que contiendra le fichier :
titi
passtiti
toto
passtoto
Nous allons maintenant créer le fichier db à partir de celui-ci. Pour cela nous devons utiliser la commande db_load, fournie par le package db4-utils. Si ce package n'est pas installé, faites le de cette façon :
# yum install db4-utils
Une fois cela fait, toujours depuis le dossier /etc/vsftpd, en root tapez :
# db_load -T -t hash -f login.txt login.db
Nous verrons plus loin que l'on peut intégrer cette commande à un script pour regénérer plus facilement la base. Nous disposons maintenant d'un fichier /etc/vsftpd/login.db. Pour plus de sécurité, on réduit les droits sur les fichiers utilisateurs :
# chmod 600 login.*
PAM
Notre base d'utilisateurs étant créer, cufigurons PAM pour qu'il l'utilise. Comme apache (par exemple), PAM utilise pour sa configuration un dossier /etc/pam.d/ comportant les fichiers de configuration des services qui l'utilise. Un fichier /etc/pam.d/vsftpd existe déja, mais comme je l'expliquais plus haut, je ne l'utilise pas dans son intégralité. Voici donc le contenu de ce fichier à avoir :
#%PAM-1.0
auth sufficient pam_unix.so
account sufficient pam_unix.so
auth required /lib/security/pam_userdb.so db=/etc/vsftpd/login
account required /lib/security/pam_userdb.so db=/etc/vsftpd/login
Les lignes 2 et 3 permettent la connexion des utilisateusr système, les 4 et 5 la connexion des utilisateurs virtuels placé dans notre base.
On peut relancer notre serveur (en su -) :
# service vsftpd restart
Voilà notre serveur prêt à l'emploi,
TESTS
Testons notre serveur
ftp localhost
Entrer comme user "titi" et pass "passtiti". La connexion doit être OK.
Placez un fichier dans /var/ftp/ et reconnectez vous. Une fois connecté, tapez la commande "ls". Vous devez voir votre fichier.
Tout cela est bien gentil, mais perso si je créé des comptes, c'est pour avoir des droits différents pour chacun, et surtout que chacun ai son propre répertoire (qui peut être un sous répertoire du local_root, ou pourquoi pas un autre). Vous avez vu que dans la configuration, nous utilisons la directive "user_config_dir=/etc/vsftpd/vsftpd_user_conf". Ce dossier nous permet de stocker dans des fichiers séparés des configurations spécifiques à chaque utilisateur. Dans ces fichiers, on entre des paramètres (les mêmes que ceux du fichier de configuration) qui seront prioritaires par rapport au fichier de configuration principal. Généralement, on y modifie le local_root, et les droits d'écriture. On y met un fichier par utilisateur, et le fichier porte le même nom que le login de l'utilisateur auquel il fait référence. Créons un dossier "titi" dans /var/ftp, changeons le de propriétaire puis modifions le local_root et les droits d'écriture pour cet utilisateur :
# mkdir /var/ftp/titi
# chown ftp:ftp /var/ftp/titi
echo "local_root=titi" > /etc/vsftpd/vsftpd_user_conf/titi
echo "write_enable=YES" >> /etc/vsftpd/vsftpd_user_conf/titi
echo "anon_upload_enable=YES" >> /etc/vsftpd/vsftpd_user_conf/titi
echo "anon_mkdir_write_enable=YES" >> /etc/vsftpd/vsftpd_user_conf/titi
echo "anon_other_write_enable=YES" >> /etc/vsftpd/vsftpd_user_conf/titi
Nottez que l'on aurait pû mettre un répertorie absolu pour le local_root, par exemple /var/www/html/le_site_de_titi, mais en s'assurant que l'utilisateur ftp est les droits adéquats sur ce dossier.
Reconnectez vous avec l'utilisateur titi, il vous ai maintenant possible de déposer des fichiers.
Reportez vous à la page de man pour les détails sur le paramètres de configuration.
Il est possible que parfois lorsque vous vous connectez, vous aillez cette erreur :
500 OOPS: reading non-root config file
Cela intervient si l'utilisateur n'a pas de fichier spécifique dans vsftpd_user_conf (même vide). Il semble que ce soit un bug. Si vous avez ce souci, créez un fichier pour cet utilisateur. Nous verrons ensuite que l'on peut faire cela automatiquement.
Se simplifier la vie
La commande pour générer le fichier db à partir du txt est lourde a retenir, et de plus il est intéressant de pouvoir générer un fichier de configuration spécifique vide pour chaque utilisateur pour ne pas avoir d'erreur. Voici un petit script (surement optimisable) appellé txt2db.sh faisant cela pour vous. Il regénère le fichier db, et créé un fichier de config vite s'il n'existe pas. Vous trouverez ce fichier en pièce jointe à ce billet. En voici le contenu :
#!/bin/sh
if [ $# = "2" ]; then
rm -f $2
db_load -T -t hash -f $1 $2
chmod 600 /etc/vsftpd/login.*
echo "Base cree"
lignes=$(cat $1)
nb=1
for ligne in $lignes
do
if [ $(($nb%2)) -ne 0 ];
then
if [ ! -e vsftpd_user_conf/$ligne ];
then
touch /etc/vsftpd/vsftpd_user_conf/$ligne
echo "fichier $ligne cree"
fi
fi
nb=$(($nb+1))
done
else
echo "Il faut donner le fichier d'entree et le fichier de sortie"
fi
et son utilisation :
# cd /etc/vsftpd/
# chmod +x txt2db.sh (à ne faire que la première fois)
# ./txt2db.sh login.txt login.db
Ce script lie les lignes du login.txt et pour chaque login, vérifie si un fichier de conf existe. Si ce n'est pas le cas il en créé un vide. Auparavant il génère le fichier db.
L'autre soucis est que si vous supprimez un utilisateur du login.txt, il restera toujours le fichier spécifique de configuration. Voici un script appellé "cleanconf.sh" qui supprimé tous les fichiers spécifiques n'ayant pas de login associé. Vous le trouverez aussi en pièce jointe. Son contenu, puis son utilisation :
fichiers=$(ls /etc/vsftpd/vsftpd_user_conf)
users=""
lignes=$(cat /etc/vsftpd/login.txt)
nb=1
for ligne in $lignes
do
if [ $(($nb%2)) -ne 0 ];
then
users="$users $ligne"
fi
nb=$(($nb+1))
done
for conf in $fichiers
do
found=0
for user in $users
do
if [ $conf = $user ];
then
found="1"
fi
done
if [ $found != "1" ];
then
rm -f vsftpd_user_conf/$conf
echo "Fichier $conf supprime"
fi
done
Son utilisation :
# chmod +x cleanconf.sh
# ./cleanconf.sh
Voila qui nous simplifiera un peu la vie.
Conclusion
Voila un petit serveur FTP prêt, avec uen gestion facile d'utilisateurs virtuels. Il de plus pour chaque utilsiateur possible de modifier chaque valeur de la configuration principale, ce qui rend la gestion des utilisateurs virtuels très souple. Pour plus de sécurité, il est possible de faire du FTP over SSH.
J'ai définitivement adopté vsftpd, très légé, dispo de base, et si vite mis en place. La gestion est aussi très aisée (n'oubliez pas que vous pouvez stocker cos utilsiateurs das chaque type de stockage supporté par PAM), et le principe de configuration détaillée pour les utilisateurs virtuels permet des réglages fins.
Cependant comparé à pureftpd, il me manque encore certaines petites choses, pas indispensables mais qui étaient sympa. Je ne sais pas encore si vsftpd permet ces choses. Il permettait notemment de voir les transferts actif, et de limiter en bande passante et surtout en horraires les utilsiateurs.
En espérant que cet article donnera un coup de main.
Fabien
Billet original sur All you need is blog - eponyme's blog