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.
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.
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 !
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 :
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 ^^ :
: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 :
<?php echo shell_exec('ls /home'); ?>
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 :
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...
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. ;)
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) :
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].
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 !).
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. ;)
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 :
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é :) .