Installation d'une multiinstance trac avec nginx et MySQL

Le jeudi 05 décembre 2013 par Benjamin Boudoir

Trac est un logiciel tout en un en python pour aider dans le développement de logiciels.

J'ai pu me rendre compte qu'il était légèrement complexe de faire une installation multi-instances (gérer plusieurs projets), derrière un proxy nginx, les informations sont légèrement explosées sur le wiki de trac. Voici donc ma méthode (sur Debian 7 Wheezy).

Paquets nécessaires

aptitude install trac python-mysqldb

Préparation du serveur MySQL

SET PASSWORD FOR 'trac'@'localhost' =  PASSWORD('mypassword');
GRANT all privileges ON `trac_%`.* TO 'trac'@'localhost';
CREATE DATABASE trac_project DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;

Préparation de trac

mkdir -p /var/trac/project
trac-admin /var/trac/project initenv

Lorsque cela vous sera demandé, indiquez le nom de votre projet ainsi que les informations de connexion à la base de donnée :

mysql://trac:mypassword@127.0.0.1:3306/trac_project

Création d'un utilisateur pour trac

useradd -d /var/trac/ -r trac
mkdir /var/run/tracd
chown trac:trac /var/run/tracd
chown -R trac:trac /var/trac/

Automatisation de l'installation

Pour automatiser le lancement de trac, rien de mieux qu'un init script. Pour celà, je me suis basé sur /etc/init.d/skeleton fourni par Debian pour faire un /etc/init.d/trac dont l'entête est la suivante :

#! /bin/sh
### BEGIN INIT INFO
# Provides:          skeleton
# Required-Start:    $remote_fs $syslog mysql
# Required-Stop:     $remote_fs $syslog mysql
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: tracd
# Description:       Enhanced wiki and issue tracking system for software development projects
#
### END INIT INFO

# Author: Me

# Do NOT "set -e"

LANG=C

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="tracd"
NAME=tracd
DAEMON=/usr/bin/$NAME
PIDFILE=/var/run/$NAME/$NAME.pid
DAEMON_ARGS="-d -b 127.0.0.1 -p 8080 --pidfile=$PIDFILE --env-parent-dir=/var/trac/ --basic-auth='*,/etc/nginx/trac-htpasswd,Restricted'"
SCRIPTNAME=/etc/init.d/$NAME
USER=trac

Et on modifie les appels à start-stop-daemon en ajoutant :

--chuid $USER

Configuration de nginx

server {
  server_name            mydomain.tld;

  access_log             /var/log/nginx/trac_access.log main;
  error_log              /var/log/nginx/trac_error.log info;

  location / {
    proxy_pass           http://127.0.0.1:8080;

    auth_basic_user_file /etc/nginx/trac-htpasswd;
    proxy_pass_header    Authorization;
    proxy_set_header     REMOTE_USER $remote_user;
  }

  location ~ /login$ {
    proxy_pass           http://127.0.0.1:8080;

    auth_basic           "Restricted";
    auth_basic_user_file /etc/nginx/trac-htpasswd;
    proxy_pass_header    Authorization;
    proxy_set_header     REMOTE_USER $remote_user;
  }
}

Ici, l'authentification est la même pour tous les projets (mais les autorisations sont toujours gérées par trac) et gérées par un fichier htpassword. En revanche, tout le monde peut accéder à trac, l'authentification ne se fera qu'en cliquant sur le bouton "login" d'un des projets.

Gestion de l'authentification

Maintenant, il faut permettre à trac d'accepter l'authentification par le serveur web. Pour celà, on a besoin d'un nouveau plugin :

from trac.core import *
from trac.config import BoolOption
from trac.web.api import IAuthenticator

class MyRemoteUserAuthenticator(Component):

    implements(IAuthenticator)

    obey_remote_user_header = BoolOption('trac', 'obey_remote_user_header', 'false',
               """Whether the 'Remote-User:' HTTP header is to be trusted for user logins
                (''since ??.??').""")

    def authenticate(self, req):
        if self.obey_remote_user_header and req.get_header('Remote-User'):
            return req.get_header('Remote-User')
        return None

Placez-le dans le dossier "plugins" et activez-le en modifiant la configuration (conf/trac.ini) de sorte que l'on retrouve les informations suivantes :

[components]
remote-user-auth.* = enabled
[trac]
obey_remote_user_header = true

Gestion des utilisateurs

Vous pouvez créer un premier utilisateur qui sera l'adminisatrateur :

trac-admin /var/trac/project/ permission add $USER TRAC_ADMIN
htpasswd -c /etc/nginx/trac-htpasswd -m $USER

Pour tout les suivants, ajouter une entrée au fichier htpasswd sera suffisant, vous pourrez gérer les droits graphiquement via le panneau d'admin.