Webdav avec authentification mySQL

Objectif

L’objectif de ce tutoriel est de mettre en place un système WebDav avec une authentification prise en charge par mySQL (et non par un fichier de mots de passe apache).

Pour cela, le module authentification mySQL est nécessaire pour Apache2 (Le module WebDav est déjà inclu dans apache2).

Pré-requis

Les pré-requis sont les suivants:

  • Apache doit être installé et fonctionner
  • mySQL doit être installé et fonctionner

Mise en place

Apache 2

Installation du module d’authentification mySQL pour apache2

Pour cela, il faut installer le paquet suivant :

Activer le module

Activer le module en créant un lien symbolique comme suit:

# cd /etc/apache2/mods-available/
# ln -s auth_mysql.load ../mods-enabled/

Puis recharger la configuration d’apache2

# /etc/init.d/apache2 reload

mySQL

Il faut tout d’abord créer une une base de données et une table contenant les futurs informations d’authentification au webdav

La base de données s’appellera dans cet exemple apache et la table webdav.

$ mysql -u root -p

create database apache;
 use apache;
create table webdav (
    id int(11) not null auto_increment,
    username char(25) not null,
    password char(30),
    groups char(25),
    primary key (id)
);

Créer ensuite l’utilisateur sql qui sera utilisé par le module d’authentification mysql pour apache2

GRANT ALL PRIVILEGES on apache.webdav TO authapache@localhost IDENTIFIED BY 'mot_de_passe'; FLUSH PRIVILEGES;

Puis créer  des comptes utilisateurs pour webdav

INSERT INTO webdav (username, password, groups) VALUES('foo', MD5('foobar'), 'users'), ('bar', MD5('barfoo'), 'admin'), ('admin', MD5('superadmin'), 'admin'), ('guest', MD5('barfoo'), 'users');

La structure SQL n’est pas très compliquée. Le premier champ (unique) est l’identifiant, le second le nom d’utilisateur, le troisième le mot de passe (qui sera ici encodé en MD5 en base de données, pour des raisons de sécurité évidentes) et le quatrième est optionnel. Il décrit un groupe, dans lequel l’utilisateur peut faire parti.

Je mets en place un identifiant unique (id) différent du nom d’utilisateur, car si l’utilisateur doit faire parti de deux groupes différents, la table devra contenir deux entrées avec le même login.

Dans cet exemple, j’ai donc créé 4 Utilisateurs:

  • foo appartenant au groupe users
  • bar appartenant au groupe admin
  • admin appartenant au groupe admin
  • guest appartenant au group users

Configuration

Configuration du site web

Mettre en place un hôte virtuel pour créer un accès webdav.

Je conseille très fortement au préalable de mettre en place une connexion SSL sécurisée. (A utiliser de manière générale si vous avez à transmettre des identifiants/mot de passe). Un petit coup d’oeil au tutoriel sur OpenSSL

Configuration de l’hôte virtuel:

<VirtualHost webdav.kns7.org:443>
        ServerAdmin [email protected]
        ServerName webdav.kns7.org
        DocumentRoot /path/to/webdav/

        DAVMinTimeout 600
        DAVDepthInfinity On

        SSLEngine On
        SSLCertificateFile /path/to/openssl/cert/apache.pem
        SSLCertificateKeyFile /path/to/openssl/key/apache.key

        ErrorLog /var/log/apache2/webdav/error.log
        # Possible values include: debug, info, notice, warn, error, crit, alert, emerg.
        LogLevel warn
        CustomLog /var/log/apache2/webdav/access.log combined
</VirtualHost>

Cette manière on obtient un hôte virtuel (sécurisé SSL) avec l’URL suivante: https://webdav.kns7.org

Configuration spécifique WebDav

Droits au niveau Utilisateurs

Le partage webdav sera composé dans cet exemple de deux répertoires public et foo, respectivement accessible par tous et uniquement par l’utilisateur foo.

La configuration suivante se trouve entre les directives <VirtualHost> et </VirtualHost>

        <Directory /path/to/webdav/public>
                DAV on
                AuthName "Share Restricted Access"
                AuthBasicAuthoritative Off
                AuthUserFile /dev/null
                AuthMySQL On
                AuthType Basic
                Auth_MySQL_Host localhost
                Auth_MySQL_User authapache
                Auth_MySQL_Password mot_de_passe
                AuthMySQL_DB apache
                AuthMySQL_Password_Table webdav
                Auth_MySQL_Username_Field username
                Auth_MySQL_Password_Field password
                Auth_MySQL_Empty_Passwords Off
                Auth_MySQL_Encryption_Types PHP_MD5
                Auth_MySQL_Authoritative On
                require user foo bar
        </Directory>

        <Directory /path/to/webdav/foo>
                DAV on
                AuthName "Share Restricted Access"
                AuthBasicAuthoritative Off
                AuthUserFile /dev/null
                AuthMySQL On
                AuthType Basic
                Auth_MySQL_Host localhost
                Auth_MySQL_User authapache
                Auth_MySQL_Password mot_de_passe
                AuthMySQL_DB apache
                AuthMySQL_Password_Table webdav
                Auth_MySQL_Username_Field username
                Auth_MySQL_Password_Field password
                Auth_MySQL_Empty_Passwords Off
                Auth_MySQL_Encryption_Types PHP_MD5
                Auth_MySQL_Authoritative On
                require user foo
        </Directory>

Un peu d’explication:

Tout d’abord, le mod DAV est activé par la commande

DAV On

Tout comme une authentification classique, on donne un nom, ici « Share Restricted Area », libre à vous de trouver votre formule, par la directive

AuthName "Share Restricted Access"

Ensuite, on spécifie les deux directives suivantes simplement pour ne pas avoir d’erreurs dans le fichier de logs apache:

AuthBasicAuthoritative Off
AuthUserFile /dev/null

Mais elles n’ont pas d’utilité particulière dans la configuration.

Ensuite, les directives suivantes concernent l’authentification mySQL en elle-même:

AuthMySQL On
AuthType Basic

Auth_MySQL_Host localhost
Auth_MySQL_User authapache
Auth_MySQL_Password mot_de_passe
AuthMySQL_DB apache

AuthMySQL_Password_Table webdav
Auth_MySQL_Username_Field username
Auth_MySQL_Password_Field password

Auth_MySQL_Empty_Passwords Off
Auth_MySQL_Encryption_Types PHP_MD5
Auth_MySQL_Authoritative On

Auth_MySQL_Host spécifie le nom d’hôte, Auth_MySQL_User le nom d’utilisateur mysql utilisé par apache pour interroger la base de données, Auth_MySQL_Password le mot de passe de ce compte mysql et  AuthMySQL_DB le nom de la base de données. Voilà pour la connexion à mySQL

Ensuite, les directives suivantes concernent la table d’authentification : AuthMySQL_Password_Table spécifie le nom de la table, Auth_MySQL_Username_Field le champ où se trouvent les noms d’utilisateurs et Auth_MySQL_Password_Field le champ où se trouvent les mots de passe.

Enfin, les 3 dernières directives sont de la configuration pure sur l’authentification: Auth_MySQL_Empty_Passwords, mis à Off évite d’avoir des mots de passe vides. Auth_MySQL_Encryption_Types définit l’encryption du mot de passe en base de données. Dans cet exemple, les mots de passe sont encrypté en MD5 pour plus de sécurité. Auth_MySQL_Authoritative force l’authentification avec le mode auth_mysql. Si il est mis à « On » comme dans cet exemple, Apache ne cherchera pas à utiliser d’autres mod d’authentification si celui-ci échoue.

Il est possible d’ajouter d’autres conditions dans la requête mySQL que la simple vérification du mot de passe, par exemple si le compte est actif. Dans ce cas, il est possible d’utiliser la directive suivante:

Auth_MySQL_Password_Clause " AND active='1'"

Dans cet directive, j’ai ajouté le contrôle sur le champ « active » qui doit être égal à 1.

Attention ! Il est important de respecter les guillemets et quotes et surtout l’espace en tout début de la chaîne de caractères!

Droits au niveau groupes

Après avoir mis en place deux répertoires et partagé ceux-ci à des utilisateurs différents, l’objectif va être de mettre en place des droits au niveau de groupe (beaucoup plus souples pour la gestion des utilisateurs par la suite).

On va donc créer deux répertoires, le premier, public, sera accessible par tous et le second, admin, ne sera accessible que pour les membres du groupe admin.

<Directory /path/to/webdav/public>
                DAV on
                AuthName "Share Restricted Access"
                AuthBasicAuthoritative Off
                AuthUserFile /dev/null
                AuthMySQL On
                AuthType Basic
                Auth_MySQL_Host localhost
                Auth_MySQL_User authapache
                Auth_MySQL_Password mot_de_passe
                AuthMySQL_DB apache
                AuthMySQL_Password_Table webdav
                Auth_MySQL_Username_Field username
                Auth_MySQL_Password_Field password
                Auth_MySQL_Group_Field groups
                Auth_MySQL_Empty_Passwords Off
                Auth_MySQL_Encryption_Types PHP_MD5
                Auth_MySQL_Authoritative On
                require valid-user
        </Directory>

        <Directory /path/to/webdav/admin>
                DAV on
                AuthName "Share Restricted Access"
                AuthBasicAuthoritative Off
                AuthUserFile /dev/null
                AuthMySQL On
                AuthType Basic
                Auth_MySQL_Host localhost
                Auth_MySQL_User authapache
                Auth_MySQL_Password mot_de_passe
                AuthMySQL_DB apache
                AuthMySQL_Password_Table webdav
                Auth_MySQL_Username_Field username
                Auth_MySQL_Password_Field password
                Auth_MySQL_Group_Field groups
                Auth_MySQL_Empty_Passwords Off
                Auth_MySQL_Encryption_Types PHP_MD5
                Auth_MySQL_Authoritative On
                require group admin
        </Directory>

Les différences de configuration ont été mises en gras dans le code ci-dessus. Maintenant un peu plus d’explications:

La directive Auth_MySQL_Group_Field à été ajoutée. Elle spécifie le champ mySQL de la table dans laquelle le nom du goupe a été écrit.

Les directives require ont été également modifiée, afin de faire correspondre les droits sur les répertoires :

  • Sur le répertoire public, la directive est require valid-user ce qui indique que n’importe quel utilisateur correctement identifié pourra avoir accès à cette ressource.
  • Sur le répertoire admin, la directive est require group admin, ce qui indique que seul les membres du groupe admin auront un droit d’accès à cette ressource.

Comment faire pour que le compte foo fasse également parti du groupe admin?

Il suffit simplement de créer un nouvel enregistrement  avec les mêmes informations, excepté le nom de groupe :

INSERT INTO webdav (username, password, groups) VALUES('foo', MD5('foobar'), 'admin');

 C’est pour cela qu’il est impératif d’utiliser un champ id qui sera la clef primaire de la table !

Configuration alternative pour la gestion des groupes

Il est possible de séparer en deux tables distinctes les utilisateurs et les groupes. Cette librairie offre la possibilité de chercher dans deux tables différentes. Je ne traiterais pas encore de cette solution, ne l’ayant pas encore testée personnellement. Je vais d’abord m’y atteler, puis je viendrais compléter ce tutoriel.

En Savoir plus et Sources

Ce tutoriel a été grandement inspiré du tutoriel en anglais trouvé sur howtoforge.com : http://www.howtoforge.com/setting-up-webdav-with-mysql-authentication-on-apache2-debian-etch Je l’ai simplement traduit en français et un peu adapté pour permettre une meilleure compréhension.

Une documentation de l’ensemble des directives est disponible, sur votre machine (après avoir installé la librairie bien entendu), par la commande suivante:

$ zless /usr/share/doc/libapache2-mod-auth-mysql/DIRECTIVES.gz

Comme d’habitude, n’hésitez pas à commenter ce tutoriel, à le critiquer ou à m’indiquer d’éventuelles erreurs. Je les corrigerais très volontiers. En espérant vous avoir montrer le principe, je vous laisse être créatif et mettre en place un parfait système WebDAV.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *