Fecha: 2018-05-14 Tiempo de lectura: 5 minutos Categoría: Operaciones Tags: git / git-shell / jaula / ssh
El otro día recibí una petición en el trabajo por parte de un cliente: poder ejecutar algunas operaciones por SSH en nuestro servidor. Solo de pensar en montar una jaula SSH con los binarios y sus librerías ya se me hizo cuesta arriba, y por eso lo hice con git-shell.
No he encontrado por internet nadie que haya hecho algo similar, así que lo he puesto por escrito en este artículo. Se trata de utilizar el shell restringido git-shell para que el usuario solo pueda utilizar los scripts o binarios presentes en la carpeta ~/git-shell-commands/
.
Por defecto, git-shell solo acepta las operaciones necesarias para trabajar remotamente con repositorios git. Esto se puede leer en la documentación:
Call the corresponding server-side command to support the client’s git push, git fetch, or git archive –remote request.
Sin embargo, ante la presencia de una carpeta ~/git-shell-commands/
también nos añade los scripts y binarios de la misma al conjunto de operaciones que podemos ejecutar.
If a ~/git-shell-commands directory is present, git shell will also handle other, custom commands by running “git-shell-commands/
” from the user’s home directory.
Esto está pensado para operaciones administrativas como crear, borrar y modificar los repositorios alojados. Sin embargo, podemos utilizarlo para limitar los comandos que un usuario puede ejecutar, sean o no de git.
Por supuesto, el soporte a operaciones remotas de git no nos molesta; al no haber repositorios, estas operaciones van a fallar de todas formas. Así pues, vamos a centrarnos en nuestras propias operaciones.
Supongamos que tenemos un servidor con SSH, al que vamos a llamar server. Para la demostración, se va a tratar de un servidor Alpine Linux, aunque esto no es relevante.
NOTA: A menos que se diga lo contrario, todos los comandos se ejecutan con root, aunque podéis usar sudo con el mismo efecto.
AVISO: Las sesiones de SSH a server responden con el nombre localhost. Esto es debido a que el servidor es un contenedor docker con el puerto 22 mapeado al puerto 22 del servidor sirius; al ser un ejemplo, prefiero no virtualizar máquinas nuevas.
Para disponer del binario git-shell, necesitamos el paquete git instalado. Si no lo tenéis hecho, es el mejor momento para hacerlo.
server:~# apk add --no-cache git
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/community/x86_64/APKINDEX.tar.gz
(1/6) Installing ca-certificates (20171114-r0)
(2/6) Installing libssh2 (1.8.0-r2)
(3/6) Installing libcurl (7.59.0-r0)
(4/6) Installing expat (2.2.5-r0)
(5/6) Installing pcre2 (10.30-r0)
(6/6) Installing git (2.15.0-r1)
Executing busybox-1.27.2-r7.trigger
Executing ca-certificates-20171114-r0.trigger
OK: 20 MiB in 20 packages
server:~#
Vamos a crear un usuario para que nuestro cliente pueda entrar por SSH; nada nuevo por el momento, con la excepción de que vamos a indicar como su shell el mismo git-shell.
server:~# adduser -D customer -s /usr/bin/git-shell
server:~# echo "customer:s3cr3t" | chpasswd
chpasswd: password for 'customer' changed
server:~#
Si el usuario intenta entrar en este punto, solo podrá utilizar las operaciones git remotas, siendo imposible que lance una sesión interactiva, o comandos sueltos por SSH.
gerard@sirius:~$ ssh customer@server
Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts.
customer@localhost's password:
Welcome to Alpine!
The Alpine Wiki contains a large amount of how-to guides and general
information about administrating Alpine systems.
See <http://wiki.alpinelinux.org>.
You can setup the system with the command: setup-alpine
You may change this message by editing /etc/motd.
fatal: Interactive git shell is not enabled.
hint: ~/git-shell-commands should exist and have read and execute access.
Connection to localhost closed.
gerard@sirius:~$
gerard@sirius:~$ ssh customer@server hostname
Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts.
customer@localhost's password:
fatal: unrecognized command 'hostname'
gerard@sirius:~$
Para activar git-shell, hay que crear la carpeta indicada ~/git-shell-commands
; los comandos que se pueden ejecutar son los que van dentro de la misma.
server:~# cd /home/customer/
server:/home/customer# mkdir git-shell-commands
server:/home/customer# chown customer:customer git-shell-commands/
server:/home/customer#
Con esto el usuario ya va a poder entrar en una sesión interactiva, aunque no dispone de comandos para ejecutar:
gerard@sirius:~$ ssh customer@server
Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts.
customer@localhost's password:
Welcome to Alpine!
The Alpine Wiki contains a large amount of how-to guides and general
information about administrating Alpine systems.
See <http://wiki.alpinelinux.org>.
You can setup the system with the command: setup-alpine
You may change this message by editing /etc/motd.
git> hostname
unrecognized command 'hostname'
git>
Solo nos faltaría rellenar la carpeta con los binarios o scripts que este usuario pueda necesitar. Como punto interesante, si existe un help
, este se va a ejecutar al entrar por SSH de forma automática, y nos puede servir para que el usuario sepa que hacer (o para que pida ayuda en el medio de una sesión).
El resto de comandos son libres y podéis hacer literalmente lo que queráis, con el entendido que estos scripts pueden invocar todos los comandos del sistema de forma normal, pero el usuario solo va a poder ejecutar estos scripts. Veamos un ejemplo:
server:/home/customer# cd git-shell-commands/
server:/home/customer/git-shell-commands# cat help
#!/bin/sh
echo "Permitted commands:"
echo " help - shows this help message"
echo " hostname - shows hostname of this server"
echo " get_connected_users - shows user currently logged on"
server:/home/customer/git-shell-commands# cat hostname
#!/bin/sh
hostname
server:/home/customer/git-shell-commands# cat get_connected_users
#!/bin/sh
n=$RANDOM
let n%=10
echo "Users connected: $n"
server:/home/customer/git-shell-commands# chown customer:customer *
server:/home/customer/git-shell-commands# chmod 755 *
server:/home/customer/git-shell-commands#
Ahora es el momento de que el usuario se conecte y vea el resultado:
gerard@sirius:~$ ssh customer@server
Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts.
customer@localhost's password:
Welcome to Alpine!
The Alpine Wiki contains a large amount of how-to guides and general
information about administrating Alpine systems.
See <http://wiki.alpinelinux.org>.
You can setup the system with the command: setup-alpine
You may change this message by editing /etc/motd.
Permitted commands:
help - shows this help message
hostname - shows hostname of this server
get_connected_users - shows user currently logged on
git> hostname
server
git> help
Permitted commands:
help - shows this help message
hostname - shows hostname of this server
get_connected_users - shows user currently logged on
git> get_connected_users
Users connected: 4
git> exit
Connection to localhost closed.
gerard@sirius:~$
Y de esta forma, el usuario queda limitado, pero con estos 3 comandos posibles.