Un serveur d'hébergement multiutilisateur sous Linux
Last updated on Friday, October 3, 2014

Ce cours est visible gratuitement en ligne.

Got it!

Introduction du cours

Bonjour !

Le but de ce tuto est de vous apprendre à installer un serveur Linux qui permette l'hébergement de plusieurs utilisateurs. Chaque utilisateur aura un accès FTP, un dossier personnel, et un dossier web.

Debian

Je vous souhaite une bonne lecture !

Prérequis

Ceci étant dit, nous pouvons commencer !

Avant toute chose, assurez-vous d'avoir un fichier /etc/apt/sources.list bien configuré et un système à jour !

Voici un exemple de sources.list :

#Attention, ce sources.list est fait pour la version "testing" de Debian, c'est-à-dire la future version stable.
#Les paquets présents dans ces dépôts sont testés, mais pas totalement sûrs du point de vue de la stabilité.
deb http://mir1.ovh.net/debian/ testing main non-free contrib
deb http://security.debian.org/ testing/updates main contrib non-free

Pour la version stable, il faut remplacer les testing par des etch.

Il suffit ensuite de taper en console deux commandes pour avoir un système à jour !

aptitude update
aptitude full-upgrade

Par souci de simplicité, on va considérer que l'on est dans un réseau local qui contient notre serveur et un autre ordinateur qui permettra de tester le serveur.
On va dire que l'adresse IP du serveur sera 192.168.0.100, même si ça n'a pas d'importance pourvu qu'on la connaisse.

Installer le serveur web : Apache 2

Nous allons commencer par installer le serveur web !
On va donc installer Apache 2 à l'aide de cette commande (toutes les commandes sont à faire en tant que root) :

aptitude install apache2

Maintenant qu'Apache est installé, on va le tester !

À partir de votre autre ordinateur, lancez un navigateur web et accédez à l'URL du serveur : http://192.168.0.100.

Logiquement, vous obtenez un énorme It works!

On va aller dans un des fichiers de configuration :

nano /etc/apache2/sites-available/default

Il suffira d'ajouter un dièse # au début de la ligne RedirectMatch ^/$ /apache2-default/ pour la commenter.

On redémarre Apache :

/etc/init.d/apache2 restart

On réessaye d'aller sur http://192.168.0.100.
Et là, magie ! Au lieu d'avoir le message de tout à l'heure, on a une arborescence qui contient uniquement le dossier apache2-default.

Ce dossier étant inutile, on va le supprimer :pirate: .
Par défaut, Apache va chercher les pages dans /var/www/.
On fait donc :

rm -r /var/www/apache2-default

Maintenant que Apache 2 fonctionne, occupons-nous du mod UserDir !

Configurer Apache 2 avec le mod UserDir

Le mod UserDir est un mod installé par défaut avec Apache 2. Il permet, une fois configuré, de faire correspondre une URL de type http://192.168.0.100/~utilisateur à un dossier /home/utilisateur, par exemple.

L'avantage est qu'il ne faut pas changer la configuration d'Apache 2 à chaque fois qu'on ajoute un utilisateur : à chaque fois qu'une URL comme la précédente sera appelée, Apache 2 vérifiera si le dossier correspondant existe sur le serveur. S'il existe, on accèdera à son contenu, sinon, on obtiendra l'erreur 404.

Pour commencer, activons le mod avec la commande suivante :

a2enmod userdir

Un message nous avertit qu'il faut recharger la configuration d'Apache, mais comme nous allons la modifier par la suite, nous la rechargerons plus tard.

Il faut ensuite configurer ce mod. Voici donc le fichier /etc/apache2/mods-available/userdir.conf tel que vous devez l'avoir par défaut :

<IfModule mod_userdir.c>
        UserDir public_html
        UserDir disabled root
 
        <Directory /home/*/public_html>
                AllowOverride FileInfo AuthConfig Limit
                Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
        </Directory>
</IfModule>

UserDir public_html signifie que l'adresse http://192.168.0.100/~utilisateur affichera le contenu du dossier [Répertoire home de utilisateur]/public_html. L'utilisateur doit donc être un utilisateur système valide !!
Pour ne pas avoir à créer à chaque fois un utilisateur système, on peut remplacer cette ligne par UserDir /home/*/public_html. Du coup, il suffit juste de créer un dossier du nom de l'utilisateur dans /home ! :)

UserDir disabled [noms d'utilisateurs] permet de désactiver la fonctionnalité UserDir pour certains utilisateurs.

Le reste du fichier de configuration sert à définir les options sur les dossiers des utilisateurs.

Voici donc une version de ce même fichier plus optimisée pour nos besoins ^^ :

<IfModule mod_userdir.c>
        UserDir /home/*/public_html
 
        <Directory /home/*/public_html>
                AllowOverride FileInfo AuthConfig Limit
                Options MultiViews Indexes IncludesNoExec
                IndexOptions FoldersFirst FancyIndexing IgnoreCase
        </Directory>
</IfModule>

Vous pouvez maintenant recharger la configuration d'Apache 2 et tester tout ça !!

/etc/init.d/apache2 reload

À ce stade, nous pouvons donc créer un utilisateur web en créant 2 dossiers :

  • le dossier /home/utilisateur qui sera la partie privée de l'utilisateur ;

  • le dossier /home/utilisateur/public_html qui sera la partie publique accessible avec l'adresse http://192.168.0.100/~utilisateur.

Installer PHP5

:magicien: PHP5 ne résistera pas très longtemps à un simple

aptitude install php5

Cette étape est rapide puisqu'une fois PHP5 installé, nos utilisateurs web peuvent l'utiliser.
Vous pouvez reprendre le test que nous avons fait tout à l'heure pour vérifier.

Cependant, si vous poussez un peu ces tests, vous allez vous apercevoir (avec stupeur :p ) qu'il est parfaitement possible pour un utilisateur d'écrire un script PHP qui va voir chez le voisin... ce qui pose un gros problème de sécurité !

Nous allons donc devoir enfermer le PHP de chaque utilisateur dans son dossier respectif. Pour cela, il suffit d'ajouter une petite ligne de rien du tout dans notre fichier /etc/apache2/mods-available/userdir.conf. On obtient ceci :

<IfModule mod_userdir.c>
        UserDir /home/*/public_html
 
        <Directory /home/*/public_html>
                AllowOverride FileInfo AuthConfig Limit
                Options MultiViews Indexes IncludesNoExec
                IndexOptions FoldersFirst FancyIndexing IgnoreCase
                php_admin_value open_basedir ".." # <-- voici la nouvelle ligne
        </Directory>
</IfModule>

En effet, il existe une fonction PHP nommée shell_exec() qui permet d'exécuter des commandes shell (sous l'utilisateur www-data, l'utilisateur d'Apache 2).
Il est donc possible de créer un script PHP dans son répertoire d'utilisateur web :

 

On a donc accès à la liste des utilisateurs !

Heureusement, PHP est doté une fonction, le safe_mode, qui permet d'interdire les fonctions de ce type. Notre fichier /etc/apache2/mods-available/userdir.conf devient donc :

<IfModule mod_userdir.c>
        UserDir /home/*/public_html
 
        <Directory /home/*/public_html>
                AllowOverride FileInfo AuthConfig Limit
                Options MultiViews Indexes IncludesNoExec
                IndexOptions FoldersFirst FancyIndexing IgnoreCase
                php_admin_value safe_mode "1"
                php_admin_value open_basedir ".."
        </Directory>
</IfModule>

Et voilà ! Nos utilisateurs peuvent mettre du PHP dans leur dossier public_html sans pour autant poser de problèmes de sécurité. :)

Installer le serveur de base de données : MySQL

Il est l'heure d'installer MySQL, pour que nos utilisateurs aient leur base de données (MySQL servira également pour vsFTPd).

aptitude install mysql-server php5-mysql

On exécute dans la foulée le script fourni avec MySQL qui permet de sécuriser la configuration de ce dernier :

mysql_secure_installation

Histoire de ne pas tout avoir à faire en console, on installe PHPMyAdmin :

aptitude install phpmyadmin

Allez ensuite avec un navigateur à l'adresse http://192.168.0.100/phpmyadmin. Mettez la langue en français, le nom d'utilisateur (root) et votre mot de passe MySQL.

Direction la page Privilèges, puis Ajouter un utilisateur. Indiquez ftp comme nom d'utilisateur, sélectionnez Local dans la liste déroulante Serveur, et indiquez un mot de passe, compliqué si possible, car il ne sera utilisé que par des scripts (vous pouvez utiliser le bouton Générer). Cochez le bouton radio Créer une base portant son nom et donner à cet utilisateur tous les privilèges sur cette base et validez.

Retournez sur la page Privilèges (il y a un onglet en haut), et cliquez sur recharger les privilèges.

MySQL est maintenant installé, configuré, et nous avons créé un utilisateur et une base de données pour le serveur FTP...

Installer le serveur FTP : vsFTPd

On installe maintenant vsFTPd et le module d'authentification par MySQL !

aptitude install vsftpd libpam-mysql

Remplaçons le fichier /etc/vsftpd.conf par celui-ci :

# 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" active les utilisateurs virtuels
# "guest_username" fait correspondre tous les utilisateurs virtuels à l'utilisateur d'Apache 2
guest_enable=YES
guest_username=www-data

# On définit les droits par défaut des fichiers uploadés
anon_umask=022

# On enferme les utilisateurs virtuels dans leur dossier
chroot_local_user=YES

# On définit le nombre maximum de sessions à 100
# On définit le nombre maximum de sessions par IP à 5
max_clients=100
max_per_ip=5

####################################
# 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


# Permet d'utiliser les configurations individuelles pour chaque utilisateur
user_config_dir=/etc/vsftpd

# Définir la plage de ports utilisée par le mode passif
pasv_min_port=20000
pasv_max_port=20050

# Message d'accueil
ftpd_banner=Bienvenue sur ce serveur FTP !

# Autoriser les utilisateurs virtuels à changer les permissions de leurs fichiers
chmod_enable=YES
virtual_use_local_privs=YES

# Utiliser le temps local et non pas le temps universel (UTC)
use_localtime=YES

# Activation du log
xferlog_enable=YES
log_ftp_protocol=YES

Ce fichier étant commenté, je ne m'étends pas dessus. ;)

Configurer vsFTPd avec pam-mysql

vsFTPd va devoir accéder à la liste des utilisateurs, qui sera placée dans notre base de donnée MySQL. Le module pam-mysql permet de faire ça. :)

On va tout d'abord retourner sur PHPMyAdmin, se logger avec l'utilisateur ftp, et sélectionner la base de donnée ftp dans le menu de gauche. Ensuite, l'onglet SQL permet de coller et d'exécuter ce code :

CREATE TABLE `ftp`.`users` (
`name` TEXT NOT NULL ,
 `pass` TEXT NOT NULL 
) ENGINE = MYISAM

Notre table étant créée, on va remplacer le fichier /etc/pam.d/vsftpd par le suivant (qui contient les informations d'accès à cette table) :

auth required pam_mysql.so host=localhost user=ftp passwd=votre_pass db=ftp table=users usercolumn=name passwdcolumn=pass crypt=1
account required pam_mysql.so host=localhost user=ftp passwd=votre_pass db=ftp table=users usercolumn=name passwdcolumn=pass crypt=1

On redémarre le serveur FTP !

/etc/init.d/vsftpd restart

On va maintenant ajouter un utilisateur pour tester tout ça !

On repasse sur PHPMyAdmin (toujours avec l'utilisateur ftp) et on va ajouter un nouvel enregistrement à notre table fraîchement créée (onglet Insérer après avoir sélectionné la table). On renseigne un nom d'utilisateur et un mot de passe. Le mot de passe doit être crypté ! Il suffit de sélectionner ENCRYPT dans la liste déroulante, lors de l'insertion.

Il faut maintenant créer le fichier de configuration de l'utilisateur : /etc/vsftpd/[nom d'utilisateur].

anon_world_readable_only=NO
local_root=/home/utilisateur
write_enable=YES
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES
hide_file=(none)
force_dot_files=YES

Pour le détail, je vous laisse la page de documentation : http://vsftpd.beasts.org/vsftpd_conf.html. Sachez qu'en gros, on définit le dossier dans lequel l'utilisateur est enfermé, on l'autorise à y écrire, et on lui permet de voir les fichiers cachés.

Et pour finir, le plus important : on crée le dossier de l'utilisateur (avec les bons droits !).

mkdir /home/[nom d'utilisateur]
chown -R www-data.www-data /home/[nom d'utilisateur]
chmod -R 700 /home/[nom d'utilisateur]

Vous pouvez maintenant tenter une connexion à votre serveur FTP !

Les scripts de gestion des comptes

Le plus gros a été fait ! L'idéal serait maintenant de créer des scripts qui permettent d'ajouter / d'enlever des utilisateurs à notre place.

Voici maintenant ma solution :

adduser.sh

#!/bin/sh
 
# Informations à compléter
pass_mysql_ftp=mot_de_passe_de_l'utilisateur_mysql_"ftp"
pass_mysql_root=mot_de_passe_de_l'utilisateur_mysql_"root"
 
# On demande la saisie d'un nom d'utilisateur et du mot de passe (2 fois)
echo -n "Nom d'utilisateur : "
read nom
echo "Mot de passe : "
read -s pass
echo "Mot de passe (le retour) : "
read -s pass2
 
# On vérifie que les 2 mots de passe soient identiques
if test $pass = $pass2 ; then
 
        # On vérifie qu'il n'existe pas déjà un autre utilisateur du même nom
        if test -d /home/$nom ; then
                echo "L'utilisateur existe deja"
        else
                # On crée les dossiers et on fixe les droits
                mkdir /home/$nom
                mkdir /home/$nom/public_html
                chown -R www-data.www-data /home/$nom
                chmod -R 700 /home/$nom
 
                # On crée le fichier de configuration pour vsFTPd
                echo "anon_world_readable_only=NO" > /etc/vsftpd/$nom
                echo "local_root=/home/$nom" >> /etc/vsftpd/$nom
                echo "write_enable=YES" >> /etc/vsftpd/$nom
                echo "anon_upload_enable=YES" >> /etc/vsftpd/$nom
                echo "anon_mkdir_write_enable=YES" >> /etc/vsftpd/$nom
                echo "anon_other_write_enable=YES" >> /etc/vsftpd/$nom
                echo "hide_file=(none)" >> /etc/vsftpd/$nom
                echo "force_dot_files=YES" >> /etc/vsftpd/$nom
 
                # On ajoute l'utilisateur dans la base de données
                mysql -u ftp -p"$pass_mysql_ftp" -D ftp -e "INSERT INTO users (name ,pass) VALUES ('$nom', ENCRYPT( '$pass' ));"
 
                # On crée une base de données où l'utilisateur est tout-puissant
                mysql -u root -p"$pass_mysql_root" -e "CREATE USER '$nom'@'localhost' IDENTIFIED BY '$pass';GRANT USAGE ON *.* TO '$nom'@'localhost' IDENTIFIED BY '$pass' WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0;CREATE DATABASE IF NOT EXISTS $nom;GRANT ALL PRIVILEGES ON $nom.* TO '$nom'@'localhost';"
                
                echo "Utilisateur ajoute avec succes"
        fi
 
else
 
        echo "Les 2 mots de passe ne sont pas identiques"
 
fi

deluser.sh

#!/bin/sh
 
# Informations à compléter
pass_mysql_ftp=mot_de_passe_de_l'utilisateur_mysql_"ftp"
pass_mysql_root=mot_de_passe_de_l'utilisateur_mysql_"root"
 
# On demande la saisie du nom de l'utilisateur à supprimer
echo -n "Nom d'utilisateur : "
read nom
 
# On vérifie qu'il existe
if test -d /home/$nom ; then
 
        # On le supprime de la liste des utilisateurs de vsFTPd
        mysql -u ftp -p"$pass_mysql_ftp" -D ftp -e "DELETE FROM users WHERE name='$nom';"
 
        # On supprime son compte et sa base de donnée MySQL
        mysql -u root -p"$pass_mysql_root" -e "DROP USER $nom@'localhost';DROP DATABASE IF EXISTS $nom;"
 
        # On supprime son fichier de configuration vsFTPd
        rm -f /etc/vsftpd/$nom
 
        # On supprime son dossier
        rm -fr /home/$nom
 
        echo "Utilisateur DETRUIT"
else
        echo "L'utilisateur n'existe pas"
fi

Vous voilà donc en possession d'un système d'hébergement multiutilisateurs ! :D
Je vous propose quelques annexes, pour préciser ou améliorer certains points. ;)

Annexes

Sécurité

On va donc résumer quels sont nos fichiers / dossiers et leurs permissions :

  • /home/utilisateur : Propriétairewww-data / Groupewww-data / Permissions700 (www-data peut tout faire) ;

  • /etc/vsftpd : Propriétaireroot / Groupewww-data / Permissions740 (root peut tout faire ; www-data peut lire) ;

  • /etc/vsftpd/utilisateur : Propriétaireroot / Groupewww-data / Permissions740 ;

  • /root/adduser.sh : Propriétaireroot / Grouperoot / Permissions700 ;

  • /root/deluser.sh : Propriétaireroot / Grouperoot / Permissions700.

Changer le propriétaire et le groupe d'un fichier : chown proprietaire.groupe fichier
Changer le propriétaire et le groupe d'un dossier (et de son contenu) : chown -R proprietaire.groupe dossier
Changer les permissions d'un fichier : chmod permissions fichier
Changer les permissions d'un dossier (et de son contenu) : chmod -R permissions dossier

Administrer les fichiers des utilisateurs

Posons deux choses :

  • vous voulez pouvoir gérer les fichiers des utilisateurs situés dans le dossier /home avec un client FTP ;

  • Vous voulez aussi pouvoir gérer votre page d'accueil qui, elle, se trouve dans /var/www.

On va donc créer un compte admin dont le dossier est /home. Il ne faut surtout pas utiliser le script, mais bien créer le fichier de configuration /etc/vsftpd/admin à la main et ajouter l'utilisateur admin dans la base de donnée avec PHPMyAdmin.

Nous avons donc un compte FTP admin pouvant naviguer et écrire dans les dossiers des utilisateurs.
On va maintenant monter le dossier /var/www dans le dossier /home/www que nous créerons. Le dossier /home/www sera donc une sorte de redirection vers /var/www.

On crée le dossier /home/www et on règle ses permissions, ainsi que celle de /var/www :

mkdir /home/www
chown -R www-data.www-data /home/www
chmod -R 700 /home/www
chown -R www-data.www-data /var/www
chmod -R 700 /var/www

On va ensuite modifier le fichier /etc/fstab, qui contient les informations sur les montages à faire au démarrage, et insérer la ligne suivante :

/var/www        /home/www        none        bind        0        0

On n'a plus qu'à faire un petit mount -a pour que les modifications soient appliquées.

On a alors accès à la racine du serveur web avec notre compte admin ! :D

Voir l'espace disque occupé

Encore une idée d'amélioration : créer un script permettant de connaître l'espace disque occupé par chaque utilisateur.
La solution qui me semble la meilleure est tout simplement d'afficher séparément la taille de tous les dossiers contenus dans le dossier /home.

Voici donc une application de cette solution :

#!/bin/sh
 
# Pour chaque dossier contenu dans /home
for dir in /home/* ; do
        
        # Si le dossier n'est pas /home/www
        if test $dir != "/home/www" ; then
 
                # On affiche sa taille
                du -hs $dir
        else
                du -hs /var/www
        fi
done

Installer des extensions PHP

Si vous avez besoin d'installer certaines extensions à PHP, comme GD pour pouvoir traiter des images par exemple, il suffit juste de l'installer avec aptitude de la manière suivante :

aptitude install php5-gd

Les fichiers .htaccess

Les fichiers .htaccess permettent de modifier la configuration d'Apache 2 de manière exceptionnelle, c'est-à-dire seulement pour le dossier dans lequel le fichier .htaccess se trouve et sans pour autant avoir à modifier le fichier de configuration principal d'Apache 2.

Pour résumer, un .htaccess peut permettre à un utilisateur de modifier la configuration d'Apache 2, avec certaines limites.

Ces limites sont définies dans notre fichier /etc/apache2/mods-available/userdir.conf :

AllowOverride FileInfo AuthConfig Limit

Pour plus d'informations sur la commande AllowOverride, jetez un coup d'oeil à la documentation d'Apache 2.2 ! ;)

J'espère que ce tuto vous a été profitable !

Vous pouvez me contacter par MP si vous avez un problème.

Je remercie vincent1870 pour sa correction de qualité malgré le fait qu'il était occupé :) .

How courses work

  • 1

    You have now access to the course contents and exercises.

  • 2

    You will advance in the course week by week. Each week, you will work on one part of the course.

  • !

    Exercises must be completed within one week. The completion deadline will be announced at the start of each new part in the course. You must complete the exercises to get your certificate of achievement.

  • 3

    At the end of the course, you will get an email with your results. You will also get a certificate of achievement if you are a

Example of certificate of achievement
Example of certificate of achievement