¿Puede especificar git-shell en .ssh / Authorized_keys para restringir el acceso a solo comandos git a través de ssh?

37

Me gustaría poder usar una clave ssh para la autenticación, pero aún así restringir los comandos que se pueden ejecutar a través del túnel ssh.

Con Subversion, he logrado esto usando un archivo .ssh / Authorized_keys como:

command="/usr/local/bin/svnserve -t --tunnel-user matt -r /path/to/repository",no-port-forwarding,no-agent-forwarding,no-X11-forwarding,no-pty ssh-rsa AAAAB3NzaC1yc2EAAAABIetc...

He intentado esto con "/ usr / bin / git-shell" en el comando, pero acabo de recibir el viejo fatal: What do you think I am? A shell?mensaje de error.

Matt Connolly
fuente

Respuestas:

30

Lo siguiente funciona para mí.

En ~/.ssh/authorized_keys:

command="./gitserve",no-port-forwarding,no-agent-forwarding,no-X11-forwarding,no-pty ssh-dss AAAAB…

En el ~/gitserveguión:

#!/bin/sh
exec git-shell -c "$SSH_ORIGINAL_COMMAND"

Tenga en cuenta que si coloca gitserveotro lugar que no sea el directorio de inicio, tendrá que ajustar el command="./gitserve"parámetro authorized_keys.

Neil Mayhew
fuente
¡Bingo! ¡Esto funciona igual que lo que esperaba lograr! Gracias.
Matt Connolly
En esta publicación relacionada en SO stackoverflow.com/questions/5871652/ ... señalan otra solución aquí: joey.kitenet.net/blog/entry/locking_down_ssh_authorized_keys
Tim
1
@Tim Esta es esencialmente la misma solución, pero exprime el contenido de mi script ~ / gitserve en claves autorizadas usando perl. Personalmente, prefiero mantenerlo en un guión separado.
Neil Mayhew
1
Entiendo, simplemente lo agregué como referencia.
Tim
¿Qué shell tiene configurado el usuario en esta configuración? /bin/bash?
M-Pixel
33

Podría utilizar con éxito git-shell directamente en el archivo de claves autorizadas sin utilizar un script adicional.

La clave es agregar \"alrededor de la variable env.

Probado en rhel6 openssh-server-5.3p1-70.el6.x86_64:

no-port-forwarding,no-agent-forwarding,command="git-shell -c \"$SSH_ORIGINAL_COMMAND\"" ssh-dss AAAA...
sophana
fuente
+1 esa es la respuesta correcta, vea svnweb.freebsd.org/base/head/crypto/openssh/…
Tino
2
Personalmente, le daría el camino completo git-shell, pero eso podría ser paranoia.
Ulrich Schwarz
¿Alguien ha encontrado una manera de restringir el directorio al que tiene acceso? Descubrí que puedo cd en un directorio antes de ejecutar git-shell, pero git-shell permite ".." y rutas absolutas.
Yokto
5

La solución de Grawity se puede modificar fácilmente para que funcione al reemplazar la línea

        exec $SSH_ORIGINAL_COMMAND

con la linea

        git-shell -c "$SSH_ORIGINAL_COMMAND"

Las citas se ocupan de los problemas reportados anteriormente, y reemplazar exec con git-shell parece un poco más seguro.

dschwen
fuente
4

git-shellestá diseñado para usarse como un shell de inicio de sesión, de modo que reciba -c "originalcommand"como argumentos. Esto no sucede con los "comandos forzados" en OpenSSH; en cambio, el comando forzado se pasa al shell configurado.

Lo que puede hacer es escribir un script que lo verifique $SSH_ORIGINAL_COMMANDy lo ejecute. Ejemplo en bash :

#!/bin/bash

SSH_ORIGINAL_COMMAND=${SSH_ORIGINAL_COMMAND/#git /git-}

case $SSH_ORIGINAL_COMMAND in
    "git-receive-pack"*|"git-upload-pack"*|"git-upload-archive"*)
        eval exec $SSH_ORIGINAL_COMMAND
        ;;
    *)
        echo "Go away." >&2
        exit 1
        ;;
esac
Gravedad
fuente
@Matt: git-shell (1) dice que los comandos son git <cmd>, git-<cmd>¿ no ?
Grawity
Hmm ... Hice ese cambio de acuerdo con lo que vi cuando lo ejecuté. Con un script bash y un script ruby, vi "git-recibir-paquete" como el comando. Cita de mi man git-shell(git 1.7.3.4): actualmente, solo se pueden llamar cuatro comandos, git-recibir-paquete git-upload-pack y git-upload-archive con un único argumento requerido, o servidor cvs (para invocar git -cvsserver).
Matt Connolly
el formato no funciona en los comentarios :(
Matt Connolly
1
Esto no funciona para mí, porque mi cliente git (1.7.5.4) envía el nombre del repositorio entre comillas simples, presumiblemente porque espera que toda la línea de comandos sea interpretada por un shell. El exec $ SSH_ORIGINAL_COMMAND luego pasa las comillas simples a git-recibir-paquete, etc., que por lo tanto no encuentra el repositorio.
Neil Mayhew
Gracias por la solución, grawity, pero no funciona para mí, por la misma razón que informó Neil Mayhew ... mi versión 1.7.x de git también envía el nombre del repositorio entre comillas simples, lo que finalmente hace $SSH_ORIGINAL_COMMANDque sea inválido y causando git-shellque se
queme
1

Para completar, y dado que la pregunta original no especificaba que la misma cuenta tenía que ser utilizable para cosas que no sean git, la respuesta obvia es usarla git-shellcomo fue diseñada para usarse: configúrela como el shell de inicio de sesión (es decir usermod, con , in /etc/passwd) para ese usuario ssh.

Si tiene una sola cuenta de usuario que desea usar de dos maneras:

  • cuando se conecta con autenticación de clave, use solo para git
  • cuando se conecte con autenticación de contraseña o use una clave privada diferente, proporcione un shell completo

... entonces se aplican las otras respuestas en este hilo. Pero si puede permitirse asignar un usuario separado a git, entonces configurar su shell git-shelles la forma más sencilla de restringirlo, y es un poco más seguro ya que no requiere scripts de shell adicionales.

Felix
fuente