SVNBOOK Chap6 httpd, the Apache HTTP Server

De Framalang Wiki.

Cette page fait partie du projet Version control with subversion.

Pseudo Code Rôle Statut
SVF Traduction Fait
Hotshot92 1ere Relecture Fait
Validation


Sommaire

httpd, the Apache HTTP Server

httpd, the Apache HTTP Server

httpd, le serveur HTTP Apache

The Apache HTTP Server is a “heavy-duty” network server that Subversion can leverage. Via a custom module, httpd makes Subversion repositories available to clients via the WebDAV/DeltaV protocol, which is an extension to HTTP 1.1 (see http://www.webdav.org/ for more information). This protocol takes the ubiquitous HTTP protocol that is the core of the World Wide Web, and adds writing—specifically, versioned writing—capabilities. The result is a standardized, robust system that is conveniently packaged as part of the Apache 2.0 software, supported by numerous operating systems and third-party products, and doesn't require network administrators to open up yet another custom port. [44] While an Apache-Subversion server has more features than svnserve, it's also a bit more difficult to set up. With flexibility often comes more complexity.

Much of the following discussion includes references to Apache configuration directives. While some examples are given of the use of these directives, describing them in full is outside the scope of this chapter. The Apache team maintains excellent documentation, publicly available on their web site at http://httpd.apache.org. For example, a general reference for the configuration directives is located at http://httpd.apache.org/docs-2.0/mod/directives.html.

Also, as you make changes to your Apache setup, it is likely that somewhere along the way a mistake will be made. If you are not already familiar with Apache's logging subsystem, you should become aware of it. In your httpd.conf file are directives that specify the on-disk locations of the access and error logs generated by Apache (the CustomLog and ErrorLog directives, respectively). Subversion's mod_dav_svn uses Apache's error logging interface as well. You can always browse the contents of those files for information that might reveal the source of a problem that is not clearly noticeable otherwise.

Le serveur HTTP Apache est un serveur réseau à tout faire que Subversion sait exploiter. Via un module adapté, httpd rend les dépôts Subversion accessibles aux clients par le protocole WebDAV/DeltaV, qui est une extension de HTTP 1.1 (voir http://www.webdav.org pour plus d'informations). Ce protocole se base sur HTTP, le protocole omniprésent à la base du World Wide Web, lui ajoute des fonctionnalités d'écriture et, en particulier, d'écriture versionnée. Le résultat est un système robuste et standardisé qui est inclus dans le logiciel Apache 2.0, supporté par de nombreux systèmes d'exploitation et outils tiers, et qui ne demande pas aux administrateurs réseaux d'ouvrir un port réseau supplémentaire [44]. Bien qu'un serveur Apache-Subversion ait plus de fonctionnalités que svnserve, il est aussi plus difficile à mettre en place. La flexibilité a bien souvent pour contrepartie la complexité.

Une grande partie de ce qui va suivre fait référence à des directives de configuration d'Apache. Bien que l'utilisation de ces directives soit illustrée par quelques exemples, les décrire complètement va bien au-delà du sujet de ce chapitre. L'équipe Apache tient à jour une documentation excellente, disponible publiquement sur leur site web à l'adresse http://httpd.apache.org. Par exemple, le guide de référence complet des directives de configuration est situé à l'adresse http://httpd.apache.org/docs-2.0/mod/directives.html.

En outre, au fur et à mesure des changements que vous apporterez à votre configuration d'Apache, il est probable que vous commettrez des erreurs. Si vous n'êtes pas déjà familier avec le sous-système de journalisation d'Apache, vous devriez apprendre à le connaître. Dans votre fichier httpd.conf des directives spécifient l'emplacement sur le disque des journaux d'accès et d'erreurs générés par Apache (les directives CustomLog et ErrorLog, respectivement). Le module mod_dav_svn de Subversion utilise également l'interface de journalisation des erreurs d'Apache. Pensez à naviguer dans ces fichiers lorsque vous recherchez des informations susceptibles de vous aider à trouver la source d'un problème.

POINT OF INTEREST: Why Apache 2?

Why Apache 2?
Pourquoi Apache 2 ?
If you're a system administrator, it's very likely that you're already running the Apache web server and have some prior experience with it. At the time of this writing, Apache 1.3 is the more popular version of Apache. The world has been somewhat slow to upgrade to the Apache 2.x series for various reasons: some people fear change, especially changing something as critical as a web server. Other people depend on plug-in modules that work only against the Apache 1.3 API, and they are waiting for a 2.x port. Whatever the reason, many people begin to worry when they first discover that Subversion's Apache module is written specifically for the Apache 2 API.
The proper response to this problem is: don't worry about it. It's easy to run Apache 1.3 and Apache 2 side by side; simply install them to separate places and use Apache 2 as a dedicated Subversion server that runs on a port other than 80. Clients can access the repository by placing the port number into the URL:
$ svn checkout http://host.example.com:7382/repos/project
Si vous êtes un administrateur système, il est très probable que vous utilisiez déjà le serveur web Apache et qui vous en ayez une expérience préalable. A l'heure où ces lignes sont écrites, Apache 1.3 est la version la plus populaire d'Apache. Le passage de la communauté à Apache 2 est assez lent, pour diverses raisons : certains ont peur du changement, en particulier quand il s'agit de toucher à quelque chose d'aussi essentiel qu'un serveur web. D'autres dépendent de greffons qui ne fonctionnent qu'avec l'interface (l'API) de Apache 1.3 et attendent qu'ils soient portés vers Apache 2. Quelle qu'en soit la raison, beaucoup de gens commencent à s'inquiéter quand ils découvrent que le module Apache de Subversion a été écrit spécifiquement pour l'API d'Apache 2.
La bonne réponse à cette question est : "Ne vous inquiétez pas !". Il est facile de faire fonctionner Apache 1.3 et Apache 2 côte à côte ; il suffit de les installer dans des endroits séparés et d'utiliser Apache 2 en tant que serveur dédié fonctionnant sur un port autre que le port 80. Les clients peuvent dès lors accéder au dépôt en indiquant le numéro de port dans l'URL :
$ svn checkout http://hote.exemple.com:7382/depot/projet

Prerequisites

Prerequisites

Prérequis

To network your repository over HTTP, you basically need four components, available in two packages. You'll need Apache httpd 2.0, the mod_dav DAV module that comes with it, Subversion, and the mod_dav_svn filesystem provider module distributed with Subversion. Once you have all of those components, the process of networking your repository is as simple as:

  • Getting httpd 2.0 up and running with the mod_dav module
  • Installing the mod_dav_svn backend to mod_dav, which uses Subversion's libraries to access the repository
  • Configuring your httpd.conf file to export (or expose) the repository

You can accomplish the first two items either by compiling httpd and Subversion from source code or by installing prebuilt binary packages of them on your system. For the most up-to-date information on how to compile Subversion for use with the Apache HTTP Server, as well as how to compile and configure Apache itself for this purpose, see the INSTALL file in the top level of the Subversion source code tree.

Pour mettre à disposition votre dépôt sur le réseau par HTTP, il vous faut quatre composants, disponibles dans deux paquets. Il vous faut Apache httpd 2.0, le module DAV mod_dav fourni avec, Subversion et le module mod_dav_svn implémentant le système de fichiers, qui est fourni avec Subversion. Une fois que vous avez tous ces composants, la procédure de mise en réseau de votre dépôt est aussi simple que :

  • Faire fonctionner httpd 2.0 avec le module mod_dav ;
  • Installer le module mod_dav_svn par derrière mod_dav (mod_dav_svn utilise les bibliothèques Subversion pour accéder au dépôt) ;
  • Configurer le fichier httpd.conf pour exporter (ou "exposer") le dépôt.

Vous pouvez accomplir les deux premières tâches ci-dessus soit en compilant httpd et Subversion à partir du code source soit en installant les paquets binaires précompilés correspondants sur votre système. Les informations les plus récentes sur la façon de compiler Subversion dans le cadre d'une utilisation en conjonction avec le serveur Apache HTTP, sur la compilation et la configuration Apache lui-même dans cet objectif, sont consultables dans le fichier INSTALL situé à la racine de l'arborescence du code source de Subversion.

Basic Apache Configuration

Basic Apache Configuration

Configuration Apache de base

Once you have all the necessary components installed on your system, all that remains is the configuration of Apache via its httpd.conf file. Instruct Apache to load the mod_dav_svn module using the LoadModule directive. This directive must precede any other Subversion-related configuration items. If your Apache was installed using the default layout, your mod_dav_svn module should have been installed in the modules subdirectory of the Apache install location (often /usr/local/apache2). The LoadModule directive has a simple syntax, mapping a named module to the location of a shared library on disk:

LoadModule dav_svn_module     modules/mod_dav_svn.so

Note that if mod_dav was compiled as a shared object (instead of statically linked directly to the httpd binary), you'll need a similar LoadModule statement for it, too. Be sure that it comes before the mod_dav_svn line:

LoadModule dav_module         modules/mod_dav.so
LoadModule dav_svn_module     modules/mod_dav_svn.so

At a later location in your configuration file, you now need to tell Apache where you keep your Subversion repository (or repositories). The Location directive has an XML-like notation, starting with an opening tag and ending with a closing tag, with various other configuration directives in the middle. The purpose of the Location directive is to instruct Apache to do something special when handling requests that are directed at a given URL or one of its children. In the case of Subversion, you want Apache to simply hand off support for URLs that point at versioned resources to the DAV layer. You can instruct Apache to delegate the handling of all URLs whose path portions (the part of the URL that follows the server's name and the optional port number) begin with /repos/ to a DAV provider whose repository is located at /var/svn/repository using the following httpd.conf syntax:

<Location /repos>
  DAV svn
  SVNPath /var/svn/repository
</Location>

Une fois que les composants requis sont installés sur votre système, il ne reste plus qu'à configurer Apache au moyen de son fichier httpd.conf. Indiquez à Apache de charger le module mod_dav_svn grâce à la directive LoadModule. Cette directive doit précéder tout autre élément de configuration lié à Subversion. Si votre serveur Apache a été installé avec la configuration par défaut, votre module mod_dav_svn devrait avoir été installé dans le sous-répertoire "modules" du répertoire d'installation d'Apache (souvent /usr/local/apache2). La directive LoadModule a une syntaxe très simple, faisant correspondre un nom de module à l'emplacement sur le disque d'une bibliothèque partagée :

LoadModule dav_svn_module     modules/mod_dav_svn.so

Notez que si mod_dav a aussi été compilé sous forme de bibliothèque partagée (et non par une édition de liens statiques qui le place directement dans l'exécutable httpd), il vous faudra une directive LoadModule pour celui-ci. Assurez-vous qu'il est placé avant la ligne mod_dav_svn :

LoadModule dav_module         modules/mod_dav.so
LoadModule dav_svn_module     modules/mod_dav_svn.so

Plus loin au sein de votre fichier de configuration, vous devrez indiquer à Apache l'endroit où réside votre dépôt (ou vos dépôts) Subversion. La directive Location possède une syntaxe de type XML, qui commence par une balise de début et se termine par une balise de fin et diverses autres directives de configuration au milieu. Le sens de la directive Location est de faire faire à Apache quelque chose de spécial quand il traite les requêtes adressées à une URL donnée ou à une de ses filles. Dans le cas de Subversion, il faut qu'Apache fasse traiter par la couche DAV les URL pointant vers les ressources versionnées. Vous pouvez indiquer à Apache de déléguer le traitement de toutes les URLs dont la partie chemin d'accès (la partie de l'URL qui suit le nom du serveur et le numéro de port optionnel) commence par /depot/ à un gestionnaire de DAV dont le dépôt est situé à l'adresse /var/svn/mon-depot en utilisant la syntaxe httpd.conf suivante :

<Location /depot>
  DAV svn
  SVNPath /var/svn/mon-depot
</Location>

If you plan to support multiple Subversion repositories that will reside in the same parent directory on your local disk, you can use an alternative directive—SVNParentPath—to indicate that common parent directory. For example, if you know you will be creating multiple Subversion repositories in a directory /var/svn that would be accessed via URLs such as http://my.server.com/svn/repos1, http://my.server.com/svn/repos2, and so on, you could use the httpd.conf configuration syntax in the following example:

<Location /svn>
  DAV svn

  # any "/svn/foo" URL will map to a repository /var/svn/foo
  SVNParentPath /var/svn
</Location>

Using the previous syntax, Apache will delegate the handling of all URLs whose path portions begin with /svn/ to the Subversion DAV provider, which will then assume that any items in the directory specified by the SVNParentPath directive are actually Subversion repositories. This is a particularly convenient syntax in that, unlike the use of the SVNPath directive, you don't have to restart Apache to create and network new repositories.

Be sure that when you define your new Location, it doesn't overlap with other exported locations. For example, if your main DocumentRoot is exported to /www, do not export a Subversion repository in <Location /www/repos>. If a request comes in for the URI /www/repos/foo.c, Apache won't know whether to look for a file repos/foo.c in the DocumentRoot, or whether to delegate mod_dav_svn to return foo.c from the Subversion repository. The result is often an error from the server of the form 301 Moved Permanently.

Si vous avez l'intention de gérer plusieurs dépôts Subversion résidant dans le même répertoire parent sur votre disque local, vous pouvez utiliser une directive alternative, SVNParentPath, pour faire état de ce répertoire parent commun. Par exemple, si vous savez que vous allez créer plusieurs dépôts Subversion dans le répertoire /var/svn, auxquels on accédera par des URL telles que http://mon.serveur.com/svn/depot1, http://mon.serveur.com/svn/depot2, etc., vous pouvez utiliser la syntaxe de configuration de httpd.conf de l'exemple suivant :

<Location /svn>
  DAV svn

  # à toute URL "/svn/truc" correspond un dépôt /var/svn/truc
  SVNParentPath /var/svn
</Location>

Par cette syntaxe, Apache va déléguer le traitement de toutes les URL dont le chemin d'accès commence par /svn/ au gestionnaire DAV de Subversion, qui ensuite supposera que tous les éléments du répertoire spécifié dans la directive SVNParentPath sont en fait des dépôts Subversion. C'est une syntaxe particulièrement pratique dans le sens où, à la différence de celles utilisant la directive SVNPath, vous n'avez pas besoin de redémarrer Apache pour créer et mettre à disposition sur le réseau de nouveaux dépôts.

Vérifiez bien que, quand vous définissez votre nouvelle directive Location, elle n'interfère pas avec d'autres emplacements exportés. Par exemple, si votre DocumentRoot (c'est-à-dire le répertoire racine des fichiers qu'Apache expose sur le web) principal est exporté vers /www, n'exportez pas de dépôt Subversion vers <Location /www/depot>. Si une requête arrivait pour l'URI /www/depot/truc.c, Apache ne saurait pas s'il doit chercher un fichier depot/truc.c dans son DocumentRoot, ou s'il doit déléguer à mod_dav_svn la tâche de renvoyer truc.c depuis le dépôt Subversion. Ceci aboutit souvent à une erreur du serveur de la forme 301 Moved Permanently.

POINT OF INTEREST: Server Names and the COPY Request

Server Names and the COPY Request
Noms de serveur et requêtes COPY
Subversion makes use of the COPY request type to perform server-side copies of files and directories. As part of the sanity checking done by the Apache modules, the source of the copy is expected to be located on the same machine as the destination of the copy. To satisfy this requirement, you might need to tell mod_dav the name you use as the hostname of your server. Generally, you can use the ServerName directive in httpd.conf to accomplish this.
ServerName svn.example.com
If you are using Apache's virtual hosting support via the NameVirtualHost directive, you may need to use the ServerAlias directive to specify additional names by which your server is known. Again, refer to the Apache documentation for full details.
Subversion se sert du type de requête COPY pour effectuer des copies de fichiers et de répertoires côté serveur. Les modules Apache vérifient que la source de la copie est bien située sur la même machine que la destination. Pour satisfaire cette exigence, vous aurez peut-être besoin de déclarer à mod_dav le nom que vous utilisez en tant que nom d'hôte de votre serveur. En général la directive ServerName peut être utilisée à cette fin.
ServerName svn.exemple.com
Si vous faites usage du support des hôtes virtuels d'Apache via la directive NameVirtualHost, la directive ServerAlias vous permettra de spécifier des noms additionnels désignant votre serveur. Encore une fois, reportez-vous à la documentation Apache pour plus de détails.

At this stage, you should strongly consider the question of permissions. If you've been running Apache for some time now as your regular web server, you probably already have a collection of content—web pages, scripts, and such. These items have already been configured with a set of permissions that allows them to work with Apache, or more appropriately, that allows Apache to work with those files. Apache, when used as a Subversion server, will also need the correct permissions to read and write to your Subversion repository.

You will need to determine a permission system setup that satisfies Subversion's requirements without messing up any previously existing web page or script installations. This might mean changing the permissions on your Subversion repository to match those in use by other things that Apache serves for you, or it could mean using the User and Group directives in httpd.conf to specify that Apache should run as the user and group that owns your Subversion repository. There is no single correct way to set up your permissions, and each administrator will have different reasons for doing things a certain way. Just be aware that permission-related problems are perhaps the most common oversight when configuring a Subversion repository for use with Apache.

Une fois rendu ici, il va vous falloir examiner sérieusement la question des droits d'accès. Si vous avez utilisé Apache depuis un certain temps en tant que serveur web principal, vous hébergez certainement pas mal de contenu : des pages web, des scripts, etc. Ces éléments ont déjà été configurés avec un ensemble de droits qui leur permet de fonctionner avec Apache, ou plus exactement qui permet à Apache de travailler avec ces fichiers. Apache, quand on l'utilise en tant que serveur Subversion, aura aussi besoin de droits d'accès corrects pour lire et écrire dans votre dépôt.

Vous devez mettre en place les droits d'accès qui satisfont les besoins de Subversion sans mettre à mal l'installation des pages web et scripts pré-existants. Ceci implique peut-être de modifier les droits d'accès de votre dépôt Subversion pour qu'ils correspondent à ceux utilisés par les autres éléments qu'Apache gère, ou bien utiliser les directives User et Group de httpd.conf pour spécifier qu'Apache doit fonctionner avec l'identifiant et le groupe qui est propriétaire de votre dépôt Subversion. Il n'y a pas une façon unique de mettre en place les droits d'accès et chaque administrateur aura des raisons différentes de faire les choses d'une manière ou d'une autre. Soyez juste conscient que les problèmes liés aux droits d'accès sont peut-être le point le plus négligé lors de la configuration d'un dépôt avec Apache.

Authentication Options

Authentication Options

Options d'authentification

At this point, if you configured httpd.conf to contain something such as the following:

<Location /svn>
  DAV svn
  SVNParentPath /var/svn
</Location>

your repository is “anonymously” accessible to the world. Until you configure some authentication and authorization policies, the Subversion repositories that you make available via the Location directive will be generally accessible to everyone. In other words:

  • Anyone can use a Subversion client to check out a working copy of a repository URL (or any of its subdirectories).
  • Anyone can interactively browse the repository's latest revision simply by pointing a web browser to the repository URL.
  • Anyone can commit to the repository.

Of course, you might have already set up a pre-commit hook script to prevent commits (see the section called “Implementing Repository Hooks”). But as you read on, you'll see that it's also possible to use Apache's built-in methods to restrict access in specific ways.

À ce stade, si vous avez configuré httpd.conf avec quelque chose du style :

<Location /svn>
  DAV svn
  SVNParentPath /var/svn
</Location>

votre dépôt est à présent accessible "anonymement" au reste du monde. Jusqu'à ce que configuriez des politiques d'authentification et de contrôle d'accès, les dépôts Subversion que vous rendez disponible via la directive Location sont généralement accessibles à tous. En d'autres termes :

  • N'importe qui peut utiliser un client Subversion pour extraire une copie de travail d'une URL du dépôt (ou de n'importe lequel de ses sous-répertoires).
  • N'importe qui peut naviguer interactivement dans la dernière révision du dépôt rien qu'en allant avec un navigateur web à l'URL du dépôt.
  • N'importe qui peut effectuer des propagations vers le dépôt.

Bien sûr, vous avez peut-être déjà mis en place une procédure automatique pré-propagation pour empêcher les propagations (voir le paragraphe intitulé "Mettre en place des procédures automatiques"). Mais en progressant dans la lecture de ce chapitre, vous verrez qu'il est également possible d'utiliser les méthodes intégrées dans Apache pour restreindre les accès de façon spécifique.

Setting up HTTP authentication

Setting up HTTP authentication

Mettre en place l'authentification HTTP

The easiest way to authenticate a client is via the HTTP Basic authentication mechanism, which simply uses a username and password to verify that a user is who she says she is. Apache provides an htpasswd utility for managing the list of acceptable usernames and passwords. Let's grant commit access to Sally and Harry. First, we need to add them to the password file:

$ ### First time: use -c to create the file
$ ### Use -m to use MD5 encryption of the password, which is more secure
$ htpasswd -cm /etc/svn-auth-file harry
New password: *****
Re-type new password: *****
Adding password for user harry
$ htpasswd -m /etc/svn-auth-file sally
New password: *******
Re-type new password: *******
Adding password for user sally
$

Next, you need to add some more httpd.conf directives inside your Location block to tell Apache what to do with your new password file. The AuthType directive specifies the type of authentication system to use. In this case, we want to specify the Basic authentication system. AuthName is an arbitrary name that you give for the authentication domain. Most browsers will display this name in the pop-up dialog box when the browser is querying the user for her name and password. Finally, use the AuthUserFile directive to specify the location of the password file you created using htpasswd.

La manière la plus facile d'authentifier un client est le mécanisme d'authentification "Basic" de HTTP, qui utilise juste un nom d'utilisateur et un mot de passe pour vérifier que l'utilisateur est bien celui qu'il prétend être. Apache fournit un utilitaire htpasswd pour gérer la liste des noms d'utilisateurs et mots de passe acceptés. Accordons le droit de propager à Sally et à Harry. D'abord, il faut les ajouter au fichier des mots de passe :

$ ### Première fois : utilisez -c pour créer le fichier
$ ### Ajoutez -m pour MD5 afin de chiffrer le mot de passe et ainsi le rendre plus sûr
$ htpasswd -cm /etc/fichier-auth-svn harry
New password: *****
Re-type new password: *****
Adding password for user harry
$ htpasswd -m /etc/fichier-auth-svn sally
New password: *******
Re-type new password: *******
Adding password for user sally
$

After adding these three directives, your <Location> block should look something like this:

<Location /svn>
  DAV svn
  SVNParentPath /var/svn
  AuthType Basic
  AuthName "Subversion repository"
  AuthUserFile /etc/svn-auth-file
</Location>

This <Location> block is not yet complete, and it will not do anything useful. It's merely telling Apache that whenever authorization is required, Apache should harvest a username and password from the Subversion client. What's missing here, however, are directives that tell Apache which sorts of client requests require authorization. Wherever authorization is required, Apache will demand authentication as well. The simplest thing to do is protect all requests. Adding Require valid-user tells Apache that all requests require an authenticated user:

<Location /svn>
  DAV svn
  SVNParentPath /var/svn
  AuthType Basic
  AuthName "Subversion repository"
  AuthUserFile /etc/svn-auth-file
  Require valid-user
</Location>

Après avoir ajouté ces trois directives, votre bloc <Location> devrait ressembler à ceci :

<Location /svn>
  DAV svn
  SVNParentPath /var/svn
  AuthType Basic
  AuthName "Depot Subversion"
  AuthUserFile /etc/fichier-auth-svn
</Location>

Ce bloc <Location> n'est pas encore complet et il ne sert pas à grand chose pour l'instant. Il indique juste à Apache que, lorsqu'un contrôle d'accès est requis, Apache doit demander un nom d'utilisateur et un mot de passe au client Subversion. Ce qui manque ici, cependant, ce sont les directives qui indiquent à Apache quelles sortes de requêtes client requièrent un contrôle d'accès. Dès que le contrôle d'accès sera demandé, Apache exigera également l'authentification. La chose la plus simple à faire est de protéger toutes les requêtes. Ajouter Require valid-user signale à Apache que toutes les requêtes exigent que l'utilisateur soit authentifié :

<Location /svn>
  DAV svn
  SVNParentPath /var/svn
  AuthType Basic
  AuthName "Depot Subversion"
  AuthUserFile /etc/fichier-auth-svn
  Require valid-user
</Location>

Be sure to read the next section (the section called “Authorization Options”) for more detail on the Require directive and other ways to set authorization policies.

One word of warning: HTTP Basic Auth passwords pass in very nearly plain text over the network, and thus are extremely insecure.

Another option is to not use Basic authentication, but to use Digest authentication instead. Digest authentication allows the server to verify the client's identity without passing the plain-text password over the network. Assuming that the client and server both know the user's password, they can verify that the password is the same by using it to apply a hashing function to a one-time bit of information. The server sends a small random-ish string to the client; the client uses the user's password to hash the string; the server then looks to see whether the hashed value is what it expected.

Configuring Apache for Digest authentication is also fairly easy, and only a small variation on our prior example. Be sure to consult Apache's documentation for full details.

<Location /svn>
  DAV svn
  SVNParentPath /var/svn
  AuthType Digest
  AuthName "Subversion repository"
  AuthDigestDomain /svn/
  AuthUserFile /etc/svn-auth-file
  Require valid-user
</Location>

If you're looking for maximum security, public key cryptography is the best solution. It may be best to use some sort of SSL encryption, so that clients authenticate via https:// instead of http://; at a bare minimum, you can configure Apache to use a self-signed server certificate. [45] Consult Apache's documentation (and OpenSSL documentation) about how to do that.

Prenez bien soin de lire le paragraphe suivant (intitulé "Options de contrôle d'accès") pour plus de détails sur la directive Require et sur les autres manières de mettre en oeuvre des politiques de contrôle d'accès.

Un petit avertissement : les mots de passe de la méthode HTTP Basic Auth circulent pratiquement en clair sur le réseau et ne sont donc pas du tout sécurisés.

Une autre possibilité est de ne pas utiliser la méthode d'authentification Basic mais d'utiliser la méthode d'authentification Digest à la place. L'authentification Digest permet au server de vérifier l'identité du client sans envoyer le mot de passe en clair sur le réseau. En supposant que le client et le serveur connaissent tous les deux le mot de passe de l'utilisateur, ils peuvent vérifier que le mot de passe est le même en l'utilisant pour appliquer une fonction de hachage à une donnée créée pour l'occasion. Le serveur envoie au client une chaîne plus ou moins aléatoire de petite taille ; le client se sert du mot de passe de l'utilisateur pour créer un condensat (hash en anglais) de cette chaîne ; le serveur examine ensuite si le condensat correspond à ses attentes.

Configurer Apache pour la méthode d'authentification Digest est également assez facile et ne comporte qu'une petite variation par rapport à notre exemple précédent. Prenez soin de consulter la documentation complète d'Apache pour plus de détails.

<Location /svn>
  DAV svn
  SVNParentPath /var/svn
  AuthType Digest
  AuthName "Depot Subversion"
  AuthDigestDomain /svn/
  AuthUserFile /etc/fichier-auth-svn
  Require valid-user
</Location>

Si vous recherchez la sécurité maximale, la cryptographie à clé publique est la meilleure solution. Il est sans doute mieux d'utiliser du chiffrement SSL afin que les clients s'authentifient via https:// au lieu de http:// ; le minimum minimorum consiste alors à configurer Apache pour qu'il utilise un certificat serveur auto-signé [45]. Consultez la documentation Apache (et la documentation OpenSSL) pour savoir comment faire.

SSL certificate management

SSL certificate management

Gestion des certificats SSL

Businesses that need to expose their repositories for access outside the company firewall should be conscious of the possibility that unauthorized parties could be “sniffing” their network traffic. SSL makes that kind of unwanted attention less likely to result in sensitive data leaks.

If a Subversion client is compiled to use OpenSSL, it gains the ability to speak to an Apache server via https:// URLs. The Neon library used by the Subversion client is not only able to verify server certificates, but can also supply client certificates when challenged. When the client and server have exchanged SSL certificates and successfully authenticated one another, all further communication is encrypted via a session key.

It's beyond the scope of this book to describe how to generate client and server certificates and how to configure Apache to use them. Many other books, including Apache's own documentation, describe this task. But what we can cover here is how to manage server and client certificates from an ordinary Subversion client.

When speaking to Apache via https://, a Subversion client can receive two different types of information:

  • A server certificate
  • A demand for a client certificate

Les entreprises qui ont besoin de rendre leur dépôts disponibles au-delà du pare-feu périmétrique de leur société doivent être conscientes que des entités non-autorisées auront la possibilité d'"écouter" leur trafic réseau. SSL permet de diminuer le risque que cette écoute conduise à des fuites de données sensibles.

Si un client Subversion est compilé pour utiliser OpenSSL, il obtient la possibilité de communiquer avec le serveur Apache via des URLs https://. La bibliothèque Neon utilisée par le client Subversion est non seulement capable de vérifier les certificats du serveur, mais aussi de renvoyer des certificats clients quand on le lui demande. Une fois que le client et le serveur ont échangé des certificats SSL et se sont authentifiés mutuellement avec succès, toute la communication qui s'ensuit est chiffrée par une clé de session.

Expliquer comment générer des certificats clients et serveurs ou comment configurer Apache pour les utiliser s'éloigne trop du sujet de ce livre. De nombreux autres livres, dont la documentation Apache elle-même, expliquent comment le faire. Mais nous pouvons quand même traiter ici la question de la gestion des certificats clients et serveurs à partir d'un client Subversion ordinaire.

Quand il communique avec Apache via https://, un client Subversion peut recevoir deux types d'informations différentes :

  • Un certificat serveur
  • Une demande de certificat client

If the client receives a server certificate, it needs to verify that it trusts the certificate: is the server really who it claims to be? The OpenSSL library does this by examining the signer of the server certificate, or certificate authority (CA). If OpenSSL is unable to automatically trust the CA, or if some other problem occurs (such as an expired certificate or hostname mismatch), the Subversion command-line client will ask you whether you want to trust the server certificate anyway:

$ svn list https://host.example.com/repos/project

Error validating server certificate for 'https://host.example.com:443':
 - The certificate is not issued by a trusted authority. Use the
   fingerprint to validate the certificate manually!
Certificate information:
 - Hostname: host.example.com
 - Valid: from Jan 30 19:23:56 2004 GMT until Jan 30 19:23:56 2006 GMT
 - Issuer: CA, example.com, Sometown, California, US
 - Fingerprint: 7d:e1:a9:34:33:39:ba:6a:e9:a5:c4:22:98:7b:76:5c:92:a0:9c:7b

(R)eject, accept (t)emporarily or accept (p)ermanently?

This dialogue should look familiar; it's essentially the same question you've probably seen coming from your web browser (which is just another HTTP client like Subversion). If you choose the (p)ermanent option, the server certificate will be cached in your private runtime auth/ area in just the same way your username and password are cached (see the section called “Client Credentials Caching”). If cached, Subversion will automatically trust this certificate in future negotiations.

Your runtime servers file also gives you the ability to make your Subversion client automatically trust specific CAs, either globally or on a per-host basis. Simply set the ssl-authority-files variable to a semicolon-separated list of PEM-encoded CA certificates:

[global]
ssl-authority-files = /path/to/CAcert1.pem;/path/to/CAcert2.pem

Many OpenSSL installations also have a predefined set of “default” CAs that are nearly universally trusted. To make the Subversion client automatically trust these standard authorities, set the ssl-trust-default-ca variable to true.

Si le client reçoit un certificat serveur, il doit vérifier que ce certificat est digne de confiance : le serveur est-il bien celui qu'il prétend être ? La bibliothèque OpenSSL effectue cette vérification en examinant le signataire du certificat serveur, aussi nommé autorité de certification (AC, ou "CA" en anglais). Si OpenSSL n'est pas capable de faire confiance automatiquement à l'autorité de certification, ou si un autre problème apparaît (tel que l'expiration du certificat ou des noms d'hôtes divergents), le client en ligne de commande de Subversion vous demandera si vous voulez faire confiance au certificat serveur malgré tout :

$ svn list https://hote.exemple.com/depot/projet

(de 'https://hote.exemple.com:443') - Le certificat conduit à une erreur inconnue :
 - Le certificat a expiré.
 - Le nom d'hôte du certificat ne correspond pas.
 - Le certificat n'est pas signé pas une autorité de confiance.
   Valider le certificat manuellement !
Informations du certificat :
 - nom d'hôte : hote.exemple.com
 - valide de Jan 30 19:23:56 2004 GMT à Jan 30 19:23:56 2006 GMT
 - signataire : CA, exemple.com, Sometown, California, US
 - empreinte : 7d:e1:a9:34:33:39:ba:6a:e9:a5:c4:22:98:7b:76:5c:92:a0:9c:7b

(R)ejet, acceptation (t)emporaire ou (p)ermanente ? 

Cette question devrait vous être familière ; c'est probablement la même que vous avez déjà dû voir posée par votre navigateur web (qui n'est rien d'autre qu'un client HTTP comme Subversion). Si vous choisissez l'option (p)ermanente, le certificat du serveur sera mis en cache dans votre zone privée auth/ de la même façon que le nom d'utilisateur et le mot de passe y sont conservés (voir le paragraphe intitulé "Mise en cache des éléments d'authentification du client"). S'il est en cache, Subversion fera automatiquement confiance à ce certificat dans les échanges futurs.

Votre fichier de serveurs dans la zone de configuration des exécutables vous permet également d'indiquer à votre client Subversion qu'il doit faire confiance automatiquement à certaines autorités de certification spécifiques, soit globalement, soit en tenant compte de la machine hôte. Il suffit d'attribuer à la variable ssl-authority-files une liste de certificats d'autorités de certification au format PEM, séparés par des points-virgules :

[global]
ssl-authority-files = /chemin/vers/certAC1.pem;/chemin/vers/certAC2.pem

De nombreuses installations d'OpenSSL possèdent par défaut une liste prédéfinie d'autorités de certification auxquelles il est fait confiance de manière quasi-universelle. Pour que le client Subversion fasse confiance à ces autorités de certification automatiquement, mettez à true la variable ssl-trust-default-ca.

--Sub Versif 26 avril 2009 à 12:15 (CEST) : format de la date de l'exemple à vérifier

When talking to Apache, a Subversion client might also receive a challenge for a client certificate. Apache is asking the client to identify itself: is the client really who it says it is? If all goes correctly, the Subversion client sends back a private certificate signed by a CA that Apache trusts. A client certificate is usually stored on disk in encrypted format, protected by a local password. When Subversion receives this challenge, it will ask you for a path to the certificate and the password that protects it:

$ svn list https://host.example.com/repos/project

Authentication realm: https://host.example.com:443
Client certificate filename: /path/to/my/cert.p12
Passphrase for '/path/to/my/cert.p12':  ********
...

Notice that the client certificate is a “p12” file. To use a client certificate with Subversion, it must be in PKCS#12 format, which is a portable standard. Most web browsers are already able to import and export certificates in that format. Another option is to use the OpenSSL command-line tools to convert existing certificates into PKCS#12.

Again, the runtime servers file allows you to automate this challenge on a per-host basis. Either or both pieces of information can be described in runtime variables:

[groups]
examplehost = host.example.com
 
[examplehost]
ssl-client-cert-file = /path/to/my/cert.p12
ssl-client-cert-password = somepassword

Once you've set the ssl-client-cert-file and ssl-client-cert-password variables, the Subversion client can automatically respond to a client certificate challenge without prompting you. [46]

--Hotshot92 29 avril 2009 à 15:02 (CEST):Le texte original ne semble pas complètement correct

Quand il communique avec Apache, un client Subversion peut également recevoir une demande (un défi) de certificat client. Apache demande au client de s'authentifier : le client est-il bien celui qu'il prétend être ? Si tout se passe bien, le client Subversion renvoie un certificat (public) signé par une autorité de certification en laquelle Apache a confiance ainsi qu'une preuve que le client possède bien la clé privée associée au certificat (la réponse au défi). La clé privée est habituellement enregistrée chiffrée dans un conteneur (au format PKCS#12) sur le disque, protégé par un mot de passe local. Quand Subversion reçoit ce défi, il vous demandera le chemin d'accès au conteneur de la clé privée ainsi que le mot de passe qui le protège :

$ svn list https://hote.exemple.com/depot/projet

Domaine d'authentification :  https://hote.exemple.com:443
Fichier du certificat client : /chemin/vers/mon/cert.p12
Phrase de passe pour '/chemin/vers/mon/cert.p12' : ********
...

Remarquez que le certificat client est dans un fichier "p12". Pour utiliser un certificat client avec Subversion, il doit être dans un conteneur au format PKCS#12, qui est un standard portable. La plupart des navigateurs web sont déjà capables d'importer et d'exporter des certificats dans ce format. Une autre option est d'utiliser les outils en ligne de commande d'OpenSSL pour convertir les certificats existants en PKCS#12.

Encore une fois, le fichier "servers" de la zone de configuration des exécutables vous permet d'automatiser la réponses à ces demandes en tenant compte de la machine hôte. L'une ou l'autre des informations, ou bien les deux, peuvent être décrites dans les variables de configuration :

[groups]
exemple-d-hote = hote.exemple.com
 
[exemple-d-hote]
ssl-client-cert-file = /chemin/vers/mon/cert.p12
ssl-client-cert-password = un-mot-de-passe

Une fois que vous avez défini les variables ssl-client-cert-file et ssl-client-cert-password, le client Subversion peut répondre automatiquement à une demande de certificat client sans la moindre interaction de votre part [46].

Authorization Options

Authorization Options

Options de contrôle d'accès

At this point, you've configured authentication, but not authorization. Apache is able to challenge clients and confirm identities, but it has not been told how to allow or restrict access to the clients bearing those identities. This section describes two strategies for controlling access to your repositories.

À ce stade, vous avez configuré l'authentification mais pas le contrôle d'accès. Apache est capable d'envoyer des défis aux clients afin de confirmer leur identité mais on ne lui a pas encore dit comment autoriser ou restreindre les accès en fonction de l'utilisateur. Ce paragraphe décrit deux stratégies pour contrôler les accès au dépôt.

Blanket access control

Blanket access control

Contrôle d'accès générique

The simplest form of access control is to authorize certain users for either read-only access to a repository or read/write access to a repository.

You can restrict access on all repository operations by adding the Require valid-user directive to your <Location> block. Using our previous example, this would mean that only clients that claimed to be either harry or sally and that provided the correct password for their respective username would be allowed to do anything with the Subversion repository:

<Location /svn>
  DAV svn
  SVNParentPath /var/svn

  # how to authenticate a user
  AuthType Basic
  AuthName "Subversion repository"
  AuthUserFile /path/to/users/file

  # only authenticated users may access the repository
  Require valid-user
</Location>

Sometimes you don't need to run such a tight ship. For example, Subversion's own source code repository at http://svn.collab.net/repos/svn allows anyone in the world to perform read-only repository tasks (such as checking out working copies and browsing the repository with a web browser), but restricts all write operations to authenticated users. To do this type of selective restriction, you can use the Limit and LimitExcept configuration directives. Like the Location directive, these blocks have starting and ending tags, and you would nest them inside your <Location> block.

La forme la plus simple de contrôle d'accès est d'autoriser des utilisateurs donnés à accéder à un dépôt en lecture seule ou en lecture/écriture.

Vous pouvez restreindre l'accès à toutes les opérations du dépôt en ajoutant la directive Require valid-user à votre bloc <Location>. Pour poursuivre dans la veine de notre exemple précédent, cela signifierait que seuls les clients disant être Harry ou Sally et qui ont fourni le bon mot de passe pour leur nom d'utilisateur respectif ont l'autorisation d'effectuer des actions sur le dépôt Subversion :

<Location /svn>
  DAV svn
  SVNParentPath /var/svn
  
  # comment authentifier un utilisateur
  AuthType Basic
  AuthName "Depot Subversion"
  AuthUserFile /chemin/vers/fichier/utilisateurs
  
  # seuls les utilisateurs authentifiés ont le droit d'accès au dépôt
  Require valid-user
</Location>

Parfois vous n'aurez pas besoin d'être aussi strict. Par exemple, le propre dépôt du code source de Subversion, situé à l'adresse http://svn.collab.net/repos/svn, autorise toute personne à effectuer des opérations de lecture du dépôt (comme extraire des copies de travail ou naviguer dans le dépôt avec un navigateur web) mais restreint toutes les opérations d'écriture aux utilisateurs authentifiés. Pour accomplir ce type de restriction sélective, vous pouvez utiliser les directives de configuration Limit et LimitExcept. Tout comme la directive Location, ces blocs doivent débuter et finir par des balises, et vous devez les imbriquer dans votre bloc <Location>.

The parameters present on the Limit and LimitExcept directives are HTTP request types that are affected by that block. For example, if you wanted to disallow all access to your repository except the currently supported read-only operations, you would use the LimitExcept directive, passing the GET, PROPFIND, OPTIONS, and REPORT request type parameters. Then the previously mentioned Require valid-user directive would be placed inside the <LimitExcept> block instead of just inside the <Location> block.

<Location /svn>
  DAV svn
  SVNParentPath /var/svn

  # how to authenticate a user
  AuthType Basic
  AuthName "Subversion repository"
  AuthUserFile /path/to/users/file

  # For any operations other than these, require an authenticated user.
  <LimitExcept GET PROPFIND OPTIONS REPORT>
    Require valid-user
  </LimitExcept>
</Location>

These are only a few simple examples. For more in-depth information about Apache access control and the Require directive, take a look at the Security section of the Apache documentation's tutorials collection at http://httpd.apache.org/docs-2.0/misc/tutorials.html.

Les paramètres présents dans les directives Limit et LimitExcept sont des types de requêtes HTTP qui sont concernés par ce bloc. Par exemple, si voulez désactiver tout accès au dépôt excepté pour les opérations de lecture déjà supportées, utilisez la directive LimitExcept, en lui passant les paramètres de type de requêtes GET, PROPFIND, OPTIONS et REPORT. Ensuite placez la directive Require valid-user mentionnée précédemment à l'intérieur du bloc <LimitExcept> au lieu de la mettre juste à l'intérieur du bloc <Location>.

<Location /svn>
  DAV svn
  SVNParentPath /var/svn

  # comment authentifier un utilisateur
  AuthType Basic
  AuthName "Depot Subversion"
  AuthUserFile /chemin/vers/fichier/utilisateurs

  # Pour toute autre opération que celles-ci, exiger un utilisateur authentifié.
  <LimitExcept GET PROPFIND OPTIONS REPORT>
    Require valid-user
  </LimitExcept>
</Location>

Ce ne sont là que quelques exemples simples. Pour des informations plus poussées sur le contrôle d'accès d'Apache et la directive Require, jetez un oeil à la section Security du recueil des tutoriaux de la documentation Apache à l'adresse http://httpd.apache.org/docs-2.0/misc/tutorials.html (site en anglais).

Per-directory access control

Per-directory access control

Contrôle d'accès par répertoire

It's possible to set up finer-grained permissions using a second Apache httpd module, mod_authz_svn. This module grabs the various opaque URLs passing from client to server, asks mod_dav_svn to decode them, and then possibly vetoes requests based on access policies defined in a configuration file.

If you've built Subversion from source code, mod_authz_svn is automatically built and installed alongside mod_dav_svn. Many binary distributions install it automatically as well. To verify that it's installed correctly, make sure it comes right after mod_dav_svn's LoadModule directive in httpd.conf:

LoadModule dav_module         modules/mod_dav.so
LoadModule dav_svn_module     modules/mod_dav_svn.so
LoadModule authz_svn_module   modules/mod_authz_svn.so

To activate this module, you need to configure your Location block to use the AuthzSVNAccessFile directive, which specifies a file containing the permissions policy for paths within your repositories. (In a moment, we'll discuss the format of that file.)

Apache is flexible, so you have the option to configure your block in one of three general patterns. To begin, choose one of these basic configuration patterns. (The following examples are very simple; look at Apache's own documentation for much more detail on Apache authentication and authorization options.)

The simplest block is to allow open access to everyone. In this scenario, Apache never sends authentication challenges, so all users are treated as “anonymous.” (See Example 6.1, “A sample configuration for anonymous access”.)

Example 6.1. A sample configuration for anonymous access

<Location /repos>
  DAV svn
  SVNParentPath /var/svn

  # our access control policy
  AuthzSVNAccessFile /path/to/access/file
</Location>

On peut également mettre en place des droits d'accès avec une granularité plus fine en utilisant un second module Apache httpd, mod_authz_svn. Ce module se saisit des diverses URL opaques qui transitent entre le client et le serveur, demande à mod_dav_svn de les décoder et ensuite met éventuellement son veto à certaines requêtes en se basant sur les politiques d'accès définies dans un fichier de configuration.

Si vous avez compilé Subversion à partir du code source, mod_authz_svn est automatiquement inclus et installé aux côtés de mod_dav_svn. De nombreux exécutables distribués l'installent automatiquement aussi. Pour vérifier qu'il est installé correctement, assurez-vous qu'il vient juste après la directive LoadModule de mod_dav_svn dans httpd.conf :

LoadModule dav_module         modules/mod_dav.so
LoadModule dav_svn_module     modules/mod_dav_svn.so
LoadModule authz_svn_module   modules/mod_authz_svn.so

Pour activer ce module, vous devez configurer votre bloc Location pour qu'il utilise la directive AuthzSVNAccessFile ; elle spécifie quel fichier contient les politiques de contrôle d'accès aux chemins de vos dépôts (dans quelques instants nous étudierons le format de ce fichier).

Apache est flexible, vous avez donc la possibilité de configurer votre bloc selon une méthode à choisir parmi trois. Pour commencer, choisissez une des méthodes de configuration de base (les exemples suivants sont très simples ; reportez-vous à la documentation Apache qui contient beaucoup plus de détails sur les options d'authentification et de contrôle d'accès d'Apache).

Le bloc le plus simple consiste à donner l'accès à tout le monde. Dans ce scénario, Apache n'envoie jamais de défi d'authentification, tous les utilisateurs sont donc traités en tant qu'"anonymes" (voir l'exemple 6.1, "Exemple-type de configuration : accès anonyme").

Example 6.1. Exemple-type de configuration : accès anonyme

<Location /depot>
  DAV svn
  SVNParentPath /var/svn

  # notre politique de contrôle d'accès
  AuthzSVNAccessFile /chemin/vers/fichier/acces
</Location>

On the opposite end of the paranoia scale, you can configure your block to demand authentication from everyone. All clients must supply credentials to identify themselves. Your block unconditionally requires authentication via the Require valid-user directive, and it defines a means to authenticate. (See Example 6.2, “A sample configuration for authenticated access”.)

Example 6.2. A sample configuration for authenticated access

<Location /repos>
  DAV svn
  SVNParentPath /var/svn

  # our access control policy
  AuthzSVNAccessFile /path/to/access/file

  # only authenticated users may access the repository
  Require valid-user

  # how to authenticate a user
  AuthType Basic
  AuthName "Subversion repository"
  AuthUserFile /path/to/users/file
</Location>          

A l'opposé sur l'échelle de la paranoïa, vous pouvez configurer votre bloc de telle sorte qu'il exige que tout le monde s'authentifie. Ici, tous les clients doivent fournir un mot de passe pour prouver leur identité. Votre bloc exige l'authentification inconditionnelle via la directive Require valid-user et définit le moyen de s'authentifier (voir l'exemple 6.2, "Exemple-type de configuration : accès authentifié").

Example 6.2. Exemple-type de configuration : accès authentifié

<Location /depot>
  DAV svn
  SVNParentPath /var/svn

  # notre politique de contrôle d'accès
  AuthzSVNAccessFile /chemin/vers/fichier/acces

  # seuls les utilisateurs authentifiés ont accès au dépôt
  Require valid-user

  # comment authentifier un utilisateur
  AuthType Basic
  AuthName "Depot Subversion"
  AuthUserFile /chemin/vers/fichier/utilisateurs
</Location>          

A third very popular pattern is to allow a combination of authenticated and anonymous access. For example, many administrators want to allow anonymous users to read certain repository directories, but want only authenticated users to read (or write) more sensitive areas. In this setup, all users start out accessing the repository anonymously. If your access control policy demands a real username at any point, Apache will demand authentication from the client. To do this, use both the Satisfy Any and Require valid-user directives together. (See Example 6.3, “A sample configuration for mixed authenticated/anonymous access”.)

Example 6.3. A sample configuration for mixed authenticated/anonymous access

<Location /repos>
  DAV svn
  SVNParentPath /var/svn

  # our access control policy
  AuthzSVNAccessFile /path/to/access/file

  # try anonymous access first, resort to real
  # authentication if necessary.
  Satisfy Any
  Require valid-user

  # how to authenticate a user
  AuthType Basic
  AuthName "Subversion repository"
  AuthUserFile /path/to/users/file
</Location>

Once you've settled on one of these three basic httpd.conf templates, you need to create your file containing access rules for particular paths within the repository. We describe this later in this chapter, in the section called “Path-Based Authorization”.

Une troisième méthode largement pratiquée consiste à autoriser à la fois des accès anonymes et des accès authentifiés. Par exemple, de nombreux administrateurs désirent autoriser les utilisateurs anonymes à lire certains répertoires dans les dépôts mais ne veulent voir que des utilisateurs authentifiés accéder en lecture (ou en écriture) à des zones plus sensibles. Dans cette configuration, tous les utilisateurs commencent par accéder au dépôt de façon anonyme. Si votre politique de contrôle d'accès exige un véritable nom d'utilisateur à un moment ou à un autre, Apache demandera au client de s'authentifier. Pour ce faire, vous devrez utiliser à la fois la directive Satisfy Any et la directive Require valid-user (voir l'exemple 6.3, "Exemple-type de configuration : accès mixte authentifié/anonyme").

Exemple 6.3. Exemple-type de configuration : accès mixte authentifié/anonyme

<Location /depot>
  DAV svn
  SVNParentPath /var/svn

  # notre politique de contrôle d'accès
  AuthzSVNAccessFile /chemin/vers/fichier/acces

  # essayer d'abord un accès anonyme,
  # ne demander une véritable authentification
  # que si nécessaire
  Satisfy Any
  Require valid-user

  # comment authentifier un utilisateur
  AuthType Basic
  AuthName "Depot Subversion"
  AuthUserFile /chemin/vers/fichier/utilisateurs
</Location>

Disabling path-based checks

Disabling path-based checks

Désactiver les contrôles sur les chemins

The mod_dav_svn module goes through a lot of work to make sure that data you've marked “unreadable” doesn't get accidentally leaked. This means it needs to closely monitor all of the paths and file-contents returned by commands such as svn checkout and svn update. If these commands encounter a path that isn't readable according to some authorization policy, the path is typically omitted altogether. In the case of history or rename tracing—for example, running a command such as svn cat -r OLD foo.c on a file that was renamed long ago—the rename tracking will simply halt if one of the object's former names is determined to be read-restricted.

All of this path checking can sometimes be quite expensive, especially in the case of svn log. When retrieving a list of revisions, the server looks at every changed path in each revision and checks it for readability. If an unreadable path is discovered, it's omitted from the list of the revision's changed paths (normally seen with the --verbose option), and the whole log message is suppressed. Needless to say, this can be time-consuming on revisions that affect a large number of files. This is the cost of security: even if you haven't configured a module such as mod_authz_svn at all, the mod_dav_svn module is still asking Apache httpd to run authorization checks on every path. The mod_dav_svn module has no idea what authorization modules have been installed, so all it can do is ask Apache to invoke whatever might be present.

On the other hand, there's also an escape hatch of sorts, which allows you to trade security features for speed. If you're not enforcing any sort of per-directory authorization (i.e., not using mod_authz_svn or similar module), you can disable all of this path checking. In your httpd.conf file, use the SVNPathAuthz directive as shown in Example 6.4, “Disabling path checks altogether”.

Example 6.4. Disabling path checks altogether

<Location /repos>
  DAV svn
  SVNParentPath /var/svn

  SVNPathAuthz off
</Location>

The SVNPathAuthz directive is “on” by default. When set to “off,” all path-based authorization checking is disabled; mod_dav_svn stops invoking authorization checks on every path it discovers.

Le module mod_dav_svn se donne beaucoup de peine pour assurer que les données que vous avez désignées comme "interdites" ne soient pas divulguées accidentellement. Cela veut dire qu'il doit surveiller étroitement tous les chemins d'accès et tous les contenus des fichiers renvoyés par des commandes telles que svn checkout et svn update. Si ces commandes tombent sur un chemin qui n'est pas lisible à cause d'une politique de contrôle d'accès, le chemin est généralement totalement omis. Dans le cas d'une recherche d'historique ou de renommage, par exemple d'une commande telle que svn cat -r ANCIENNE_REVISION truc.c sur un fichier qui a été renommé il y a longtemps, le suivi des renommages va simplement s'arrêter si un des anciens noms de l'objet se révèle être en accès restreint en lecture.

Ces contrôles sur les chemins peuvent parfois être assez coûteux, tout particulièrement dans le cas de svn log. Quand il demande une liste de révisions, le serveur examine chaque chemin modifié dans chaque révision et vérifie qu'il a le droit d'être lu. Si un chemin interdit est découvert, il est omis de la liste des chemins modifiés par la révision (obtenue habituellement par l'option --verbose) et le message de propagation est entièrement supprimé. Il va sans dire que ceci peut prendre un certain temps pour les révisions qui ont touché à un grand nombre de fichiers. C'est le coût de la sécurité : même si vous n'avez pas du tout configuré de module tel que mod_authz_svn, le module mod_dav_svn va quand même demander à httpd Apache de vérifier les droits d'accès pour chaque chemin. Le module mod_dav_svn n'est pas au courant de la liste des modules qui ont été installés, donc tout ce qu'il peut faire est de demander à Apache de lancer n'importe quel contrôle qui soit présent.

D'un autre côté, il existe une sorte d'échappatoire qui vous permet de faire un compromis entre les fonctions de sécurité et la vitesse. Si vous ne mettez pas en oeuvre de contrôle d'accès sur les chemins (c'est-à-dire, si vous n'utilisez ni mod_authz_svn ni un module similaire), vous pouvez désactiver tous ces contrôles sur les chemins. Dans votre fichier httpd.conf, utilisez la directive SVNPathAuthz comme illustré dans l'exemple 6.4, "Désactiver complètement les contrôles sur les chemins".

Exemple 6.4. Désactiver complètement les contrôles sur les chemins

<Location /depot>
  DAV svn
  SVNParentPath /var/svn

  SVNPathAuthz off
</Location>

La directive SVNPathAuthz est activée par défaut. Quand on la désactive, tous les contrôles d'accès basés sur les chemins sont désactivés ; mod_dav_svn arrête de contrôler chaque chemin qu'il traite.

Extra Goodies

Extra Goodies

Fonctionnalités bonus

We've covered most of the authentication and authorization options for Apache and mod_dav_svn. But there are a few other nice features that Apache provides.

Nous avons traité la plupart des options d'authentification et de contrôle d'accès pour Apache et mod_dav_svn. Mais Apache fournit quelques autres fonctionnalités sympathiques.

Repository browsing

Repository browsing

Naviguer dans les dépôts

One of the most useful benefits of an Apache/WebDAV configuration for your Subversion repository is that the youngest revisions of your versioned files and directories are immediately available for viewing via a regular web browser. Since Subversion uses URLs to identify versioned resources, those URLs used for HTTP-based repository access can be typed directly into a web browser. Your browser will issue an HTTP GET request for that URL; based on whether that URL represents a versioned directory or file, mod_dav_svn will respond with a directory listing or with file contents.

Since the URLs do not contain any information about which version of the resource you wish to see, mod_dav_svn will always answer with the youngest version. This functionality has the wonderful side effect that you can pass around Subversion URLs to your peers as references to documents, and those URLs will always point at the latest manifestation of that document. Of course, you can even use the URLs as hyperlinks from other web sites, too.

Un des avantages les plus frappants d'avoir une configuration Apache/WebDAV pour votre dépôt Subversion est que les révisions les plus récentes de vos fichiers et répertoires versionnés sont immédiatement consultables à l'aide d'un navigateur web classique. Puisque Subversion utilise des URL pour identifier les ressources versionnées, ces URL utilisées pour accéder aux dépôts via HTTP peuvent être tapées directement dans un navigateur web. Votre navigateur enverra une requête HTTP GET pour cette URL ; selon que cette URL représente ou non un fichier ou un répertoire versionné, mod_dav_svn renverra soit la liste des éléments du répertoire soit le contenu du fichier.

Comme les URL ne contiennent pas d'informations concernant la version de la ressource vous voulez voir, mod_dav_svn renverra toujours la version la plus récente. Cette fonctionnalité a un merveilleux effet secondaire : vous pouvez partager avec vos pairs des URL Subversion en guise de références à des documents, et ces URL pointeront toujours vers la dernière version des documents. Bien sûr, vous pouvez aussi utiliser ces URL en tant que liens hypertextes dans d'autres sites web.

POINT OF INTEREST: Can I View Older Revisions?
Can I View Older Revisions?
Puis-je consulter d'anciennes révisions ?
With an ordinary web browser? In one word: nope. At least, not with mod_dav_svn as your only tool.
Your web browser speaks ordinary HTTP only. That means it knows only how to GET public URLs, which represent the latest versions of files and directories. According to the WebDAV/DeltaV specification, each server defines a private URL syntax for older versions of resources, and that syntax is opaque to clients. To find an older version of a file, a client must follow a specific procedure to “discover” the proper URL; the procedure involves issuing a series of WebDAV PROPFIND requests and understanding DeltaV concepts. This is something your web browser simply can't do.
So, to answer the question, one obvious way to see older revisions of files and directories is by passing the --revision (-r) argument to the svn list and svn cat commands. To browse old revisions with your web browser, however, you can use third-party software. A good example of this is ViewVC (http://viewvc.tigris.org/). ViewVC was originally written to display CVS repositories through the Web, [47] and the latest releases are able to understand Subversion repositories as well.
Avec un navigateur web classique ? En un mot : non. Ou, du moins, pas avec mod_dav_svn pour seul outil.
Votre navigateur web ne sait communiquer qu'en langage HTTP ordinaire. Ce qui signifie qu'il sait seulement obtenir, par requête GET, des URL publiques, qui représentent les versions les plus récentes des fichiers et répertoires. D'après la spécification de WebDAV/DeltaV, chaque serveur définit une syntaxe privée d'URL pour les anciennes versions des ressources, et cette syntaxe est incompréhensible pour les clients. Pour obtenir une ancienne version d'un fichier, un client doit suivre une procédure spécifique pour "découvrir" l'URL appropriée ; cette procédure nécessite d'envoyer une série de requêtes WebDAB PROPFIND et de comprendre les concepts DeltaV. C'est quelque chose que votre navigateur web n'est pas capable de faire.
Donc, pour répondre à la question, une méthode évidente permettant de consulter d'anciennes versions de fichiers et de répertoires est de passer l'argument --revision (-r) aux commandes svn list et svn cat. Pour naviguer dans les anciennes révisions avec votre navigateur web, vous pouvez utiliser des logiciels tiers. Un bon exemple en est ViewVC (http://viewvc.tigris.org/). ViewVC a été écrit à l'origine dans le but d'afficher des dépôts CVS sur le web [47], et les dernières versions sont également capables de travailler avec les dépôts Subversion.
Proper MIME type

Proper MIME type

Types MIME appropriés

When browsing a Subversion repository, the web browser gets a clue about how to render a file's contents by looking at the Content-Type: header returned in Apache's response to the HTTP GET request. The value of this header is some sort of MIME type. By default, Apache will tell the web browsers that all repository files are of the “default” MIME type, typically text/plain. This can be frustrating, however, if a user wishes repository files to render as something more meaningful—for example, it might be nice to have a foo.html file in the repository actually render as HTML when browsing.

To make this happen, you need only to make sure that your files have the proper svn:mime-type set. We discuss this in more detail in the section called “File Content Type”, and you can even configure your client to automatically attach proper svn:mime-type properties to files entering the repository for the first time; see the section called “Automatic Property Setting”.

So in our example, if one were to set the svn:mime-type property to text/html on file foo.html, Apache would properly tell your web browser to render the file as HTML. One could also attach proper image/* MIME-type properties to image files and ultimately get an entire web site to be viewable directly from a repository! There's generally no problem with this, as long as the web site doesn't contain any dynamically generated content.

Quand il consulte un dépôt Subversion, le navigateur web obtient un indice pour savoir comment rendre le contenu d'un fichier en examinant l'entête Content-Type qui fait partie de la réponse envoyée par Apache à la requête HTTP GET. La valeur de cet entête est en quelque sorte un type MIME. Par défaut, Apache va indiquer aux navigateurs web que tous les fichiers du dépôt sont du type MIME par défaut, en général text/plain. Cela peut être frustrant, cependant, si un utilisateur désire visualiser les fichiers du dépôt de manière plus appropriée - par exemple, cela pourrait être une bonne chose d'afficher un fichier truc.html du dépôt sous forme de HTML navigable.

Pour rendre ceci possible, il suffit de vous assurer que vos fichiers ont bien le svn:mime-type approprié de défini. Plus de détails sur ce sujet sont disponibles dans le paragraphe "Type de contenu des fichiers", et vous pouvez même configurer votre dépôt pour qu'il associe automatiquement la valeur de svn:mime-type appropriée aux fichiers qui arrivent dans le dépôt pour la première fois ; reportez-vous au paragraphe intitulé "Configurer des propriétés de façon automatique".

Donc, dans notre exemple, si quelqu'un attribuait la valeur text/html à la propriété svn:mime-type du fichier truc.html, Apache indiquerait avec justesse à votre navigateur web de rendre le fichier comme du HTML. On pourrait aussi associer des propriétés ayant des valeurs image/* appropriées aux fichiers d'images et en fin de compte faire qu'un site web entier soit consultable directement à travers un dépôt ! Ceci ne pose en général pas de problème, du moment que le site web ne possède pas de contenu généré dynamiquement.

Customizing the look

Customizing the look

Personnaliser l'aspect

You generally will get more use out of URLs to versioned files—after all, that's where the interesting content tends to lie. But you might have occasion to browse a Subversion directory listing, where you'll quickly note that the generated HTML used to display that listing is very basic, and certainly not intended to be aesthetically pleasing (or even interesting). To enable customization of these directory displays, Subversion provides an XML index feature. A single SVNIndexXSLT directive in your repository's Location block of httpd.conf will instruct mod_dav_svn to generate XML output when displaying a directory listing, and to reference the XSLT stylesheet of your choice:

<Location /svn>
  DAV svn
  SVNParentPath /var/svn
  SVNIndexXSLT "/svnindex.xsl"
  ...
</Location>

Using the SVNIndexXSLT directive and a creative XSLT stylesheet, you can make your directory listings match the color schemes and imagery used in other parts of your web site. Or, if you'd prefer, you can use the sample stylesheets provided in the Subversion source distribution's tools/xslt/ directory. Keep in mind that the path provided to the SVNIndexXSLT directory is actually a URL path—browsers need to be able to read your stylesheets to make use of them!

En général vous utiliserez plus souvent les URL de fichiers versionnés, après tout c'est là que le contenu intéressant réside. Mais vous aurez peut-être l'occasion de naviguer dans le contenu d'un répertoire Subversion, et vous remarquerez rapidement que le HTML généré pour afficher la liste des éléments du répertoire est très rudimentaire, et certainement pas conçu pour être agréable d'un point de vue esthétique (ni même intéressant). Afin d'activer la personnalisation de l'affichage de ces répertoires, Subversion fournit une fonctionnalité d'index XML. La présence d'une directive SVNIndexXSLT dans le bloc Location du fichier httpd.conf de votre dépôt conduira mod_dav_svn à générer un résultat en XML quand il affiche la liste des éléments d'un répertoire, et à faire référence à la feuille de style XSLT de votre choix :

<Location /svn>
  DAV svn
  SVNParentPath /var/svn
  SVNIndexXSLT "/index-svn.xsl"
  ...
</Location>

A l'aide de la directive SVNIndexXSLT et d'une feuille de style XSLT faisant preuve de créativité, vous pouvez adapter les listes de contenus de répertoires aux schémas de couleur et d'imagerie utilisés dans d'autres parties de votre site web. Ou, si vous préférez, vous pouvez utiliser les exemples de feuilles de style fournis dans le répertoire tools/xslt/ du code source de Subversion. Gardez à l'esprit que le chemin d'accès fourni au répertoire SVNindexXSLT est en fait une URL - les navigateurs de chemins doivent déjà être capables de lire vos feuilles de style pour les utiliser !

Listing repositories

Listing repositories

Afficher la liste des dépôts

If you're serving a collection of repositories from a single URL via the SVNParentPath directive, then it's also possible to have Apache display all available repositories to a web browser. Just activate the SVNListParentPath directive:

<Location /svn>
  DAV svn
  SVNParentPath /var/svn
  SVNListParentPath on
  ...
</Location>

If a user now points her web browser to the URL http://host.example.com/svn/, she'll see a list of all Subversion repositories sitting in /var/svn. Obviously, this can be a security problem, so this feature is turned off by default.

Si vous desservez un ensemble de dépôts à partir d'une URL unique via la directive SVNParentPath, il est possible de faire afficher par Apache tous les dépôts disponibles dans un navigateur web. Il suffit d'activer la directive SVNListParentPath :

<Location /svn>
  DAV svn
  SVNParentPath /var/svn
  SVNListParentPath on
  ...
</Location>

Si un utilisateur pointe son navigateur web à l'URL http://hote/exemple.com/svn/, il verra une liste de tous les dépôts Subversion situés dans /var/svn. Évidemment, ceci peut poser des problèmes de sécurité, cette fonctionnalité est donc désactivée par défaut.

Apache logging

Apache logging

Journalisation Apache

Because Apache is an HTTP server at heart, it contains fantastically flexible logging features. It's beyond the scope of this book to discuss all of the ways logging can be configured, but we should point out that even the most generic httpd.conf file will cause Apache to produce two logs: error_log and access_log. These logs may appear in different places, but are typically created in the logging area of your Apache installation. (On Unix, they often live in /usr/local/apache2/logs/.)

The error_log describes any internal errors that Apache runs into as it works. The access_log file records every incoming HTTP request received by Apache. This makes it easy to see, for example, which IP addresses Subversion clients are coming from, how often particular clients use the server, which users are authenticating properly, and which requests succeed or fail.

Unfortunately, because HTTP is a stateless protocol, even the simplest Subversion client operation generates multiple network requests. It's very difficult to look at the access_log and deduce what the client was doing—most operations look like a series of cryptic PROPPATCH, GET, PUT, and REPORT requests. To make things worse, many client operations send nearly identical series of requests, so it's even harder to tell them apart.

mod_dav_svn, however, can come to your aid. By activating an “operational logging” feature, you can ask mod_dav_svn to create a separate log file describing what sort of high-level operations your clients are performing.

Comme Apache est avant tout un serveur HTTP, il contient des fonctionnalités de journalisation d'une flexibilité fantastique. Détailler toutes les façons dont la journalisation peut être configurée sort du cadre de ce livre, mais nous voulons quand même vous faire remarquer que même le fichier httpd.conf le plus générique conduit Apache à créer deux fichiers journaux : error_log et access_log. Ces journaux peuvent apparaître à différents endroits, mais sont en général créés dans la zone de journalisation de votre installation Apache (sur Unix, ils résident souvent dans /usr/local/apache2/logs).

Le fichier error_log décrit toutes les erreurs internes qu'Apache rencontre au cours de son fonctionnement. Le fichier access_log enregistre toutes les requêtes HTTP reçues par Apache. Ceci permet de voir facilement, par exemple, de quelles adresses IP les clients Subversion se connectent, à quelle fréquence un client donné utilise le serveur, quels utilisateurs se sont authentifiés correctement et quelles requêtes ont échoué ou réussi.

Malheureusement, parce qu'HTTP est un protocole sans notion d'état, même la plus simple opération du client Subversion génère plusieurs requêtes réseau. Il est donc très difficile d'examiner le fichier access_log et d'en déduire ce que le client faisait - la plupart des opérations se présentent sous la forme de séries de requêtes PROPPATCH, GET, PUT et REPORT énigmatiques. Pour couronner le tout, de nombreuses opérations du client envoient des séries de requêtes quasi-identiques, il est donc encore plus difficile de les distinguer.

Cependant, mod_dav_svn peut venir à votre rescousse. En activant la fonctionnalité de "journalisation opérationnelle", vous pouvez demander à mod_dav_svn de créer un fichier séparé décrivant quelles sortes d'opérations de haut niveau vos clients effectuent.

To do this, you need to make use of Apache's CustomLog directive (which is explained in more detail in Apache's own documentation). Be sure to invoke this directive outside your Subversion Location block:

<Location /svn>
  DAV svn
  ...
</Location>

CustomLog logs/svn_logfile "%t %u %{SVN-ACTION}e" env=SVN-ACTION

In this example, we're asking Apache to create a special logfile, svn_logfile, in the standard Apache logs directory. The %t and %u variables are replaced by the time and username of the request, respectively. The really important parts are the two instances of SVN-ACTION. When Apache sees that variable, it substitutes the value of the SVN-ACTION environment variable, which is automatically set by mod_dav_svn whenever it detects a high-level client action.

So, instead of having to interpret a traditional access_log like this:

[26/Jan/2007:22:25:29 -0600] "PROPFIND /svn/calc/!svn/vcc/default HTTP/1.1" 207 398
[26/Jan/2007:22:25:29 -0600] "PROPFIND /svn/calc/!svn/bln/59 HTTP/1.1" 207 449
[26/Jan/2007:22:25:29 -0600] "PROPFIND /svn/calc HTTP/1.1" 207 647
[26/Jan/2007:22:25:29 -0600] "REPORT /svn/calc/!svn/vcc/default HTTP/1.1" 200 607
[26/Jan/2007:22:25:31 -0600] "OPTIONS /svn/calc HTTP/1.1" 200 188
[26/Jan/2007:22:25:31 -0600] "MKACTIVITY /svn/calc/!svn/act/e6035ef7-5df0-4ac0-b811-4be7c823f998 HTTP/1.1" 201 227
...

you can peruse a much more intelligible svn_logfile like this:

[26/Jan/2007:22:24:20 -0600] - get-dir /tags r1729 props
[26/Jan/2007:22:24:27 -0600] - update /trunk r1729 depth=infinity send-copyfrom-args
[26/Jan/2007:22:25:29 -0600] - status /trunk/foo r1729 depth=infinity
[26/Jan/2007:22:25:31 -0600] sally commit r1730

For an exhaustive list of all actions logged, see the section called “High-level logging”.

Pour ce faire, vous devez utiliser la directive CustomLog d'Apache (qui est expliquée en détail dans la documentation Apache). Prenez soin de placer cette directive en dehors de votre bloc Location de Subversion :

<Location /svn>
  DAV svn
  ...
</Location>

CustomLog logs/journal_svn "%t %u %{SVN-ACTION}e" env=SVN-ACTION

Dans cet exemple, nous demandons à Apache de créer un fichier journal spécial, journal_svn, dans le répertoire classique de journaux d'Apache (logs). Les variables %t et %u sont remplacées par l'horodatage et le nom d'utilisateur de la requête, respectivement. Les points importants sont les deux instances de SVN-ACTION. Quand Apache trouve cette variable, il lui substitue la valeur de la variable d'environnement SVN-ACTION, modifiée automatiquement par mod_dav_svn quand il détecte une action haut-niveau du client.

Donc, au lieu d'avoir à interpréter le fichier access_log traditionnel qui ressemble à :

[26/Jan/2007:22:25:29 -0600] "PROPFIND /svn/calc/!svn/vcc/default HTTP/1.1" 207 398
[26/Jan/2007:22:25:29 -0600] "PROPFIND /svn/calc/!svn/bln/59 HTTP/1.1" 207 449
[26/Jan/2007:22:25:29 -0600] "PROPFIND /svn/calc HTTP/1.1" 207 647
[26/Jan/2007:22:25:29 -0600] "REPORT /svn/calc/!svn/vcc/default HTTP/1.1" 200 607
[26/Jan/2007:22:25:31 -0600] "OPTIONS /svn/calc HTTP/1.1" 200 188
[26/Jan/2007:22:25:31 -0600] "MKACTIVITY /svn/calc/!svn/act/e6035ef7-5df0-4ac0-b811-4be7c823f998 HTTP/1.1" 201 227
...

vous pouvez vous contenter de parcourir le fichier journal_svn, qui est bien plus intelligible :

[26/Jan/2007:22:24:20 -0600] - get-dir /tags r1729 props
[26/Jan/2007:22:24:27 -0600] - update /trunk r1729 depth=infinity send-copyfrom-args
[26/Jan/2007:22:25:29 -0600] - status /trunk/machin r1729 depth=infinity
[26/Jan/2007:22:25:31 -0600] sally commit r1730

Pour une liste exhaustive de toutes les actions journalisées, reportez-vous au paragraphe intitulé "Journalisation de haut niveau".

Write-through proxying

Write-through proxying

Utilisation d'un mandataire en écriture

One of the nice advantages of using Apache as a Subversion server is that it can be set up for simple replication. For example, suppose that your team is distributed across four offices around the globe. The Subversion repository can exist only in one of those offices, which means the other three offices will not enjoy accessing it—they're likely to experience significantly slower traffic and response times when updating and committing code. A powerful solution is to set up a system consisting of one master Apache server and several slave Apache servers. If you place a slave server in each office, users can check out a working copy from whichever slave is closest to them. All read requests go to their local slave. Write requests get automatically routed to the single master server. When the commit completes, the master then automatically “pushes” the new revision to each slave server using the svnsync replication tool.

This configuration creates a huge perceptual speed increase for your users, because Subversion client traffic is typically 80–90% read requests. And if those requests are coming from a local server, it's a huge win.

In this section, we'll walk you through a standard setup of this single-master/multiple-slave system. However, keep in mind that your servers must be running at least Apache 2.2.0 (with mod_proxy loaded) and Subversion 1.5 (mod_dav_svn).

Un des avantages notables d'Apache comme serveur Subversion est qu'il peut être configuré pour effectuer de la réplication. Par exemple, imaginez que votre équipe soit répartie sur quatre sites dans différents coins du globe. Le dépôt Subversion ne peut exister que sur un de ces sites, ce qui signifie que les trois autres sites n'auront pas un accès très satisfaisant - ils devront sans doute faire avec un trafic plus lent et des temps de réponse plus longs lors des mises à jour et des propagations. Une solution très puissante est de mettre en place un système constitué d'un serveur Apache maître et de plusieurs serveurs Apache esclaves. Si vous placez un serveur esclave sur chacun des sites, les utilisateurs peuvent extraire une copie de travail de l'esclave qui est le plus proche d'eux. Toutes les requêtes de lecture vont au serveur esclave local. Les requêtes d'écriture sont automatiquement routées vers l'unique serveur maître. Lorsque la propagation se termine, le maître "pousse" la nouvelle révision vers chaque serveur esclave en utilisant l'outil de réplication svnsync.

Cette configuration permet une immense amélioration de la vitesse perçue par les utilisateurs, car le trafic d'un client Subversion est généralement constitué à 80 - 90 % de requêtes de lecture. Et si ces requêtes sont traitées par un serveur local, le gain est énorme.

Dans ce paragraphe, nous allons vous accompagner dans la mise en place standard de ce système comportant un maître unique et plusieurs esclaves. Cependant, gardez à l'esprit que vos serveurs doivent faire tourner au moins Apache 2.2.0 (avec le module mod_proxy chargé) et Subversion 1.5 (mod_dav_svn).

Configure the servers

Configure the servers

Configurer les serveurs

First, configure your master server's httpd.conf file in the usual way. Make the repository available at a certain URI location, and configure authentication and authorization however you'd like. After that's done, configure each of your “slave” servers in the exact same way, but add the special SVNMasterURI directive to the block:

<Location /svn>
  DAV svn
  SVNPath /var/svn/repos
  SVNMasterURI http://master.example.com/svn
  ...
</Location>

This new directive tells a slave server to redirect all write requests to the master. (This is done automatically via Apache's mod_proxy module.) Ordinary read requests, however, are still serviced by the slaves. Be sure that your master and slave servers all have matching authentication and authorization configurations; if they fall out of sync, it can lead to big headaches.

Next, we need to deal with the problem of infinite recursion. With the current configuration, imagine what will happen when a Subversion client performs a commit to the master server. After the commit completes, the server uses svnsync to replicate the new revision to each slave. But because svnsync appears to be just another Subversion client performing a commit, the slave will immediately attempt to proxy the incoming write request back to the master! Hilarity ensues.

The solution to this problem is to have the master push revisions to a different <Location> on the slaves. This location is configured to not proxy write requests at all, but to accept normal commits from (and only from) the master's IP address:

<Location /svn-proxy-sync>
  DAV svn
  SVNPath /var/svn/repos
  Order deny,allow
  Deny from all
  # Only let the server's IP address access this Location:
  Allow from 10.20.30.40
  ...
 </Location>

Pour commencer, configurez le fichier httpd.conf de votre serveur maître de la façon habituelle. Mettez le dépôt à disposition à un certain emplacement URI et configurez l'authentification ainsi que le contrôle d'accès comme vous le souhaitez. Une fois que c'est fait, configurez chacun de vos serveurs "esclaves" exactement de la même manière, mais ajoutez la directive SVNMasterURI au bloc :

<Location /svn>
  DAV svn
  SVNPath /var/svn/depot
  SVNMasterURI http://maitre.exemple.com/svn
  ...
</Location>

Cette nouvelle directive indique à un serveur esclave de rediriger toutes les requêtes d'écriture vers le maître (ce qui est accompli automatiquement par le module mod_proxy d'Apache). Les requêtes ordinaires de lecture, cependant, sont toujours traitées par les esclaves. Assurez-vous que vos serveurs maître et esclaves ont tous des configurations identiques d'authentification et de contrôle d'accès ; s'ils ne peuvent plus se synchroniser, cela peut conduire à beaucoup d'ennuis.

Ensuite nous devons nous occuper du problème de la récursion infinie. Avec la configuration actuelle, imaginez ce qui se va se passer quand un client Subversion va effectuer une propagation vers le serveur maître. Une fois la propagation terminée, le serveur utilise svnsync pour répliquer la nouvelle révision vers chaque esclave. Mais comme svnsync ne se présente que comme un simple client en train d'effectuer une propagation, l'esclave va immédiatement tenter d'envoyer vers le maître la requête d'écriture qui vient d'arriver ! Et là, patatras !

La solution consiste à s'arranger pour que le maître pousse les révisions vers un emplacement <Location> distinct au sein des dépôts esclaves. Cet emplacement est configuré non pas pour servir de mandataire pour les requêtes d'écriture mais pour accepter les propagations normales en provenance de l'adresse IP du maître (et seulement de lui) :

<Location /svn-proxy-sync>
  DAV svn
  SVNPath /var/svn/depot
  Order deny,allow
  Deny from all
  # Ne laisse que le serveur ayant l'adresse indiquée accéder à cet emplacement :
  Allow from 10.20.30.40
  ...
 </Location>
Set up replication

Set up replication

Mettre en place la réplication

Now that you've configured your Location blocks on master and slaves, you need to configure the master to replicate to the slaves. This is done the usual way— using svnsync. If you're not familiar with this tool, see the section called “Repository Replication” for details.

First, make sure that each slave repository has a pre-revprop-change hook script which allows remote revision property changes. (This is standard procedure for being on the receiving end of svnsync.) Then log into the master server and configure each of the slave repository URIs to receive data from the master repository on the local disk:

$ svnsync init http://slave1.example.com/svn-proxy-sync file://var/svn/repos
Copied properties for revision 0.
$ svnsync init http://slave2.example.com/svn-proxy-sync file://var/svn/repos
Copied properties for revision 0.
$ svnsync init http://slave3.example.com/svn-proxy-sync file://var/svn/repos
Copied properties for revision 0.

# Perform the initial replication
$ svnsync sync http://slave1.example.com/svn-proxy-sync
Transmitting file data ....
Committed revision 1.
Copied properties for revision 1.
Transmitting file data .......
Committed revision 2.
Copied properties for revision 2.
...
$ svnsync sync http://slave2.example.com/svn-proxy-sync
Transmitting file data ....
Committed revision 1.
Copied properties for revision 1.
Transmitting file data .......
Committed revision 2.
Copied properties for revision 2.
...

$ svnsync sync http://slave3.example.com/svn-proxy-sync
Transmitting file data ....
Committed revision 1.
Copied properties for revision 1.
Transmitting file data .......
Committed revision 2.
Copied properties for revision 2.
...

Une fois que vous avez configuré les blocs Location du maître et des esclaves, vous devez configurer le maître pour que la réplication vers les esclaves fonctionne. Ceci se fait de la manière habituelle, en utilisant svnsync. Si vous n'êtes pas familier avec cet outil, reportez-vous au paragraphe intitulé "Réplication de dépôt" pour plus de détails.

Tout d'abord, assurez-vous que chaque dépôt esclave a une procédure automatique pre-revprop-change qui autorise les modifications de propriétés de révisions à distance (cette étape fait partie de la procédure standard pour un serveur qui reçoit les révisions de svnsync). Ensuite, connectez-vous au serveur maître et configurez l'URI de chaque dépôt esclave pour qu'il reçoive les données en provenance du dépôt maître sur le disque local :

$ svnsync init http://esclave1.exemple.com/svn-proxy-sync file://var/svn/depot
Propriétés copiées pour la révision 0.
$ svnsync init http://esclave2.exemple.com/svn-proxy-sync file://var/svn/depot
Propriétés copiées pour la révision 0.
$ svnsync init http://esclave3.exemple.com/svn-proxy-sync file://var/svn/depot
Propriétés copiées pour la révision 0.

# Effectue la réplication initiale
$ svnsync sync http://esclave1.exemple.com/svn-proxy-sync
Transmission des données ........................................
Révision 1 propagée.
Propriétés copiées pour la révision 1.
Transmission des données ..
Révision 2 propagée.
Propriétés copiées pour la révision 2.
...
$ svnsync sync http://esclave2.exemple.com/svn-proxy-sync
Transmission des données ........................................
Révision 1 propagée.
Propriétés copiées pour la révision 1.
Transmission des données ..
Révision 2 propagée.
Propriétés copiées pour la révision 2.
...

$ svnsync sync http://esclave3.exemple.com/svn-proxy-sync
Transmission des données ........................................
Révision 1 propagée.
Propriétés copiées pour la révision 1.
Transmission des données ..
Révision 2 propagée.
Propriétés copiées pour la révision 2.
...

After this is done, we configure the master server's post-commit hook script to invoke svnsync on each slave server:

#!/bin/sh
# Post-commit script to replicate newly committed revision to slaves

svnsync sync http://slave1.example.com/svn-proxy-sync > /dev/null 2>&1
svnsync sync http://slave2.example.com/svn-proxy-sync > /dev/null 2>&1
svnsync sync http://slave3.example.com/svn-proxy-sync > /dev/null 2>&1

The extra bits on the end of each line aren't necessary, but they're a sneaky way to allow the sync commands to run in the background so that the Subversion client isn't left waiting forever for the commit to finish. In addition to this post-commit hook, you'll need a post-revprop-change hook as well so that when a user, say, modifies a log message, the slave servers get that change also:

#!/bin/sh
# Post-revprop-change script to replicate revprop-changes to slaves

REV=${2}
svnsync copy-revprops http://slave1.example.com/svn-proxy-sync ${REV} > /dev/null 2>&1
svnsync copy-revprops http://slave2.example.com/svn-proxy-sync ${REV} > /dev/null 2>&1
svnsync copy-revprops http://slave3.example.com/svn-proxy-sync ${REV} > /dev/null 2>&1

The only thing we've left out here is what to do about locks. Because locks are strictly enforced by the master server (the only place where commits happen), we don't technically need to do anything. Many teams don't use Subversion's locking features at all, so it may be a nonissue for you. However, if lock changes aren't replicated from master to slaves, it means that clients won't be able to query the status of locks (e.g., svn status -u will show no information about repository locks). If this bothers you, you can write post-lock and post-unlock hook scripts that run svn lock and svn unlock on each slave machine, presumably through a remote shell method such as SSH. That's left as an exercise for the reader!

Une fois que c'est fait, nous configurons la procédure automatique post-propagation (post-commit) du serveur maître pour qu'elle lance svnsync sur chaque serveur esclave :

#!/bin/sh
# Procédure post-propagation pour répliquer les révisions nouvellement propagées vers les esclaves

svnsync sync http://esclave1.exemple.com/svn-proxy-sync > /dev/null 2>&1
svnsync sync http://esclave2.exemple.com/svn-proxy-sync > /dev/null 2>&1
svnsync sync http://esclave3.exemple.com/svn-proxy-sync > /dev/null 2>&1

Les symboles en plus à la fin de chaque ligne ne sont pas nécessaires, mais constituent un moyen astucieux d'autoriser svnsync à lancer des commandes qui fonctionneront à l'arrière-plan, de telle sorte que le client subversion ne se retrouvera pas à attendre indéfiniment que la propagation se termine. en plus de cette procédure post-propagation, vous aurez également besoin d'une procédure post-revprop-change pour que, disons, quand un utilisateur modifie un message de propagation, les serveurs esclaves reçoivent aussi cette modification :

#!/bin/sh
# Procédure post-revprop-change pour répliquer les modifications revprop-changes vers les esclaves

REV=${2}
svnsync copy-revprops http://esclave1.exemple.com/svn-proxy-sync ${REV} > /dev/null 2>&1
svnsync copy-revprops http://esclave2.exemple.com/svn-proxy-sync ${REV} > /dev/null 2>&1
svnsync copy-revprops http://esclave3.exemple.com/svn-proxy-sync ${REV} > /dev/null 2>&1

La seule chose que nous n'avons pas détaillé concerne les verrous. Comme les verrous sont gérés strictement par le serveur maître (le seul endroit où des propagations ont lieu), nous n'avons en théorie pas besoin de faire quoi que ce soit. De nombreuses équipes n'utilisent pas du tout les fonctionnalités de verrouillage de Subversion, il s'agit donc peut-être pour vous d'un faux problème. Cependant, si les modifications de verrous ne sont pas répliquées du maître vers les esclaves, cela signifie que les clients ne seront pas capables d'interroger l'état des verrous (par exemple, svn status -u ne donnera aucune information sur les verrous du dépôt). Si cela vous embête, vous pouvez écrire des procédures automatiques post-verrouillage et post-déverrouillage qui lancent svn lock et svn unlock sur les serveurs esclaves, vraisemblablement à l'aide d'une méthode de connexion à distance telle que SSH. Nous laissons ceci en guise d'exercice au lecteur !

Caveats

Caveats

Avertissements

Your master/slave replication system should now be ready to use. A couple of words of warning are in order, however. Remember that this replication isn't entirely robust in the face of computer or network crashes. For example, if one of the automated svnsync commands fails to complete for some reason, the slaves will begin to fall behind. For example, your remote users will see that they've committed revision 100, but then when they run svn update, their local server will tell them that revision 100 doesn't yet exist! Of course, the problem will be automatically fixed the next time another commit happens and the subsequent svnsync is successful—the sync will replicate all waiting revisions. But still, you may want to set up some sort of out-of-band monitoring to notice synchronization failures and force svnsync to run when things go wrong.

Votre système de réplication maître/esclave devrait à présent être prêt à l'emploi. Cependant, quelques consignes de prudence sont de mise. Souvenez-vous que la réplication n'est pas totalement robuste en ce qui concerne les plantages machine ou réseau. Par exemple, si l'une des commandes svnsync automatisées demeure inachevée, pour quelque raison que ce soit, les esclaves vont commencer à être décalés. Par exemple, vos utilisateurs distants verront qu'ils ont propagé la révision 100, mais quand ils exécuteront svn update, leur serveur local leur indiquera que la révision 100 n'existe pas encore ! Bien sûr, le problème se réglera automatiquement dès qu'une autre propagation aura lieu et que la commande svnsync qui s'ensuivra aura fonctionné - cette synchronisation répliquera toutes les révisions en attente. Néanmoins, vous pourriez décider de mettre en place une surveillance des décalages, vérifiant le bon fonctionnement de la synchronisation et qui, en cas de problème, déclenche une nouvelle exécution de svnsync.

POINT OF INTEREST: Can We Set Up Replication with svnserve?
Can We Set Up Replication with svnserve?
Pouvons-nous mettre en place la réplication avec svnserve ?
If you're using svnserve instead of Apache as your server, you can certainly configure your repository's hook scripts to invoke svnsync as we've shown here, thereby causing automatic replication from master to slaves. Unfortunately, at the time of this writing there is no way to make slave svnserve servers automatically proxy write requests back to the master server. This means your users would only be able to check out read-only working copies from the slave servers. You'd have to configure your slave servers to disallow write access completely. This might be useful for creating read-only “mirrors” of popular open source projects, but it's not a transparent proxying system.
Si vous utilisez svnserve au lieu d'Apache comme serveur, vous pouvez tout à fait configurer les procédures automatiques de votre dépôt pour qu'elles lancent svnsync comme nous l'avons expliqué ici, lançant ainsi la réplication automatique du maître vers les esclaves. Malheureusement, à l'heure où nous écrivons ces lignes, il n'y a pas moyen de s'assurer que des serveurs esclaves svnserve envoient automatiquement les requêtes d'écriture vers le serveur maître. Cela veut dire que vos utilisateurs ne pourraient pas extraire des copies de travail en lecture seule des serveurs esclaves. Il vous faudrait configurer vos serveurs esclaves pour qu'ils refusent complètement tout accès en écriture. Cela peut être utile pour créer des "miroirs" en lecture seule de projets open source populaires, mais il ne s'agit alors plus d'un système de mandataire d'écriture transparent.

Other Apache features

Other Apache features

Autres fonctionnalités d'Apache

Several of the features already provided by Apache in its role as a robust web server can be leveraged for increased functionality or security in Subversion as well. The Subversion client is able to use SSL (the Secure Sockets Layer, discussed earlier). If your Subversion client is built to support SSL, it can access your Apache server using https:// and enjoy a high-quality encrypted network session.

Equally useful are other features of the Apache and Subversion relationship, such as the ability to specify a custom port (instead of the default HTTP port 80) or a virtual domain name by which the Subversion repository should be accessed, or the ability to access the repository through an HTTP proxy.

Finally, because mod_dav_svn is speaking a subset of the WebDAV/DeltaV protocol, it's possible to access the repository via third-party DAV clients. Most modern operating systems (Win32, OS X, and Linux) have the built-in ability to mount a DAV server as a standard network “shared folder.” This is a complicated topic, but also wondrous when implemented. For details, read Appendix C, WebDAV and Autoversioning.

Note that there are a number of other small tweaks one can make to mod_dav_svn that are too obscure to mention in this chapter. For a complete list of all httpd.conf directives that mod_dav_svn responds to, see the section called “Directives”.

Il y a également plusieurs fonctionnalités fournies par Apache, en tant que serveur web robuste, dont on peut tirer profit pour améliorer les fonctionnalités ou la sécurité de Subversion. Le client Subversion est capable d'utiliser SSL (Secure Socket Layer - le protocole de sécurisation des échanges sur internet, présenté auparavant). Si votre client Subversion a été compilé en incluant le support de SSL, il peut accéder à votre serveur Apache en utilisant des URL https:// et bénéficier d'une session réseau avec un chiffrement de grande qualité.

D'autres fonctionnalités de la relation Apache/Subversion sont également tout aussi utiles, comme par exemple la possibilité de spécifier un port personnalisé (au lieu du port HTTP par défaut :80) ou un nom de domaine virtuel par lequel accéder au dépôt Subversion ou la possibilité d'accéder au dépôt via un serveur mandataire HTTP.

Enfin, comme mod_dav_svn se sert d'un sous-ensemble du protocole WebDAV/DeltaV pour communiquer, il est possible d'accéder au dépôt depuis des clients DAV tiers. La possibilité de monter un serveur DAV en tant que "dossier partagé" réseau standard est intégrée dans la plupart des systèmes d'exploitation modernes (Win32, OS X et Linux). C'est un sujet compliqué, mais merveilleux une fois mis en place. Pour plus de détails, consultez l'Annexe C, WebDAV et l'autoversionnement.

Notez qu'il y a un certain nombre d'autres petits bricolages que l'on peut faire autour de mod_dav_svn qui sont trop obscurs pour être mentionnés dans ce chapitre. Pour voir la liste complète de toutes les directives httpd.conf auxquelles mod_dav_svn obéit, reportez-vous au paragraphe intitulé "Directives".