{{tag>FTP vsftpd}} ====== 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 [[http://vsftpd.beasts.org/|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 [[http://vsftpd.beasts.org/#docs|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 [[http://vsftpd.beasts.org/vsftpd_conf.html|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 : * la doc officielle : * sur le site de vsFTPd : * la **page officielle** du projet : http://vsftpd.beasts.org/ * les **tutoriaux** : ftp://vsftpd.beasts.org/users/cevans/untar/vsftpd-2.0.3/EXAMPLE/ * la page de **manuel**(très importante!) : http://vsftpd.beasts.org/vsftpd_conf.html * la **FAQ** : ftp://vsftpd.beasts.org/users/cevans/untar/vsftpd-2.0.3/FAQ * comme d'habitude, n'oubliez pas de consulter la documentation spécifique dans le répertoire ''/usr/share/doc/vsftpd/'' et les ''man''. Vous y retrouverez d'ailleurs tous les documents pré-cités, mais également les fameux "README*", "changelog*" et toute la clique ;) * en vrac: * **la spécification du protocole FTP**(RFC en français) : http://www.eisti.fr/res/norme/rfc959/959tm.htm * la page consacrée à **vsFTPd sur freshmeat** : http://freshmeat.net/projects/vsftpd/ * la page de **manuel de PAM**(en français) : http://www.delafond.org/traducmanfr/man/man8/pam.8.html * pour gérer votre **db Berkeley** : http://www.sleepycat.com/docs/utility/index.html voili-voilou, bonne lecture ;)