Introducción
Me parece una excelente práctica tener todos mis proyectos y trabajos respaldados en un servidor remoto. Para mis proyectos personales generalmente uso GitHub, dejando los repositorios abiertos a la comunidad. Sin embargo, no quiero mezclar mis proyectos personales y Open Source con aquellos que corresponden a servicios que ofrezco a otros. Para este segundo caso, la mejor solución es usar mi propio servidor como servidor Git, haciendo los push directamente allí. Las ventajas que esto me ofrece son: una mayor autoridad sobre mis propios datos, un control de acceso personalizado por si en el futuro quiero colaborar, y una mayor personalización.
Configurar Servidor Git
Primero es importante tener en cuenta que Git permite conectarse sin credenciales usando el protocolo git://, que usa el puerto 9418 por defecto. De esta manera cualquier usuario podría clonar los repositorios sin restricciones. Para el uso que yo le voy a dar no usaré nunca el protocolo git://, sino que en cambio usaré Git sobre ssh, que viene habilitado por defecto. Usando ssh no se necesita tener ningún daemon ejecutándose en segundo plano, ya que los comandos se ejecutan en el servidor vía ssh usando git-shell como intérprete, que es mucho más seguro que bash. Git también permite escuchar a través del protocolo https:// con credenciales, pero usar ssh resulta mucho más sencillo, por lo cual descartaré esa opción.
-
Crear el usuario dedicado para Git. El hecho de que sea un usuario dedicado lo hace mucho más seguro. Además, al usar
git-shellcomo intérprete en lugar debash, no puede usarse para administrar el servidor remotamente.sudo useradd -m -s /usr/bin/git-shell git -
Crear la carpeta para las claves SSH y el archivo
authorized_keys. Es importante queauthorized_keysexista como archivo antes de añadir claves, de lo contrario algunos sistemas lo crearán como directorio y la autenticación no funcionará.mkdir /home/git/.ssh chmod 700 /home/git/.ssh touch /home/git/.ssh/authorized_keys chmod 600 /home/git/.ssh/authorized_keys -
Cambiar el propietario de
/home/git/para añadir una capa extra de seguridad, y crear la carpetarepos.sudo chown root:root /home/git sudo chmod 711 /home/git sudo mkdir /home/git/repos sudo chown git:git /home/git/repos -
Deshabilitar la autenticación por contraseña y habilitar la autenticación por clave pública editando
/etc/ssh/sshd_config:PasswordAuthentication no PubkeyAuthentication yesY reiniciar el servicio:
sudo systemctl restart sshd -
Añadir las claves públicas de los usuarios autorizados al archivo
authorized_keys:cat ~/.ssh/id_ed25519.pub >> /home/git/.ssh/authorized_keys
A partir de aquí ya es posible crear repositorios bare y hacer push directamente al servidor:
git init --bare /home/git/repos/mi-proyecto.git
Y desde el cliente:
git remote add origin ssh://git@mi-servidor/home/git/repos/mi-proyecto.git
git push -u origin main
Git-shell-commands
Descripción
Los git-shell-commands son scripts ejecutables que extienden las capacidades de git-shell. Cuando un usuario se conecta vía SSH al servidor, git-shell actúa como intérprete restringido — solo permite operaciones git y los comandos personalizados que se hayan definido.
Comandos Built-in
Por defecto git-shell únicamente permite las operaciones básicas de git: clonar, hacer push y pull. Cualquier intento de ejecutar otros comandos es rechazado. Esto lo hace ideal para un servidor git dedicado, ya que el usuario no puede usar la conexión SSH para administrar el servidor.
Crear Personalizados
Se pueden crear comandos personalizados, creando scritps en el directorio ~/git-shell-commands/ del usuario git. Cada script se convierte en un comando disponible vía SSH:
ssh git@servidor nuevo-comando
Los scripts pueden estar escritos en cualquier lenguaje disponible en el servidor, aunque lo más habitual es usar bash o sh. Por ejemplo, el comando new que crea un repositorio bare:
#!/bin/sh
if [ -z "$1" ]; then
echo "Usage: new <repo-name>"
exit 1
fi
git init --bare /home/git/repos/$1.git
echo "Repo $1 created."
Servidor Git en Docker
Prefiero alojar el servidor Git dentro de un contenedor Docker, tanto por seguridad como por portabilidad. Para eso creé una imagen personalizada basada en Alpine Linux junto con un docker-compose que gestiona su configuración. La imagen incluye comandos de gestión de repositorios accesibles vía ssh (new, list, delete, etc.), datos persistentes mediante bind mounts, soporte para agregar claves ssh sin reiniciar el contenedor, y arranque automático con el sistema.
Está disponible en el siguiente repositorio:
https://github.com/maagenta/git-server-docker/tree/main