¿Cómo restringir a los usuarios de SSH a un conjunto predefinido de comandos después de iniciar sesión?

Esta es una idea para una seguridad. Nuestros empleados deben tener acceso a algunos comandos en un servidor Linux, pero no a todos. Por ejemplo, tendrán la posibilidad de acceder a un archivo de registro ( less logfile ) o iniciar comandos diferentes ( shutdown.sh / run.sh ).

Información de fondo:

Todos los empleados acceden al servidor con el mismo nombre de usuario: nuestro producto se ejecuta con permisos de usuario “normales”, no se necesita “instalación”. Simplemente descomprímelo en su directorio de usuario y ejecútelo. Gestionamos varios servidores donde nuestra aplicación está “instalada”. En cada máquina hay un usuario johndoe . Nuestros empleados a veces necesitan acceso a la aplicación en la línea de comandos para acceder y verificar los archivos de registro o para reiniciar la aplicación a mano. Solo algunas personas tendrán acceso completo a la línea de comando.

Estamos utilizando la autenticación ppk en el servidor.

Sería genial si employee1 solo puede acceder al archivo de registro y employee2 también puede hacer X etc.

Solución: como solución usaré la opción de command como se indica en la respuesta aceptada . Haré mi propio pequeño script de shell que será el único archivo que se puede ejecutar para algunos empleados. El script ofrecerá varios comandos que se pueden ejecutar, pero no otros. Usaré los siguientes parámetros en authorized_keys como se indica aquí :

 command="/bin/myscript.sh",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-dss AAAAB3....o9M9qz4xqGCqGXoJw= user@host 

Esto es suficiente seguridad para nosotros. Gracias, comunidad!

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”)

ssh sigue la tradición rsh utilizando el progtwig de shell del usuario desde el archivo de contraseñas para ejecutar comandos.

Esto significa que podemos resolver esto sin involucrar la configuración de ssh de ninguna manera.

Si no desea que el usuario tenga acceso al shell, simplemente reemplace el shell del usuario con un script. Si miras en /etc/passwd , verás que hay un campo que asigna un intérprete de comandos de shell a cada usuario. El script se utiliza como el shell tanto para su ssh user@host inicio de sesión interactivo ssh user@host como para los comandos ssh user@host command arg ...

Aquí hay un ejemplo. Creé un usuario foo cuyo shell es un script. El script imprime el mensaje my arguments are: seguido por sus argumentos (cada uno en una línea separada y en corchetes angulares) y termina. En el caso de inicio de sesión, no hay argumentos. Esto es lo que sucede:

 webserver:~# ssh foo@localhost foo@localhost'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 foo@localhost cat /etc/passwd foo@localhost's password: my arguments are: < -c>  

Nuestro “shell” recibe una invocación de estilo -c , con el comando completo como un solo argumento, del mismo modo que /bin/sh lo recibiría.

Como puede ver, lo que podemos hacer ahora es desarrollar aún más el script para que reconozca el caso cuando ha sido invocado con un argumento -c , y luego analiza la cadena (digamos por coincidencia de patrón). Esas cadenas que están permitidas se pueden pasar al shell real al invocar recursivamente /bin/bash -c . El caso de rechazo puede imprimir un mensaje de error y terminar (incluido el caso cuando falta -c ).

Tienes que tener cuidado de cómo escribes esto. Recomiendo escribir solo coincidencias positivas que permitan solo cosas muy específicas y no permitir todo lo demás.

Nota: si eres root , aún puedes iniciar sesión en esta cuenta anulando el shell en el comando su , como este su -s /bin/bash foo . (Sustituto shell de elección.) No raíz no puede hacer esto.

Aquí hay un script de ejemplo: restrinja al usuario a usar ssh para acceder a los repositorys en /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 progtwigs de Git git-upload-pack y git-receive-pack no tengan huecos o escotillas de escape que den acceso a los usuarios al sistema.

Eso es inherente a este tipo de esquema de restricción. El usuario está autenticado para ejecutar código en un cierto dominio de seguridad, y estamos bloqueando una restricción para limitar ese dominio a un subdominio. Por ejemplo, si permite que un usuario ejecute el comando vim en un archivo específico para editarlo, el usuario puede obtener un shell con :!sh[Enter] .

Lo que estás buscando se llama Shell Restringido . Bash proporciona un modo tal en el que los usuarios solo pueden ejecutar comandos presentes en sus directorios principales (y no pueden moverse a otros directorios), lo que podría ser suficiente para usted.

He encontrado que este hilo es muy ilustrativo, aunque un poco anticuado.

Deberías adquirir `rssh ‘, el shell restringido

Puede seguir las guías de restricción mencionadas anteriormente, son más bien autoexplicativas y fáciles de seguir. Comprenda los términos `chroot jail ‘y cómo implementar de manera efectiva las configuraciones de sshd / terminal, y así sucesivamente.

Siendo que la mayoría de sus usuarios acceden a sus terminales a través de sshd, probablemente también deba buscar en sshd_conifg, el archivo de configuración de daemon SSH, para aplicar ciertas restricciones a través de SSH. Ten cuidado, sin embargo. Comprenda adecuadamente lo que intenta implementar, ya que las ramificaciones de las configuraciones incorrectas probablemente sean bastante graves.

¿Por qué no escribes tu propio login-shell? Sería bastante simple usar Bash para esto, pero puedes usar cualquier idioma.

Ejemplo en Bash

Use su editor favorito para crear el archivo /root/rbash.sh (este puede ser cualquier nombre o ruta, pero debe ser chown root:root y chmod 700 ):

 #!/bin/bash commands=("man" "pwd" "ls" "whoami") timestamp(){ date +'%Y-%m-%s %H:%M:%S'; } log(){ echo -e "$(timestamp)\t$1\t$(whoami)\t$2" > /var/log/rbash.log; } trycmd() { # Provide an option to exit the shell if [[ "$ln" == "exit" ]] || [[ "$ln" == "q" ]] then exit # You can do exact string matching for some alias: elif [[ "$ln" == "help" ]] then echo "Type exit or q to quit." echo "Commands you can use:" echo " help" echo " echo" echo "${commands[@]}" | tr ' ' '\n' | awk '{print " " $0}' # You can use custom regular expression matching: elif [[ "$ln" =~ ^echo\ .*$ ]] then ln="${ln:5}" echo "$ln" # Beware, these double quotes are important to prevent malicious injection # For example, optionally you can log this command log COMMAND "echo $ln" # Or you could even check an array of commands: else ok=false for cmd in "${commands[@]}" do if [[ "$cmd" == "$ln" ]] then ok=true fi done if $ok then $ln else log DENIED "$cmd" fi fi } # Optionally show a friendly welcome-message with instructions since it is a custom shell echo "$(timestamp) Welcome, $(whoami). Type 'help' for information." # Optionally log the login log LOGIN "$@" # Optionally log the logout trap "trap=\"\";log LOGOUT;exit" EXIT # Optionally check for '-c custom_command' arguments passed directly to shell # Then you can also use ssh user@host custom_command, which will execute /root/rbash.sh if [[ "$1" == "-c" ]] then shift trycmd "$@" else while echo -n "> " && read ln do trycmd "$ln" done fi 

Todo lo que tiene que hacer es configurar este ejecutable como su shell de inicio de sesión. Por ejemplo, edite su /etc/passwd y reemplace su shell de inicio de sesión actual de ese usuario /bin/bash con /root/rbash.sh .

Este es solo un ejemplo simple, pero puede hacerlo tan avanzado como lo desee, la idea está allí. Tenga cuidado de no bloquearse cambiando el shell de inicio de sesión de su propio usuario y único. Y siempre prueba símbolos y comandos extraños para ver si realmente es seguro.

Puede probarlo con: su -s /root/rbash.sh .

¡Cuidado , asegúrese de hacer coincidir todo el comando y tenga cuidado con los comodines! Mejor excluir los símbolos de Bash tales como ; , & , && , || , $ y backticks para estar seguro.

Dependiendo de la libertad que le dé al usuario, no será mucho más seguro que esto. Descubrí que a menudo solo necesitaba crear un usuario que tuviera acceso a solo unos pocos comandos relevantes, y en ese caso, esta es realmente la mejor solución. Sin embargo, si desea dar más libertad, una cárcel y permisos podrían ser más apropiados. Los errores se hacen fácilmente y solo se notan cuando ya es demasiado tarde.

Es posible que desee ver la configuración de una cárcel .

Otra forma de ver esto es utilizar ACL POSIX, debe ser compatible con su sistema de archivos, sin embargo, puede tener un ajuste detallado de todos los comandos en Linux de la misma manera que tiene el mismo control en Windows (sin la interfaz de usuario más agradable) ) enlazar

Otra cosa a considerar es PolicyKit .

Tendrás que hacer un poco de google para que todo funcione, ya que definitivamente no es una fortaleza de Linux en este momento.