--- title: "Cómo montar un servidor Git privado con SSH en Ubuntu 24.04" description: "Monta un servidor Git privado en Ubuntu 24.04 con un usuario git limitado a git-shell, acceso por claves SSH, repositorios bare y copias de seguridad diarias." category: "Despliegue de Aplicaciones" language: es source: https://cubepath.com/es/docs/despliegue-de-aplicaciones/configuracion-de-servidor-git-privado updated: 2026-09-25 --- # Cómo montar un servidor Git privado con SSH en Ubuntu 24.04 Git no necesita ningún servicio especial para funcionar como servidor: basta con un repositorio "bare" en una máquina accesible por SSH. En este tutorial montarás un servidor Git privado en Ubuntu 24.04 con un usuario `git` dedicado, restringido a `git-shell` para que solo pueda ejecutar operaciones de Git, acceso mediante claves SSH y una copia de seguridad diaria de los repositorios. Es la opción más ligera y segura para un equipo pequeño; al final verás cuándo conviene pasar a una plataforma web como Gitea o Forgejo. ## Requisitos previos - Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath. Sirve cualquier tamaño: Git sobre SSH apenas consume recursos. - Un usuario no root con privilegios `sudo` y acceso SSH al servidor. - En tu equipo local, Git instalado y un par de claves SSH. Si no tienes una, créala con `ssh-keygen -t ed25519`. - El puerto 22 (SSH) accesible desde los equipos que usarán el servidor. A lo largo de la guía, sustituye `your_server_ip` por la IP o el nombre DNS de tu servidor. ## Paso 1: Instalar Git en el servidor Conéctate al servidor, actualiza el índice de paquetes e instala Git: ```bash sudo apt update sudo apt install git ``` Comprueba la versión instalada: ```bash git --version ``` ```output git version 2.43.0 ``` Si usas UFW, asegúrate de que SSH está permitido antes de activar el cortafuegos, o te quedarás sin acceso: ```bash sudo ufw allow OpenSSH sudo ufw enable sudo ufw status ``` ```output Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) ``` ## Paso 2: Crear el usuario git con git-shell Todos los desarrolladores se conectarán como el mismo usuario `git`, cada uno con su propia clave. Para que ese usuario no pueda abrir una shell normal, se le asigna `git-shell`, una shell restringida que solo acepta los comandos que usa Git (`git-receive-pack`, `git-upload-pack` y `git-upload-archive`). Comprueba dónde está `git-shell`: ```bash which git-shell ``` ```output /usr/bin/git-shell ``` Crea el usuario con esa shell y su directorio personal: ```bash sudo useradd --create-home --shell /usr/bin/git-shell git ``` El usuario no tiene contraseña, así que solo podrá entrar con clave SSH. Compruébalo: ```bash getent passwd git ``` ```output git:x:1001:1001::/home/git:/usr/bin/git-shell ``` ## Paso 3: Autorizar las claves SSH de los desarrolladores Crea el directorio `.ssh` del usuario `git` con los permisos que exige OpenSSH: ```bash sudo install -d -m 700 -o git -g git /home/git/.ssh sudo install -m 600 -o git -g git /dev/null /home/git/.ssh/authorized_keys ``` En tu equipo local, muestra tu clave pública y cópiala: ```bash cat ~/.ssh/id_ed25519.pub ``` ```output ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... ana@portatil ``` En el servidor, edita el archivo de claves autorizadas: ```bash sudo nano /home/git/.ssh/authorized_keys ``` Añade una línea por desarrollador, anteponiendo la opción `restrict` a cada clave. `restrict` desactiva el reenvío de puertos, de agente y X11 y la asignación de terminal, que Git no necesita: ```text restrict ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... ana@portatil restrict ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... luis@sobremesa ``` Para revocar el acceso de alguien, basta con borrar su línea. Desde tu equipo local, prueba la conexión: ```bash ssh git@your_server_ip ``` ```output fatal: Interactive git shell is not enabled. hint: ~/git-shell-commands should exist and have read and execute access. Connection to your_server_ip closed. ``` Ese mensaje confirma que la autenticación con clave funciona y que `git-shell` impide abrir una sesión interactiva. Si en cambio ves `Permission denied (publickey)`, revisa la sección de solución de problemas. ## Paso 4: Crear un repositorio bare Un repositorio bare contiene solo la base de datos de Git, sin copia de trabajo, y es el formato adecuado para recibir `push`. Guarda los repositorios en `/srv/git`, propiedad del usuario `git`: ```bash sudo install -d -m 750 -o git -g git /srv/git ``` Crea el primer repositorio con la rama inicial `main`. El comando se ejecuta como `git` para que los archivos tengan el propietario correcto: ```bash sudo -u git git init --bare --initial-branch=main /srv/git/miproyecto.git ``` ```output Initialized empty Git repository in /srv/git/miproyecto.git/ ``` Repite este comando por cada repositorio nuevo. La terminación `.git` es una convención para los repositorios bare. ## Paso 5: Clonar y subir cambios desde tu equipo En tu equipo local, clona el repositorio usando la ruta absoluta en el servidor: ```bash git clone git@your_server_ip:/srv/git/miproyecto.git ``` ```output Cloning into 'miproyecto'... warning: You appear to have cloned an empty repository. ``` Crea un primer commit y súbelo: ```bash cd miproyecto echo "# Mi proyecto" > README.md git add README.md git commit -m "Primer commit" git push origin main ``` ```output To your_server_ip:/srv/git/miproyecto.git * [new branch] main -> main ``` Si ya tienes un proyecto local, en lugar de clonar añade el servidor como remoto y sube la rama: ```bash git remote add origin git@your_server_ip:/srv/git/miproyecto.git git push -u origin main ``` Para comprobar que el commit ha llegado, lista las referencias del remoto: ```bash git ls-remote origin ``` ```output 3f9c2a1e8b7d6c5f4a3b2c1d0e9f8a7b6c5d4e3f HEAD 3f9c2a1e8b7d6c5f4a3b2c1d0e9f8a7b6c5d4e3f refs/heads/main ``` ### Acortar la URL de los repositorios (opcional) Para escribir `miservidor:miproyecto.git` en lugar de la IP y la ruta completa, añade un alias en `~/.ssh/config` de tu equipo local: ```bash nano ~/.ssh/config ``` ```text Host miservidor HostName your_server_ip User git IdentityFile ~/.ssh/id_ed25519 ``` La ruta del repositorio sigue siendo absoluta, así que el clon queda así: ```bash git clone miservidor:/srv/git/miproyecto.git ``` ## Paso 6: Programar copias de seguridad de los repositorios Los repositorios están en un único directorio, así que un archivo comprimido diario con rotación es suficiente como copia local. Guárdala después fuera del servidor (almacenamiento de objetos, otro servidor) para protegerte de la pérdida del disco. Crea el script de copia: ```bash sudo nano /usr/local/bin/git-backup ``` ```bash #!/usr/bin/env bash set -euo pipefail src="/srv/git" dest="/var/backups/git" keep_days=14 mkdir -p "$dest" tar -czf "$dest/git-$(date +%F).tar.gz" -C "$(dirname "$src")" "$(basename "$src")" find "$dest" -name 'git-*.tar.gz' -mtime +"$keep_days" -delete ``` Hazlo ejecutable y pruébalo: ```bash sudo chmod 755 /usr/local/bin/git-backup sudo /usr/local/bin/git-backup ls -lh /var/backups/git/ ``` ```output -rw-r--r-- 1 root root 1.2K Sep 25 10:40 git-2026-09-25.tar.gz ``` Programa la ejecución diaria a las 03:30 con un archivo en `/etc/cron.d`: ```bash sudo nano /etc/cron.d/git-backup ``` ```text 30 3 * * * root /usr/local/bin/git-backup ``` Para restaurar, extrae el archivo en `/srv` y devuelve la propiedad al usuario `git`: ```bash sudo tar -xzf /var/backups/git/git-2026-09-25.tar.gz -C /srv sudo chown -R git:git /srv/git ``` ## Solución de problemas **`Permission denied (publickey)`.** El servidor no acepta tu clave. Comprueba los permisos: `/home/git/.ssh` debe ser `700`, `authorized_keys` `600` y ambos propiedad de `git`. Revisa también que la clave está en una sola línea, sin saltos. El motivo exacto aparece en el log de SSH del servidor: ```bash sudo journalctl -u ssh -n 20 --no-pager ``` **`fatal: '/srv/git/miproyecto.git' does not appear to be a git repository`.** La ruta no existe o está mal escrita. Recuerda que es la ruta absoluta en el servidor e incluye la terminación `.git`. **`error: insufficient permission for adding an object to repository database`.** Hay archivos del repositorio que no pertenecen al usuario `git`, normalmente porque se creó o modificó con `sudo` sin `-u git`. Corrige la propiedad: ```bash sudo chown -R git:git /srv/git ``` **`fatal: detected dubious ownership in repository` al ejecutar comandos en el servidor.** Aparece si ejecutas Git sobre `/srv/git` con un usuario que no es el propietario. Ejecuta esos comandos como `git`, por ejemplo `sudo -u git git -C /srv/git/miproyecto.git log --oneline`. ## Conclusión Tienes un servidor Git privado en Ubuntu 24.04 al que los desarrolladores acceden por SSH con su propia clave, con un usuario limitado a operaciones de Git y copias diarias de los repositorios. Este esquema da a todos los usuarios acceso a todos los repositorios; si necesitas permisos por repositorio o rama, puedes añadir Gitolite sobre el mismo servidor, y si quieres interfaz web, pull requests e incidencias, instala Gitea o Forgejo. También puedes usar hooks `post-receive` en los repositorios bare para desplegar automáticamente tras cada `push`.