Intern:IT:HowTo:GIT Server
Dieses HowTo beschreibt die Installation eines GIT-Servers mit gitolite als administratives Tool
zur Verwaltung von Repositories. Um den Zugriff auf die Repositories zu sichern, wird der Zugriff via smart-http-backend bereitgestellt.
Zusätzlich soll die Benutzerauthentifizierung gegen ein LDAP vorgenommen werden.
Inhaltsverzeichnis |
git & gitweb
Die Installation von GIT und gitweb auf einem Linux Server gestaltet sich durch die Repositories sehr einfach.
Distributionen
gentoo linux
Auf einem gentoo kann git einfach über portage kompiliert werden.
emerge -av git --quiet
These are the packages that would be merged, in order: Calculating dependencies... done! [ebuild R ] dev-vcs/git-1.7.8.6 USE="blksha1 curl iconv perl python threads webdav -cgi -cvs -doc -emacs -gtk (-ppcsha1) -subversion -tk -xinetd" 3,953 kB Total: 1 package (1 reinstall), Size of downloads: 3,953 kB Would you like to merge these packages? [Yes/No]
Um gitweb mitzuinstallieren muss hier das cgi USE-Flag enabled werden.
debian
Für debian installieren wir das Paket git und gitweb
apt-get install git gitweb
gitweb
Nach der Installation müsste sich gitweb im Verzeichnis /usr/share/gitweb befinden. Es kann nun eine globale Konfigurations-Datei in /etc/gitweb.conf erstellt werden oder man setzt über den verwendeten Webserver die ENV-Variable GITWEB_CONFIG auf seine Konfigurations-Datei.
# path to git projects (<project>.git) $projectroot = "/pfad/zu/den/repositories"; # directory to use for temp files $git_temp = "/tmp"; # target of the home link on top of all pages #$home_link = $my_uri || "/"; # html text to include at home page $home_text = "indextext.html"; # file with project list; by default, simply scan the projectroot dir. #$projects_list = $projectroot; $projects_list = "/pfad/zur/projects.list"; # stylesheet to use $stylesheet = "gitweb.css"; # javascript code for gitweb $javascript = "gitweb.js"; # logo to use $logo = "git-logo.png"; # the 'favicon' $favicon = "git-favicon.png";
gitolite
Zuerst erstellen wir einen User der gitolite und die Repositories zur Verfügung stellt, switchen den User und erstellen einen Ordner /home/<username>/bin
useradd -g <name oder id der webserver Gruppe> -m <username> su -l <username> -c bash mkdir bin
Um gitolite zu installieren clonen wir das GIT-Repository und checken die gewünschte Version aus.
git clone https://github.com/sitaramc/gitolite.git git checkout v3.04
Anschließend führen wir das Install Script aus, erstellen ein SSH-Key-Pair für den Administrator und adden diesen in gitolite.
./gitolite/install -ln ssh-keygen -t rsa # der Dateiname enstpricht dem Username des Administrators ./bin/gitolite setup -pk <username>.pub
Die erstellten Schlüsselpaare können nun verwendet werden um das gitolite-admin.git Repository zu bearbeiten. Bevor man allerdings neue Repositories anlegt sollte man noch die UMASK in der ~/.gitolite.rc so konfigurieren, dass die Webserver-Gruppe Lese/Schreib Rechte bekommt.
## Für 770 owner (rwx), group (rwx), others (---) UMASK => 0007,
Nun benötigen wir ein kleines Wrapper-Script, dass vom Webserver aufgerufen wird und den User auf den git-user switched.
smart-http-wrapper.sh
#!/bin/sh exec sudo -E -u porg /pfad/zur/gitolite-shell
Damit nun der Webserver User ohne eine Passwortabrage nur die gitolite-shell ausführen kann fügen wir folgende Zeile der /etc/sudoers Datei hinzu:
<username webserver> ALL = (<username git>) NOPASSWD: SETENV: /pfad/zur/gitolite-shell
Authentifizierung vs. Autorisierung
gitolite selbst kann und will auch keine User-Authentifizierung vornehmen, dies ist die Aufgabe anderer Tools wie z.B. ssh oder der http-Server. Es wird lediglich eine Autorisierung vorgenommen, bei der geprüft wird ob ein User Schreib- bzw. Lese- Zugriff hat.
lighttpd
Als Webserver wird lighttpd verwendet. Dieser hat seit längerem LDAP-Support für HTTP-Authentication.
Für den GIT Server benötigen wir folgende Module:
server.modules = ( ... "mod_alias", "mod_auth", "mod_cgi", "mod_fastcgi", "mod_redirect", "mod_rewrite", "mod_setenv" ... )
$SERVER["socket"] == ":80" { server.document-root = "/var/www/htdocs" server.indexfiles += ( "index.cgi" ) cgi.assign = ( ".cgi" => "/usr/bin/perl" ) url.redirect = ( "^/(.*)\.git$" => "/?p=$1.git;a=summary" ) setenv.add-environment = ( "GITWEB_CONFIG" => "/var/www/gitweb.conf", ) $HTTP["useragent"] =~ "^git" { alias.url += ( "/git" => "/pfad/zur/smart-http-wrapper.sh" ) url.rewrite-once = ( "^/git$" => "/git/", "^/(.*)" => "/git/$1" ) $HTTP["url"] =~ "^/git" { cgi.assign = ( "" => "" ) setenv.add-environment = ( "GITOLITE_HTTP_HOME" => "/pfad/zum/git/home", "GIT_PROJECT_ROOT" => "/pfad/zu/git/repositories", "GIT_HTTP_EXPORT_ALL" => "", "REMOTE_USER" => "anonymous" ) } } }
$SERVER["socket"] == ":443" { ssl.engine = "enable" ssl.pemfile = "/pfad/zum/zertifikat.pem" server.document-root = "/var/www/htdocs" server.indexfiles += ( "index.cgi" ) cgi.assign = ( ".cgi" => "/usr/bin/perl" ) url.redirect = ( "^/(.*)\.git$" => "/?p=$1.git;a=summary" ) setenv.add-environment = ( "GITWEB_CONFIG" => "/var/www/gitweb.conf", ) $HTTP["useragent"] =~ "^git" { alias.url += ( "/git" => "/pfad/zur/smart-http-wrapper.sh" ) url.rewrite-once = ( "^/git$" => "/git/", "^/(.*)" => "/git/$1" ) $HTTP["url"] =~ "^/git" { cgi.assign = ( "" => "" ) setenv.add-environment = ( "GITOLITE_HTTP_HOME" => "/pfad/zum/git/home", "GIT_PROJECT_ROOT" => "/pfad/zu/git/repositories", "GIT_HTTP_EXPORT_ALL" => "", ) auth.backend = "ldap" auth.backend.ldap.hostname = "hostname" #auth.backend.ldap.starttls = "enable" #auth.backend.ldap.ca-file = "/pfad/zur/ca.crt" auth.backend.ldap.base-dn = "ou=user,dc=name,dc=tld" auth.backend.ldap.filter = "(&(uid=$)(memberof=cn=git,ou=group,dc=name,dc=tld))" auth.backend.ldap.bind-dn = "cn=git,ou=service,dc=name,dc=tld" auth.backend.ldap.bind-pw = "secret-string" auth.backend.ldap.allow-empty-pw = "disable" auth.require = ( "/git" => ( "method" => "basic", "realm" => "git repositories", "require" => "valid-user" ) ) } } }