User Tools

Site Tools


howtos:subversion

This is an old revision of the document!


Howto: Subversion aufsetzen

Wie wurde SVN konkret für das SE konfiguriert?

Die verwendete Konfiguration setzt auf der Verwendung des Apache im Zusammenwirken mit DAV auf. DAV steht für “Distributed Authoring and Versioning” und bildet die Schnittstelle zwischen dem Apachen und Subversion. Die Verbindung erfolgt über SSL. Jede Benutzerauthentifizierung läuft über das vorhandene LDAP, die Benutzerauthorisierung über zentrale Dateien, die von der Gruppe “staff”, der jeder wissenschaftliche Mitarbeiter des SE angehört, editiert werden können. Das Setup wurde auf einem Debian 2.6.12 gemacht. Das Basisverzeichnis lautet bei dieser Konfiguration /svn, die Repository-Struktur ist die folgende:

/svn/shared/projects

/svn/shared/LV

/svn/shared/thesis

/svn/private

Jedes dieser Verzeichnisse bildet eine Art “Behälter” (technische Bezeichnung: “SVN-Parent-Path”) und stellt eine thematische Gliederung dar. Entsprechend der Ordnernamen können in diesen “Behältern” Repositories angelegt werden, also zB. /svn/shared/staff/mitarbeiter1, wobei “mitarbeiter1” das eigentliche Repository ist, “/svn/shared/staff” der “Behälter”.

Wichtig sind außerdem die Verzeichnisse

/svn/scripts

/svn/auth

Bisher ist für alle WiMis nur das Verzeichnis /svn/auth relevant, in der die zentralen Dateien für die Benutzerauthorisierung liegen.
Achtung: Für Apache2.2 sind zum Teil andere Einstellungen nötig!

Installation benötigter Pakete

apt-get install apache2 apache2-common openssl subversion subversion-tools libapache2-svn

Für Apache2.2:

apt-get install apache2 apache2.2-common openssl subversion subversion-tools libapache2-svn

Konfiguration

Apache2.0

  1. SSL-Zertifikat anlegen (siehe HowTo: Zertifikate)
  2. /etc/apache2/apache2.conf:
  • Einfügen einer Location-Direktive (hier am Beispiel des “private”-Repository-“Behälters”; OHNE die Zeilennummern natürlich, Erläuterung der einzelnen Zeilen siehe unten!):
     1 <Location /svn/private/> 
     2 DAV svn 
     3 SVNParentPath /svn/private/ 
     4 SSLRequireSSL 
     5 AuthType Basic 
     6 AuthName "svn>private" 
     7 #AuthUserFile /svn/auth/userlist_private 
     8 AuthLDAPURL ldaps://foucault.se.uni-hannover.de:636/ou=People,dc=se,dc=uni-hannover,dc=de?uid?sub?(objectClass=*) 
     9 AuthzSVNAccessFile /svn/auth/accesslist_private 
     10 Require valid-user 
     11</Location>

Erläuterungen zur Location-Directive

Zeile 1: Hier ist der absolute Pfad zum Repository-Behälter anzugeben, mit abschließendem Slash! Wenn in einem Browser also auf "https://cvs.uni-annover.de/svn/private/" zugegriffen wird, greift der Apache, sobald der String, der in Zeile 1 angegeben wird, gefunden wird, auf das Verzeichnis, das in Zeile 3 angegeben ist, zurück. Gibt man also zB anstatt “/svn/private/” “privatrepositories/” an, so greift der Apache, sobald im URL-String der Teilstring “privatrepositories/” beinhaltet ist, auf die Ressource, die in Zeile 3 angegeben ist, zurück. Vorsicht! Wenn man zwei Repository-Behälter hat und eine Location-Directive (also Zeile 1) für den einen Repository-Behälter “private/svn” und beim anderen “private/svn/spielerei” heißt, so werden alle Anfragen auf das Repository “spielerei” auf “/private/svn” weitergeleitet, weil die Location-Direktive “private/svn/spieler” den Teilstring “private/svn” enthält und der Apache das erste, bzw. kürzeste Ergebnis, auswählt!

Zeile 2: Einbindung des DAV-Moduls für den Apache2, welches für svn (Subversion) angewendet wird

Zeile 3: Ressource innerhalb des *nix-Dateisystems, auf das der Apache zurück greifen soll. Es muss der absolute Pfad angegeben werden, MIT ABSCHLIESSENDEM SLASH!!!

Zeile 4: Erzwingt die Verwendung einer gesicherten SSL-Verbindung

Zeile 5: Legt den Apache-Authorisierungsmechanismus fest

Zeile 6: Steht im Abfragefenster für das Passwort als erklärender Hinweis, für welche Ressource jetzt ein Passwort verlangt wird.

Zeile 7: Muss kommentiert bleiben. Für den Fall, dass der LDAP-Server komplett ausfällt, kann dennoch eine Arbeit mit dem SVN-System statt finden, in dem das Kommentarzeichen in Zeile 7 entfernt wird und die Zeile 8 auskommentiert wird. Als nächstes müsste dann in der Datei /svn/auth/userlist_private für jeden, der darin ein Repository besitzt, mit dem Befehl “htpasswd2 -m /svn/auth/userlist_private BENUTZERNAME” ein Passwort angelegt werden. Dies ist zB für den Fall gedacht, dass eine Lehrveranstaltung statt findet und LDAP bis auf weiteres nicht verfügbar ist. So könnte dennoch der Lehrbetrieb aufrecht erhalten werden, indem mit o.g. Befehl vorübergehend mittels dieses Alternativweges auf die Repositories zurück gegriffen werden kann. Wichtig! Wenn die Datei /svn/auth/userlist_{private|shared_staff|etc…} noch nicht existiert, muss anstelle von “htpasswd2 -m …” “htpasswd2 -c -m …” (c = “create”) angegeben werden. Ein “touch /svn/auth/userlist_{private|shared_staff|etc…}” reicht NICHT aus!

Zeile 8: Alle Authentifizierungsanfragen werden an den hier aufgeführten LDAP-Server weitergeleitet.

Zeile 9: Legt die Authorisierungsdatei für den entsprechenden Repository-Behälter fest. Auch hier ist ebenfalls der absolute Pfad innerhalb des Dateisystems anzugeben, allerdings ohne abschließenden Slash.

Zeile 10: Verlangt eine positive Authentifizierung eines gültigen Benutzers.

Zeile 11: Schließt die Location-Direktive ab.

Apache2.2

  • Die Location-Direktiven werden nicht in der apache2.conf gemacht, sondern in einem eigenen Virtual-Host-Container, welcher in einer Datei im Verzeichnis /etc/apache2/site-available/ gespeichert wird. Nebst den “üblichen” Einstellungen wie Root-Verzeichnis und Log-Directory wird in dieser Datei zusätzlich für jedes Repository eine Location-Direktive nach unten stehendem Muster angelegt:
<Location /svn/private/>
    <Location /svn/private/>
         DAV svn
         SVNParentPath /svn/private/
         SSLRequireSSL
         AuthType Basic
         AuthName "svn>private"
#        AuthUserFile /svn/auth/userlist_private
         AuthLDAPURL ldap://schiller.se.uni-hannover.de:389/ou=People,dc=se,dc=uni-hannover,dc=de?uid?sub?(objectClass=*) TLS
         AuthzLDAPAuthoritative On
         AuthBasicAuthoritative Off
         AuthBasicProvider ldap
         AuthzSVNAccessFile /svn/auth/accesslist_private
         Require valid-user
    </Location>
</Location> 

Neu sind die Einträge “AuthBasicAuthoriztative Off”, “AuthzLDAPAuthoritative On”, sowie “AuthBasicProvider ldap”. Auch die AuthLDAPURL hat sich verändert, man beachte das TLS am Ende der Zeile!
Da LDAP über TLS verschlüsselt kommuniziert, ist eine Veränderung in der Hauptkonfigurationsdatei des Apache nötig. Am Ende der Datei etc/apache2/apache2.conf werden folgende Einträge ergänzt:

LDAPTrustedGlobalCert CERT_BASE64 /etc/ssl/certs/certchain.pem
LDAPTrustedMode STARTTLS
LDAPVerifyServerCert On

Das angegebene CA-Cert muss sich natürlich an entsprechender Stelle befinden.

Außerdem müssen einige Module installiert, bzw. aktiviert werden:

apt-get install libapache2-mod-ldap-userdir libapache-authznetldap-perl
a2enmod userdir authnz_ldap

Anlegen des SVN-Systems

Je nachdem, wie man in der apache2.conf (s.o.) die Struktur für die Repository-Behältnisse vorgesehen hat, müssen entsprechend auch alle Ordner angelegt werden. Im Beispiel oben wird das Verzeichnis “/svn/private/” als Basisverzeichnis definiert und der Zugriff auf die Datei accesslist_private im Verzeichnis /svn/auth/ verlangt. Die hiesige Umsetzung am SE basiert auf den folgenden Befehlen:

mkdir /svn
mkdir /svn/shared
mkdir /svn/shared/staff
mkdir /svn/shared/LV
mkdir /svn/shared/thesis
mkdir /svn/auth
mkdir /svn/scripts (siehe unten)

Alle Verzeichnisse (bis auf “scripts” müssen www-data gehören (Benutzername des Apache2) und als Gruppe “staff” haben, damit alle WiMis auch auf das Dateisystem lesend Zugriff haben.

Entsprechend:

chown -R www-data:staff /svn
chmod -R 750 /svn

Als nächstes müssen die Authorisierungslisten angelegt…

touch /svn/auth/accesslist_private
touch /svn/auth/accesslist_shared_staff
touch /svn/auth/accesslist_shared_LV
touch /svn/auth/accesslist_shared_thesis

…und die Rechte angepasst werden:

chown www-data:staff /svn/auth/*
chmod 660 /svn/auth/*

Anlegen neuer Repositories

Dazu gibt es ein kleines, primitives Bash-Skript, welches im Verzeichnis /svn/scripts liegt und den Namen mkrepository trägt.

/svn/scripts/mkrepository /PATH/TO/REPO-LOCATION REPONAME USER SECONDUSER SECONDUSER-PERMS

Manuell können neue Repositories mit folgendem Befehl (per root) erzeugt werden:

svnadmin create /ABSOLUTE/PATH/TO/REPO

Allerdings müssen dann für jeden Ordner die Zugriffsrechte auf 750, für jede Datei auf 660 und der Besitzer und die Gruppe auf www-data:staff geändert werden. All dies nimmt das Skript ab.

Setzen von Zugriffsrechten

Alle Zugriffsrechte für jedes Repository werden über die zentralen Dateien, die in /svn/auth liegen, gesteuert. Jeder Repository-Behälter hat eine solche Datei und entsprechend muss für ein Repository zB “/svn/private/person1” auch die access-Datei “/svn/auth/accesslist_private” editiert werden.

An dieser Stelle soll das Schema der “accesslist” anhand des Beispiels “/svn/private/person1” dargestellt werden.

Wichtige Vorbemerkung:
Jede Zeile in der Accesslist stellt eine Rechtevergabe dar. Wenn man die Rechtevergabe mit einem Semikolon versieht und/oder hinter die Rechtevergabe einen Kommentar mit der Raute (#) einleitet, wird beim Zugriff auf das Repository, für das man die Rechte editiert hat, ein “Permission Denied” vom Apache ausgegeben. Semikolons am Ende einer Rechtevergabezeile dürfen also nie gesetzt werden und Kommentare entweder über oder unter eine Rechtevergabezeile!
Person1 hat ein Repository im Repository-Behälter “/svn/private/” mit dem Namen “person1” (standardmäßig wird vom mkrepository-Skript der Repository-Name auf den Benutzernamen des Besitzers gesetzt). Da dieses Repository ein privates ist, soll entsprechend zunächst auch nur Person1 auf dieses Repository Zugriff haben, und zwar lesend und schreibend. Der Eintrag in der accesslist_private lautet demnach:

[person1:/]
Person1 = rw

In den eckigen Klammern steht der Name des Repositories, gefolgt von einem Doppelpunkt und einen Slash. Das bedeutet, dass die darauffolgenden Berechtigungen, in diesem Fall Person1 = rw, sich auf alle Unterverzeichnisse beziehen. Man kann das Slash auch als eine Art “Wurzel” verstehen, nämlich die Wurzel des Repositories “person1”. Person1 = rw bedeutet natürlich, dass “Person1” read- und write-Permissions in seinem Repository hat. “Person1” muss in jedem Fall ein Benutzername sein, der in der gleichen Schreibweise auch im LDAP steht!

Im Laufe der Zeit entwickelt Person1 mehrere Java-Projekte. In seinem Repository sind inzwischen mehrere Unterordner:

trunk/java-ftp-client
trunk/java-ftp-client-gui
trunk/java-google-mars

Anmerkung: Mit dem Eclipse-Plugin Subversive wird automatisch ein Verzeichnis “trunk” erstellt, welches das Hauptarbeitsverzeichnis darstellt.

Jetzt hat Person1 die Kernanwendung seines Java-FTP-Clients beendet und möchte seine Arbeit nun veröffentlichen. Also erstellt er einen “branch” (ebenfalls mit Subversive), sodass seine Repository-Struktur nun so aussieht:

trunk/java-ftp-client
trunk/java-ftp-client-gui
trunk/java-google-mars
branch/java-ftp-client/v1.0

Damit auch allgemein Zugriff, natürlich nur lesend, auf sein Ergebnis zugegriffen werden kann, muss die accesslist_private wie folgt verändert werden:

[person1:/]
Person1 = rw
 
[person1:/branch]
* = r

Bedeutung: Im Unterverzeichnis /branch des Repositories “person1” hat nun jeder “*” lesend “r” Zugriff. Allerdings wäre es sicherer, wenn Person1 lieber einen allgemein nutzbaren Benutzer anlegt und entsprechend auch ein Passwort generiert, welches er natürlich veröffentlicht. Wichtig zu bemerken ist, dass nach wie vor nur Person1 auf alles lesend und schreibend Zugriff hat und lediglich erweiterte Leserechte auf ein Unterverzeichnis gegeben wurde.
ACHTUNG: Sollte der anonyme Zugriff auf ein Repository gewünscht sein, dann muss im Config-File des Apache in der Location-Direktive des jeweiligen SVN-Containers noch folgendes ergänzt werden:

Satisfy Any

Die komplette Location-Direktive - hier am Beispiel “projects” - sieht dann so aus:

<Location /svn/shared/projects/>
 DAV svn
 SVNParentPath /svn/shared/projects/
 SSLRequireSSL
 AuthType Basic
 AuthName "svn>shared>projects"
 #AuthUserFile /svn/auth/userlist_shared_staff
 AuthLDAPURL ldaps://foucault.se.uni-hannover.de:636/ou=People,dc=se,dc=uni-hannover,dc=de?uid?sub?(objectClass=*)
 AuthzSVNAccessFile /svn/auth/accesslist_shared_projects
 Satisfy Any
 Require valid-user
</Location>

Person1 möchte nun einen Kumpel an seiner Google-Mars-Arbeit mitwirken lassen, allerdings hat der gar nichts mit seinen anderen Projekten zu tun. Person1 erweitert erneut die accesslist wie folgt:

[person1:/]
Person1 = rw
 
[person1:/branch]
* = r
 
[person1:/trunk/java-google-mars]
kumpel1 = rw

Dadurch hat sein Kumpel1 nun lesend und schreibend Zugriff auf sein Google-Mars-Projekt. Wenn jetzt der kleine Bruder von Kumpel1 sich mit Java beschäftigen und anhand eines Beispiels dazulernen will, kann Person1 dem gerecht werden, in dem er die accesslist so editiert, dass der kleine Bruder von kumpel1 nur lesen kann (weil kleiner Bruder keinen Plan von Java hat und nix kaputt machen soll):

[person1:/]
Person1 = rw
 
[person1:/branch]
* = r
 
[person1:/trunk/java-google-mars]
kumpel1 = rw
kleinerBruderKumpel1 = r

Dieses Beispiel ließe sich beliebig fortsetzen. Kernaussage ist, dass man mithilfe dieser Listen äußerst feingranular Rechte setzen und wieder entziehen kann.

Verwendete Quellen

  • SVN-Book (siehe unten)

Offizielles Handbuch

Interne Verweise

Quelltext zum Skript "mkrepository"

Howto: Subclipse in Eclipse integrieren (Hinweis dazu: Bitte die Vorbemerkung unbedingt beachten!)

howtos/subversion.1377891200.txt.gz · Last modified: 2013/08/30 21:33 by martin · Currently locked by: 172.21.0.5,216.73.216.147