Cómo montar tu propio servidor git

danigm's picture

Git es un sistema de control de versiones distribuido, diseñado para manejar de todo, desde proyectos pequeños hasta proyecto muy grandes, con velocidad y eficiencia. Git se está usando en multitud de proyectos libres, como el kernel de linux, gnome, qt, etc...

Montar git en un servidor para poder gestionar diferntes repositorios de tus proyectos es bastante fácil. Voy a explicar cómo montarlo permitiendo el acceso para lectura/escritura por ssh utilizando clave pública ssh para autenticar, sin necesidad de dar acceso ssh completo al servidor a los usuarios.

Lo primero es crear un usuario nuevo en el sistema, que se va a utilizar para autenticar y en el home de este usuario vamos a mantener todos los repositorios.

# adduser git

Ahora editamos el fichero /etc/shadow para no permitir el acceso por contraseña, habría que cambiar una línea similar a esta:

git:$1$7234989xcv8s9df9898asdf98x:14494:0:99999:7:::

por:

git:*:14494:0:99999:7:::

Ahora nos autenticamos como el usuario git, y creamos los directorios necesarios:

# su - git
$ mkdir gits
$ mkdir .ssh
$ chmod 700 .ssh

Añadimos el siguiente script para restringir el uso de ssh a comandos permitidos y dentro de un entorno controlado:

[php]
#!/bin/bash

#access.sh

BASE=/home/git/gits
BASEPATH="~/gits"
cd $BASE
echo "$USER2 $SSH_ORIGINAL_COMMAND" >> log

COMMAND=$(echo $SSH_ORIGINAL_COMMAND | cut -d" " -f1)
PATH=$(echo $SSH_ORIGINAL_COMMAND | cut -d" " -f2 | sed "s/'//g")

if [ "$COMMAND" = "create_repo" ]
then
PATH=$(echo $PATH | /bin/sed "s/\.//g")
/usr/bin/git init --bare $PATH.git
cd $PATH.git
/bin/touch git-daemon-export-ok
/usr/bin/git update-server-info
else
COMMAND="$COMMAND '$BASEPATH$PATH'"

/usr/bin/git-shell -c "$COMMAND"
fi
[/php]

Este script permite crear repositorios con el comando create_repo y también permite el acceso a repositorios en el sistema, tanto para hacer pull como para hacer push.

Ahora, por cada usuario al que queramos dar acceso para crear repositorios o dar la posibilidad de hacer push/pull en los repos hay que añadir una línea en el fichero .ssh/authorized_keys, con la clave pública del usuario en cuestión:

command="USER2=danigm /home/git/access.sh" ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQXA5U0/GWd+TnmRUPhD+mwJH43Nfeu0SasdfcCS35DE5i2jzsaI3P7mNhvB15yKkzqbQ3a2hm+RK6APpEBGAZmAJGUasdf/vsdVsdRIXvioP680BDkubpcwott8CXKfo/5KjWSUMrUJm6DMypEAzJix/IurEJqCftLwkroBC8gLpys2HtHG7sadfxcvOVLDASxwMm0ZCQ7aFRtMiLP9GV3RkW84fhuWKMgIHZAXZANMylXlPE71aqlFlpEEae98m50F1UDalOxZePNRWoTaeuG5PzmkZPjre45ICm6bEcSsS89m7/GP7i87afE0znrEvpRm/jltTkdebuEGQCV7AIwDYw== danigm@computer

Como variables de entorno le pasamos al script el nombre de usuario, que en este ejemplo no se usa nada más que para el log, pero modificando el script de access.sh se podría usar para gestionar permisos de acceso a determinados repositorios, etc.

Al poner command en el fichero authorized_keys justo antes de la clave pública del usuario (id_rsa.pub) se consigue que sea este script el que se ejecute cada vez que el usuario entre con esa clave, por lo tanto se puede restringir qué puede utilizar.

Con esto ya tendríamos un servidor git montado. Ahora cualquier usuario cuya clave pública esté en el fichero authorized_keys puede crear un repositorio de la siguiente forma:

$ ssh git@servidorgit.com create_repo mirepo
Initialized empty Git repository in /home/git/gits/mirepo.git/    

Y ahora podemos hacer push y pull sin restricciones:

$ git clone ssh://git@servidorgit.com/mirepo
$ cd mirepo
$ echo "test" > testfile
$ git add testfile
$ git commit -m "test"
$ git push

Si queremos dar acceso externo para lectura, podemos hacerlo por http, por ejemplo, si tenemos un servidor web funcionando en el mismo servidor es tan fácil como poner el directorio /home/git/gits como visible.

Ahora para poner la ginda a nuestro servidor git podemos instalar una aplicación web que muestre el log, las diferencias, los ficheros, etc. Para ello existen multitud de aplicaciones que se pueden instalar:

https://git.wiki.kernel.org/index.php/InterfacesFrontendsAndTools#Web_In...

tags: