SVN-Server für den SSH-Zugriff einrichten

Alle Welt verwendet heute Git zur Versionskontrolle (ich auch), aber mitunter reichen die Funktionen von Subversion = SVN vollkommen aus. Und manchmal ist weniger eben mehr, vor allem wenn es gar nicht in erster Linie um die Versionskontrolle und die Verwaltung mehrerer Zweige geht, sondern vielmehr um ein geordnetes Arbeiten mehrerer Personen an einem gemeinsamen Projekt …

Update 28.10.2016: lshell statt ForceCommand.

Diese Anleitung fasst zusammen, wie Sie ein SVN-Repo einrichten, bei dem der Zugriff via SSH erfolgt, wobei sich die SVN-Benutzer aber dennoch nicht am Linux-Server einloggen können.

Ich gehe im Weiteren davon aus, dass auf dem Server bereits ein SSH-Server läuft. Soweit noch nicht installiert, ist auch das Paket subversion erforderlich, das Sie unter Debian/Ubuntu z.B. so installieren:

apt-get install subversion

Ein neues SVN-Repository einrichten

Wo soll das SVN-Repository gespeichert werden? Im Prinzip haben Sie hier freie Wahl. Ein geeigneter Ort ist das /home-Verzeichnis. Mit den folgenden Kommandos wird dort zuerst svn-repos angelegt. Dort können später einmal mehrere Repositories gespeichert werden. svnadmin create mein-projekt erzeugt das erste derartige Repository und legt dazu gleich das gleichnamige Unterverzeichnis an. Alle Kommandos müssen mit root-Rechten ausgeführt werden, unter Ubuntu also mit sudo.

mkdir /home/svn-repos
cd /home/svn-repos
svnadmin create mein-projekt
cd mein-projekt
nano/vi/jmacs conf/svnserve.conf

Mit dem Editor Ihrer Wahl passen Sie nun die Datei conf/svnserv.conf an. Wichtig sind für die hier vorgestellte Konfiguration ist eine Einstellung, die oft schon standardmäßig gilt:

# in /home/svn-repos/mein-projekt/conf/svnserv.conf
# ...   
# kein anonymer Zugriff
anon-access=none

SVN-Gruppe

Für alle Benutzer (Logins) am Linux-Server, die in Zukunft auf das SVN-Repository zugreifen dürfen, legen Sie nun die Gruppe svn an. Bereits vorhandene Benutzer fügen Sie mit usermod -a -G dieser Gruppe hinzu.

groupadd svn
usermod -a -G svn existing-user1
usermod -a -G svn existing-user2
...

Außerdem stellen Sie die Zugriffsrechte der Dateien der SVN-Repos so ein, dass alle Gruppenmitglieder der svn-Gruppe die Dateien lesen und verändern sowie alle Verzeichnisse betreten dürfen.

chgrp -R svn /home/svn-repos/
chmod -R g+rw /home/svn-repos/
chmod g+rwx $(find /home/svn-repos/ -type d)

Beachten Sie, dass das weiter oben ausgeführte Kommando svnadmin einige Unterverzeichnisse des Repositories mit dem Setgid-Bit eingerichtet hat, z.B. /home/svn-repos/mein-projekt/db. Diese Bit bewirkt, dass neue Dateien in diesem Verzeichnis nicht der Default-Gruppe des jeweiligen Benutzer gehören, sondern derselben Gruppe, dem das übergeordnete Verzeichnis gehört. Diese Setgid-Bits müssen erhalten bleiben!

ls -ld /home/svn-repos/mein-projekt/db
drwxrwsr-x 6 root svn 4096 Feb 13 23:57 /home/svn-repos/mein-projekt/db
      ^

SVN-only-Benutzer

Möglicherweise müssen Sie auch neue Logins für Personen einrichten, die bisher keinen Account auf Ihrem Server hatten, aber in Zukunft SVN nutzen sollen. Wichtig ist, dass diese Benutzer der SVN-Gruppe angehören:

useradd -G svn -m new-user1
useradd -G svn -m new-user2
passwd new-user1
passwd new-user2
...

Grundsätzlich können sich diese Benutzer nun via SSH auf Ihrem Server anmelden und dort arbeiten. Wenn Sie das nicht wünschen, können Sie durch wenige Zeilen in sshd_config erreichen, dass via SSH nur ein einziges Kommando ausgeführt werden darf, nämlich svnserver -t:

# in /etc/ssh/sshd_config
...
Match User new-user1
  ForceCommand svnserve -t
Match User new-user2
  ForceCommand svnserve -t
...

Damit diese Einstellungen wirksam werden, müssen Sie den SSH-Server auffordern, die Konfiguration neu einzulesen:

service ssh reload

Ein wesentlicher Nachteil dieser Konfiguration besteht darin, dass die betroffenen Benutzer weder Ihr eigenes Passwort verändern noch SSH-Key-Dateien einrichten können.

lshell statt ForceCommand (Update 28.10.2016)

Bei aktuellen Ubuntu-Versionen scheint die vorhin beschriebene Konfiguration mit ForceCommand nicht mehr zu funktionieren. (Ich habe nicht recherchiert, warum das so ist.)

Eine alternative Lösung bietet die lshell (github-Projekt). Installation unter Ubuntu erfolgt mit apt install lshell.

Zur Konfiguration ist die Datei /etc/lshell.conf vorgesehen. In der Gruppe [default] erlauben Sie als einziges reguläres Kommando passwd, und als einziges Kommando via SSH svnserve:

# in der Datei /etc/lshell.conf
# alle anderen Einstellungen belassen!
[default]
allowed         : [ 'passwd' ]               
overssh         : [ 'svnserve' ]

# wenn Sie lshell für verschiedene Benutzer mit 
# unterschiedlichen Einstellungen benötigen, lesen 
# Sie die Kommentare in lshell.conf

Jetzt müssen Sie nur noch die SVN-only-Benutzer der lshell zuordnen:

chsh new-user1 -s /bin/lshell
chsh new-user2 -s /bin/lshell

Ein großer Nachteil der lshell besteht darin, dass es für den Anwender keine Möglichkeit gibt, via ssh-copy-id einen SSH-Key hochzuladen. Der Versuch endet in der Fehlermeldung forbidden char/command over SSH (siehe auch lshell issue 163).

umask-Einstellung für svnserve

Jetzt gilt es nur noch, eine (wichtige!) Kleinigkeit nicht zu vergessen: Das Kommando svnserve, das für den eigentlichen SVN-Zugriff via SSH verantwortlich ist, wird mit den Default-umask-Einstellungen des Systems ausgeführt, unter Ubuntu z.B. mit 0022. Das hat zur Folge, dass neue Dateien für andere Mitglieder der svn-Gruppe zwar lesbar sind, aber nicht veränderbar. Das führt unweigerlich zu Zugriffskonflikten auf die SVN-internen Datenbankdateien.

Abhilfe schafft ein Mini-Script, dass zuerst umask 007 und dann svnserve ausführt. Dieses Script speichern Sie in der Datei /usr/local/bin/svnserve. Da sich /usr/local/bin im PATH vor /usr/bin befindet, wird nun bei jedem Aufruf von svnserve das folgende Script ausgeführt, das dann seinerseits das richtige svnserve-Kommando startet, aber eben mit liberaleren umask-Einstellungen. Sie erreichen damit, dass jede neue Datei, die im Rahmen von SVN-Operationen erzeugt wird, von allen Mitgliedern der SVN-Gruppe gelesen und verändert werden darf.

#!/bin/bash
# Datei /usr/local/bin/svnserve
umask 007
exec /usr/bin/svnserve "$@"

Anwendung

Alle Benutzer, die der SVN-Gruppe angehören, können nun wie folgt einen Checkout des SVN-Repos auf ihrem lokalen Rechner durchführen:

svn co svn+ssh://<user-name>@<host-name>/home/svn-repos/mein-projekt

Quellen