Mittwoch, 5. März 2008
[*]

Subversion mit svn+ssh-Protokoll und Eclipse

, 13:45

Diese Anleitung muß ich für ein paar Kollegen im Moment sowieso schreiben, und vielleicht interessiert das ja noch irgendjemanden. Bevor ich also wieder so ein unkommunikatives Word-Dokument rumschicke:

1. Subclipse

Im Gegensatz zu CVS wird der Nachfolger Subversion von Eclipse (noch?) nicht direkt unterstützt — dabei hat Subversion viele Vorteile (z.B. atomare Transaktionen und Versionierung über Verschiebungen und Umbenennungen hinweg). Zuerst müssen wir das deshalb in Form eines Plugins nachrüsten: Subclipse gibt es bei tigris.org, und eine Installationsanleitung ist auch dort.

So, jetzt kann man in Eclipse die „SVN Repository Exploring perspective“ öffnen und dort die Adresse seines Repositories eintragen.

Add SVN Repository

Auf UNIXoiden Betriebssystemen wie Linux, Solaris und MacOS X kann man den folgenden Schritt überspringen. Dort ist ssh in der Regel installiert, im Pfad und kann als Tunnel gestartet werden ohne Fensterchen aufzumachen.

2. ssh-Tunnel aufbauen

Subversion unterstützt einen Haufen unterschiedlicher Protokolle. Neben dem direkten Dateizugriff auf das Repository und einem eigenen Protokoll für lokale Aufrufe unterstützt es WebDAV über http(s) durch ein Apache-Modul und kann über verschiedene Remote-Shell-Protokoll tunneln. Wenn man die Repositories (so wie wir) auf einem UNIX-Server lagert und keine Lust hat, sich mit dem svnDAV-Apache-Modul und seiner zweiten Benutzerverwaltung herumzuschlagen, dann ist das svn+ssh-Protokoll eine günstige Wahl. Leider kommt Windows ohne ssh-Client (im Repository Explorer sieht man unklare Fehlermeldungen wie „Das Verzeichnis ist nicht da.“), deshalb muß Abhilfe geschaffen werden.

Wenn man z.B. OpenSSH für Windows im Pfad hat (wenn Subclipse also ssh.exe ausführen kann), dann kommt zumindest eine Verbindung zustande, ssh läuft aber in diesen häßlichen schwarzen Fenstern der Eingabeaufforderung und fragt auch dort nach dem Paßwort. Eine schönere Alternative bietet das zu TortoiseSVN (das ich ohnehin empfehle) gehörige TortoisePlink. Das ist eine GUI-Variante des eigentlich zum PuTTY-Paket gehörigen ssh-Tunnels plink. Wenn man den Rest von TortoiseSVN nicht installieren möchte, dann funktioniert TortoisePlink.exe auch allein.

Welches Programm man für den Tunnel auch immer aussucht, man muß es Subversion bekanntmachen: in der Datei %APPDATA%\Subversion\config gibt es einen entsprechenden Abschnitt:

### Section for configuring tunnel agents.
[tunnels]
### Configure svn protocol tunnel schemes here.  By default, only
### the 'ssh' scheme is defined.  You can define other schemes to
### be used with 'svn+scheme://hostname/path' URLs.  A scheme
### definition is simply a command, optionally prefixed by an
### environment variable name which can override the command if it
### is defined.  The command (or environment variable) may contain
### arguments, using standard shell quoting for arguments with
### spaces.  The command will be invoked as:
###   <command> <hostname> svnserve -t
### (If the URL includes a username, then the hostname will be
### passed to the tunnel agent as <user>@<hostname>.)  If the
### built-in ssh scheme were not predefined, it could be defined
### as:
# ssh = $SVN_SSH ssh
ssh = C:/Programme/TortoiseSVN/bin/TortoisePlink.exe
### If you wanted to define a new 'rsh' scheme, to be used with
### 'svn+rsh:' URLs, you could do so as follows:
# rsh = rsh
### Or, if you wanted to specify a full path and arguments:
# rsh = /path/to/rsh -l myusername
### On Windows, if you are specifying a full path to a command,
### use a forward slash (/) or a paired backslash (\\) as the
### path separator.  A single backslash will be treated as an
### escape for the following character.

(das ist natürlich nur ein Beispiel, der tatsächliche Pfad zum ssh-Tunnel kann anders sein).

„Schon“ haben wir Verbindung.

3. Die lästige Paßwortabfrage loswerden

Bei jeder Aktion poppt jetzt aber (vielleicht sogar mehrmals) ein Fenster auf und fragt nach dem Paßwort. Das kann auf Dauer sehr lästig werden, deshalb richten wir im folgenden ssh-Authentifizierung durch kryptographische Schlüssel ein (dazu braucht man aber Shell-Zugriff und ein eigenes home-Verzeichnis auf dem Subversion-Server):

Wer OpenSSH-basierte Tunnel benutzt hat es hier leichter, denn ein Aufruf von ssh-keygen reicht in der Regel um alle notwendigen Dateien zu erzeugen und dorthin zu legen, wo ssh sie auch wiederfindet.

Für PuTTY-basierte Systeme benötigen wir PuTTYgen (auch hier) und erzeugen uns damit eine Schlüsseldatei (.ppk):

PuttyGEN

Leider gibt es keinen festen Ort, an dem Plink die wiederfindet, deshalb ändert sich die obige Beispielkonfiguration folgendermaßen:

### Section for configuring tunnel agents.
[tunnels]
### Configure svn protocol tunnel schemes here.  By default, only
### the 'ssh' scheme is defined.  You can define other schemes to
### be used with 'svn+scheme://hostname/path' URLs.  A scheme
### definition is simply a command, optionally prefixed by an
### environment variable name which can override the command if it
### is defined.  The command (or environment variable) may contain
### arguments, using standard shell quoting for arguments with
### spaces.  The command will be invoked as:
###   <command> <hostname> svnserve -t
### (If the URL includes a username, then the hostname will be
### passed to the tunnel agent as <user>@<hostname>.)  If the
### built-in ssh scheme were not predefined, it could be defined
### as:
# ssh = $SVN_SSH ssh
ssh = C:/Programme/TortoiseSVN/bin/TortoisePlink.exe -2 -i "C:/Dokumente und Einstellungen/trenger/ssh/putty_key_rsa.ppk"
### If you wanted to define a new 'rsh' scheme, to be used with
### 'svn+rsh:' URLs, you could do so as follows:
# rsh = rsh
### Or, if you wanted to specify a full path and arguments:
# rsh = /path/to/rsh -l myusername
### On Windows, if you are specifying a full path to a command,
### use a forward slash (/) or a paired backslash (\\) as the
### path separator.  A single backslash will be treated as an
### escape for the following character.

(das ist wieder nur ein Beispiel, die tatsächlichen Pfade können natürlich anders sein)

Für die Sicherheitsfanatiker darf an dieser Stelle auf keinen Fall verschwiegen werden, daß wir jetzt in beiden Beispielen den ssh-Schlüssel nicht mit einer Passphrase geschützt haben. Das sollte man so nur tun, wenn man den Rechner, auf dem der Schlüssel liegt gut unter Kontrolle hat (so daß niemand die Schlüsseldatei nehmen und die Identität stehlen kann). In Umgebungen mit geringerer Systemsicherheit sollte man mit ssh-agent bzw. Pageant arbeiten (das zu erklären sprengt aber diesen Artikel).

Der Schlüssel muß auf der Serverseite natürlich noch als Zutrittsberechtigt eingetragen werden. Dafür wird die Textform des öffentlichen Schlüssels an die Datei ~/.ssh/authorized_keys (auf dem Server!) angehängt. Wer oben ssh-keygen benutzt hat, der findet seinen öffentlichen Schlüssel in der Datei ~/.ssh/id_rsa.pub (oder %APPDATA%\ssh\id_rsa.pub), wer PuTTYgen benutzt, der sieht auf der Oberfläche eigens ein Feld „Public key for pasting into OpenSSH authorized_keys file:“ (praktisch, oder?).

Jetzt sollte man ohne Paßwortabfrage auf den Server kommen.

4. Checkout

In der Regel liegt das Modul, in dem das Eclipse-Projekt enthalten ist — anders als bei CVS — jetzt nicht direkt im Stammordner des Repositories sondern in einem Unterordner „trunk“. Das liegt am unterschiedlichen Konzept der Branches und Tags (die bei Subversion durch eine simple versionierte Kopie erzeugt werden). Diese Struktur wird aber nicht von der Software erzwungen und kann deshalb von Fall zu Fall abweichen.

svn checkout

Nach dem Checkout unterscheidet sich die grundsätzliche Bedienung (Team->Update, Team->Commit,…) der Versionsverwaltung in Eclipse erstmal nicht von der CVS-Variante. Als weiterführende Lektüre (auch zu dem Thema, wie das denn jetzt mit den Branches funktioniert) empfehle ich das Buch Version Control with Subversion.

13 Reaktionen:

  1. Gravatar

    Hi,
    großes lob an diese schöne Anleitung.
    Ich versuche schon seit Tagen svn+ssh zu laufen zu bekommen. Ich bekomme auch eine ssh Verbindung ohne Passwörter nur mit den keys hin. Es erscheint dann die Komandozeile meines Servers.
    Nur subversion funktioniert nicht. Hast du die subversion.config auf dem Server oder dem client geändert?
    Wenn ich die plink auf dem Client eintrage, wechselt meine Fehler meldung von „Kann Tunnel nicht erzeugen:“ auf „Netzwerkverbindung wurde unerwartet geschlossen“. kannst du mir da weiterhelfen?

  2. Gravatar

    Ja, da kann ich helfen:

    1. Die Konfigurationsdatei wird auf dem Client angepasst.

    2. Wenn man plink (statt TortoisePlink) verwendet, dann fragt es bei der ersten Verbindung in einem unsichtbaren Fenster, ob man dem ssh-Fingerabdruck des Servers vertraut, und ob man ihn zu den „known_hosts“ hinzufügen möchte. Ruf‘ die Kommandozeile genau so, wie Subversion es tun soll, mal in einer Eingabeaufforderung auf (also z.B. „plink -2 -i schluessel.ppk benutzer@host“). Nur wenn dann ohne weitere Ausgaben der Prompt kommt, kann die Verbindung für den Tunnel genutzt werden.

    (P.S.: Dieselbe Fehlermeldung kommt übrigens auch, wenn auf dem Server svn nicht im Pfad ist.)

  3. Gravatar

    Vielen vielen Dank für die wirklich schnelle Antwort (s. uhrzeit) 🙂

    Ich habe wie du beschrieben hast die Kommunikation mit plink getestet und vestgestellt das nicht nur der Promt, sonder auch immer einige zusätzliche Zeichen übertragen werden. Die lag an FreeSSHD, welchen eine „neue Console“ verwendet. Seitdem ich dieses „Feature“ ausgeschaltet bekomme ich auch den blanken Promt c:/ssh/privateKeys>.

    Bei Tortoise bekam ich weiterhin die Fehlermeldung „Netzwerk unerwartet geschlossen“. Ich habe mich mal mit plink am server angemeldet und festgestellt, dass ich trotz der Angabe von Subversion in der Systemvariable PATH svnserve nicht aufrufen konnte. Erst als ich die bin-Dateien in das Verzeichniss c:/ssh:/privateKeys kopiert habe funktioniert auch Tortoise.

    jippi 😀

    Nachdem ich nun auch die ersten Daten eingecheckt habe, hab ich gesehen, dass ich als Author SYSTEM eingetragen bin. Weißst du wie ich das auf den namen ändere, den ich bei der Anmeldung von SSH verwendet habe? Ist das vieleicht auch der Grund für die nicht funktionierende PATH variable?

    Viele Grüße und vielen vielen Dank für die Hilfe

  4. Gravatar

    Hmmm. Da bin ich jetzt auch überfragt. Das liegt am ehesten an den Einstellungen des FreeSSHD, der wahrscheinlich svnserve nicht mit den richtigen Privilegien ausführt (das ist aber geraten, denn bei uns laufen die Server alle unter UNIX, und da funktioniert das Rechtekonzept etwas anders).

  5. Gravatar

    Schon ganz gut, aber noch nicht 100%.
    Was ist wenn man verschiedene Server mit verschiedenen Schlüsseln und verschiedenen Benutzer verwendet?

    Ganz einfach, man nimmt den -i Parameter von Dir aus der Config wieder raus.
    Dafür legt man dann in Putty eine Session mit dem Namen des Hosts an.
    In dieser Session kann man dann Benutzer und Schlüssel angeben.
    Wenn TortoisePLink eine passende Putty-Session findet, dann verwendet es diese.
    Damit funktionieren auch Externals wunderbar.
    Siehe auch http://www.maddes.net/software/subversion.htm#svn+ssh_client

  6. Gravatar

    Cool, danke! Darauf war ich noch nicht gekommen.

  7. Gravatar

    Sehr guter Blog Einträg. Einer ergänzung noch. Bei der svn+ssh://… URL muss man als Repository einen KOMPLETTEN Pfas zum Repository eintragen, also z.B.

    svn+ssh://host.domain.org/home/username/myrepo

  8. Gravatar

    Noch eine ergänzung. Beim installieren von subclipse kann man auch SVNKit mit installieren. Das ist ein pureJava SSH Client. Dann gehts auch ganz Eclipse intern unter Windows.

  9. Gravatar

    SVNKit ist tatsächlich nützlich — aber neuer als dieser Artikel.

  10. Gravatar

    Hallo zusammen,
    ich finde den Artikel auch sehr hilfreich. Nur ein Hinweis zu SVNKit: wird das verwendet, kann man den fingerprint des Servers nicht mehr prüfen, da der SSH Client in pure Java diese Funktion nicht hat.
    Viele Grüße
    Marcus

  11. Gravatar

    Vielleicht habe ich etwas übersehen, aber Ich habe gerade festgestellt, dass man dem user eine Shell geben soll in der passwd. Wenn ich das nicht tue, bricht bei mir die Verbindung ab.

  12. Gravatar

    Ja, das ist richtig. Der Benutzer muss das svn-Backend (svnserve -c) aufrufen können. Wenn man das etwas absichern möchte, dann kann man aber eine rbash (oder rsh) einrichten.

  13. […] für den Administrator. Der sollte als root oder mit dem eigenen Useraccount erzeugt werden (in diesem älteren Artikel habe ich das schon einmal beschrieben, auch die sicherheitsrelevante Überlegung, ob der Schlüssel […]

Kommentare willkommen