Hau weg die .htpasswd: Apache Authentifizierung mit mod-auth-mysql

Noch aus den Urzeiten der Webserver stammt die HTTP-Authentifizierung mit der man sich im Browser gegenüber dem Webserver als jemand Berechtigter ausweisen kann. Das Verfahren mag ein wenig angestaubt wirken und die Fenster könnten sie auch mal schöner Designen aber solange es keinen Nachfolger für die RFC 2617 gibt hat sich etwas an der Art wie man die Passwörter speichert geändert. Fast alle Tutorials zur Absicherung des Indianers erklären wie ihr mithilfe von htpasswd eine Datei erzeugen und für den Ordner mit den Partyfotos das man an eine Handvoll Leute weitergibt reicht das ja auch vollkommen aus. Aber wenn man ein paar Subversion Repos und Trac Installationen mit einem haufen Usern hat wünscht man sich eine Lösung bei der die User in einer Datenbank liegen und man das ganze über ein Webinterface verwalten kann. Und genau das ist mit dem Apache Modul mod-auth-mysql.

Datenbank

User und Datenbank anlegen
Du kannst einen eigenen Benutzer für mod-auth-mysql anlegen, musst es aber nicht.

CREATE USER 'mysqlauth'@'localhost' IDENTIFIED BY 'passwort'
GRANT USAGE ON * . * TO 'mysqlauth'@'localhost' IDENTIFIED BY 'passwort';
CREATE DATABASE IF NOT EXISTS `mysqlauth` ;
GRANT ALL PRIVILEGES ON `mysqlauth` . * TO 'mysqlauth'@'localhost';

Tabellen anlegen
Die Tabellenstruktur basiert auf der von http://www.arune.se/tech:svnwithmysqlauth mit der Erweitung um die Virtuellen Gruppen und die Views für den .htpasswd Ersatz.

CREATE TABLE IF NOT EXISTS `groups` (
`groupid` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`groupname` VARCHAR(50) NOT NULL,
`groupvirtual` VARCHAR(150) NOT NULL,
PRIMARY KEY  (`groupid`),
UNIQUE KEY `name` (`groupname`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS `usergroup` (
`userid` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`groupid` INT(10) UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY  (`userid`,`groupid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS `users` (
`userid` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`username` VARCHAR(50) NOT NULL,
`password` VARCHAR(60) NOT NULL,
`firstname` VARCHAR(255) NOT NULL,
`lastname` VARCHAR(255) NOT NULL,
`email` VARCHAR(255) NOT NULL,
PRIMARY KEY  (`userid`),
UNIQUE KEY `login` (`username`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

CREATE VIEW `mysqlauth` AS SELECT `users`.*,`groups`.*
FROM ((`users` JOIN `groups`) JOIN `usergroup`)
WHERE ((`usergroup`.`userid` = `users`.`userid`)
AND (`groups`.`groupid` = `usergroup`.`groupid`));

Apache 2 mit mod-auth-mysql unter Debian/Ubuntu

mod-auth-mysql
Die Installation des Moduls geht recht einfach über apt-get:

sudo apt-get install libapache2-mod-auth-mysql

Es gibt auch ein “mod_auth_mysql” Modul für Fedora, RHEL bzw. CentOS das soweit ich das in Erfahrung bringen konnte auf modauthmysql.sourceforge.net basiert, während man bei Debian ein eigenes Repository pflegt. Wenn deine Distribution das Modul nicht mitliefert kannst du dir auch das mod_auth_mysql Modul von WordPress.org übersetzen. All diese Module unterscheiden sich aber durch die Syntax die man in die httpd.conf von Apache verwenden muss. Bedenke das wenn du dieses Howto auf eine andere Distribution bzw ein anderes mod-auth-mysql Modul anwenden möchtest.

Folgender Code ist für den <Location > Teil deiner httpd.conf:

DAV svn
AuthType Basic
AuthName "lala"
AuthUserFile /dev/null
require valid-user
AuthMYSQL on
AuthBasicAuthoritative off
AuthMySQL_Authoritative on
AuthMySQL_Host localhost
AuthMySQL_User mysqlauth
AuthMySQL_Password ******
AuthMySQL_DB svnauth
AuthMySQL_Password_Table mysqlauth_user
AuthMySQL_Username_Field username
AuthMySQL_Password_Field password
AuthMySQL_Empty_Passwords off
AuthMySQL_Encryption_Types Crypt_DES PHP_MD5

Nginx mit nginx_auth_mysql

Das ganze geht natürlich auch mit nginx. Der Vorteil ist, das man einen Request schon am Reverse Proxy ablehnen kann und gar nicht erst den Apache im Hintergrund belästigen muss. Jedoch gibt es kein eingebautes Modul um gegen mySQL zu authentifizieren aber du kannst dir nginx recht einfach zusammen mit dem nginx_auth_mysql Modul selber übersetzen:

1. nginx runterladen und entpacken

wget http://nginx.org/download/nginx-0.7.65.tar.gz
tar -xzvf nginx-0.7.65.tar.gz

2. nginx_auth_mysql auschecken

svn export http://code.svn.wordpress.org/nginx_auth_mysql/

3. nginx mit nginx_auth_mysql bauen
Wenn du unter Debian bist und willst das dein selbstgebauter nginx aus den Standard nginx Verzeichnissen ließt aber selbst an einem anderen Ort liegt (damit beim nächsten Update des Debian Paketes dein eigenbau Binary nicht überschrieben wird) kannst du die Zeile kopieren mit der auch das Debian Paket von nginx gebaut wird. Das auth_mysql Modul wird auch gleich mitgebaut.

./configure --prefix=/usr/local/nginx
--conf-path=/etc/nginx/nginx.conf
--error-log-path=/var/log/nginx/error.log
--pid-path=/var/run/nginx.pid
--lock-path=/var/lock/nginx.lock
--http-log-path=/var/log/nginx/access.log
--http-client-body-temp-path=/var/lib/nginx/body
--http-proxy-temp-path=/var/lib/nginx/proxy
--http-fastcgi-temp-path=/var/lib/nginx/fastcgi
--with-debug
--with-http_stub_status_module
--with-http_flv_module
--with-http_ssl_module
--with-http_dav_module
--add-module=../nginx_auth_mysql/

4. nging nginx.conf
Der folgende Code gehört in deine nginx.conf innerhalb eines location { … } Teils:

auth_mysql_realm "lerl";
auth_mysql_host "localhost";
auth_mysql_user "mysqlauth";
auth_mysql_password "******";
auth_mysql_database "mysqlauth_priv";
auth_mysql_table "users";
auth_mysql_password_column "password";
auth_mysql_user_column "username";
auth_mysql_encryption_type "md5";

Leave a Reply

Your email address will not be published. Required fields are marked *