Sie sind auf Seite 1von 13

Eine Arbeitsgruppe an meiner Hochschule bat mich darum, einen Server mit Git (und

Trac) zu installieren. Ich bin der Bitte nachgekommen und habe auf einem Rechner
Ubuntu 9.10 und dann darauf Git und Trac installiert. Diesen Artikel schreibe ich auch als
Gedächtnisstütze für mich, falls ich so eine Maschine noch mal aufsetzen muss.

Einige Hinweise zu dieser Anleitung:

- ich übernehme keinerlei Haftung für irgendwelche Schäden, die durch die Befolgung
dieser Anleitung entstehen
- das Setup ist nicht optimal, da der git-daemon häufig Repositories nicht exportiert.
Irgendwo befindet sich ein Bug in meiner Konfiguration und ich finde ihn nicht. Hinweise
werden erbeten, falls jemand beim Nachvollziehen dieser Anleitung auf den Fehler stößt. 
- gitosis hat bei diesem Setup leider nicht die Macht, die es haben sollte, weil der git-
daemon nicht immer eingebunden wird. Durch die Verwendung einer Public-Key-
Authentification sollten aber keine Sicherheitsprobleme auftreten. Falls jemand eines
entdecken sollte, lasst es mich bitte wissen.
- die Installation eines solchen Setups ist nichts für Anfänger und dauert seine Zeit. Wer
schneller good-to-go sein will, sollte sich die Angebote von www.github.com und
www.lighthouseapp.com näher anschauen.

Nach der erfolgreichen Installation von Ubuntu (Server oder Desktop spielt dabei keine
Rolle), brauchen wir erst mal ein paar grundlegende Pakete. Desktop-spezifische Pakete
lasse ich außen vor, ich gehe von einer Serverinstallation aus. Aber, wie gesagt, eine
Desktop-Variante von Ubuntu arbeitet genau so zuverlässig.

Als erstes führe ich, immer, ein

sudo aptitude update && sudo aptitude safe-upgrade

aus, um erst mal sicherzustellen, dass unser System wirklich auf dem aktuellsten Stand
ist.

1. Installation und Konfiguration des grundlegenden Systems

Jetzt machen wir uns an die Installation einiger benötigter Pakete, die für den späteren
Betrieb von Git und Trac erforderlich oder auf jeden Fall sinnvoll sind:

sudo aptitude install ssh build-essential ntp

Da es sich bei der Maschine um einen Server handelt, sollte diese auf jeden Fall einen
Fully Qualified Domain Name und eine feste IP-Adresse erhalten:

sudo nano /etc/network/interfaces

lässt einen die Interface-Konfiguration bearbeiten. Diese sollte nach getaner Arbeit
folgenden Inhalt haben:

# This file describes the network interfaces available on your


system
# and how to activate them. For more information, see interfaces
(5).

# The loopback network interface


auto lo
iface lo inet loopback

# The primary network interface


auto eth0
iface eth0 inet static
address 192.168.0.11
netmask 255.255.255.0
network 192.168.0.0
broadcast 192.168.0.255
gateway 192.168.0.1

Nachdem die Datei gespeichert ist, musst der entsprechende Dienst neugestartet
werden:

sudp /etc/init.d/networking restart

Jetzt sollte die Netzwerkschnittstelle 'eth0' die IP-Adresse 192.168.0.11 haben und mit
dem Netzwerk kommunizieren können. Sollte eure Netzwerkkonfiguration von meiner hier
genannte abweichen, müsst ihr eure Konfiguration natürlich entsprechend anpassen.
Testen kann man das beispielsweise mit dem Kommando 'ping'.

Passt nun eure hosts an:

sudo nano /etc/hosts

Diese sollte folgenden Inhalt bekommen:

127.0.0.1 localhost.localdomain localhost


127.0.1.1 server1
192.168.0.11 server1.domain.tld server1

# The following lines are desirable for IPv6 capable hosts


::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts

Speichert diese Datei und gebt jetzt folgenden Befehl ein:

sudo echo server1.domain.tld > /etc/hostname

Ich starte im Allgemeinen nun das komplette System neu um zu sehen, ob alle
Einstellungen auch nach einem Neustart funktionieren:

sudo reboot
Nun sollten die Kommandos:

hostname
hostname -f

beide 'server1.domain.tld' zeigen.

Bei .domain und .tld handelt es sich natürlich um individuelle Werte, die ihr selbst setzen
müsst.

2. Konfiguration der Git-Dienste

2.1 Installation von Git

Ganz einfach:

sudo aptitude install git-core git-daemon-run

2.2 Automatisches Starten des git-daemon

Nachdem die Installation abgeschlossen ist, müssen wir unter Umständen erst mal dafür
sorgen, dass der git-daemon auch wirklich startet. Bedingt durch einen Bug (https://
bugs.launchpad.net/ubuntu/+source/runit/+bug/439049) in der aktuellen Version von
Ubuntu (9.10) startet er nämlich nicht unbedingt automatisch. Um dieses Problem zu
beheben, müssen wir mittels

sudo nano /etc/init/runsvdir.conf

die Datei runsvdir.conf bearbeiten und die ersten Zeilen (start on runlevel x) durch
folgende Zeile ersetzen:

start on runlevel [2345]

Theoretisch sollte das durch das System automatisch erledigt worden sein, wenn nicht,
hilft der genannte Fix. Am Besten sollte man das System nun neu starten, um
sicherzustellen, dass der git-daemon auch wirklich läuft. Am einfachsten lässt sich das
mittels

ps aux |grep git

überprüfen. Der Output sollte auf jeden Fall eine Zeile mit dem Inhalt

/usr/lib/git-core/git-daemon --verbose --base-path=[...]

beinhalten. Wenn das der Fall ist, sollte der git-daemon laufen. Dieser ist erforderlich,
damit man mittels des Git-Protokolls mit dem Server kommunizieren kann.

2.3 Einrichten eines Benutzers für Git


Mittels des nachfolgenden Kommandos wird auf dem Server ein Benutzer namens git
angelegt, in dessen Home-Verzeichnis sich später die Git-Repositories befinden:

sudo adduser \
--system \
--shell /bin/sh \
--gecos 'git version control' \
--group \
--disabled-password \
--home /home/git \
git

Jetzt legen wir ein Verzeichnis für die Repositories im Home-Verzeichnis des Benutzers
git an:

sudo -u git mkdir /home/git/repositories

Damit der git-daemon auch weiß, wo sich die Repositories befinden, müssen wir dem
Dienst sagen, wo er suchen soll. Dazu editieren wir die Datei run des git-daemon:

sudo nano /etc/sv/git-daemon/run

Der Parameter --base-path muss entsprechend angepasst werden. Anstelle der


bisherigen Inhalte muss dort also /home/git/repositories stehen:

/usr/lib/git-core/git-daemon --verbose --base-path=/home/git/


repositories

Nach einem Neustart des Dienstes mittels

sudo sv restart git-daemon

und ein paar Sekunden Wartezeit sollte der git-daemon nun wissen, wo er nach
Repositories zu suchen hat.

3. Initiale Konfiguration der Clients

3.1 Public SSH Key bereitstellen

Der in 2.2 angelegte Benutzer hat kein Passwort, kann sich also regulär auch nicht per
SSH am System anmelden. Dieses Szenario eignet sich hervorragend für den Fall, dass
nicht für jeden Entwickler ein eigener SSH-Account angelegt werden soll. Damit dieser
sich aber trotzdem am System über den Benutzer git anmelden kann, kopieren wir den
Key des jeweiligen Benutzers auf den Server. Diese initiale Einrichtung muss von einem
Benutzer des Servers durchgeführt werden, der entsprechende Rechte besitzt, also
beispielsweise dem Administrator (aka bei der Installation erstellter Nutzer).

Zu allererst erstellt jeder Benutzer auf seiner Maschine einen Schlüssel:

ssh-keygen -t rsa -C "user@domain.tld"


Man sollte ein sicheres Kennwort als Passphrase verwenden. Im Verzeichnis .ssh des
jeweiligen Benutzers sollten sich nun zwei Dateien befinden, id_rsa und id_rsa.pub.
Letzteres ist der Public Key, welcher nun auf den Server kopiert werden muss.

Auf dem Server:

mkdir user-keys

Auf dem Client:

scp .ssh/id_rsa.pub adminuser@servername-oder-ip:user-keys/


username.pub

Also beispielsweise

scp .ssh/id_rsa.pub ulf@mygitserver.local:user-keys/ulf.pub

Diesen Prozess wiederholt man nun für jeden Benutzer, der via Git mit dem Server
arbeiten soll.

Nachdem die benötigten Schlüssel auf dem Server sind, kopiert man deren Inhalte noch
in die Datei .ssh/authorized_keys. Dies geschieht am einfachsten und fehlerfreisten
mittels des folgenden Befehls:

sudo -u git mkdir /home/git/.ssh


cat user-keys/schlüsselname.pub >> /home/git/.ssh/authorized_keys

Auch dieser Prozess muss für jeden vorhandenen Schlüssel durchgeführt werden. Ab
sofort kann jeder Benutzer, dessen Schlüssel auf dem Server liegt und sich in der Datei
authorized_keys befindet über den Benutzeraccount 'git' mittels des SSH-Protokolls auf
den Server zugreifen.

Testen kann man das, indem man sich von einem Client mittels

ssh git@servername

mit der Maschine verbindet. War die Verbindung erfolgreich, hat alles geklappt. Wenn
nicht, sollte man die vorherigen Schritte erneut durchführen bzw. jeden einzelnen prüfen.

3.2 Git-Projekt auf einem Client erstellen und auf den Server kopieren

Theoretisch genügt ein leeres Verzeichnis, um zu testen, ob alles geklappt hat. In diesem
leeren (oder auch nicht-leeren) Verzeichnis geben wir nun folgendes ein:

git init
git add .
git commit -a -m "initial import"
git remote add origin ssh://git@servername/home/git/repositories/
test.git
git config user.name "Dein Name"
git config user.email "deineadresse@domain.tld"
touch .git/git-daemon-export-ok
scp -rp .git git@servername:repositories/test.git
git push --all

- mittels git init wird das Verzeichnis .git mit den für Git erforderlichen Inhalten erstellt. 
- git add . fügt alle Dateien im aktuellen Verzeichnis zum working tree hinzu. 
- git commit erstellt einen (vorerst lokalen) commit. 
- git config fügt Zeilen zur lokalen Git-Konfiguration hinzu, in denen
Benutzerinformationen zu finden sind. 
- git remote add fügt eine weitere Zeile zur lokalen Konfiguration des aktuellen Git-
Repositories, in der sich die Information befindet, wo das aktuelle Repository abgelegt
werden soll. 
- die Datei git-daemon-export-ok teilt dem git-daemon mit, dass das Repository nach
außen hin verfügbar sein soll. git push lädt Änderungen auf der lokalen Seite auf den
Server hoch.

3.3 Clone des soeben angelegten Repositories und pushen von Änderungen

Wechselt nun in ein anderes (möglichst leeres) Verzeichnis und testet, ob der Clone auch
funktioniert:

git clone git://192.168.0.28/test.git

Es sollten nun einige Ausgaben seitens Git erfolgen. Wenn alles geklappt hat, sollte sich
nun im aktuellen Verzeichnis ein neues Verzeichnis mit dem Namen "test" befinden.
Wechselt nun in dieses Verzeichnis und legt mittels

touch testfile

eine leere Datei zum Testen an. 

Jetzt muss leider die config-Datei des Clones angepasst werden, da ich bisher keine
Möglichkeit gefunden habe, direkt über das Git-Protokoll zu pushen.

nano .git/config

Die Zeile 'url' in der Sektion [remote "origin"] muss nun so angepasst werden, dass
anstelle von 

git://servername/repositoryname.git

ssh://git@servername/home/git/repositories/repositoryname.git

steht.

Speichert und gebt nun folgendes ein:

git add . && git commit -a -m "test commit" && git push --all

Der Prozess sollte erfolgreich sein.


Wenn mir an dieser Stelle jemand sagen kann, wie auch über das Git-Protokoll gepusht
werden kann, bin ich für jeden Hinweis dankbar. Üblich wäre es nämlich, dem Benutzer
'git' die Shell 'git-shell' zuzuweisen, was bei dieser Arbeitsweise leider nicht geht und eine
Sicherheitslücke, wenn auch eine kleine, darstellt.

4. Vergabe von Rechten auf Repositories mittels gitosis

Zuallererst muss gitosis installiert werden:

sudo aptitude install gitosis

Nun wird die initiale Konfiguration von gitosis erstellt. Voraussetzung dafür ist ein Public
Key, wie bereits in 3.1 erläutert.

sudo -H -u git gitosis-init < /home/oc/user-keys/ulf.pub

Damit auch alles funktioniert, passen wir die Rechte an einem so genannten Hook Script
an:

sudo chmod 755 /home/git/repositories/gitosis-admin.git/hooks/


post-update

Nun holen wir das soeben erstellte Repository auf einen der Clients. Dazu führen wir auf
einem Client den folgenden Befehl aus:

git clone ssh://git@servername/home/git/repositories/gitosis-


admin.git

Auch hier sollte theoretisch das Git-Protokoll funktionieren, bei meinen Tests schlug das
aber leider fehl.

Auf dem Client sollte sich nun ein Verzeichnis mit dem Namen 'gitosis-admin' befinden.
Wenn wir in dieses mittels

cd gitosis-admin

wechseln, finden wir eine Datei, 'gitosis.conf' und ein Verzeichnis, 'keydir'. Im
Verzeichnis 'keydir' sollte der Public Key des vorhin verwendeten Nutzers liegen.

Nun editieren wir die Datei 'gitosis.conf' und fügen folgendes ans Ende der Datei ein:

[group myteam]
members = ulf alice bob
writable = test

Die Benutzergruppe 'myteam' besteht also aus den Mitgliedern ulf, alice und bob. Die
Gruppe hat Schreibrechte auf das Repository 'test'. Dieses Repository sollte bereits
existieren, wenn nicht, legen wir es wie weiter oben beschrieben an.
Damit Alice und Bob nun auch tatsächlich mitspielen dürfen, müssen deren Public Keys
noch in das (weiterhin lokale) Repisitory gitosis-admin kopiert werden. Kopiert nun also
die von den Benutzern Alice und Bob erhaltenen Schlüssel in das Verzeichnis:

cd gitosis-admin
cp ~/alice.pub ~/bob.pub keydir/

Nun fügen wir die Schlüssel zum Working Tree hinzu:

git add keydir/alice.pub keydir/bob.pub

Die geänderte Konfiguration gleichen wir nun mit dem Server ab:

git commit -a -m "alice, bob and ulf have write access to test"
git push --all

Mittels des Kommandos

git clone git@servername:/home/git/repositories/test.git

sollten nun auch Alice und Bob das Repository clonen können.

5. Installation und Konfiguration von Trac

5.1 Installation

Die Installation von Trac ist recht simpel. Ich empfehle aber, nicht die (veraltete) Version
aus den Ubuntu-Repositories zu verwenden, sondern die aktuelle Version mittels
easy_install zu installieren. Damit das funktionieren kann, brauchen wir aber erst mal ein
paar Pakete:

sudo aptitude install python-dev python-setuptools subversion

Nun installieren wir Trac mittels

sudo easy_install Trac

Das funktioniert nur, wenn (wie weiter oben beschrieben) die Pakete python-setuptools,
python-dev und subversion installiert sind. Ansonsten geht entweder gar nichts oder man
bekommt Warnmeldungen.

Jetzt brauchen wir noch ein Plugin, welches unsere Git-Repositories in Trac einbindet.
Dessen Installation erfolgt folgendermaßen:

svn co http://trac-hacks.org/svn/gitplugin
cd gitplugin/0.11/
sudo easy_install .

Nach Abschluss dieser Schritte, kann man Trac nun konfigurieren:


sudo mkdir /var/trac
sudo trac-admin /var/trac/project initenv

Um weitere Projekte anzulegen, wiederholt ihr den letzten Befehl einfach mit einem
anderen Verzeichnisnamen (also beispielsweise /var/trac/megaproject).

Gebt als Typ des Repository git und außerdem den vollständigen Pfad zum gewünschten
Git-Repository an.

Um das Git-Plugin einzubinden, ist noch ein wenig Handarbeit erforderlich:

sudo nano /var/trac/project/conf/trac.ini

Fügt hier folgenden Code ein:

[components]
tracext.git.* = enabled

Nun könnt ihr die Trac-Installation mittels des in Python geschriebenen Tracd testen:

sudo tracd --port 8000 /var/trac/project

Wenn ihr nun die IP (oder den Namen) eures Servers gefolgt von :8000/project in euren
Webbrowser eingebt, solltet ihr das Wiki von Trac sehen. Außerdem müsste unter dem
Punkt "Browse Source" euer zuvor spezifiziertes Git-Repository einzusehen sein.

Sollte hier irgendetwas nicht funktionieren, prüft eure trac.ini auf fehlerhafte Einträge.
Beliebte Fehler sind falsch angegebene Repository-Typen oder -Pfade.

5.2 Anbindung von Trac an den Apache

Um nicht den recht eingeschränkten tracd zu verwenden (keine Benutzerauthentifikation,


relativ schlechte Performance), binden wir unsere Trac-Installation an den Apache:

5.2.1 Anlegen eines virtuellen Hosts für Trac

Zuallererst installieren wir den Apache samt aller für den Betrieb von Trac benötigten
Pakete:

sudo aptitude install apache2 libapache2-mod-python libapache2-


mod-authnz-external pwauth

Mittels

sudo nano /etc/apache2/sites-available/trac

legen wir eine neue leere Datei für den Container an. Dieser sollte folgenden Inhalt
bekommen:

<Location /trac>
SetHandler mod_python
PythonInterpreter main_interpreter
PythonHandler trac.web.modpython_frontend
PythonOption TracEnvParentDir /var/trac
PythonOption TracUriRoot /trac
PythonOption PYTHON_EGG_CACHE /tmp
AuthType Basic
AuthName "Trac"
AuthBasicProvider external
AuthExternal pwauth
require valid-user
require group git
</Location>

AddExternalAuth pwauth /usr/sbin/pwauth


SetExternalAuthMethod pwauth pipe

5.2.2 Nutzer für den Zugriff auf Trac konfigurieren

Das Verzeichnis, und somit auch die komplette Trac-Installation, wird mit einem
Kennwortschutz versehen. Zugriffsberechtigt sind nur Systembenutzer. Neue
Systembenutzer legt ihr mit folgendem Befehl an:

sudo adduser username

Solltet ihr dies an dieser Stelle nicht wünschen, müsst ihr eigentlich nur die Zeilen ab
"AuthType Basic" bis "require group git" wegfallen lassen. Die allerletzten beiden Zeilen
(AddExternalAuth, etc.) braucht ihr ebenfalls nicht. Alternativ lässt sich hier natürlich auch
ein Zugangsschutz mit der klassischen .htpasswd realisieren. Ich verweise an dieser
Stelle einfach mal auf Google, die Einrichtung ist simpel.

In meinem Beispiel ist außerdem zu berücksichtigen, dass nur Benutzer, die Mitglied der
Gruppe 'git' sind zugangsberechtigt sind. Entsprechende Benutzer müssen also mittels

sudo usermod -a -G git username

erst einmal der Gruppe hinzugefügt werden.

Nun aktivieren wir mittels

sudo a2ensite trac && sudo a2enmod authnz_external

die neu hinzugefügte Apache-Konfiguration und starten den Webserver einfach mal
komplett neu:

sudo /etc/init.d/apache2 restart

Übergebt nun eurem Webserver die Rechte am kompletten Trac-Verzeichnis:

sudo chown -R www-data:www-data /var/trac/


Nun solltet ihr über euren Browser mittels servername/trac passwortgeschützt auf eure
Trac-Installation zugreifen können. Auf der nun angezeigten Seite werden alle Projekte
aufgelistet. Solltet ihr das nicht wünschen, müsst ihr den virtuellen Host so anpassen,
dass die Variable 'PythonOption TracEnvParentDir' 'PythonOption TracEnvDir' lautet, das
angegebene Verzeichnis muss dann natürlich entsprechend angepasst werden.

Das Schöne an dieser Lösung ist, dass der Systemnutzer auch gleich verwendet wird, um
sich auch bei Trac anzumelden. Neue Dokumente können also diesem Benutzer
zugeordnet werden. Hat sich ein Benutzer bereits angemeldet, kann er mittels des Trac-
Befehls 'trac-admin' zum Administrator dieser Trac-Instanz gemacht werden:

sudo trac-admin /var/trac/project permission add username


TRAC_ADMIN

5.3 Absichern der Trac-Installation via HTTP Secure (https)

5.3.1 Erstellen der Schlüsseldaten

Mittels

openssl genrsa -out server1.key 1024

erstellen wir unseren privaten, 1024 Bit starken Schlüssel mit dem Dateinamen
server1.key.

Nun erstellen wir unser selbst-signiertes Zertifikat:

openssl genrsa -des3 -out server1.key 1024

Das Kennwort sollte mindestens acht Zeichen lang sein und den bekannten Kriterien
eines sicheren Kennworts entsprechen.

Mittels

openssl rsa -in server1.key -out server1.key.insecure

legen wir nun einen unsicheren Schlüssel für die Generierung des CSR an. Die beiden
folgenden Kommandos wechseln die Namen der beiden Dateien, um den CSR ohne
Passwort zu generieren:

mv server1.key server1.key.secure
mv server1.key.insecure server1.key

Generierung des CSR:

openssl req -new -key server1.key -out server1.csr

Generierung des Zertifikats:

openssl x509 -req -days 3650 -in server1.csr -signkey server1.key


-out server1.crt
Die erforderlichen Informationen werden nun nacheinander abgefragt. Bei 'Common
Name (eg, YOUR name)' solltet ihr euren Maschinennamen, also server1.domain.tld,
eingeben. Das erstellte Zertifikat ist rund 10 Jahre gültig. Leider (?) wird es von keinem
Browser ohne weiteres akzeptiert, dies ist aber bei selbst-signierten Zertifikaten
vollkommen normal.

5.3.2 Vorbereiten des Apache für die Verwendung von https

Mittels

sudo a2enmod ssl


sudo /etc/init.d/apache restart

aktivieren wir die SSL-Unterstützung des Apache. Um die zuvor generierten Schlüssel
auch nutzen zu können, kopieren wir sie in das Standardverzeichnis für Zertifikate des
Apache:

sudo cp server1.crt /etc/ssl/certs/


sudo cp server1.key /etc/ssl/certs/

Editieren wir nun den vHost unserer Trac-Installation

sudo nano /etc/apache2/sites-available/trac

und sorgen dafür, dass unsere Datei so aussieht:

<VirtualHost *>
ServerName server1.oc.local
SSLEngine on
SSLCertificateFile /etc/ssl/certs/server1.crt
SSLCertificateKeyFile /etc/ssl/certs/server1.key

<Location /trac>
SetHandler mod_python
PythonInterpreter main_interpreter
PythonHandler trac.web.modpython_frontend
PythonOption TracEnvParentDir /var/trac
PythonOption TracUriRoot /trac
PythonOption PYTHON_EGG_CACHE /tmp
AuthType Basic
AuthName "Trac"
AuthBasicProvider external
AuthExternal pwauth
require valid-user
require group git
</Location>

AddExternalAuth pwauth /usr/sbin/pwauth


SetExternalAuthMethod pwauth pipe
</VirtualHost>
Außerdem editieren wir die Datei ports.conf des Apache

sudo nano /etc/apache2/ports.conf

und hinterlassen sie wie folgt:

# If you just change the port or add more ports here, you will
likely also
# have to change the VirtualHost statement in
# /etc/apache2/sites-enabled/000-default
# This is also true if you have upgraded from before 2.2.9-3 (i.e.
from
# Debian etch). See /usr/share/doc/apache2.2-common/NEWS.Debian.gz
and
# README.Debian.gz

#NameVirtualHost *:80
#Listen 80

<IfModule mod_ssl.c>
# SSL name based virtual hosts are not yet supported,
therefore no
# NameVirtualHost statement here
Listen 443
</IfModule>

Ab sofort sollte unser Apache nur noch Verbindungen über Port 443 entgegennehmen.
Der Nutzer der Trac-Installation muss nun also explizit https als Protokoll beim Aufruf der
Seite angeben, http ist "aus". Ein abschliessendes

sudo /etc/init.d/apache2 restart

startet den Apache neu, um die veränderte Konfiguration zu übernehmen.