This is an old revision of the document!
Table of Contents
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
- SSL-Zertifikat anlegen (siehe HowTo: Zertifikate)
- /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!)
