Ein Freund fragte mich kürzlich, ob ich ihm einen SVN-Server aufsetzen könne. Ich habe selbst von SVN keine Ahnung und habe auch nicht vor mich einzulesen, da ich mit git ganz fit bin. Das ist also nur eine kleine Gedankenstütze für mich.

Voraussetzungen

  • funktionierender Apache2 auf einem Linuxsystem (hier: Debian)

Zielsetzung

Ziel soll es sein, dass ein Freund sich per SSH auf meinem Server einloggen kann und dann per „svnadmin“ die Repositories erstellt. Danach kann er über den Apache-VHost svn.misterunknown.de auf diese Repos zugreifen und diese verändern. Es gibt allerlei externe Programme, die mit dem Server kommunizieren können, beispielsweise TortoiseSVN.

Vorgehen

Als erstes hab ich die SVN-Erweiterung von Apache installiert.

apt-get install libapache2-svn

Anschließend kann man sich die (auskommentierte) Default-Konfiguration mal angucken (im Apache 2.4 heißt die Datei /etc/apache2/mods-available/dav_svn.conf). Ich dort allerdings alles auskommentiert gelassen und einen frischen VHost aufgesetzt:

<VirtualHost *:44
        ServerName svn.misterunknown.de
        ServerAdmin webmaster@misterunknown.de

        SSLEngine On # man sollte Verschlüsselung benutzen
        ...

        <Location />
                DAV svn
                SVNParentPath /data/svn
                SVNListParentPath on

                AuthType Basic # Authentifizierung einrichten
                ...
                <LimitExcept GET PROPFIND OPTIONS REPORT>
                        Require group svn
                </LimitExcept>
        </Location>

        DocumentRoot /data/svn
        <Directory /data/svn>
                Require all granted
                AllowOverride None
        </Directory>

        ... # normales Error- und Access-Log definieren
        CustomLog /var/log/apache2/vhosts/svn.misterunknown.de-svn.log "%t %u %{SVN-ACTION}e" env=SVN-ACTION
</VirtualHost>

Kurz die wichtigsten Zeilen erklärt:

  • 1, 5, 6: Ich würde unbedingt raten, den VHost per SSL zu verschlüsseln. Ich habe dazu ein StartSSL-Zertifikat genutzt, es geht aber auch Lets encrypt oder ein selbst-signiertes. Hauptsache eure Daten werden nicht unverschlüsselt übertragen.
  • 9-12: Hier wird das Verhalten des SVN-Moduls bestimmt. Ich habe also den Pfad /data/svn/, den ich als SVN-Parent-Path definiere. Das heißt innerhalb dieses Verzeichnisses können dann mehrere SVN-Repositories liegen. Mit der Option SVNListParentPath lege ich fest, dass die Repositories ähnlich eines DirectoryListings angezeigt werden.
  • 14: Es empfiehlt sich außerdem eine Authentifizierung davor zu hängen. Definiert man direkt hier ein „Require irgendwas“ kann man den gesamten VHost absichern…
  • 16-18: … möchte man dagegen ein öffentlich lesbares Repository haben, kann man sich mit diesen 3 Zeilen behelfen. Das heißt quasi, dass man für alle Request-Methoden ungleich GET, PROPFIND, OPTIONS und REPORT in der Gruppe svn sein muss (.htgroup).
  • 21-25: Hier definieren wir ein Fallback-DocumentRoot. Dort habe ich nur eine index.html hingelegt, die keinen relevanten Inhalt hat.
  • 27: Hier kann man noch LogFiles definieren, ich habe ganz klassisch ein Error- und ein Access-Log eingerichtet.
  • 28: Dieses Log ist speziell für SVN-Aktionen gedacht.

Damit hätten wirs. Jetzt kommt es nur noch auf die Berechtigungen an und das ist schon etwas tricky.

Dateiberechtigungen

Das Problem bei verschiedenen Usern (SSH-Benutzer + Webserver) unter Linux ist, wie man sicherstellt, dass alle sowohl lesend als auch schreibend auf die Dateien zugreifen können. Als erstes habe ich für diesen Zweck eine Gruppe eingerichtet und mit dem SGID-Bit dafür gesorgt, dass alle Dateien und Verzeichnisse die gleiche Gruppe bekommen:

mkdir -p /data/svn
useradd -M -d /data/svn -s /bin/bash sshuser
groupadd www-svn
usermod -aG www-svn sshuser
usermod -aG www-svn www-data
chgrp www-svn /data/svn
chmod g+ws /data/svn

Bis hier her sollte alles klar sein. Das Problem: Wenn ich als sshuser per „svnadmin“ ein Repository anlege, wird zwar die Gruppe korrekt gesetzt, allerdings werden die Schreibrechte nicht übernommen. Das führt dazu, dass der Webserver die Daten zwar sieht, aber nicht verändern kann. Was ist also die Abhilfe? ACLs.

Es ist das erste mal, dass ich sowas wirklich einsetze, bisher brauchte ich das alles noch nicht. So schwierig ist das aber nicht, wer Hilfe braucht, kann sich hier kann man sich einlesen. Die Vorgehensweise bei mir war so:

# sicher gehen, dass die Gruppe überall Schreibrecht hat
chmod -R g+w /data/svn
# ACL setzen
setfacl -Rd -m group:www-svn:rwx /data/svn

Damit werden für neue Dateien und Verzeichnisse auch Gruppenschreibrechte gesetzt, und sowohl der sshuser als auch der Webserver können darauf zugreifen.

Nächster Beitrag Vorheriger Beitrag