Diese Dokumentation wurde zur Beschreibung der Serie 1.7.x von Apache™ Subversion® erstellt. Falls Sie eine unterschiedliche Version von Subversion einsetzen, sei Ihnen dringend angeraten, bei http://www.svnbook.com/ vorbeizuschauen und stattdessen die zu Ihrer Version von Subversion passende Version dieser Dokumentation heranzzuiehen.

httpd, der Apache HTTP-Server

Der Apache HTTP-Server ist ein Hochleistungs-Netzwerk-Server, den Subversion zu seinem Vorteil nutzen kann. Über ein angepasstes Modul macht httpd Subversion-Projektarchive für Clients über das WebDAV/DeltaV-Protokoll[55] verfügbar, welches eine Erweiterung von HTTP 1.1 ist. Dieses Protokoll nimmt das allgegenwärtige HTTP-Protokoll, das der Kern des World Wide Web ist, und fügt Schreibfähigkeiten – im Besonderen, versioniertes Schreiben – hinzu. Das Ergebnis ist ein standardisiertes, robustes System, das auf geeignete Weise als Teil der Software Apache 2.0 verteilt wird, die von zahlreichen Betriebssystemen und Drittanbieter-Produkten unterstützt wird und keine Netzwerk-Administratoren benötigt, um einen weiteren speziellen Port zu öffnen.[56] Während ein Apache-Subversion-Server mehr Möglichkeiten bietet als svnserve, ist er allerdings auch etwas schwieriger einzurichten. Flexibilität geht oft mit Komplexität einher.

Viele der folgenden Erläuterungen beziehen sich auf Konfigurationsdirektiven von Apache. Obwohl ein paar Beispiele zur Verwendung dieser Direktiven gegeben werden, würde deren erschöpfende Behandlung dieses Kapitel sprengen. Das Apache-Team verfügt über hervorragende Dokumentation, die auf deren Web-Seite http://httpd.apache.org frei verfügbar ist. So befindet sich beispielsweise eine allgemeine Referenz der Konfigurationsdirektiven unter http://httpd.apache.org/docs-2.0/mod/directives.html.

Falls Sie Änderungen an den Einstellungen von Apache vornehmen, ist es wahrscheinlich, dass sich irgendwo ein Fehler einschleicht. Wenn Sie noch nicht mit der Protokollierung von Apache vertraut sind, sollten sie sich damit vertraut machen. In der Datei httpd.conf befinden sich Direktiven, die angeben, wo auf der Platte sich die von Apache erzeugten Zugriffs- und Fehlerprotokollierungsdateien befinden (die Direktiven CustomLog bzw. ErrorLog). Auch mod_dav_svn von Subversion verwendet die Protokollierungsschnittstelle von Apache. Sie können jederzeit den Inhalt dieser Dateien nach Informationen durchforsten, die eine Problemquelle aufdecken könnten, die sonst nicht offensichtlich wäre.

Voraussetzungen

Um Ihr Projektarchiv im Netz über HTTP zur Verfügung zu stellen, brauchen Sie grundsätzlich vier Komponenten, die in zwei Paketen verfügbar sind. Sie benötigen Apache httpd 2.0 oder neuer, das dazu gelieferte DAV-Modul mod_dav, Subversion und das mitgelieferte Dateisystemmodul mod_dav_svn. Sobald Sie über all diese Komponenten verfügen, ist die Bereitstellung Ihres Projektarchivs über das Netz ganz einfach:

  • Inbetriebnahme von httpd mit dem Modul mod_dav

  • Installation des mod_dav_svn-Backends zu mod_dav, das die Bibliotheken von Subversion für den Zugriff auf das Projektarchiv verwendet

  • Konfiguration Ihrer Datei httpd.conf, um das Projektarchiv zu exportieren (oder sichtbar zu machen)

Sie können die ersten beiden Punkte bewerkstelligen, indem Sie entweder httpd und Subversion aus den Quellen übersetzen oder als vorgefertigte Binärpakete auf Ihrem System installieren. Die aktuellsten Informationen zur Übersetzung von Subversion in Verbindung mit dem Apache HTTP-Server sowie die Übersetzung und Konfigurierung von Apache zu diesem Zweck finden Sie in der Datei INSTALL in der obersten Verzeichisebene des Quelltextes von Subversion.

Grundlegende Konfiguration von Apache

Sobald alle notwendigen Komponenten auf Ihrem System installiert sind, bleibt nur noch die Konfiguration von Apache über seine Datei httpd.conf. Weisen Sie Apache mit der Direktive LoadModule an, das Modul mod_dav_svn zu laden. Diese Direktive muss vor allen Konfigurationseinträgen in Verbindung mit Subversion stehen. Falls Ihr Apache mit dem vorgegebenen Aufbau installiert wurde, sollte sich das Modul mod_dav_svn im Unterverzeichnis modules des Apache-Installationsverzeichnisses befinden (oft /usr/local/apache2). Die Direktive LoadModule hat eine einfache Syntax, wobei ein benanntes Modul auf den Ort einer Shared-Library auf der Platte abgebildet wird:

LoadModule dav_svn_module     modules/mod_dav_svn.so

Apache interpretiert den Bibliothekspfad des Konfigurationseintrags LoadModule als relativ zum Wurzelverzeichnis seines eigenen Servers. Falls er wie gezeigt konfiguriert ist, wird Apache in seinem eigenen modules/ Unterverzeichnis nach der Shared-Library des Subversion DAV-Moduls suchen. Abhängig davon, wie Subversion auf Ihrem System installiert wurde, kann es sein, dass Sie einen ganz anderen Pfad für diese Bibliothek angeben müssen, vielleicht sogar einen absoluten Pfad wie im folgenden Beispiel:

LoadModule dav_svn_module     C:/Subversion/lib/mod_dav_svn.so

Falls mod_dav als Shared-Objekt übersetzt wurde (statt statisch direkt in die httpd-Binärdatei gelinkt worden zu sein), benötigen Sie hierfür ebenfalls einen ähnlichen LoadModule-Eintrag. Stellen Sie sicher, dass er vor der mod_dav_svn-Zeile steht:

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

Weiter unten in der Konfigurationsdatei sollten Sie Apache nun mitteilen, wo Sie Ihr Subversion-Projektarchiv (oder Ihre Projektarchive) aufbewahren. Die Direktive Location besitzt eine XML-ähnliche Notation, beginnend mit einem öffnenden Tag, endend mit einem schließenden Tag und verschiedener anderer Konfigurationsdirektiven dazwischen. Der Zweck der Direktive Location besteht darin, Apache anzuweisen, etwas Besonderes zu tun, falls Anfragen bearbeitet werden, die an einen bestimmten URL oder dessen Kinder gerichtet sind. Im Fall von Subversion möchten Sie, dass Apache die Unterstützung für URLs, die auf versionierte Ressourcen zeigen, einfach an die DAV-Schicht weiterleitet. Sie können Apache anweisen, die Bearbeitung aller URLs, deren Pfadteile (der Teil des URL, der nach dem Servernamen und der optionalen Portnummer steht) mit /repos/ beginnen, an einen DAV-Provider zu delegieren, dessen Projektarchiv unter /var/svn/repository liegt, indem Sie die folgende httpd.conf-Syntax verwenden:

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

Falls Sie planen, mehrere Subversion-Projektarchive zu unterstützen, die sich unterhalb eines gemeinsamen Elternverzeichnisses auf Ihrer lokalen Platte befinden, können Sie eine alternative Direktive, SVNParentPath, verwenden, um auf das gemeinsame Elternverzeichnis hinzuweisen. Wenn Sie beispielsweise wissen, dass Sie mehrere Subversion-Projektarchive in einem Verzeichnis /var/svn anlegen möchten, auf die über URLs wie http://my.server.com/svn/repos1, http://my.server.com/svn/repos2 usw. zugegriffen werden soll, könnten Sie die Konfigurationssyntax von httpd.conf aus dem folgenden Beispiel verwenden:

<Location /svn>
  DAV svn

  # Automatisch irgendein "/svn/foo" URL auf Projektarchiv /var/svn/foo abbilden
  SVNParentPath /var/svn
</Location>

Die Verwendung dieser Syntax veranlasst Apache, die Bearbeitung aller URLs, deren Pfadteil mit /svn/ beginnt, an den Subversion-DAV-Provider weiterzuleiten, der dann davon ausgeht, dass alle Objekte in dem durch die SVNParentPath-Direktive spezifizierten Verzeichnis tatsächlich Subversion-Projektarchive sind. Dies ist insofern eine besonders bequeme Syntax, da Sie im Gegensatz zur Direktive SVNPath Apache nicht neu starten müssen, wenn Sie Projektarchive hinzufügen oder entfernen.

Achten Sie beim Definieren Ihrer neuen Location darauf, dass sie sich nicht mit anderen bereits exportierten überschneidet. Wenn beispielsweise Ihre Haupt-DocumentRoot nach /www exportiert wird, sollten Sie ein Subversion-Projektarchiv nicht in <Location /www/repos> exportieren. Falls eine Anfrage für den URI /www/repos/foo.c hereinkommt, weiß Apache nicht, ob die Datei repos/foo.c in DocumentRoot gesucht wird oder ob es die Herausgabe von foo.c aus dem Projektarchiv an mod_dav_svn delegieren soll. Das Ergebnis ist oftmals ein Fehler vom Server der Form 301 Moved Permanently.

An dieser Stelle sollten Sie ernsthaft über Berechtigungen nachdenken. Falls Sie Apache schon eine Zeit lang als Ihren regulären Web-Server in Betrieb haben, werden Sie wahrscheinlich bereits eine Ansammlung von Inhalt haben, etwa Webseiten, Skripte usw. Diese Dinge sind bereits mit einer Menge an Berechtigungen versehen, die es ihnen erlauben, mit Apache zusammen zu arbeiten, oder passender, die es Apache erlauben, mit diesen Dateien zu arbeiten. Wenn Apache als Subversion-Server eingesetzt wird, braucht er ebenfalls die richtigen Berechtigungen zum Lesen und Schreiben Ihres Subversion-Projektarchivs.

Sie werden ein Berechtigungssystem festlegen müssen, das die Anforderungen von Subversion erfüllt, ohne dabei bestehende Webseiten oder Skriptinstallationen zu beeinträchtigen. Das kann bedeuten, dass die Berechtigungen für Ihr Projektarchiv an die anderen Dinge angepasst werden müssen, die Apache für Sie zur Verfügung stellt, oder dass Sie die Direktiven User und Group in httpd.conf verwenden, um Apache mit denjenigen Anwender- und Gruppenkennungen laufen zu lassen, die auch das Subversion-Projektarchiv besitzt. Es gibt keine einzig richtige Methode, um die Berechtigungen zu vergeben, und jeder Administrator wird bestimmte Gründe haben, um es auf eine bestimmte Art zu tun. Seien Sie sich lediglich bewusst, dass Probleme im Zusammenhang mit den Berechtigungen am häufigsten übersehen werden, wenn ein Subversion-Projektarchiv für die Verwendung mit Apache eingerichtet wird.

Authentifikationsoptionen

Falls Sie httpd.conf dergestalt konfiguriert haben, so dass sie etwa den folgenden Eintrag enthält:

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

kann die Welt anonym auf Ihr Projektarchiv zugreifen. Bis Sie Authentifikations- und Autorisierungsrichtlinien konfiguriert haben, sind die über die Direktive Location zur Verfügung gestellten Projektarchive allgemein für jedermann zugreifbar. Mit anderen Worten:

  • Jeder kann mit einem Subversion-Client eine Arbeitskopie eines Projektarchiv-URLs (oder irgendeines der Unterverzeichnisse) auschecken.

  • Jeder kann interaktiv die letzte Revision des Projektarchivs durchstöbern, indem der Projektarchiv-URL einfach mit einem Web-Browser geöffnet wird.

  • Jeder kann an das Projektarchiv übergeben.

Natürlich kann es sein, dass Sie schon längst ein pre-commit Hook-Skript bereitgestellt haben, um Übergaben zu verhindern (siehe „Erstellen von Projektarchiv-Hooks“). Sie werden jedoch beim Weiterlesen feststellen, dass es möglich ist, die eingebauten Methoden von Apache zu verwenden, um den Zugriff auf bestimmte Art und Weise einzuschränken.

[Tipp] Tipp

Die erforderliche Authentifizierung verhindert zwar, dass unerlaubte Anwender direkt auf das Projektarchiv zugreifen, schützt aber nicht die Vertraulichkeit der Netzwerkaktivitäten erlaubter Anwender. Siehe „Schutz des Netzwerkverkehrs durch SSL“ zur Konfiguration Ihres Servers mit SSL-Verschlüsselung, die eine zusätzliche Sicherheitsschicht bietet.

Einfache Authentifizierung

Die einfachste Methode, einen Client zu authentifizieren geht über den HTTP-Basic-Authentifikationsmechanismus, der einfach einen Anwendernamen und ein Passwort verwendet, um die Identität eines Anwenders sicherzustellen. Apache stellt das Dienstprogramm htpasswd[57] zur Verfügung, welches die Verwaltung von Dateien übernimmt, die Anwendernamen und Passwörter beinhalten.

[Warnung] Warnung

Die einfache Authentifizierung ist extrem unsicher, da Passwörter fast im Klartext über das Netz geschickt werden. Siehe „Digest authentication“ für Details zur Verwendung des wesentlich sichereren Digest Mechanismus.

Legen Sie zunächst eine Passwort-Datei und erlauben Sie den Zugriff für die Anwender Harry und Sally:

$ ### Beim 1. Mal: -c verwenden, um die Datei anzulegen
$ ### -m für die sicherere MD5-Verschlüsselung des Passworts verwenden
$ htpasswd -c -m /etc/svn-auth.htpasswd harry
New password: *****
Re-type new password: *****
Adding password for user harry
$ htpasswd -m /etc/svn-auth.htpasswd sally
New password: *******
Re-type new password: *******
Adding password for user sally
$
<Location /svn>
  DAV svn
  SVNParentPath /var/svn
  # Authentication: Basic
  AuthName "Subversion repository"
  AuthType Basic
  AuthUserFile /etc/svn-auth.htpasswd
</Location>

Diese Direktiven funktionieren wie folgt:

  • AuthName ist ein beliebiger Name, den Sie für Ihre Authentifikationsdomäne wählen. Die meisten Browser zeigen diesen Namen im Dialog an, wenn der Browser den Anwender nach seinem Namen und dem Passwort fragt.

  • AuthType spezifiziert den Typ der zu verwendenden Authentifikation.

  • AuthUserFile spezifiziert den Ort der zu verwendenden Passwortdatei.

Allerdings bewirkt dieser <Location>-Block noch nichts sinnvolles. Er teilt Apache lediglich mit, dass es sich den Anwendernamen und das Passwort vom Subversion-Client besorgen soll, falls eine Autorisierung benötigt wird. (Wenn eine Autorisierung erforderlich ist, benötigt Apache auch eine Authentifikation.) Was hier jedoch noch fehlt, sind Direktiven, die Apache sagen, welche Arten von Client-Anfragen eine Autorisierung erfordern; momentan sind das keine. Das Einfachste ist es, anzugeben, dass alle Anfragen eine Autorisierung erfordern, indem dem Block die Anweisung Require valid-user hinzugefügt wird:

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

  # Authentication: Basic
  AuthName "Subversion repository"
  AuthType Basic
  AuthUserFile /etc/svn-auth.htpasswd

  # Authorization: Authenticated users only
  Require valid-user
</Location>

Zu Details über die Direktive Require und anderen Möglichkeiten, Autorisierungsrichtlinien festzulegen, sehen Sie unter „Autorisierungsoptionen“ nach.

Digest authentication

Digest-Authentifizierung ist eine Verbesserung der Basic-Authentifizierung, die es dem Server ermöglicht, die Identität des Clients zu bestätigen, ohne das Passwort ungeschützt durch das Netz zu schicken. Sowohl Client als auch Server erzeugen einen nicht rückgängig zu machenden MD5-Hashwert des Anwendernamens, Passworts, verlangter URI und einer Einwegnummer, die vom Server vergeben wird und jedes Mal geändert wird, wenn eine Authentifizierung benötigt wird. Der Client sendet seinen Hash an den Server und der Server verifiziert dann, dass die Hashes zusammenpassen.

Die Konfigurierung von Apache für die Digest-Authentifizierung ist unkompliziert und nur eine kleine Abweichung von unserem vorangegangenen Beispiel:

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

  # Authentication: Digest
  AuthName "Subversion repository"
  AuthType Digest
  AuthUserFile /etc/svn-auth.htdigest

  # Authorization: Authenticated users only
  Require valid-user
</Location>

Beachten Sie, dass AuthType nun auf Digest gesetzt ist, und wir einen unterschiedlichen Pfad für AuthUserFile angegeben haben. Digest-Authentifizierung verwendet ein unterschiedliches Dateiformat als Basic-Authentifizierung; es wird mit Apaches Dienstprogramm htdigest erzeugt[58] statt mit htpasswd. Digest-Authentifizierung besitzt auch das zusätzliche Konzept eines Bereichs, realm, der dem Wert der Direktive AuthName entsprechen muss. Die Passwortdatei kann wie folgt erzeugt werden:

$ ### Beim ersten Mal: -c zum Erzeugen der Datei verwenden
$ htdigest -c /etc/svn-auth.htdigest "Subversion repository" harry
Adding password for harry in realm Subversion repository.
New password: *****
Re-type new password: *****
$ htdigest /etc/svn-auth.htdigest "Subversion repository" sally
Adding user sally in realm Subversion repository
New password: *******
Re-type new password: *******
$

Autorisierungsoptionen

An diesem Punkt haben Sie die Authentifizierung eingerichtet, nicht jedoch die Autorisierung. Apache kann Clients auffordern und Identitäten bestätigen, aber es wurde ihm noch nicht gesagt, wie er den Zugriff von Clients mit diesen Identitäten erlauben oder einschränken soll. Dieser Abschnitt beschreibt zwei Strategien, um den Zugriff auf Ihre Projektarchive zu kontrollieren.

Pauschale Zugriffskontrolle

Die einfachste Form der Zugriffskontrolle besteht darin, bestimmten Nutzern entweder nur Lesezugriff oder Lese- und Schreibzugriff auf ein Projektarchiv zu gewähren.

Sie können den Zugriff auf alle Operationen im Projektarchiv einschränken, indem Sie Require valid-user direkt dem <Location>-Block hinzufügen. Das Beispiel von „Digest authentication“ erlaubt nur Clients, die sich erfolgreich authentifiziert haben, um irgendetwas mit dem Subversion-Projektarchiv zu machen:

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

  # Authentifizierung: Digest
  AuthName "Subversion repository"
  AuthType Digest
  AuthUserFile /etc/svn-auth.htdigest

  # Autorisierung: Nur für authentifizierte Anwender
  Require valid-user
</Location>

Manchmal müssen Sie gar nicht so ein strenges Regiment führen. So erlaubt beispielsweise das eigene Projektarchiv von Subversion unter http://svn.collab.net/repos/svn allen auf der Welt lesende Operationen (wie etwa das Auschecken von Arbeitskopien und das Stöbern im Projektarchiv), beschränkt jedoch Schreiboperationen auf authentifizierte Nutzer. Die Direktiven Limit und LimitExcept erlauben diese Art der selektiven Einschränkung. Ähnlich der Direktive Location haben diese Blöcke Start- und Ende-Tags, die Sie innerhalb Ihres <Location>-Blocks unterbringen.

Die für die Direktiven Limit und LimitExcept verfügbaren Parameter sind HTTP-Anfrage-Typen, die von diesem Block beeinflusst werden. Falls Sie beispielsweise anonyme Nur-Lese-Zugriffe erlauben wollen, so würden Sie die Direktive LimitExcept (mit den Anfrage-Parametern GET, PROPFIND, OPTIONS und REPORT) verwenden und die vorher erwähnte Direktive Require valid-user im Block <LimitExcept> statt nur innerhalb des <Location>-Blocks einfügen.

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

  # Authentifizierung: Digest
  AuthName "Subversion repository"
  AuthType Digest
  AuthUserFile /etc/svn-auth.htdigest

  # Autorisierung: Nur authentifizierte Anwender für nicht Nur-Lese
  #                (Schreib-) Operationen; anonymes Lesen zulassen
  <LimitExcept GET PROPFIND OPTIONS REPORT>
    Require valid-user
  </LimitExcept>
</Location>

Dies sind nur ein paar einfache Beispiele. Für tiefer gehende Informationen über Apaches Zugriffskontrolle und die Direktive Require sollten Sie im Abschnitt Security der Apache Lehrbuchsammlung unter http://httpd.apache.org/docs-2.0/misc/tutorials.html nachlesen.

Verzeichnisweise Zugangskontrolle

Es ist möglich, detailliertere Zugriffsrechte mithilfe von mod_authz_svn einzurichten. Dieses Apache-Modul schnappt sich die verschiedenen undurchsichtigen URLs, die vom Client zum Server gereicht werden, fordert mod_dav_svn auf, sie zu dekodieren, und unterbindet dann möglicherweise Anforderungen entsprechend in einer Konfigurationsdatei definierter Zugriffsregeln.

Falls Sie Subversion aus Quellcode gebaut haben, ist mod_authz_svn automatisch neben mod_dav_svn gebaut und installiert worden. Viele binäre Distributionen installieren es ebenfalls automatisch. Um die korrekte Installation zu überprüfen, müssen Sie sicherstellen, dass es direkt hinter der LoadModule-Direktive von mod_dav_svn in httpd.conf auftaucht:

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

Zur Aktivierung dieses Moduls müssen Sie Ihren <Location>-Block mit der Direktive AuthzSVNAccessFile konfigurieren, die eine Datei mit Zugriffsrichtlinien für Pfade in Ihren Projektarchiven bezeichnet. (Gleich werden wir auf das Format dieser Datei eingehen.)

Da Apache flexibel ist, haben Sie die Wahl, Ihren Block auf eine von drei Arten zu konfigurieren. Fangen Sie mit der Auswahl eines dieser grundlegenden Konfigurationsmuster an. (Die folgenden Beispiele sind sehr einfach gehalten; sehen Sie sich die mitgelieferte Apache-Dokumentation an, um wesentlich mehr Einzelheiten zu den Authentifikations- und Autorisierungsoptionen von Apache zu erfahren.)

Der offenste Ansatz besteht aus Zugang für jeden. Das bedeutet, dass Apache niemals Aufforderungen zur Authentifikation sendet, so dass alle Anwender als anonymous behandelt werden. (Siehe Beispiel 6.2, „Eine Beispielkonfiguration für anonymen Zugang“.)

Beispiel 6.2. Eine Beispielkonfiguration für anonymen Zugang

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

  # Authentifizierung: keine

  # Autorisierung: pfadbasierte Zugangskontrolle
  AuthzSVNAccessFile /path/to/access/file
</Location>

Am anderen Ende der Paranoia-Skala können Sie Apache dergestalt konfigurieren, dass er alle Clients authentifiziert. Dieser Block verlangt eine unbedingte Authentifikation durch die Direktive Require valid-user und definiert wie berechtigte Anwender authentifiziert werden sollen. (Siehe Beispiel 6.3, „Eine Beispielkonfiguration für authentifizierten Zugang“.)

Beispiel 6.3. Eine Beispielkonfiguration für authentifizierten Zugang

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

  # Authentifizierung: Digest
  AuthName "Subversion repository"
  AuthType Digest
  AuthUserFile /etc/svn-auth.htdigest

  # Autorisierung: pfadbasierte Zugangskontrolle; nur für authentifizierte Anwender
  AuthzSVNAccessFile /path/to/access/file
  Require valid-user
</Location>

Ein drittes sehr verbreitetes Muster ist es, eine Kombination aus authentifizierten und anonymen Zugriff zu erlauben. So möchten beispielsweise viele Administratoren für anonyme Anwender den Lesezugriff auf bestimmte Verzeichnisse des Projektarchivs freigeben, während für heikle Bereichen nur authentifizierte Anwender zugelassen werden. Bei dieser Einstellung greifen alle Anwender zunächst anonym auf das Projektarchiv zu. Falls Ihre Zugangsrichtlinien an einer Stelle einen echten Anwendernamen erfordern sollte, fordert Apache den Client auf, sich zu authentisieren. Eingestellt wird dieses Verhalten mit den Direktiven Satisfy Any sowie Require valid-user. (Siehe Beispiel 6.4, „Eine Beispielkonfiguration für gemischten authentifizierten/anonymen Zugang“.)

Beispiel 6.4. Eine Beispielkonfiguration für gemischten authentifizierten/anonymen Zugang

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

  # Authentifizierung: Digest
  AuthName "Subversion repository"
  AuthType Digest
  AuthUserFile /etc/svn-auth.htdigest

  # Autorisierung: pfadbasierte Zugangskontrolle; zunächst anonymen Zugang
  #                versuchen, doch wenn nötig authentifizieren
  AuthzSVNAccessFile /path/to/access/file
  Satisfy Any
  Require valid-user
</Location>

Der nächste Schritt ist, eine Autorisierungsdatei zu erstellen, die Zugangsregeln für bestimmte Pfade innerhalb des Projektarchivs enthält. Wie, beschreiben wir später in „Pfadbasierte Autorisierung“.

Abstellen pfadbasierter Prüfungen

Das Modul mod_dav_svn unternimmt einen hohen Arbeitsaufwand, um sicherzustellen, dass Daten, die Sie als nicht lesbar markiert haben, nicht versehentlich nach draußen geraten. Das bedeutet, dass es aufmerksam alle Pfade überwachen muss, die von Befehlen wie svn checkout und svn update zurückgegeben werden. Begegnen diese Befehle einem Pfad, der aufgrund einer Autorisierungsrichtlinie nicht lesbar ist, wird dieser Pfad üblicherweise vollständig unterdrückt. Im Fall der Historien- oder Umbenennungsverfolgung, z.B. mit einem Befehl wie svn cat -r OLD foo.c auf einer Datei, die vor langer Zeit umbenannt wurde, bleibt die Umbenennungsverfolgung einfach stehen, wenn einer der früheren Namen des Objektes als lesebeschränkt erkannt wird.

All diese Pfadüberprüfungen können manchmal sehr teuer werden, besonders mit svn log. Wenn eine Liste mit Revisionen erstellt wird, sieht der Server bei jedem geänderten Pfad in jeder Revision nach, ob er lesbar ist. Falls ein nicht lesbarer Pfad entdeckt wird, taucht er in der Liste der geänderten Pfade dieser Revision nicht auf (normalerweise sichtbar mit der Option --verbose (-v)), und die gesamte Protokollnachricht wird unterdrückt. Es bedarf wohl keiner Erwähnung, dass dies bei Revisionen, die eine große Anzahl an Pfaden betreffen, sehr zeitaufwändig sein kann. Das ist der Preis für Sicherheit: selbst wenn Sie überhaupt kein Modul wie mod_authz_svn konfiguriert haben, fordert das Modul mod_dav_svn Apache httpd auf, Autorisierungsüberprüfungen für jeden Pfad vorzunehmen. Das Modul mod_dav_svn weiß nicht, welche Autorisierungsmodule installiert wurden, also kann es lediglich Apache auffordern, all das aufzurufen, was vorhanden sein könnte.

Auf der anderen Seite gibt es auch eine Art Notausgang, der es Ihnen erlaubt, Sicherheitsmerkmale gegen Geschwindigkeit zu tauschen. Falls Sie nicht irgendeine Art verzeichnisbasierter Autorisierung durchsetzen möchten (d.h., mod_authz_svn oder ähnliche Module nicht verwenden), können Sie die gesamte Pfadüberprüfung abstellen. Verwenden Sie die Direktive SVNPathAuthz in Ihrer Datei httpd.conf wie in Beispiel 6.5, „Abstellen aller Pfadüberprüfungen“ gezeigt.

Beispiel 6.5. Abstellen aller Pfadüberprüfungen

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

  SVNPathAuthz off
</Location>

Standardmäßig steht die Direktive SVNPathAuthz auf on. Auf off gesetzt, wird die gesamte pfadbasierte Autorisierungsüberprüfung abgestellt. mod_dav_svn beendet den Aufruf von Autorisierungsüberprüfungen für jeden entdeckten Pfad.

Schutz des Netzwerkverkehrs durch SSL

Die Verbindung zu einem Projektarchiv über http:// bedeutet, dass alle Subversion-Aktivitäten im Klartext über das Netzwerk geschickt werden. Dass heißt, dass Operationen wie das Auschecken, Übergaben und Aktualisierungen potentiell durch Unbefugte, die den Netzwerkverkehr abschnorcheln, abgefangen werden können. Die Verschlüsselung des Verkehrs mit SSL ist eine gute Maßnahme, um möglicherweise heikle Informationen im Netzwerk zu schützen.

Wird ein Subversion-Client für die Verwendung von OpenSSL übersetzt, erlangt er die Fähigkeit, mit einem Apache-Server über https://-URLs zu kommunizieren, wobei sämtlicher Verkehr durch einen Sitzungsschlüssel pro Verbindung verschlüsselt wird. Die vom Subversion-Client verwendete WebDAV-Bibliothek kann nicht nur Server-Zertifikate verifizieren, sondern nach Aufforderung auch Client-Zertifikate liefern.

Konfiguration von Subversion Server SSL Zertifikaten

Es würde den Rahmen dieses Buches sprengen, wenn beschrieben würde, wie SSL Client- und Server-Zertifikate erzeugt werden und wie Apache für ihre Verwendung konfiguriert wird. Viele andere Bücher, darunter Apaches eigene Dokumentation, erläutern diese Aufgabe.

[Tipp] Tipp

SSL-Zertifikate von wohlbekannten Instanzen sind in der Regel kostenpflichtig, doch können Sie als Minimallösung Apache so konfigurieren, das er ein selbstgezeichnetes Zertifikat verwendet, dass durch ein Werkzeug wie etwa OpenSSL erzeugt wurde (http://openssl.org).[59]

Subversion-Client SSL-Zertifikat-Verwaltung

Bei einer Verbindung zu Apache über https:// kann ein Subversion-Client zwei unterschiedliche Arten von Antworten empfangen:

  • Ein Server-Zertifikat

  • Eine Aufforderung zur Vorlage eines Client-Zertifikats

Server-Zertifikat

Wenn der Client ein Server-Zertifikat empfängt, muss er sicherstellen, dass der Server derjenige ist, für den er sich ausgibt. OpenSSL macht das, indem der Unterzeichner des Server-Zertifikats, die sogenannte Certificate Authority (CA), oder Zertifizierungsstelle, untersucht wird. Falls OpenSSL der CA nicht automatisch vertrauen kann, oder falls ein anderes Problem auftaucht (etwa ein abgelaufenes Zertifikat oder ein nicht übereinstimmender Rechnername), fragt Sie der Subversion-Kommandozeilenclient, ob Sie dem Server-Zertifikat dennoch vertrauen möchten:

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

Fehler bei der Validierung des Serverzertifikats für »https://host.example.com:443«:
 - Das Zertifikat ist nicht von einer vertrauenswürdigen Instanz ausgestellt
   Überprüfen Sie den Fingerabdruck, um das Zertifikat zu validieren!
Zertifikats-Informationen:
 - Hostname: host.example.com
 - Gültig: von Jan 30 19:23:56 2004 GMT bis Jan 30 19:23:56 2006 GMT
 - Aussteller: CA, example.com, Sometown, California, US
 - Fingerabdruck: 7d:e1:a9:34:33:39:ba:6a:e9:a5:c4:22:98:7b:76:5c:92:a0:9c:7b

Ve(r)werfen, (t)emporär akzeptieren oder (p)ermanent akzeptieren?

Dieser Dialog ist im Wesentlichen dieselbe Frage, die Sie bei Ihrem Web-Browser gesehen haben (der auch bloß ein weiterer HTTP-Client ist, so wie Subversion). Falls Sie die Option (p)ermanent auswählen, wird Subversion das Server-Zertifikat in Ihrem privaten Laufzeitbereich auth/ zwischengespeichert, ebenso wie Ihr Anwendername und Passwort (siehe „Client-Zugangsdaten“), und diesem Zertifikat bei künftigen Protokollverhandlungen vertrauen.

Ihre Laufzeit-Datei servers ermöglicht es Ihrem Subversion-Client ebenso, automatisch bestimmten CAs zu vertrauen, entweder global oder pro Host. Setzen Sie die Variable ssl-authority-files auf eine durch Semikolons getrennte Liste PEM-kodierter CA-Zertifikate:

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

Viele OpenSSL-Installationen besitzen auch eine vordefinierte Menge von Standard-CAs, denen nahezu allgemein vertraut wird. Damit der Subversion-Client diesen Standard-Zertifizierungsstellen automatisch vertraut, setzen Sie die Variable ssl-trust-default-ca auf true.

Client certificate challenge

Falls der Client eine die Aufforderung erhält, ein Client-Zertifikat vorzulegen, ersucht Apache den Client, sich zu identifizieren. Der Client muss ein Zertifikat zurückschicken, das von einer CA signiert wurde, der Apache vertraut, zusätzlich mit einer Aufforderungserwiederung (Challenge Response), die beweist, dass der Client in Besitz des zum Zertifikat gehörigen privaten Schlüssels ist. Für gewöhnlich wird der private Schlüssel und das Client-Zertifikat, durch eine lokale Passphrase geschützt, verschlüsselt auf Platte gespeichert. Wenn Subversion diese Aufforderung erhält, fragt es Sie nach dem Pfad zum Zertifikat und der Passphrase, das jenes schützt:

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

Anmeldebereich: https://host.example.com:443
Client Zertifikatsdatei: /path/to/my/cert.p12
Passphrase für »/path/to/my/cert.p12«:  ********

Beachten Sie, dass die Zugangsdaten des Clients in einer .p12-Datei gespeichert werden. Um ein Client-Zertifikat mit Subversion verwenden zu können, muss es im PKCS#12-Format vorliegen, was einem portablen Standard entspricht. Die meisten Web-Browser können Zertifikate in diesem Format im- und exportieren. Eine weitere Option ist es, die OpenSSL-Kommandozeilenwerkzeuge zu verwenden, um bestehende Zertifikate in PKCS#12 zu überführen.

Die Laufzeitdatei servers erlaubt Ihnen auch, diese Aufforderung pro Host zu automatisieren. Falls Sie die Variablen ssl-client-cert-file und ssl-client-cert-password setzen, kann Subversion automatisch auf Client-Zertifikat-Anforderungen antworten, ohne bei Ihnen nachzufragen:

[groups]
examplehost = host.example.com

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

Sicherheitsbewusstere Leute lassen möglicherweise ssl-client-cert-password weg, um zu vermeiden, die Passphrase im Klartext auf Platte zu speichern.

Extra Schmankerl

Die meisten Authentifikations- und Autorisierungsoptionen für Apache und mod_dav_svn haben wir abgehandelt. Es gibt jedoch noch ein paar weitere nette Dinge, die Apache zu bieten hat.

Stöbern im Projektarchiv

Einer der nützlichsten Vorteile eines Apache/WebDAV Aufbaus für Ihr Subversion Projektarchiv besteht darin, dass Ihre versionierten Dateien und Verzeichnisse unmittelbar mit einem gewöhnlichen Webbrowser betrachtet werden können. Da Subversion zur Identifizierung versionierter Ressourcen URLs verwendet, können diese URLs für den HTTP-basierten Zugriff direkt im Webbrowser eingetippt werden. Ihr Browser verschickt daraufhin für diesen URL eine HTTP GET-Anfrage; je nachdem, ob dieser URL ein versioniertes Verzeichnis oder eine Datei repräsentiert, antwortet mod_dav_svn mit der Auflistung eines Verzeichnisinhalts oder mit dem Inhalt einer Datei.

URL Syntax

Falls die URLs keinerlei Informationen über die Ressourcenversion enthalten, die Sie sehen möchten, wird mod_dav_svn stets mit der jüngsten Version antworten. Diese Funktionalität hat den wundervollen Nebeneffekt, dass Sie Subversion-URLs als Dokumentverweise an Ihre Mitarbeiter weitergeben können, die stets auf die neuesten Ausprägungen dieser Dokumente zeigen werden. Natürlich können Sie diese URLs auch aus anderen Webseiten heraus verwenden.

Seit Subversion 1.6 unterstützt mod_dav_svn eine öffentliche URI Syntax zur Untersuchung älterer Revisionen sowohl von Dateien als auch Verzeichnissen. Die Syntax verwendet den Teil des Query-Strings des URL, um entweder die Peg-Revision oder die operative Revision oder beide anzugeben, die Subversion dann verwendet, um die in Ihrem Browser darzustellende Version zu ermitteln. Fügen Sie dem Query-String das Namens-Wert-Paar p=PEGREV, hinzu, wobei PEGREV eine Revisionsnummer ist, die die Peg-Revision festlegt, die Sie für die Abfrage anwenden möchten. Verwenden Sie r=REV, wobei REV eine Revisionsnummer ist, die die operative Revisionsnummer festlegt.

Wenn Sie beispielsweise die letzte Version einer Datei README.txt in /trunk Ihres Projektes sehen möchten, zeigen Sie mit Ihrem Webbrowser auf die Projektarchiv-URL dieser Datei, die ähnlich der folgenden aussehen sollte:

http://host.example.com/repos/project/trunk/README.txt

Falls Sie nun eine ältere Version dieser Datei sehen wollten, fügen Sie dem Query-String der URL eine operative Revision hinzu:

http://host.example.com/repos/project/trunk/README.txt?r=1234

Was ist, falls das Objekt, das Sie sehen möchten, nicht mehr in der letzten Revision des Projektarchivs vorhanden ist? Hierbei ist eine Peg-Revision sehr hilfreich:

http://host.example.com/repos/project/trunk/deleted-thing.txt?p=321

Natürlich können Sie Peg-Revisions- und Angaben für operative Revisionen kombinieren, um genau anzugeben, was genau Sie sehen möchten:

http://host.example.com/repos/project/trunk/renamed-thing.txt?p=123&r=21

Der obige URL würde Revision 21 des Objekts anzeigen, das in Revision 123 an der Stelle /trunk/renamed-thing.txt im Projektarchiv lag. Siehe „Peg- und operative Revisionen“ für eine detaillierte Erörterung dieser Konzepte von Peg-Revision und operativer Revision. Sie könnten etwas schwer verständlich sein.

Zur Erinnerung: Diese Funktionalität von mod_dav_svn bietet nur ein eingeschränktes Stöbererlebnis im Projektarchiv. Sie können Verzeichnislisten und Dateiinhalte sehen, jedoch keine Revisionseigenschaften (wie etwa Protokollnachrichten) oder Datei- oder Verzeichniseigenschaften. Für Leute, die weitergehende Informationen zum Projektarchiv und seiner Geschichte benötigen gibt es hierfür mehrere Softwarepakete von Drittanbietern. Hierzu zählen beispielsweise ViewVC (http://viewvc.tigris.org), Trac (http://trac.edgewall.org) und WebSVN (http://websvn.info). Diese Werkzeuge von Drittanbietern beeinträchtigen nicht die eingebaute Stöberfähigkeit von mod_dav_svn und bieten im Allgemeinen weitergehende Funktionalität, wozu die Anzeige der eben erwähnten Mengen von Eigenschaften, die Anzeige von Unterschieden zwischen Dateirevisionen u.a. gehört.

Passender MIME-Typ

Während des Durchstöberns eines Subversion-Projektarchivs bekommt der Web-Browser Hinweise zur Darstellung des Inhalts einer Datei, indem er in den Content-Type:-Header von Apaches Antwort auf die HTTP GET-Anfrage schaut. Der Wert dieses Headers ist eine Art MIME-Typ. Standardmäßig teilt Apache den Web-Browsern mit, dass alle Dateien des Projektarchivs den Standard-MIME-Typen besitzen, normalerweise text/plain. Das kann jedoch frustrierend sein, wenn ein Anwender möchte, dass Dateien aus dem Projektarchiv etwas aussagekräftiger dargestellt werden; beispielsweise wäre es nett, wenn eine Datei foo.html aus dem Projektarchiv auch als HTML-Datei angezeigt würde.

Um das zu erreichen, müssen Sie nur sicherstellen, dass Ihre Dateien den passenden svn:mime-type gesetzt haben. Im Detail besprechen wir das in „Datei-Inhalts-Typ“. Sie können Ihren Client sogar so konfigurieren, dass er automatisch passende svn:mime-type-Eigenschaften an Dateien hängt, wenn sie das erste Mal in das Projektarchiv eingebracht werden (siehe „Automatisches Setzen von Eigenschaften“).

Um mit unserem Beispiel fortzufahren, wenn also jemand die Eigenschaft svn:mime-type mit dem Wert text/html an die Datei foo.html hänge, würde Apache Ihrem Browser wahrscheinlich mitteilen, dass die Datei als HTML darzustellen sei. Man könnte auch passende image/*-MIME-Type-Eigenschaften an Bilddateien hängen und somit eine komplette Webpräsenz direkt aus dem Projektarchiv heraus sichtbar machen! Solange die Webpräsenz keinen dynamisch erzeugten Inhalt hat, gibt es damit im Allgemeinen kein Problem.

Anpassung der Darstellung

Gemeinhin werden Sie mehr Nutzen aus URLs auf versionierte Dateien ziehen – hier liegt schließlich der interessante Inhalt. Gelegentlich werden Sie beim Durchstöbern eines Subversion-Verzeichnisinhalts feststellen, dass das zur Darstellung verwendete HTML sehr einfach ist und bestimmt nicht ästhetisch ansprechend (oder gar interessant). Um eine Anpassung dieser Verzeichnisdarstellungen zu ermöglichen, stellt Subversion einen XML-Index-Mechanismus zur Verfügung. Eine einzelne SVNIndexXSLT-Direktive im Location-Block des Projektarchivs in httpd.conf fordert mod_dav_svn auf, bei der Anzeige von Verzeichnisinhalten XML auszugeben und ein XSLT-Stylesheet Ihrer Wahl zu verwenden:

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

Wenn Sie die Direktive SVNIndexXSLT zusammen mit einem gestalterischen XSLT-Stylesheet verwenden, können Sie die Verzeichnisinhalte an das Farbschema und die bildliche Darstellung anderer Teile Ihrer Webpräsenz anpassen. Sollten Sie es vorziehen, können Sie auch die Beispiel-Stylesheets aus dem Verzeichnis tools/xslt/ des Subversion-Quelltextpakets verwenden. Beachten Sie, dass die Pfadangabe des Verzeichnisses SVNIndexXSLT tatsächlich um einen URL-Pfad handelt – Browser müssen Ihre Stylesheets lesen können, um sie zu verwenden!

Anzeige von Projektarchiven

Falls Sie mit einem einzelnen URL eine Ansammlung von Projektarchiven über die Direktive SVNParentPath verfügbar machen, ist es auch möglich, dass Apache einem Web-Browser alle verfügbaren Projektarchive anzeigt. Sie müssen nur die Direktive SVNListParentPath aktivieren:

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

Falls ein Anwender nun mit dem Web-Browser auf den URL http://host.example.com/svn/ geht, sieht er eine Liste aller Projektarchive unterhalb von /var/svn. Offensichtlich kann dies ein Sicherheitsproblem sein, so dass dieser Mechanismus standardmäßig abgestellt ist.

Protokollierung von Apache

Da Apache im Grunde genommen ein HTTP-Server ist, beinhaltet er fantastisch anpassungsfähige Protokollierungsmöglichkeiten. Es würde den Rahmen dieses Buches sprengen, alle Protokollierungseinstellungen zu erörtern, doch soll darauf hingewiesen werden, dass selbst die gewöhnlichste httpd.conf-Datei Apache veranlasst, zwei Protokolldateien anzulegen: error_log und access_log. Diese Protokolldateien können an unterschiedlichen Orten liegen, werden normalerweise aber im Protokollbereich Ihrer Apache-Installation angelegt. (Unter Unix liegen sie oft in /usr/local/apache2/logs/.)

Die Datei error_log zeichnet sämtliche internen Fehler beim Betrieb von Apache auf. Die Datei access_log protokolliert jede von Apache empfangene eingehende HTTP-Abfrage. Das macht es einfach, festzustellen, von welchen IP-Adressen Subversion-Clients kommen, wie oft bestimmte Clients den Server benutzen, welche Anwender sich richtig anmelden und welche Abfragen erfolgreich sind oder fehlschlagen.

Da HTTP ein zustandsloses Protokoll ist, erzeugt selbst die einfachste Funktion eines Subversion Clients leider mehrere Netzwerkabfragen. Es ist sehr schwer, anhand der Datei access_log herzuleiten, was der Client tat; die meisten Funktionen sehen aus wie eine Folge kryptischer PROPPATCH-, GET-, PUT- und REPORT-Abfragen. Und, was alles noch komplizierter macht: viele Client-Funktionen schicken fast identische Anfragen, was ein Auseinanderhalten erschwert.

mod_dav_svn kann Ihnen jedoch helfen. Durch die Aktivierung einer operativen Protokollierung können Sie mod_dav_svn veranlassen, eine gesonderte Protokolldatei anzulegen, die festhält, welche Art von Funktionen Ihre Clients auf höherer Ebene ausführen.

Um das zu bewerkstelligen, müssen Sie die Apache-Direktive CustomLog verwenden (die detailliert in der Dokumentation zu Apache beschrieben wird). Stellen Sie sicher, dass Sie die Direktive außerhalb Ihres Subversion Location-Blocks verwenden:

<Location /svn>
  DAV svn
  …
</Location>

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

In diesem Beispiel veranlassen wir Apache, die spezielle Protokolldatei svn_logfile im standardmäßigen Verzeichnis für Apache Protokolldateien, logs, anzulegen. Die Variablen %t und %u werden durch die Zeit bzw. den Anwendernamen der Anfrage ersetzt. Die wirklich wichtigen Teile sind die zwei Instanzen von SVN-ACTION. Wenn Apache diese Variable sieht, ersetzt er den Wert der Umgebungsvariablen SVN-ACTION, die automatisch von mod_dav_svn belegt wird, wenn eine Client-Funktion auf hoher Ebene feststellt wird.

Statt also eine traditionelle access_log-Protokolldatei auswerten zu müssen, die etwa so aussieht:

[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
…

können Sie eine weit verständlichere Datei svn_logfile durchgehen, die so aussieht:

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

Zusätzlich zur Umgebungsvariablen SVN-ACTION besetzt mod_dav_svn auch die Variablen SVN-REPOS und SVN-REPOS-NAME, die den Dateisystempfad zum Projektarchiv bzw. dessen Basisnamen beinhalten. Es sei empfohlen, Referenzen auf eine oder beide dieser Variablen in Ihre CustomLog Formatbeschreibung einzufügen; besonders dann, falls Sie Informationen aus mehreren Projektarchiven in einer einzelnen Protokolldatei sammeln.

Eine vollständige Liste mit allen protokollierten Aktionen finden Sie unter „Protokollierung auf hohem Niveau“.

Proxy mit Weiterleitung beim Schreiben

Einer der netten Vorteile von Apache als Subversion-Server ist die Möglichkeit zur Einrichtung eines einfachen Abgleichs. Nehmen wir zum Beispiel an, dass Ihr Team über vier Standorte auf der Welt verteilt ist. Da das Subversion-Projektarchiv nur an einem davon untergebracht sein kann, ist es für die anderen drei Standorte kein Vergnügen, darauf zuzugreifen, da sie wahrscheinlich eine spürbar langsamere Verbindung und längere Antwortzeiten beim Aktualisieren und Abliefern von Code erdulden müssen. Eine leistungsfähige Lösung besteht darin, ein System aufzusetzen, das aus einem Master-Apache-Server und mehreren Slave-Apache-Servern besteht. Falls Sie an jedem Standort einen Slave-Server aufstellen, können die Anwender eine Arbeitskopie vom nächstgelegenen Slave auschecken. Alle Leseanfragen gehen an den Server vor Ort. Schreibanfragen werden automatisch an den einzigen Master-Server weitergeleitet. Wenn die Übergabe abgeschlossen ist, schiebt der Master automatisch die neue Revision mithilfe des Abgleichswerkzeugs svnsync auf jeden Slave-Server.

Diese Konfiguration bewirkt eine riesige, für Ihre Anwender deutlich wahrnehmbare Geschwindigkeitszunahme, da der Netzverkehr von Subversion-Clients normalerweise zu 80—90% aus Leseabfragen besteht. Und wenn diese Abfragen von einem lokalen Server kommen, ist das ein Riesengewinn.

In diesem Abschnitt begleiten wir Sie durch eine Standard-Einrichtung dieses Ein-Master/Mehrere-Slaves-Systems. Denken Sie jedoch daran, dass auf Ihren Servern mindestens Apache 2.2.0 (mit geladenem mod_proxy) und Subversion 1.5 (mod_dav_svn) laufen muss.

[Anmerkung] Anmerkung

Unseres ist nur ein Beispiel, wie Sie eine Konfiguration für einen durchreichenden Subversion-Proxy einrichten können. Es gibt auch andere Ansätze. Anstatt den Master-Server Änderungen an jeden Slave-Server schicken zu lassen, könnten beispielsweise diee Slave-Server periodisch diese Änderungen vom Master abrufen. Oder vielleicht könnte der Master Änderungen an einen einzigen Slave schicken, der dann die selbe Änderung an den nächsten Slave weitergibt, und so der Reihe entlang weiterreicht. Administratoren sei nahegelegt, diesen Abschnitt zu verwenden, um ein grundsätzliches Verständnis darüber zu erlangen, was in einem Subversion-WebDAV-Proxy Szenario vor sich geht, und denjenigen Lösungsansatz zu wählen, der für ihre Organisation am besten funktioniert.

Einrichtung der Server

Konfigurieren Sie zunächst die Datei httpd.conf des Master-Servers auf die übliche Art. Stellen Sie das Projektarchiv unter einem bestimmten URI zur Verfügung und richten Sie nach ihren Wünschen die Authentifizierung sowie Autorisierung ein. Sobald dies erledigt ist, konfigurieren Sie jeden Ihrer Slave-Server auf exakt dieselbe Art, fügen jedoch die besondere Direktive SVNMasterURI dem Block hinzu:

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

Diese neue Direktive teilt dem Slave-Server mit, alle Schreibanfragen an den Master weiterzuleiten. (Dies geschieht durch das Apache-Modul mod_proxy automatisch.) Gewöhnliche Leseanfragen werden jedoch immer noch von den Slaves bedient. Stellen Sie sicher, dass Ihre Master- und Slave-Server die gleichen Authentifikations- und Autorisierungs-Konfigurationen haben; falls sie nicht mehr synchron sein sollten, kann das zu heftigen Kopfschmerzen führen.

Als nächstes müssen wir uns um das Problem unendlicher Rekursion kümmern. Stellen Sie sich vor, was unter der gegenwärtigen Konfiguration passiert, wenn ein Subversion-Client eine Übergabe an den Master-Server vornimmt. Wenn die Übergabe abgeschlossen ist, benutzt der Server svnsync, um die neue Revision nach jedem Slave zu replizieren. Da sich aber svnsync wie ein gewöhnlicher Subversion-Client bei einer Übergabe verhält, wird der Slave sofort versuchen, die hereinkommende Schreibaufforderung zurück an den Master weiterzuleiten! Da kommt Freude auf.

Die Lösung des Problems besteht darin, den Master Revisionen an eine unterschiedliche <Location> auf den Slaves senden zu lassen. Dieser Ort ist dergestalt konfiguriert, dass Schreibanfragen nicht weitergeleitet werden, sondern normale Übergaben von der IP-Adresse des Masters (und nur von dort) angenommen werden:

<Location /svn-proxy-sync>
  DAV svn
  SVNPath /var/svn/repos
  Order deny,allow
  Deny from all 
  # Nur Zugriffe auf diese Location von der IP-Adresse des Servers erlauben:
  Allow from 10.20.30.40
  …
</Location>
Einrichten der Replizierung

Nachdem Sie nun Ihre Location-Blöcke auf Mastern und Slaves konfiguriert haben, müssen Sie nun Ihren Master für die Replizierung zu den Slaves einrichten. Unser Anwendungsbeispiel verwendet svnsync, welches detailliert in „Replizierung mit svnsync“ behandelt wird.

Stellen Sie zunächst sicher, dass jedes Slave-Projektarchiv ein pre-revprop-change-Hook-Skript hat, das Änderungen an Revisions-Eigenschaften aus der Ferne ermöglicht. (Das ist Standard, wenn von svnsync empfangen wird.) Melden Sie sich dann auf dem Master-Server an und konfigurieren jede der Slave-Projektarchiv-URIs, so dass sie Daten vom Master-Projektarchiv auf der lokalen Platte empfangen:

$ svnsync init http://slave1.example.com/svn-proxy-sync \
               file:///var/svn/repos 
Eigenschaften für Revision 0 kopiert.
$ svnsync init http://slave2.example.com/svn-proxy-sync \
               file:///var/svn/repos 
Eigenschaften für Revision 0 kopiert.
$ svnsync init http://slave3.example.com/svn-proxy-sync \
               file:///var/svn/repos 
Eigenschaften für Revision 0 kopiert.

# Die initiale Replizierung durchführe

$ svnsync sync http://slave1.example.com/svn-proxy-sync \
$ svnsync sync http://slave1.example.com/svn-proxy-sync 
Übertrage Daten ....
Revision 1 übertragen.
Eigenschaften für Revision 1 kopiert.
Übertrage Daten ....
Revision 2 übertragen.
Eigenschaften für Revision 2 kopiert.
…

$ svnsync sync http://slave2.example.com/svn-proxy-sync \
               file:///var/svn/repos  
Übertrage Daten ....
Revision 1 übertragen.
Eigenschaften für Revision 1 kopiert.
Übertrage Daten ....
Revision 2 übertragen.
Eigenschaften für Revision 2 kopiert.
…

$ svnsync sync http://slave3.example.com/svn-proxy-sync \
               file:///var/svn/repos 
Übertrage Daten ....
Revision 1 übertragen.
Eigenschaften für Revision 1 kopiert.
Übertrage Daten ....
Revision 2 übertragen.
Eigenschaften für Revision 2 kopiert.
…

Nachdem das erledigt ist, wird das post-commit-Hook-Skript des Master-Servers konfiguriert, damit svnsync auf jedem Slave-Server aufgerufen wird:

#!/bin/sh 
# Post-Commit-Skript zum Replizieren der neu übergebenen Revision an die Slaves

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

Die zusätzlichen Stückchen am Ende jeder Zeile sind zwar nicht notwendig, erlauben es aber den Sync-Befehlen, auf eine leise Art und Weise im Hintergrund zu laufen, so dass der Subversion-Client keine Ewigkeit auf den Abschluss der Übergabe warten muss. Zusätzlich zu diesem post-commit-Hook werden Sie außerdem einen post-revprop-change-Hook benötigen, damit, wenn ein Anwender beispielsweise eine Protokollnachricht verändert, die Slave-Server diese Änderung ebenfalls mitbekommen:

#!/bin/sh 
# Post-revprop-Change-Skript zur Weitergabe der Änderung an den Revisionseigenschaften an die Slaves

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

Das Einzige, was wir hier ausgelassen haben, ist die Behandlung von Sperren auf Anwenderebene (der Sorte svn lock). Sperren werden vom Master-Server während der Übergabeoperationen durchgesetzt; alle Informationen zu Sperren werden jedoch während Leseoperationen wie svn update und svn status durch den Slave-Server verteilt. An und für sich müsste eine voll funktionsfähige Proxy-Umgebung die Sperrinformationen vom Master-zum Slave-Server perfekt replizieren. Leider sind die meisten der hierfür eingesetzten Mechanismen auf die eine oder andere Art unzureichend[60]. Viele Teams verwenden die Sperrfunktionalität von Subversion überhaupt nicht, so dass es Sie gar nicht betreffen könnte. Leider können wir den Teams, die Sperren verwenden, keine Empfehlungen aussprechen, wie diese Schwäche umgangen werden kann.

Warnungen

Nun sollte Ihr Master-Slave-Replizierungssystem einsatzbereit sein. An dieser Stelle sind einige Worte zur Warnung angebracht. Bedenken Sie, dass diese Replizierung nicht vollständig robust gegenüber Rechner- und Netzwerkausfällen ist. Wenn beispielsweise einer der automatisierten svnsync-Befehle aus irgendeinem Grund nicht vollständig abgeschlossen wird, beginnen die Slaves, hinterher zu hinken. Ihre entfernten Anwender werden sehen, dass sie Revision 100 übergeben haben; wenn sie allerdings svn update aufrufen, wird ihr lokaler Server ihnen mitteilen, dass Revision 100 noch nicht existiert! Natürlich wird das Problem automatisch mit der nächsten Übergabe behoben wenn das folgende svnsync erfolgreich ist – alle wartenden Revisionen werden dann repliziert. Trotzdem möchten Sie vielleicht eine zusätzliche Überwachung einrichten, um auf Synchronisierungsfehler hingewiesen zu werden, damit Sie in diesem Fall svnsync erneut aufrufen können.

Eine weitere Einschränkung des Modells eines durchreichenden Proxyeinsatzes betrifft nicht übereinstimmende Versionen – und zwar der installierten Subversion-Version – zwischen dem Master und den Slave-Servern. Jede neue Veröffentlichung von Subversion kann dem Netzwerkprotokoll, das zwischen den Clients und den Servern verwendet wird neue Funktionalität hinzufügen (und macht dies auch oftmals). Da die Aushandlung der Funktionalität mit dem Slave erfolgt, wird hier das Protokoll und der Funktionalitätsumfang des Slaves benutzt. Allerdings werden Schreiboperationen ziemlich wörtlich an den Master-Server weitergereicht. Daher besteht immer die Gefahr, dass der Slave-Server eine Funktionalitäts-Anfrage auf eine Art beantwortet, die für den Slave zutrifft, für den Master aber nicht, sofern er eine ältere Version von Subversion betreibt. Das kann dazu führen, dass der Client eine neue Funktionalität verwenden möchte, die der Master nicht versteht, und somit zu einem Fehler. Es existieren einige bekannte Probleme dieser Art in Subversion 1.7, das eine größere Überarbeitung seines HTTP-Protokolls einführte. Falls Sie einen Slave mit Subversion 1.7 vor einem Master mit einer Version vor 1.7 betreiben, sollten Sie den Subversion <Location>-Block Ihres Slave-Servers mit der Direktive SVNAdvertiseV2Protocol Off konfigurieren.

[Tipp] Tipp

Für ein bestmögliches Ergebnis sollten Sie versuchen, die selbe Version von Subversion auf dem Master- und Slave-Server laufen zu lassen.

Andere Funktionen von Apache

Einige der Funktionen, die Apache als robuster Webserver mitbringt, können auch zur Verbesserung der Funktionalität und Sicherheit in Subversion verwendet werden. Der Subversion-Client kann SSL (den bereits besprochenen Secure Sockets Layer) verwenden. Falls ihr Subversion-Client mit SSL-Unterstützung gebaut wurde, kann er auf Ihren Apache-Server mit https:// zugreifen und sich einer verschlüsselten Netzwerksitzung von hoher Qualität erfreuen.

Gleichermaßen nützlich sind andere Funktionen der Beziehung zwischen Apache und Subversion, wie etwa die Möglichkeit, einen besonderen Port zu spezifizieren (statt des HTTP Standard-Ports 80), oder einen virtuellen Domain-Namen, unter dem das Subversion-Projektarchiv erreichbar sein soll, oder die Möglichkeit, das Projektarchiv über einen HTTP-Proxy zu erreichen.

Da mod_dav_svn eine Teilmenge des WebDAV/DeltaV-Protokolls spricht, ist es möglich, auf das Projektarchiv über DAV-Clients von Drittanbietern zuzugreifen. Die meisten modernen Betriebssysteme (Win32, OS X und Linux) besitzen die eingebaute Fähigkeit, einen DAV-Server als eine Standard-Netz-Freigabe einzuhängen. Das ist eine komplizierte Angelegenheit, doch ebenso erstaunlich, wenn es implementiert ist. Zu Einzelheiten, siehe Anhang C, WebDAV und Autoversionierung.

Beachten Sie, dass es noch eine Anzahl weiterer kleiner Schräubchen gibt, an denen man bei mod_dav_svn drehen kann, die aber zu verworren sind, um sie hier im Kapitel aufzuführen. Eine vollständige Liste aller httpd.conf Direktiven, auf die mod_dav_svn reagiert, finden Sie unter „Anweisungen“ in Kapitel 9, Die vollständige Subversion Referenz.



[56] Die hassen so etwas echt.

[59] Obgleich selbstgezeichnete Zertifikate anfällig für Man-in-the-Middle-Angriffe sind, ist ein solcher Angriff schwieriger für einen laienhaften Beobachter durchzuführen als ungeschützte Passwörter abzuschnorcheln.