This text is a work in progress—highly subject to change—and may not accurately describe any released version of the Apache™ Subversion® software. Bookmarking or otherwise referring others to this page is probably not such a smart idea. Please visit http://www.svnbook.com/ for stable versions of this book.

svnserve, un serveur sur mesure

Le programme svnserve est un serveur léger, capable de dialoguer avec des clients sur un réseau TCP/IP en utilisant un protocole dédié avec gestion des états. Les clients contactent le serveur svnserve en utilisant une URL qui commence par svn:// ou svn+ssh://. Cette section explique différentes mises en œuvre de svnserve, l'authentification des clients sur le serveur et la configuration d'un contrôle d'accès approprié pour vos dépôts.

Démarrage du serveur

Il existe différentes façons de démarrer le programme svnserve :

  • lancer svnserve en tant que serveur autonome, à l'écoute de requêtes ;

  • utiliser le démon Unix inetd pour lancer une instance temporaire de svnserve quand une requête arrive sur un port déterminé ;

  • utiliser SSH pour lancer une instance temporaire de svnserve dans un tunnel chiffré ;

  • lancer svnserve en tant que service Microsoft Windows ;

  • lancer svnserve en tant que tâche launchd.

Les sections qui suivent vont détailler ces différentes mises en œuvre de svnserve.

svnserve en serveur autonome

Le plus facile est de démarrer svnserve en tant que serveur autonome. Pour ce faire, utilisez l'option -d (d pour « daemon » qui est l'appellation consacrée pour les serveurs Unix) :

$ svnserve -d
$               # svnserve est maintenant actif, en écoute sur le port 3690

Lorsque vous lancez svnserve en serveur autonome, vous pouvez utiliser les options --listen-port et --listen-host pour spécifier le port et l'adresse voulus pour « écouter ».

Une fois le serveur démarré de cette manière, tous les dépôts présents sur votre machine seront accessibles par le réseau. Un client doit spécifier un chemin absolu dans l'URL du dépôt. Par exemple, si un dépôt est situé sous /var/svn/projet-1, un client l'atteindra par svn://hote.exemple.com/var/svn/projet-1. Pour renforcer la sécurité, vous pouvez passer l'option -r à svnserve afin de restreindre l'export aux dépôts situés sous le chemin indiqué. Par exemple :

$ svnserve -d -r /var/svn
…

L'utilisation de l'option -r modifie le chemin que le serveur considère comme la racine du système de fichiers à exporter. Les clients utiliseront alors des URL ne comportant pas cette portion du chemin (ce qui rend les URL plus courtes et plus discrètes) :

$ svn checkout svn://hote.exemple.com/projet-1
…

svnserve via inetd

Si vous désirez que inetd lance le processus, il vous faudra passer l'option -i (--inetd). Dans l'exemple suivant, nous montrons le résultat de la commande svnserve -i, mais notez bien que ce c'est pas de cette manière que l'on démarre le serveur ; reportez-vous aux paragraphes qui suivent l'exemple pour savoir comment configurer inetd pour qu'il démarre svnserve.

$ svnserve -i
( success ( 2 2 ( ) ( edit-pipeline svndiff1 absent-entries commit-revprops d\
epth log-revprops atomic-revprops partial-replay ) ) )

Quand on l'invoque avec l'option --inetd, svnserve tente de communiquer avec un client Subversion via l'entrée et la sortie standards (stdin et stdout) en utilisant un protocole spécifique. C'est le comportement habituel de tout programme lancé par inetd. L'IANA a réservé le port 3690 pour le protocole Subversion ; sur un système Unix vous pouvez donc ajouter au fichier /etc/services les lignes suivantes (si elles n'existent pas déjà) :

svn           3690/tcp   # Subversion
svn           3690/udp   # Subversion

Si votre système utilise un serveur inetd classique de type Unix, vous pouvez ajouter la ligne suivante au fichier /etc/inetd.conf :

svn stream tcp nowait proprio-svn /usr/bin/svnserve svnserve -i

Assurez-vous que l'utilisateur « proprio-svn » possède des droits d'accès appropriés pour vos dépôts. Dès lors, quand une connexion client arrive sur le port 3690, inetd va créer un processus svnserve pour lui répondre. Bien sûr, vous pouvez également ajouter l'option -r à cette ligne de configuration, pour restreindre les dépôts qui sont exportés.

svnserve via xinetd

Certains systèmes d'exploitation fournissent le serveur xinetd en lieu et place de inetd. Fort heureusement, vous pouvez configurer svnserve pour s'interfacer aussi avec xinetd. Pour ce faire, vous devez créer un fichier /etc/xinetd.d/svn avec le contenu suivant :

# default: on
# description: serveur Subversion pour le protocole svn
service svn
{
  disabled        = no
  port            = 3690
  socket_type     = stream
  protocol        = tcp
  wait            = no
  user            = proprio-svn
  server          = /usr/local/bin/svnserve 
  server_args     = -i -r /chemin/vers/les/depots
}

Vérifier que le fichier /etc/services contient bien les références des ports relatifs au protocole svn (comme indiqué dans la section intitulée « svnserve via xinetd »), sinon le serveur ne démarrera pas correctement.

Sur les distributions de type Redhat, vous devez activer le nouveau service à l'aide de la commande chkconfig --add svn. Ensuite, vous pourrez activer ou désactiver le serveur au moyen de l'interface graphique.

svnserve encapsulé dans un tunnel

Le mode tunnel est une troisième façon de lancer svnserve, via l'option -t. Ce mode présuppose qu'un programme de connexion à distance tel que rsh ou ssh a permis à un utilisateur de s'authentifier avec succès et lance alors un processus privé svnserve pour le compte de cet utilisateur (remarquez qu'en tant qu'utilisateur vous aurez rarement, sinon jamais, l'occasion de lancer svnserve avec l'option -t en ligne de commande ; c'est le serveur SSH qui le fait à votre place). Le programme svnserve se comporte alors normalement (utilisation des entrées/sorties stdin et stdout) et suppose que le trafic est redirigé automatiquement vers le client par un tunnel. Quand svnserve est lancé par un gestionnaire de tunnel comme ici, soyez sûr que l'utilisateur authentifié possède les droits suffisants de lecture et d'écriture sur les fichiers de la base de données. C'est essentiellement la même chose que quand un utilisateur local accède au dépôt via des URL file://.

Cette option est décrite en détail plus loin dans ce chapitre, dans la section intitulée « Encapsulation de svnserve dans un tunnel SSH ».

svnserve en tant que service Windows

Si votre système Windows est un descendant de Windows NT (Windows 2000 ou plus récent), vous pouvez lancer svnserve en tant que service Windows. C'est généralement une méthode bien plus agréable que de le lancer en démon indépendant via l'option (-d). Utiliser le mode démon nécessite de lancer une console, de taper une commande et ensuite de laisser la fenêtre de la console tourner indéfiniment. Un service Windows, au contraire, tourne à l'arrière-plan, peut être lancé automatiquement au démarrage et peut être démarré ou arrêté à l'aide de la même interface d'administration que les autres services Windows.

Vous devrez définir le nouveau service en utilisant l'outil en ligne de commande SC.EXE. De façon analogue à la ligne de configuration inetd, il vous faudra fournir la commande de lancement précise de svnserve pour que Windows le lance au démarrage :

C:\> sc create svn
        binpath= "C:\svn\bin\svnserve.exe --service -r C:\depot"
        displayname= "Serveur Subversion"
        depend= Tcpip
        start= auto

Ceci définit un nouveau service Windows nommé « svn », qui exécute une commande particulière svnserve.exe quand il démarre (dont la racine est, dans ce cas, C:\depot). Il y a toutefois un certain nombre de précautions à prendre avec cet exemple.

Premièrement, remarquez que le programme svnserve.exe doit toujours être lancé avec l'option --service. Toute autre option de svnserve doit ensuite être spécifiée sur la même ligne, mais vous ne pouvez pas ajouter d'options qui seraient en conflit avec celle-ci, telles que --daemon (-d), --tunnel, ou --inetd (-i). D'autres options, comme -r ou --listen-port ne posent pas de problème. Deuxièmement, faites attention aux espaces quand vous tapez la commande SC.EXE : les groupes clé= valeur ne doivent pas comporter d'espace dans clé= et doivent comporter exactement une espace avant valeur. Enfin, faites attention aux espaces présentes dans la ligne de commande que vous indiquez. Si le nom d'un répertoire contient des espaces (ou tout autre caractère qui ait besoin d'être banalisé), placez l'ensemble du contenu de binpath entre guillemets, qui doivent eux-mêmes être banalisés :

C:\> sc create svn
        binpath= "\"C:\program files\svn\bin\svnserve.exe\" --service -r C:\depot"
        displayname= "Serveur Subversion"
        depend= Tcpip
        start= auto

Notez aussi que le terme binpath prête à confusion : sa valeur est une ligne de commande, pas le chemin d'accès à un exécutable. C'est pourquoi vous devez l'entourer de guillemets s'il contient des espaces.

Une fois que le service a été créé, il peut être arrêté, démarré ou interrogé à l'aide des outils standards de l'interface graphique (le programme « Services » des outils d'administration) ou de la ligne de commande :

C:\> net stop svn
C:\> net start svn

Le service peut aussi être désinstallé (c'est-à-dire supprimé) en effaçant sa définition : sc delete svn. Prenez soin d'arrêter le service auparavant ! Le programme SC.EXE possède de nombreuses autres sous-commandes ; tapez sc /? en ligne de commande pour en savoir plus.

svnserve en tant que tâche launchd

Mac OS X (10.4 et supérieur) utilise launchd pour gérer les processus, y compris les démons, de la machine et des utilisateurs. Une tâche launchd est spécifiée par des paramètres dans un fichier de propriétés XML et la commande launchctl sert à gérer le cycle de vie de ces tâches.

Quand il est configuré pour fonctionner en tant que tâche launchd, svnserve est automatiquement lancé à la demande dès qu'un trafic réseau entrant de type Subversion svn:// doit être pris en charge. C'est beaucoup plus pratique qu'une configuration qui demande à lancer svnserve en tant que processus permanent en arrière-plan.

Pour configurer svnserve en tant que tâche launchd, commencez par créer un fichier de définition de la tâche nommé /Library/LaunchDaemons/org.apache.subversion.svnserve.plist. Exemple 6.1, « Exemple de fichier de définition de tâche launchd pour svnserve » donne un exemple d'un tel fichier.

Exemple 6.1. Exemple de fichier de définition de tâche launchd pour svnserve

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
    "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>Label</key>
        <string>org.apache.subversion.svnserve</string>
        <key>ServiceDescription</key>
        <string>Accès aux dépôts Subversion locaux en utilisant le protocole svn://</string>
        <key>ProgramArguments</key>
        <array>
            <string>/usr/bin/svnserve</string>
            <string>--inetd</string>
            <string>--root=/var/svn</string>
        </array>
        <key>UserName</key>
        <string>proprio-svn</string>
        <key>GroupName</key>
        <string>proprio-svn</string>
        <key>inetdCompatibility</key>
        <dict>
            <key>Wait</key>
            <false/>
        </dict>
        <key>Sockets</key>
        <dict>
            <key>Listeners</key>
            <array>
                <dict>
                    <key>SockServiceName</key>
                    <string>svn</string>
                    <key>Bonjour</key>
                    <true/>
                </dict>
            </array>
        </dict>
    </dict>
</plist>

[Avertissement] Avertissement

Le système launchd peut être difficile à appréhender. Heureusement, la documentation existe pour les commandes décrites dans cette section. Par exemple, lancez man launchd depuis la ligne de commande pour avoir accès à la page de manuel de launchd lui-même ou man launchd.plist pour lire le format des définitions de tâches, etc.

Une fois le fichier de définition de tâche créé, vous pouvez activer la tâche en utilisant launchctl load :

$ sudo launchctl load \
       -w /Library/LaunchDaemons/org.apache.subversion.svnserve.plist

Pour être tout à fait franc, cette commande ne lance pas réellement svnserve immédiatement. Elle indique simplement à launchd comment lancer svnserve lorsqu'un flux entrant arrive sur le port svn  il sera stoppé après que le flux a été pris en charge.

[Note] Note

Comme nous voulons que svnserve soit une tâche accessible sur toute la machine, nous devons utiliser sudo pour gérer la tâche avec les droits d'administrateur. Notez également que les clés UserName et GroupName dans le fichier de définition sont optionnelles. Si elles sont omises, la tâche sera exécutée avec l'identifiant de l'utilisateur ayant lancé la tâche.

Désactiver la tâche est tout aussi facile à faire ; utilisez launchctl unload :

$ sudo launchctl unload \
       -w /Library/LaunchDaemons/org.apache.subversion.svnserve.plist

launchctl vous propose aussi d'interroger l'état des tâches. Si la tâche est chargée, il y aura une ligne qui mentionne le Label spécifié dans le fichier de définition de la tâche :

$ sudo launchctl list | grep org.apache.subversion.svnserve
-       0       org.apache.subversion.svnserve
$

Authentification et contrôle d'accès intégrés

Quand un client se connecte au processus svnserve, les choses suivantes se passent :

  • Le client sélectionne un dépôt particulier.

  • Le serveur analyse le fichier conf/svnserve.conf de ce dépôt et commence à suivre les politiques d'authentification et de contrôle d'accès qui y sont décrites.

  • En fonction des politiques définies, une des choses suivantes a lieu :

    • Le client est autorisé à lancer des requêtes anonymes, sans jamais recevoir le moindre défi d'authentification.

    • Le client peut recevoir un défi d'authentification à tout instant.

    • Si l'on est en mode tunnel, le client déclare lui-même avoir déjà satisfait à une authentification externe (généralement par SSH).

Le serveur svnserve ne sait envoyer, par défaut, que des défis d'authentification CRAM-MD5[63]. Plus précisément, le serveur envoie une petite quantité de données aux clients. Le client utilise l'algorithme de hachage MD5 pour créer une empreinte combinant les données et le mot de passe, puis renvoie l'empreinte en guise de réponse. Le serveur effectue le même calcul avec le mot de passe enregistré pour vérifier que le résultat est identique. Le mot de passe ne circule ainsi jamais en clair sur le réseau.

Si votre serveur svnserve a été compilé en incluant le support de SASL, non seulement il sait comment envoyer des défis CRAM-MD5, mais il connaît aussi probablement un grand nombre d'autres mécanismes d'authentification. Consultez la section intitulée « Utilisation de svnserve avec SASL » plus loin dans ce chapitre pour savoir comment configurer l'authentification et le chiffrement avec SASL.

Le client peut bien sûr aussi être authentifié en externe par un gestionnaire de tunnel tel que ssh. Dans ce cas, le serveur se contente de prendre l'identifiant par lequel il a été lancé et de s'en servir comme utilisateur authentifié. Pour plus de détails, reportez-vous plus loin à la section intitulée « Encapsulation de svnserve dans un tunnel SSH ».

Vous avez sûrement déjà deviné que le fichier svnserve.conf est le mécanisme central qui contrôle les politiques d'authentification et de contrôle d'accès. Ce fichier a le même format que d'autres fichiers de configuration (voir la section intitulée « Zone de configuration des exécutables ») : les noms de paragraphes sont entourés de crochets ([ et ]), les lignes de commentaires commencent par des dièses (#) et chaque paragraphe contient des variables spécifiques qui peuvent être définies (variable = valeur). Examinons ces fichiers et apprenons à les utiliser.

Création d'un fichier utilisateurs et d'un domaine d'authentification

Pour ce qui suit, la section [general] de svnserve.conf contient toutes les variables dont vous avez besoin. Commencez par modifier les valeurs de toutes les variables : choisissez un nom pour le fichier qui contiendra vos noms d'utilisateur ainsi que vos mots de passe et choisissez un domaine d'authentification :

[general]
password-db = fichier-utilisateurs
realm = exemple de domaine

Le domaine (realm dans le fichier de configuration) est un nom que vous définissez. Il indique aux clients à quelle sorte d'« espace de noms » ils se connectent ; le client Subversion l'affiche dans l'invite d'authentification et l'utilise comme clé (en combinaison avec le nom de machine et le port du serveur) pour mettre en cache les éléments d'authentification sur le disque (voir la section intitulée « Mise en cache des éléments d'authentification »). La variable password-db pointe vers un fichier séparé qui contient une liste de noms d'utilisateurs et de mots de passe, utilisant le même format usuel. Par exemple :

[users]
harry = motdepassemachin
sally = motdepassebidule

La valeur de password-db peut correspondre à un chemin absolu ou à un chemin relatif vers le fichier des utilisateurs. Pour de nombreux administrateurs, conserver le fichier dans la zone conf/, aux côtés de svnserve.conf, est une solution simple et facile. D'un autre côté, il se pourrait que deux dépôts, voire plus, doivent partager le même fichier ; dans ce cas, le fichier devrait sans doute être situé dans un répertoire plus accessible. Les dépôts partageant le même fichier utilisateurs devraient aussi être configurés de sorte qu'ils soient dans le même domaine, puisque la liste des utilisateurs définit, par essence, un domaine d'authentification. Quel que soit l'emplacement du fichier, faites attention à positionner les droits en lecture/écriture de façon appropriée. Si vous savez sous quel nom d'utilisateur svnserve fonctionnera, restreignez l'accès au fichier utilisateurs en conséquence.

Mise en place du contrôle d'accès

Il y a deux variables supplémentaires à définir dans le fichier svnserve.conf : elles déterminent ce que les utilisateurs non-authentifiés (anonymes) et les utilisateurs authentifiés ont le droit de faire. Les variables anon-access et auth-access peuvent contenir les valeurs none, read, ou write. Choisir la valeur none empêche à la fois lecture et écriture ; read autorise l'accès en lecture seule au dépôt et write autorise l'accès complet en lecture/écriture au dépôt. Par exemple :

[general]
password-db = fichier-utilisateurs
realm = exemple de domaine

# les utilisateurs anonymes ne peuvent accéder au dépôt qu'en lecture
anon-access = read

# les utilisateurs authentifiés peuvent à la fois lire et écrire
auth-access = write

Les lignes présentes dans le fichier contiennent en fait les valeurs par défaut des variables, au cas où vous oublieriez de les définir. Si vous voulez être encore plus prudent, vous pouvez complètement interdire les accès anonymes :

[general]
password-db = fichier-utilisateurs
realm = exemple de domaine

# les utilisateurs anonymes ne sont pas autorisés
anon-access = none

# les utilisateurs authentifiés peuvent à la fois lire et écrire
auth-access = write

Le processus serveur sait interpréter non seulement ce contrôle d'accès générique, mais aussi des restrictions d'accès plus fines associées à des fichiers et répertoires spécifiques du dépôt. Pour utiliser cette fonctionnalité, vous devez définir un fichier contenant des règles plus détaillées, puis faire pointer la variable authz-db vers ce fichier :

[general]
password-db = fichier-utilisateurs
realm = exemple de domaine

# Règles d'accès propres à certains emplacements
authz-db = fichier-authz

Nous étudions la syntaxe du fichier authz plus loin dans ce chapitre, dans la section intitulée « Contrôle d'accès basé sur les chemins ». Notez que la variable authz-db n'est pas mutuellement exclusive avec les variables anon-access et auth-access ; si toutes les variables sont définies en même temps, toutes les règles doivent être satisfaites pour que l'accès soit autorisé.

Utilisation de svnserve avec SASL

L'authentification par CRAM-MD5 suffit aux besoins de bon nombre d'équipes. Cependant, si votre serveur (et vos clients Subversion) ont été compilés avec la bibliothèque « Cyrus Simple Authentication and Security Layer » (SASL), vous avez à votre disposition un certain nombre d'options d'authentification et de chiffrement.

Normalement, quand un client Subversion se connecte à svnserve, le serveur envoie un message de bienvenue qui liste les fonctionnalités qu'il supporte et le client répond avec une liste similaire. Si le serveur est configuré pour exiger une authentification, il envoie ensuite un défi listant les mécanismes d'authentification disponibles ; le client répond en choisissant un des mécanismes et l'authentification se déroule ensuite par quelques échanges de messages. Même quand SASL n'est pas présent dans la liste, le client et le serveur sont capables d'utiliser les mécanismes CRAM-MD5 et ANONYMOUS (voir la section intitulée « Authentification et contrôle d'accès intégrés »). Si le serveur et le client ont été compilés pour inclure SASL, un certain nombre d'autres mécanismes d'authentification sont éventuellement disponibles. Néanmoins, vous devez configurer explicitement SASL sur le serveur pour qu'ils soient proposés.

Authentification par SASL

Pour activer les mécanismes spécifiques à SASL sur le serveur, il faut faire deux actions. D'abord, créez un paragraphe [sasl] dans le fichier svnserve.conf de votre dépôt avec le couple clé/valeur initial :

[sasl]
use-sasl = true

Ensuite, créez le fichier principal de configuration de SASL, appelé svn.conf, à un endroit où la bibliothèque SASL saura le trouver (généralement dans un répertoire où sont situés les greffons SASL). Vous devez localiser le répertoire des greffons de votre système, tel que /usr/lib/sasl2/ ou /etc/sasl2/ (notez qu'il ne s'agit pas là du fichier svnserve.conf qui réside dans votre dépôt !).

Sur un serveur Windows vous devez aussi éditer la base de registre (à l'aide d'un outil tel que regedit) pour indiquer à SASL les emplacements où chercher. Créez une clé nommée [HKEY_LOCAL_MACHINE\SOFTWARE\Carnegie Mellon\Project Cyrus\SASL Library] et placez-y deux clés : l'une appelée SearchPath (dont la valeur est le chemin du répertoire contenant les bibliothèques de greffons SASL sasl*.dll) et l'autre appelée ConfFile (dont la valeur est le chemin du répertoire parent contenant le fichier svn.conf que vous avez créé).

Parce que SASL fournit de très nombreux mécanismes d'authentification, il serait insensé (et bien au-delà du cadre de ce livre) d'essayer de décrire toutes les configurations serveurs possibles. Nous vous recommandons plutôt de lire la documentation fournie dans le sous-répertoire doc/ du code source de SASL. Elle décrit en détail chaque mécanisme, ainsi que la manière de configurer le serveur correctement pour chacun d'entre eux. Dans ce paragraphe, nous nous contentons de donner un exemple simple de configuration du mécanisme DIGEST-MD5. Par exemple, si votre fichier subversion.conf (ou svn.conf) contient ce qui suit :

pwcheck_method: auxprop
auxprop_plugin: sasldb
sasldb_path: /etc/ma_bdd_sasl
mech_list: DIGEST-MD5

vous demandez à SASL de proposer le mécanisme DIGEST-MD5 aux clients et de comparer les mots de passe des utilisateurs à une base de mots de passe privée située à l'emplacement /etc/ma_bdd_sasl. Un administrateur système pourra ensuite utiliser le programme saslpasswd2 pour ajouter ou modifier les noms d'utilisateurs et les mots de passe contenus dans cette base de données :

$ saslpasswd2 -c -f /etc/ma_bdd_sasl -u domaine utilisateur

Quelques consignes de prudence : tout d'abord, l'argument « domaine » qui est passé à saslpasswd2 doit correspondre au même domaine que celui que vous avez défini dans le fichier svnserve.conf ; s'ils ne correspondent pas, l'authentification échouera. En outre, à cause d'une limitation de SASL, ce domaine commun doit être une chaîne sans espace. Enfin, si vous décidez d'utiliser la base de données standard de mots de passe SASL, assurez-vous que le programme svnserve a accès en lecture à ce fichier (et éventuellement aussi en écriture, si vous utilisez un mécanisme tel que OTP).

Ceci est une manière simple de configurer SASL. De nombreux autres mécanismes d'authentification sont disponibles et les mots de passe peuvent être conservés dans des conteneurs différents, par exemple des annuaires LDAP ou des bases de données SQL. Reportez-vous à la documentation complète de SASL pour plus de détails.

Souvenez-vous que si vous configurez votre serveur pour qu'il n'autorise que certains mécanismes d'authentification SASL, tous les clients qui se connectent ont l'obligation de supporter SASL. Tout client Subversion compilé sans SASL (ce qui inclut tous les clients antérieurs à la version 1.5) est incapable de se connecter. D'un autre côté, ce type de restriction est peut-être exactement ce que vous recherchez (« Mes clients doivent tous utiliser Kerberos ! »). Néanmoins, si vous voulez permettre à des clients non-SASL de se connecter, pensez bien à inclure le mécanisme CRAM-MD5 dans les choix possibles. Tous les clients savent utiliser CRAM-MD5, qu'ils aient des fonctionnalités SASL ou pas.

Chiffrement SASL

SASL est également capable d'effectuer le chiffrement des données si un mécanisme particulier le supporte. Le mécanisme intégré CRAM-MD5 ne supporte pas le chiffrement, mais DIGEST-MD5 le supporte et d'autres mécanismes tels que SRP requièrent l'utilisation de la bibliothèque OpenSSL. Pour activer ou désactiver différents niveaux de chiffrement, vous pouvez définir deux variables dans le fichier svnserve.conf de votre dépôt :

[sasl]
use-sasl = true
min-encryption = 128
max-encryption = 256

Les variables min-encryption et max-encryption contrôlent le niveau de chiffrement exigé par le serveur. Pour désactiver complètement le chiffrement, mettez les deux valeurs à 0. Pour activer une simple somme de contrôle sur les données (par exemple pour empêcher toute manipulation douteuse et garantir l'intégrité des données sans chiffrement), mettez les deux valeurs à 1. Si vous voulez autoriser le chiffrement, sans que ce soit obligatoire, mettez 0 pour la valeur minimale et un nombre de bits donné pour la valeur maximale. Pour exiger un chiffrement inconditionnel, mettez les deux valeurs à un nombre plus grand que 1. Dans l'exemple précédent, nous obligeons les clients à utiliser au moins un chiffrement 128 bits et au plus un chiffrement 256 bits.

Encapsulation de svnserve dans un tunnel SSH

L'authentification intégrée (ainsi que SASL) peuvent être très pratiques, car ils évitent d'avoir à créer de véritables comptes systèmes. D'un autre côté, certains administrateurs ont déjà des systèmes d'authentification bien établis en place. Dans ce cas, tous les utilisateurs du projet possèdent déjà des comptes systèmes et peuvent se connecter au serveur par SSH.

Utiliser SSH en conjonction avec svnserve est facile. Le client utilise juste une URL svn+ssh:// pour se connecter :

$ whoami
harry


$ svn list svn+ssh://hote.exemple.com/depot/projet
harryssh@hote.exemple.com's password:  *****

truc
machin
bidule
…

Dans cet exemple, le client Subversion lance un processus local ssh, se connecte à hote.exemple.com, s'authentifie en tant que harryssh (en accord avec la configuration SSH des utilisateurs) puis un processus svnserve privé est généré automatiquement sur la machine distante, processus dont le propriétaire est l'utilisateur harryssh. La commande svnserve est lancée en mode tunnel (-t) et son protocole réseau est encapsulé dans la connexion chiffrée par ssh, le gestionnaire de tunnel. Si le client effectue une propagation, l'auteur de la nouvelle révision sera l'utilisateur authentifié (harryssh).

Ce qu'il est important de comprendre ici est que le client Subversion ne se connecte pas à un serveur svnserve fonctionnant en permanence. Cette méthode d'accès ne requiert pas la présence d'un démon, ni ne vérifie s'il y en a un qui tourne. Elle se base entièrement sur la capacité de ssh à générer un processus svnserve temporaire, qui ensuite se termine une fois la connexion SSH close.

Quand vous utilisez des URL svn+ssh:// pour accéder à un dépôt, souvenez-vous que c'est le programme ssh qui envoie l'invite d'authentification, pas le client svn. Cela signifie qu'il n'y a pas de mise en cache automatique de mots de passe (voir la section intitulée « Mise en cache des éléments d'authentification »). Le fonctionnement du client Subversion fait qu'il accède souvent au dépôt par des connexions multiples, bien que les utilisateurs ne s'en rendent habituellement pas compte grâce à la fonctionnalité de mise en cache du mot de passe. Lorsque vous utilisez des URL svn+ssh://, les utilisateurs risquent de trouver ça pénible que ssh demande le mot de passe de façon répétitive pour toute connexion vers l'extérieur. La solution est d'utiliser un outil séparé de mise en cache du mot de passe, tel que ssh-agent sur Unix ou pageant sur Windows.

Quand le trafic passe par un tunnel, les accès sont contrôlés principalement par les droits sur les fichiers de la base de données liés au système d'exploitation ; c'est quasiment pareil que si Harry accédait au dépôt directement via une URL file://. Si plusieurs utilisateurs systèmes accèdent au dépôt directement, il est de bon ton de les placer dans un même groupe et vous devez faire attention aux umasks (prenez soin de lire la section intitulée « Accès au dépôt par plusieurs méthodes » plus loin dans ce chapitre). Mais même dans le cas de l'encapsulation, vous pouvez toujours utiliser le fichier svnserve.conf pour bloquer l'accès, en spécifiant juste auth-access = read ou auth-access = none[64].

Vous vous attendez à ce que cette histoire d'encapsulation SSH se termine ici, mais ce n'est pas le cas. Subversion vous permet de créer des comportements d'encapsulation personnalisés dans votre fichier de configuration (voir la section intitulée « Zone de configuration des exécutables »). Par exemple, supposons que vous vouliez utiliser RSH au lieu de SSH[65]. Dans le paragraphe [tunnels] de votre fichier config, définissez-le comme ceci :

[tunnels]
rsh = rsh

À présent vous pouvez utiliser cette nouvelle définition d'encapsulation par le biais d'un schéma d'URL qui correspond au nom de votre nouvelle variable : svn+rsh://hote/chemin. Lorsqu'il utilise le nouveau type d'URL, le client Subversion lance en fait en arrière-plan la commande rsh hote svnserve -t. Si vous incluez un nom d'utilisateur dans l'URL (par exemple svn+rsh://nomdutilisateur@hote/chemin), le client va l'inclure dans sa commande (rsh nomdutilisateur@hote svnserve -t). Mais vous pouvez définir des schémas d'encapsulation bien plus évolués :

[tunnels]
joessh = $JOESSH /opt/alternate/ssh -p 29934

Cet exemple illustre plusieurs choses. D'abord, il indique comment faire pour que le client Subversion lance un exécutable d'encapsulation particulier (celui situé à l'emplacement /opt/alternate/ssh) avec des options particulières. Dans ce cas, se connecter à une URL svn+joessh:// lance un exécutable SSH particulier avec les arguments -p 29934 (utile si vous voulez que le programme d'encapsulation se connecte à un port non standard).

Ensuite, il indique comment définir une variable d'environnement personnalisée capable de remplacer le nom du programme d'encapsulation. Configurer la variable d'environnement SVN_SSH est un moyen simple de modifier le programme d'encapsulation par défaut. Mais s'il vous faut différents programmes d'encapsulation pour différents serveurs, chacun se connectant par exemple à un port différent ou passant des options différentes à SSH, vous pouvez utiliser le mécanisme illustré dans cet exemple. Concrètement, si nous donnons une valeur à la variable d'environnement JOESSH, cette valeur remplacera la totalité de la valeur de la variable d'encapsulation — $JOESSH serait exécuté au lieu de /opt/alternate/ssh -p 29934.

Astuces de configuration de SSH

Il est possible de contrôler non seulement la manière dont le client lance ssh, mais aussi le comportement de sshd sur votre machine. Dans ce paragraphe, nous indiquons comment contrôler la commande svnserve précise qui est exécutée par sshd, ainsi que comment faire pour que plusieurs utilisateurs partagent un même compte système.

Mise en œuvre initiale

Pour commencer, localisez le répertoire « home » du compte utilisateur que vous utilisez pour lancer svnserve. Assurez-vous que ce compte possède un biclé de clés publique/privée et que l'utilisateur peut se connecter en s'authentifiant par la méthode à clé publique. L'authentification par mot de passe ne fonctionnera pas, puisque toutes les astuces SSH qui suivent consistent à utiliser le fichier authorized_keys.

S'il n'existe pas déjà, créez le fichier authorized_keys (sur Unix, c'est généralement ~/.ssh/authorized_keys). Chaque ligne de ce fichier décrit une clé publique autorisée à se connecter. Ces ligne sont généralement de la forme :

  ssh-dsa AAAABtce9euch… utilisateur@exemple.com

Le premier champ décrit le type de clé, le second champ est la clé elle-même, encodée en base 64, et le troisième champ est un commentaire. Cependant, c'est un fait moins connu que la ligne toute entière peut être précédée par un champ command :

 
  command="programme" ssh-dsa AAAABtce9euch… utilisateur@exemple.com

Quand le champ command est présent, le serveur SSH va lancer le programme indiqué en lieu et place de l'habituel svnserve en mode tunnel que le client Subversion a demandé. En découlent un certain nombre d'astuces côté serveur. Dans les exemples suivants, nous abrégeons les lignes du fichier par :

  command="programme" TYPE CLÉ COMMENTAIRE

Contrôle de la commande à exécuter

Comme nous pouvons spécifier la commande exécutée côté serveur, il devient facile de désigner un exécutable svnserve spécifique et de lui passer des arguments supplémentaires :

  command="/chemin/vers/svnserve -t -r /racine/virtuelle" TYPE CLÉ COMMENTAIRE

Dans cet exemple, /chemin/vers/svnserve peut être un script personnalisé construit autour de svnserve qui spécifie le umask à utiliser (voir la section intitulée « Accès au dépôt par plusieurs méthodes »). Il indique aussi comment « ancrer » svnserve dans un répertoire racine virtuel, ce qui est aussi très souvent utilisé quand svnserve fonctionne en tant que démon. Le but est soit de restreindre l'accès à certaines parties du système, soit simplement d'éviter que l'utilisateur ait à taper un chemin absolu dans l'URL svn+ssh://.

Il est également possible d'avoir plusieurs utilisateurs partageant un compte utilisateur unique. Au lieu de créer un compte système distinct pour chaque utilisateur, générez plutôt un biclé de clés publique/privée pour chaque personne. Placez ensuite chaque clé publique dans le fichier authorized_users, une par ligne, et utilisez l'option --tunnel-user :

  command="svnserve -t --tunnel-user=harry" TYPE1 CLÉ1 harry@exemple.com
  command="svnserve -t --tunnel-user=sally" TYPE2 CLÉ2 sally@exemple.com

Cet exemple permet à la fois à Harry et à Sally de se connecter au même compte utilisateur avec l'authentification via leur clé publique. Une commande propre à chacun sera exécutée ; l'option --tunnel-user signale à svnserve que l'argument fourni doit être considéré comme le nom de l'utilisateur authentifié. Sans --tunnel-user, toutes les propagations sembleraient venir du même compte utilisateur partagé.

Finalement, un dernier avertissement : autoriser l'accès d'un utilisateur au serveur via une clé publique dans un compte partagé n'empêche pas forcément d'autres formes d'accès SSH, même si vous avez spécifié une valeur pour le champ command dans le fichier authorized_keys. Par exemple, l'utilisateur aura toujours accès au shell via SSH, il sera capable rediriger les flux X11 ou tout autre port de votre serveur. Pour accorder le moins de droits possibles à l'utilisateur, vous pouvez spécifier des options de restriction immédiatement après la commande du champ command :

  command="svnserve -t --tunnel-user=harry",no-port-forwarding,no-agent-forw
arding,no-X11-forwarding,no-pty TYPE1 CLÉ1 harry@exemple.com

Notez bien que tout ceci doit tenir sur une seule ligne, vraiment sur une seule ligne, car les fichiers SSH authorized_keys n'autorisent même pas le caractère habituel de continuation de ligne (\). L'unique raison pour laquelle nous avons rajouté une coupure est pour que cela tienne dans le format physique d'un livre.



[63] Voir la RFC 2195.

[64] Notez qu'utiliser le moindre contrôle d'accès avec svnserve n'a de sens que si les utilisateurs ne peuvent pas le contourner en accédant directement au répertoire du dépôt en utilisant d'autres outils (tels que cd ou vi) ; comment mettre en place de telles restrictions est décrit dans la section intitulée « Contrôle de la commande à exécuter ».

[65] Nous ne le recommandons vraiment pas, car RSH est significativement moins sécurisé que SSH.