Installer un serveur FTP avec ProFTPd & MySQL

Si vous avez beaucoup d'utilisateurs à ajouter sur votre serveur FTP ou tout simplement la nécessité de pouvoir ajouter/supprimer des utilisateurs facilement sans devoir créer un utilisateur local pour chacun d'entre eux, il est alors intéressant de lier ProFTPd avec une base de donnée MySQL.

Informations

Ce tutoriel se base sur une distribution Linux Debian. L'adresse (hostname) de notre serveur sera ftp.example.com et l'adresse IP de notre serveur sera 192.168.0.100. Il convient donc de remplacer ces informations par celles de votre serveur.

Préambule

Nous allons dans un premier temps mettre à jour notre serveur avec les commandes suivantes.

apt-get update
apt-get upgrade

Pré-requis (Apache, MySQL, phpMyAdmin)

Bien que phpMyAdmin ne soit pas obligatoire, nous l'installons pour des questions de simplicité Si vous avez déjà installé ces paquets sur votre serveur, vous poussez passer à l'étape suivante.

apt-get install mysql-server mysql-client php5 phpmyadmin apache2

Il vous sera demandé de spécifier un mot de passe pour votre utilisateur "root@localhost", celui-ci correspond à l'utilisateur plein pouvoirs par défaut sur votre serveur MySQL, c'est à vous de choisir le mot de passe de votre choix (Pensez à prendre un mot de passe compliqué comportant au moins 8 caractères avec lettres & chiffres ;) )

Ensuite, il vous sera demandé de choisir quel serveur web reconfigurer automatiquement, choisissez apache2 => Cela va créer un alias permettant d'accéder à phpmyadmin via http://ftp.example.com/phpmyadmin.

Installer ProFTPd avec le support MySQL

apt-get install proftpd-mod-mysql

Vous devrez alors choisir sous quel mode faire tourner ProFTPd, nous allons ici choisir standalone. (Voir ci-dessous les modes existants et leur significations)

  • from inetd : le serveur FTP sera démarré à la demande : idéal si peu de connexions
  • standalone : le serveur FTP tournera en permanence, prêt à accepter des connexions à tout moment : idéal si beaucoup de connexions

Créer l'utilisateur & le groupe

Nous allons créer un groupe & un utilisateur sur la machine sur lequel nos utilisateurs FTP seront mappés. Si le userid 2001 n'est pas disponible sur votre système, utilisez en un autre mais pensez à vous en souvenir pour la suite du tutoriel

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

Créer la base de donnée MySQL pour ProFTPd

Vous pouvez soit rentrer les requêtes SQL directement sur phpMyAdmin ou directement dans la console (comme nous allons le voir ci-dessous). Les informations ci-dessous ( nom de la base de données, des tables, etc.) peuvent être modifiés selon vos besoins, mais attention à bien reporter vos modifications dans la suite de ce tutoriel.

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;

Attention ! Remplacez "password" par le mot de passe que vous souhaitez pour votre utilisateur "proftpd" !

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 bigint(20) unsigned NOT NULL default '0',
bytes_out_avail bigint(20) unsigned NOT NULL default '0',
bytes_xfer_avail bigint(20) 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 bigint(20) unsigned NOT NULL default '0',
bytes_out_used bigint(20) unsigned NOT NULL default '0',
bytes_xfer_used bigint(20) 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;

Configurer ProFTPd

Nous allons utiliser nano pour l'édition des fichiers, si vous ne le possédez pas vous pouvez l'installer en utilisant "apt-get install nano" ou vous pouvez également utiliser vi ou tout autre éditeur.

nano /etc/proftpd/modules.conf

Et activer les modules suivants

[...]
# Install proftpd-mod-mysql or proftpd-mod-pgsql to use this
LoadModule mod_sql.c
[...]
# Install proftpd-mod-mysql to use this
LoadModule mod_sql_mysql.c
[...]
# Install proftpd-mod-pgsql or proftpd-mod-mysql to use this
LoadModule mod_quotatab_sql.c
[...]

Maintenant ouvrez un autre fichier, commentez la section correspondant aux quotas & dé-commentez l'inclusion du fichier sql.conf

nano /etc/proftpd/proftpd.conf
[...]
#<IfModule mod_quotatab.c>
#QuotaEngine off
#</IfModule>
[...]
#
# Alternative authentication frameworks
#
#Include /etc/proftpd/ldap.conf
Include /etc/proftpd/sql.conf
[...]

Et enfin, éditez le fichier sql.conf

nano /etc/proftpd/sql.conf

Remplacez tout le contenu du fichier par les lignes ci-dessous en modifiant les identifiants vers la base de donnée SQL (Utilisateur & mot de passe de la ligne SQLConnectInfo

#
# Proftpd sample configuration for SQL-based authentication.
#
# (This is not to be used if you prefer a PAM-based SQL authentication)
#

<IfModule mod_sql.c>
#
# Choose a SQL backend among MySQL or PostgreSQL.
# Both modules are loaded in default configuration, so you have to specify the backend
# or comment out the unused module in /etc/proftpd/modules.conf.
# Use 'mysql' or 'postgres' as possible values.
#
#SQLBackend        mysql
#
#SQLEngine on
#SQLAuthenticate on
#
# Use both a crypted or plaintext password
#SQLAuthTypes Crypt Plaintext
#
# Use a backend-crypted or a crypted password
#SQLAuthTypes Backend Crypt
#
# Connection
#SQLConnectInfo proftpd@sql.example.com proftpd_user proftpd_password
#
# Describes both users/groups tables
#
#SQLUserInfo users userid passwd uid gid homedir shell
#SQLGroupInfo groups groupname gid members
#
DefaultRoot ~

SQLBackend              mysql
# 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
CreateHome 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

</IfModule>

On redémarre le processus ProFTPd

/etc/init.d/proftpd restart

Ajouter les données à la base de données

mysql -u root -p
USE ftp;

Si vous avez changer l'iduser précédemment lors de la création de l'utilisateur local, pensez à le changer dans la requête ci-dessous.

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

Cette étape est facultative, celle-ci permet de mettre en place des quotas d'utilisations sur un utilisateur FTP. Retrouvez les détails des quotas sur le site de ProFTPd

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);

Maintenant, on crée notre utilisateur !

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, '', '');
  • userid: L'identifiant de notre utilisateur FTP (ex: exampleuser).
  • passwd: Mot de passe non crypté de notre utilisateur
  • uid: L'userid de l'utilisateur FTP (ex: 2001).
  • gid: Le groupid du groupe FTP (ex: 2001).
  • homedir: Le dossier de l'utilisateur FTP (ex: /home/www.example.com). Si le dossier n'existe pas, il sera créer automatiquement lors de la première connexion. L'utilisateur est enfermé dans son dossier, celui-ci ne pourra accéder à d'autres dossiers.

Votre serveur FTP est désormais fonctionnel !

Vous avez une question ou une suggestion ? N'hésitez pas à réagir dans les commentaires !