Proftpd, compte virtuel et MySQL

Cet article décrit comment installer un serveur Proftpd qui utilise des utilisateurs virtuel avec une base de données MySQL en lieu et place du système traditionnel. Grâce à ce système, vous pouvez configurer un nombre important d'utilisateurs, et en plus la possibilité de gérer les quotats.
Pour l'administration de la base de données, nous allons utiliser l'outil phpmyadmin. Celui-ci simplifie l'utilisation de la base de donnée sans se soucier de la ligne de commande.

Ce tutoriel sera basé sur la distribution Debian Sarge 3.1 et Gentoo. Il devrait donc fonctionner aussi pour les distributions Ubuntu, knoppix. Pour toutes les autres distributions, seule la partie de l'installation diffère, la configuration reste identique.
Ce document est fourni sans aucune garantie.

1 Installation de MySQL et phpMyAdmin

Debian:

apt-get install mysql-server mysql-client libmysqlclient12-dev phpmyadmin 

Réponder aux questions posées:

Enable suExec? -- Yes
Configuring mysql-server (Install Hints) -- OK   
Which web server would you like to reconfigure automatically? -- apache, apache2   
Do you want me to restart apache now? -- Yes

Gentoo :

emerge mysql phpmyadmin

Créer un mot de passe pour l'utilisateur root (remplacer votrepassword par le mot de passe que vous voulez ):

mysqladmin -u root password votrepass


2 Installer Proftpd avec le support de MySQL

Pour la distribution Debian, il existe un paquet préconfigurer :

apt-get install proftpd-mysql  Run proftpd from inetd or standalone? -- standalone

Pour la distribution Gentoo :

USE="mysql softquota" emerge proftpd 

Ensuite créer un groupe ftp ("ftpgroup") and un utilisateur ("ftpuser") qui vous permettra de mapper les utilisateurs virtuel vers celui-ci. utiliser un group et userid qui est libre sur votre system:

groupadd -g 2001 ftpgroup  useradd -u 2001 -s /bin/false -d /bin/null -c "proftpd user" -g ftpgroup ftpuser 


3 Créer la base de données MySQL pour Proftpd

Maintenand vous pouvez créer une base de données appelé ftp et un utilisateur MySQL nommé proftpd qui peremettra au daemon proftpd de l'utilisé pour se connecter à la base de données ftp :

mysql -u root -p

 

create database ftp; 
GRANT SELECT, INSERT, UPDATE, DELETE ON ftp.* TO 'proftpd'@'localhost' IDENTIFIED BY 'password'; 
GRANT SELECT, INSERT, UPDATE, DELETE ON ftp.* TO 'proftpd'@'localhost.localdomain' IDENTIFIED BY 'password'; 
FLUSH PRIVILEGES; 

Remplacer le  password que vous avez choisi pour l'utilisateur  proftpd. Rester sur le shell MySQL et créer la base de données:

USE ftp;  
CREATE TABLE ftpgroup ( 
groupname varchar(16) NOT NULL default '', 
gid smallint(6) NOT NULL default '5500', members varchar(16) NOT NULL default '', 
KEY groupname (groupname)) 
TYPE=MyISAM COMMENT='ProFTP group table'; 
 
CREATE TABLE ftpquotalimits ( 
name varchar(30) default NULL, 
quota_type enum('user','group','class','all') NOT NULL default 'user', 
per_session enum('false','true') NOT NULL default 'false', 
limit_type enum('soft','hard') NOT NULL default 'soft', bytes_in_avail int(10) unsigned NOT NULL default '0',
bytes_out_avail int(10) unsigned NOT NULL default '0', 
bytes_xfer_avail int(10) unsigned NOT NULL default '0', 
files_in_avail int(10) unsigned NOT NULL default '0', 
files_out_avail int(10) unsigned NOT NULL default '0',
files_xfer_avail int(10) unsigned NOT NULL default '0') 
TYPE=MyISAM;  
 
CREATE TABLE ftpquotatallies ( 
name varchar(30) NOT NULL default '', 
quota_type enum('user','group','class','all') NOT NULL default 'user', 
bytes_in_used int(10) unsigned NOT NULL default '0', 
bytes_out_used int(10) unsigned NOT NULL default '0', 
bytes_xfer_used int(10) unsigned NOT NULL default '0', 
files_in_used int(10) unsigned NOT NULL default '0', 
files_out_used int(10) unsigned NOT NULL default '0', 
files_xfer_used int(10) unsigned NOT NULL default '0' ) 
TYPE=MyISAM;  
 
CREATE TABLE ftpuser ( 
id int(10) unsigned NOT NULL auto_increment, 
userid varchar(32) NOT NULL default '', 
passwd varchar(32) NOT NULL default '', 
uid smallint(6) NOT NULL default '5500', 
gid smallint(6) NOT NULL default '5500', 
homedir varchar(255) NOT NULL default '', 
shell varchar(16) NOT NULL default '/sbin/nologin', 
count int(11) NOT NULL default '0', 
accessed datetime NOT NULL default '0000-00-00 00:00:00', 
modified datetime NOT NULL default '0000-00-00 00:00:00', 
PRIMARY KEY (id), UNIQUE KEY userid (userid) ) 
TYPE=MyISAM COMMENT='ProFTP user table';  
 
quit; 

De retour dans le shell Linux.
Nous allons suposés que le nom de domaine du serveru FTP est server1.exemple.com et que nous pouvons accèder à phpMyAdmin par http://server1.example.com/phpmyadmin/. (Vous pouvez utiliser l'adresse IP)

4 Configurer Proftpd

Ouvrir le fichier /etc/proftpd.conf et ajouter les lignes suivantes :

# This is a basic ProFTPD configuration file (rename it to 
# 'proftpd.conf' for actual use.  It establishes a single server
# and a single anonymous login. It assumes that you have a user/group
# "nobody" and "ftp" for normal operation and anon.
ServerName "ProFTPD Default Installation"
ServerType standalone
DefaultServer on
# Port 21 is the standard FTP port.
Port 21
# Umask 022 is a good standard umask to prevent new dirs and files
# from being group and world writable.
Umask 022
# To prevent DoS attacks, set the maximum number of child processes
# to 30.  If you need to allow more than 30 concurrent connections
# at once, simply increase this value.  Note that this ONLY works
# in standalone mode, in inetd mode you should use an inetd server
# that allows you to limit maximum number of processes per service
# (such as xinetd).
MaxInstances 30
# Set the user and group under which the server will run.
User nobody
Group nogroup
DefaultRoot ~
# The passwords in MySQL are encrypted using CRYPT
SQLAuthTypes Plaintext Crypt
SQLAuthenticate users* groups*
# used to connect to the database
# databasename@host database_user user_password
SQLConnectInfo ftp@localhost proftpd password
# Here we tell ProFTPd the names of the database columns in the "usertable"
# we want it to interact with. Match the names with those in the db
SQLUserInfo ftpuser userid passwd uid gid homedir shell
# Here we tell ProFTPd the names of the database columns in the "grouptable"
# we want it to interact with. Again the names match with those in the db
SQLGroupInfo ftpgroup groupname gid members
# set min UID and GID - otherwise these are 999 each
SQLMinID 500
# create a user's home directory on demand if it doesn't exist
SQLHomedirOnDemand on
# Update count every time user logs in
SQLLog PASS updatecount
SQLNamedQuery updatecount UPDATE "count=count+1, accessed=now() WHERE userid='%u'" ftpuser
# Update modified everytime user uploads or deletes a file
SQLLog STOR,DELE modified
SQLNamedQuery modified UPDATE "modified=now() WHERE userid='%u'" ftpuser
# User quotas
# ===========
QuotaEngine on
QuotaDirectoryTally on
QuotaDisplayUnits Mb
QuotaShowQuotas on
SQLNamedQuery get-quota-limit SELECT "name, quota_type, per_session, limit_type, bytes_in_avail, bytes_out_avail, bytes_xfer_avail, files_in_avail, files_out_avail, files_xfer_avail FROM ftpquotalimits WHERE name = '%{0}' AND quota_type = '%{1}'"
SQLNamedQuery get-quota-tally SELECT "name, quota_type, bytes_in_used, bytes_out_used, bytes_xfer_used, files_in_used, files_out_used, files_xfer_used FROM ftpquotatallies WHERE name = '%{0}' AND quota_type = '%{1}'"
SQLNamedQuery update-quota-tally UPDATE "bytes_in_used = bytes_in_used + %{0}, bytes_out_used = bytes_out_used + %{1}, bytes_xfer_used = bytes_xfer_used + %{2}, files_in_used = files_in_used + %{3}, files_out_used = files_out_used + %{4}, files_xfer_used = files_xfer_used + %{5} WHERE name = '%{6}' AND quota_type = '%{7}'" ftpquotatallies
SQLNamedQuery insert-quota-tally INSERT "%{0}, %{1}, %{2}, %{3}, %{4}, %{5}, %{6}, %{7}" ftpquotatallies
QuotaLimitTable sql:/get-quota-limit
QuotaTallyTable sql:/get-quota-tally/update-quota-tally/insert-quota-tally
RootLogin off
RequireValidShell off

Soyez sur que vous avez remplacé le password par le mot de passe réel de l'utilisateur proftpd à la ligne SQLConnectInfo!

Redémarrer Proftpd:

/etc/init.d/proftpd restart

5 Remplir la BDD et tester

Pour rempir la base de données, vous pouvez utiliser le shell MySQL :

 

mysql -u root -p
USE ftp;

Dans un premier temps, vous devez créer une entrée dans la table ftpgroup qui contient le groupname, le groupid and le username It contains the groupname, the groupid and the username du ftp group/user que vus avez crée à la fin de la partie (remplacer le groupid par celui approprié) :

INSERT INTO `ftpgroup` (`groupname`, `gid`, `members`) VALUES ('ftpgroup', 2001, 'ftpuser');

Maintenant nous devons créer un nouveau utilisateur virtuel ceci est à faire dans les tables ftpquotalimits et ftpuser :

INSERT INTO `ftpquotalimits` (`name`, `quota_type`, `per_session`, `limit_type`, `bytes_in_avail`, `bytes_out_avail`, `bytes_xfer_avail`, `files_in_avail`, `files_out_avail`, `files_xfer_avail`) VALUES ('exampleuser', 'user', 'true', 'hard', 15728640, 0, 0, 0, 0, 0);
INSERT INTO `ftpuser` (`id`, `userid`, `passwd`, `uid`, `gid`, `homedir`, `shell`, `count`, `accessed`, `modified`) VALUES (1, 'exampleuser', 'secret', 2001, 2001, '/home/www.example.com', '/sbin/nologin', 0, '', '');
 
quit;

(Ne pas oublier de remplacer le group et l'userid 2001 en accord avec ce que vous avez mis précédement).

Maintenant ouvrer votre client FTP et essayer de vous connecter . Avec les paramètres suivant
HOST : server1.example.com (ou l'adresse IP de votre system)
LOGIN : exampleuser
PASSWORD : secret.

Si vous êtes connecté, alors tout va bien!

Maintenant si vous lancer la commande

ls -l /home

Vous devriez voir un répertoire /home/www.example.com qui a été crée automatiquement, et il appartient à ftpuser/ftpgroup.
To leave the MySQL shell, type

quit;

5.1 Administration de la base de données

Pour beaucoup de personnes, il est plus facile d'avoir une interface graphique pour gérer MySQL, vous pouvez donc utiliser phpMyAdmin (dans cette exemple http://server1.example.com/phpmyadmin/).

Cependant pour créer un utilisateur, vous avez seulement besoin de créer les entrées dans les tables ftpquotalimits et ftpuser :

Table ftpuser:

The important columns are these (the others are handled by MySQL or Proftpd automatically, so do not fill these manually!):

* userid: Le nom de l'utilisateur virtuel.
* passwd: Le password non crtypté de l'utilisateur.
* uid: L'userid crée à la fin de la partie 2.
* gid: Le groupeid créer à la fin de la partie 2.
* homedir: Le répertoire de l'utilisateur virtuel. Si il n'existe pas, alors il sera crée lorsque l'utilisateur se connectera la première fois. L'utilisateur virtuel n'aura pas accès aux autres répertoires.
* shell: Défini à ok alors /sbin/nologin est utilisé par défaut.

Table ftpquotalimits :

Les colonnes importantes sont (les autres sont gérées automatiquement pas MySQL et Proftpd):

* name: Le nom de l'utilisateur virtuel.
* quota_type: user ou group. User par défaut.
* per_session: true ou false. true siginifie que les quotas sont effetifs seulement pour la session en cours. Par exemple, si l'utilisateur à un quota de 15 Mo et qu'il a envoyé 15 Mo durant la session, alors il ne peut plus rien envoyé. Mais si il se déconnecte et se reconnecte, il peut à nouveau envoyer des fichiers. false signifie que l'utilisateur a seulement 15 Mo et pas plus même si il se reconnecte.
* limit_type: hard ou soft. hard : impossible de dépasser la limite, soft : peut être dépassé temporairement. Utiliser hard de préférence.
* bytes_in_avail: Limite en octet pour l'envoi (15728640 pour 15 MB). 0 signifie illimité.
* bytes_out_avail: Limite en octet pour le téléchargement. 0 signifie illimité.
* bytes_xfer_avail: Limite du transfer en octet. 0 signifie illimité.
* files_in_avail: Limite du nombre de fichier en envoi. 0 signifie illimité.
* files_out_avail: Limite du nombre de fichier Download limit in files. 0 signifie illimité.
* files_xfer_avail: Tranfer limit in files. 0 signifie illimité.

La table ftpquotatallies est utilisé par proftpd pour gérer les quotas automatiquement.
6 Anonymous FTP

Si vous voulez créer un accès anonyme sur votre ftp, suivez les instructions:
Premièrement vous devez créer un utilisateur nommé anonymous_ftp. L'utilisateur doit avoir un répertoire /home/anonymous_ftp :

groupadd -g 2002 anonymous_ftp
useradd -u 2002 -s /bin/false -d /home/anonymous_ftp -m -c "Anonymous FTP User" -g anonymous_ftp anonymous_ftp

Remplacer 2002 par un grou¯/userid qui est libre sur votre système.
Ensuite créer le répertoire /home/anonymous_ftp/incoming qui permet de stocker les fichiers:

mkdir /home/anonymous_ftp/incoming
chown anonymous_ftp:nogroup /home/anonymous_ftp/incoming

Et ensuite, ouvrer /etc/proftpd.conf et ajouter les lignes suivantes:

<Anonymous ~anonymous_ftp>
User anonymous_ftp   
Group nogroup   
# We want clients to be able to login with "anonymous" as well as "ftp"   
UserAlias anonymous anonymous_ftp   
# Cosmetic changes, all files belongs to ftp user   
DirFakeUser on anonymous_ftp
DirFakeGroup on anonymous_ftp   
RequireValidShell off   
# Limit the maximum number of anonymous logins   
MaxClients 10   
# We want 'welcome.msg' displayed at login, and '.message' displayed   
# in each newly chdired directory.   
DisplayLogin welcome.msg   
DisplayFirstChdir .message   
# Limit WRITE everywhere in the anonymous chroot   
<Directory *>     
<Limit WRITE>       
DenyAll     
</Limit>   
</Directory>   
# Uncomment this if you're brave.   
<Directory incoming>     
# Umask 022 is a good standard umask to prevent new files and dirs     
# (second parm) from being group and world writable.     
Umask 022  022
<Limit READ WRITE>              
DenyAll              
</Limit>             
<Limit STOR>
AllowAll
</Limit>   
</Directory> 
</Anonymous>

Et redémarrer Proftpd:

/etc/init.d/proftpd restart

Maintenant, les utilisateurs anonymes peuvent se logguer pour télécharger des fichiers dans /home/anonymous_ftp, mais les uploads sont limités au seul répertoire /home/anonymous_ftp/incoming et une fois que le fichier est envoyé, il ne peut être lu ou télécharger (l'administrateur doit le déplacer pour le rendre disponible).

Links

Proftpd: http://www.proftpd.org/
MySQL: http://www.mysql.com/
phpMyAdmin: http://www.phpmyadmin.net/