Subversion über Apache erreichbar machen

Es gibt viele Gründe, warum man den Zugriff auf ein SVN-Repository über Apache zur Verfügung stellen will: Diverse Authentifizierungsmethoden, Lesezugriff über den Browser, SSL-Verschlüsselung und Logging. Ausgehend vom letzten Blogartikel zum Themamöchte ich in diesem Artikel beschreiben, wie man Apache dazu bringen kann, ein Subversion-Repository mit SSL-Verschlüsselung zugänglich zu machen.

Apache bietet von Hause aus sehr viele Authentifizierungsmethoden. Außerdem ist es möglich, Authentifikationssysteme von Drittanbietern zu integrieren. Beispielsweise setzen Firmen für die Authentifikation einen zentralen LDAP-Server ein. Über entsprechende Apache-Module lässt sich Subversion also einfach in die bestehende Infrastruktur einbinden.

Das SVN-Modul für Apache stellt darüber hinaus einen einfachen Lesezugriff auf das Repository bereit. Der Nutzer kann mit dem Browser durch das Repository zu navigieren und sich Dateien im Browser anschauen oder herunterladen. Nutzer können sich dadurch schnell einen Überblick über das Repository verschaffen.

Apache bietet mit https einen einfachen Weg, die Verbindung zwischen Client und Server zu verschlüsseln. Besonders dann, wenn Kennwörter über das Internet ausgetauscht werden, bietet sich eine sichere Verbindung an.

Nicht zuletzt die Logging-Fähigkeit von Apache ist ein Grund, Apache anstelle von svnserve einzusetzen. Auf diese Weise ist die Fehlersuche sehr viel einfacher, da man entsprechende Meldungen im Fehlerlog auswerten kann. Außerdem bietet sich die Protokollierung der Zugriffe an, wenn das Repository auch aus dem Internet erreichbar sein muss. Dadurch werden Manipulationsversuche ebenso protokolliert.

Verschiedene Zugriffsmethoden für das SVN-Repository

An dieser Stelle kommt freilich die Frage auf, ob es möglich ist, svnserve und Apaches mod_dav_svn nebeneinander zu betreiben. Das Subversion-Buch (Kapitel 6, Abschnitt “Using Multiple Repository Access Methods”) spricht sich diesbezüglich positiv aus: “But is it possible—or safe—for your repository to be accessed by multiple methods simultaneously? The answer is yes, provided you use a bit of foresight.” Es ist also durchaus möglich. Das Problem besteht beispielsweise in den Dateirechten. Wer Subversion mit svnserve betreibt und den svnserve-Prozess unter einem dedizierten User betreibt, muss entsprechende Dateirechte für den Webserver vergeben. Im folgenden Schritt solljedoch erst einmal erklärt werden, welche Module benötigt werden.

Module installieren

Um Subversion über apache 2.2 betreiben zu können, werden folgende Module benötigt:

Modul Beschreibung
mod_dav Das DAV-Modul wird standardmäßig mit Apache ausgeliefert, sollte also immer enthalten sein und muss nur aktiviert werden.
mod_dav_svn Modul muss manuell nachinstalliert und aktiviert werden.

Unter Debian-basierten Systemen kann das Modul mod_dav_svn einfach über aptitude oder apt-get installiert werden. Für Apache 2.2 muss dazu das Paket libapache2-svn installiert werden:

root@linux:~# apt-get install libapache2-svn

Unter Ubuntu 9.04 werden bei der Installation des oben genannten Pakets die erforderlichen Module mod_dav und mod_dav_svn direkt aktiviert. Lediglich der Webserver mus neu gestartet werden, damit die Module geladen werden:

root@linux:~# /etc/init.d/apache2 restart

Der Vorteil der Installation unter Ubuntu und Debian ist, dass das Paketystem die ganze grundlegende Modulkonfiguration für einen erledigt. So muss man die installierten Module nicht selbst mit der LoadModule-Direktive in der httpd.conf freischalten.

Subversion-Modul für Apache konfigurieren

In Ubuntu liegen die Konfigurationsdateien für jedes Modul im Verzeichnis /etc/apache2/mods-availabe/ – so auch die Datei dav_svn.conf. Um Apache für den Betrieb mit Subversion zu konfigurieren, muss diese Datei angepasst werden. Da aber Apache bereits für weitere virtuelle Hosts konfiguriert ist, bietet es sich an, die dav_svn-Konfiguration ebenso als virtuellen Host zu konfigurieren. Unter Ubuntu legst du dir also im Verzeichnis /etc/apache2/sites-available/ eine entsprechende Datei mit dem Namen subversion an:

root@linux:~# vim /etc/apache2/sites-available/suversion

Der Editor vim öffnet damit eine neue Datei im Verzeichnis mit den Konfigurationsdateien für die virtuellen Hosts.

Zunächst einmal soll ein virtueller Host angelegt werden, der mit dem SSL-Protokoll angesprochen wird:

<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName svn.local
SSLEngine on
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key

BrowserMatch “.*MSIE.*” \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
</VirtualHost>
</IfModule>

Um das VirtualHost-Element ist ein IfModule-Element gesetzt, das überprüft, ob das Apache-Modul für SSL geladen worden ist. Nur dann, wenn dieses Modul zur Verfügung steht, wird der folgende virtuelle Host angelegt, andernfalls steht er nicht zur Verfügung. Der virtuelle Host erhält den Servernamen svn.local, was durch die ServerName-Direktive festgelegt wird. Ferner wird mit der Direktive SSLEngine on SSL aktiviert. Mit den Direktiven SSLCertificateFile und SSLCertificateKeyFile wird das SSL-Zertifikat sowie die zum Zertifikat gehörende Schlüsseldate angegeben. Die im Beispiel verwendeten Zertifikate sind standardmäßig in Ubuntu vorhanden.

Im folgenden Schritt soll nun das Subversion-Repository konfiguriert werden:

<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName svn.local
<Location /svn>
DAV svn
SVNPath /var/svn/repos
</Location>

SSLEngine on
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key

BrowserMatch “.*MSIE.*” \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
</VirtualHost>
</IfModule>

Im Element Location wird spezifiziert, dass der URL-Pfad /svn/ mit dem Repository gemappt wird, das mit der Direktive SVNPath spezifiziert ist. Somit kann über die URL http://svn/svn/ auf das Repository zugegriffen werden.

In der vorgestellten Konfiguration könnte zwar einfach auf den Server zugegriffen werden, das Problem ist jedoch, dass es keine Zugriffsbeschränkung gibt. Jeder, der im Netzwerk ist, kann lesend und schreibend auf das Repository zugreifen. Mit der folgenden Konfiguration muss sich der Nutzer auf jeden Fall authentifzieren:

<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName svn.local
<Location /svn>
DAV svn
SVNPath /var/svn/repos
AuthType Basic
AuthName "Subversion repository"
AuthUserFile /var/www/vhosts/svn/files/svn-auth-file
Require valid-user
</Location>

SSLEngine on
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key

BrowserMatch “.*MSIE.*” \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
</VirtualHost>
</IfModule>

Mit der Direktive AuthType wird der Authentifizierungstyp ausgewählt. In diesem Fall wurde der einfache Authentifzierungsmechanismus Basic ausgewählt. Mit der Direktive AuthName wird der Titel für den Browser-Dialog vorgegeben, in dem der Nutzer den Benutzernamen und das Passwort einzutragen haben. Mit AuthUserFile wird der absolute Pfad zur Datei angegeben, in der der Benutzername und das Passwort für die Authentifizierung gespeichert ist. Für dieses Beispiel habe ich einfach das Verzeichnis innerhalb der virtuellen Hosts gewählt, in das aus dem WWW nicht zugegriffen werden kann. Lediglich Apache kann lesend und schreibend auf die Datei zugreifen. Mit der letzten Direktive Require wird schließlich angegeben, dass nur authentifizierte Nutzer (valid-user) auf die angegebene Ressource zugreifen dürfen.

Passwortdatei anlegen

Im folgenden Schritt soll nun die Passwortdatei svn-auth-file angelegt werden. Dazu wird das Apache-Tool htpasswd benutzt. Zuerst jedoch muss das fehlende Verzeichnis im vhost-Zweig des Webserver-Basisverzeichnisses angelegt werden:

root@linux:~# mkdir -p /var/www/vhosts/svn/files

Anschließend werden die notwendigen Accounts angelegt:

root@linux:/var/www/vhosts/svn/files# htpasswd -cm svn-auth-file harry
New password:
Re-type new password:
Adding password for user harry
root@linux:/var/www/vhosts/svn/files#

Mit der Option -c wird htpasswd übrigens angewiesen, eine neue Datei anzulegen. Der Name der Datei ist der zweite Parameter. Damit gleich beim Anlegen der Datei ein Account mitangelegt wird, übergeben wir dem Programm htpasswd die Option m. Somit wird htpasswd mit den Optionen -cm, dem Namen der Passwortdatei und dem User-Namen aufgerufen. Anschließend fordert htpasswd uns dazu auf, ein Passwort einzugeben. Die wiederholte Passworteingabe dient dazu, die erste Passworteingabe zu bestätigen, um auf diese Weise Tippfehler auszuschließen. Anschließend kann Apache dazu aufgefordert werden, die Konfiguration neu zu laden:

root@linux:~# /etc/init.d/apache2 reload

Wer das Subversion-Repository beschrieben mit svnserve angelegt hat, wird feststellen, dass Apache nicht auf das Repository zugreifen kann.

ACL: Dateien des Repositorys für Apache freigeben

Das Repository unter /var/svn/repos/ gehört dem User svnowner, die Gruppe ist nobody. svnowner ist auch der User, unter dem der svnserve-Prozess läuft. Theoretisch könnte man die Gruppe nobody durch eine neue Gruppe ersetzen, der www-data und svnowner zugeordnet werden, beispielsweise svngroup oder dergleichen. Dies kann jedoch zu Problemen führen, wenn durch Schreibzugriffe die Dateizugriffsrechte zu restriktiv gesetzt werden. Wenn beispielsweise www-data eine SVN-Datei beschreibt und dadurch Besitzer der Datei wird, kann es sein, dass die Zugriffsrechte auf 640 gesetzt werden: Nur der Besitzer kann lesen und schreiben, die Gruppe nur lesen. Dadurch kann svnowner nicht mehr auf das Repository zugreifen.

Diesen Problemen kann man von Anfang an aus dem Weg gehen, indem man ACLs benutzt. Damit ACLs überhaupt gesetzt werden können, müssen jedoch zwei Vorbedingungen erfüllt sein:

  • Das Dateisystem muss ACLs unterstützen.
  • Bei bestimmten Dateisystemen wie EXT3 muss die ACL-Unterstützung über eine Mount-Option aktiviert werden.

Da ich EXT3 benutze, musste ich in der /etc/fstab die Option acl setzen:

/dev/sda2 / ext3 rw,acl 0 1

Die bestehende Option rw wurde einfach durch die Option acl erweitert. Zu beachten ist, dass Optionen durch Kommata separiert werden.

ACL-Einstellungen für Repository-Dateien setzen

ACL-Zugriffsrechte werden mit dem Befehl setfacl gesetzt. Da die SVN-Dateien bereits dem User svnowner gehören, müssen die ACL-Zugriffsrechte für den User www-data gesetzt werden. Unter dem User www-data läuft in Debian- und Ubuntu-Systemen der Apache Webserver. Mit den folgenden Befehlen werden die notwendigen Rechte gesetzt:

root@linux:/var/svn# setfacl -R -m u:www-data:rwx repos
root@linux:/var/svn# setfacl -R -d u:www-data:rwx repos

Im ersten Befehl mit dem Schalter -m werden die ACL-Einstellungen für die aktuellen Dateien gesetzt. Der Schalter -R bedeutet “rekursiv”. Dadurch werden alle Unterverzeichnisse des angegebenen Verzeichnisses repos rekursiv durchlaufen und jede Datei sowie jedes Verzeichnis erhält die angegebenen ACL-Einstellungen.

Ganz wichtig ist der zweite Befehl mit dem Schalter -d. Mit diesem werden Default-ACL-Einstellungen gesetzt. Da svnserve die Eigenschaft hat, Temporäre Dateien anzulegen und mit diesen anschließend bestehende Dateien zu ersetzen, würden ACL-Einstellungen verloren gehen. Mit den Default-ACL-Einstellungen erhält jede neu angelegte Datei im Verzeichnis eine Standard-ACL-Einstellung.

Zugriff auf das Repository über den Browser

Damit sind alle notwendigen Einstellungen vorgenommen. Nun ist es auch möglich, die Apache-Konfiguration zu testen. Dazu könnt ihr einfach mit einem Browser auf die Repository-URL zugreifen und durch die Verzeichnisse des Repositorys navigieren.

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>