Intern:IT:HowTo:GIT Server

Aus PILARKTO.ORG Open Laboratory e.V.
Wechseln zu: Navigation, Suche


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"
         )
       )
     }
   }
 }