También puede restringir las claves a los comandos permitidos (en el archivo authorized_keys).
Es decir. el usuario no iniciaría sesión a través de ssh y luego tendría un conjunto restringido de comandos, sino que solo se le permitiría ejecutar esos comandos a través de ssh (por ejemplo, "ssh somehost bin/showlogfile")
Lo que buscas se llama Shell Restringido. Bash proporciona un modo en el que los usuarios solo pueden ejecutar comandos presentes en sus directorios de inicio (y no pueden moverse a otros directorios), lo que podría ser lo suficientemente bueno para usted.
He encontrado que este hilo es muy ilustrativo, aunque un poco anticuado.
ssh
sigue el rsh
tradición utilizando el programa de shell del usuario del archivo de contraseñas para ejecutar comandos.
Esto significa que podemos resolver esto sin involucrar a ssh
configuración de ninguna manera.
Si no desea que el usuario pueda tener acceso al shell, simplemente reemplace el shell de ese usuario con un script. Si miras en /etc/passwd
Verá que hay un campo que asigna un intérprete de comandos de shell a cada usuario. El script se usa como shell tanto para su inicio de sesión interactivo ssh [email protected]
así como para comandos ssh [email protected] command arg ...
.
Aquí hay un ejemplo. Creé un usuario foo
cuyo caparazón es un script. El script imprime el mensaje my arguments are:
seguido de sus argumentos (cada uno en una línea separada y entre paréntesis angulares) y termina. En el caso de registro, no hay argumentos. Esto es lo que sucede:
webserver:~# ssh [email protected]
[email protected]'s password:
Linux webserver [ snip ]
[ snip ]
my arguments are:
Connection to localhost closed.
Si el usuario intenta ejecutar un comando, se ve así:
webserver:~# ssh [email protected] cat /etc/passwd
[email protected]'s password:
my arguments are:
<-c>
<cat /etc/passwd>
Nuestro "shell" recibe un -c
invocación de estilo, con el comando completo como un argumento, de la misma manera que /bin/sh
lo recibiría.
Entonces, como puede ver, lo que podemos hacer ahora es desarrollar más el script para que reconozca el caso cuando se invocó con un -c
argumento, y luego analiza la cadena (digamos por coincidencia de patrones). Las cadenas que están permitidas se pueden pasar al shell real invocando recursivamente /bin/bash -c <string>
. El caso de rechazo puede imprimir un mensaje de error y terminar (incluido el caso cuando -c
falta).
Tienes que tener cuidado con cómo escribes esto. Recomiendo escribir solo coincidencias positivas que permitan solo cosas muy específicas y no permitan todo lo demás.
Nota: si eres root
, aún puede iniciar sesión en esta cuenta anulando el shell en el su
comando, como este su -s /bin/bash foo
. (Sustituya el shell de su elección). Los no root no pueden hacer esto.
Aquí hay un script de ejemplo:restrinja al usuario para que solo use ssh
para git
acceso a repositorios bajo /git
.
#!/bin/sh
if [ $# -ne 2 ] || [ "$1" != "-c" ] ; then
printf "interactive login not permitted\n"
exit 1
fi
set -- $2
if [ $# != 2 ] ; then
printf "wrong number of arguments\n"
exit 1
fi
case "$1" in
( git-upload-pack | git-receive-pack )
;; # continue execution
( * )
printf "command not allowed\n"
exit 1
;;
esac
# Canonicalize the path name: we don't want escape out of
# git via ../ path components.
gitpath=$(readlink -f "$2") # GNU Coreutils specific
case "$gitpath" in
( /git/* )
;; # continue execution
( * )
printf "access denied outside of /git\n"
exit 1
;;
esac
if ! [ -e "$gitpath" ] ; then
printf "that git repo doesn't exist\n"
exit 1
fi
"$1" "$gitpath"
Por supuesto, confiamos en que estos programas Git git-upload-pack
y git-receive-pack
no tenga orificios ni escotillas de escape que permitan a los usuarios acceder al sistema.
Eso es inherente a este tipo de esquema de restricción. El usuario está autenticado para ejecutar código en un determinado dominio de seguridad y estamos aplicando una restricción para limitar ese dominio a un subdominio. Por ejemplo, si permite que un usuario ejecute el vim
comando en un archivo específico para editarlo, el usuario puede simplemente obtener un shell con :!sh[Enter]
.