Cómo usar un shell de inicio de sesión no predeterminado para inicio de sesión ssh

9

Actualmente estoy trabajando en una red que usa LDAP para la autenticación. Habiendo establecido zshcomo mi shell de inicio de sesión, me encontré con un problema de obtener acceso remoto a través sshde una de las máquinas en la red que, aparentemente, no se ha zshinstalado. El inicio de sesión falla con

Dec 8 19:16:11 abert sshd[20649]: User sorokine not allowed because shell /bin/zsh does not exist

Entonces, la pregunta es básicamente: ¿Cómo puedo decirle a la máquina remota que use un shell de inicio de sesión diferente al que se configuró en LDAP?

OpenSSH_6.0p1 Debian-4 + deb7u2, OpenSSL 1.0.1e

Sascha
fuente
¿Ha considerado cambiar su shell LDAP a algo más universal como, /bin/shy luego, tener a su ~/.profileejecutivo remoto el shell apropiado si está disponible?
RobertL
Esa sería una opción, pero no muy limpia, por lo que preferiría evitarla si es posible.
Sascha
stackoverflow
Trevor Boyd Smith

Respuestas:

10

Si su shell de inicio de sesión no se puede ejecutar en alguna máquina, entonces no puede iniciar sesión a través de SSH, o por la mayoría de los otros métodos. El servidor SSH siempre ejecuta su shell de inicio de sesión. Si pasa un comando en la sshlínea de comando, el shell de inicio de sesión se ejecuta con -cy la cadena de comando¹ como argumentos; de lo contrario, el shell de inicio de sesión se ejecuta como un shell de inicio de sesión sin argumento.

Si hubiera una manera de evitar el shell de inicio de sesión, sería un agujero de seguridad. Una cuenta puede configurarse como una cuenta restringida al hacer que su shell de inicio de sesión sea un programa que solo realiza una tarea específica; por ejemplo, el shell de inicio de sesión podría ser git-shellpermitir solo el acceso a un repositorio git, o rssh, etc.

Para iniciar sesión en esa máquina, deberá hacer arreglos para /bin/zshestar presente o cambiar su shell de inicio de sesión a algo que esté presente.

Lo que recomiendo en un entorno heterogéneo como este es mantenerlo /bin/shcomo su shell de inicio de sesión, porque está presente en todas partes. Establezca la SHELLvariable de entorno en /bin/zshsi está presente, de esa manera obtendrá zsh como un shell interactivo.

if [ -x /bin/zsh ]; then
  export SHELL=/bin/zsh
fi

Mientras lo hace, esto le permite evitar codificar el camino zsh.

if SHELL=$(command -v zsh); then
  export SHELL
else
  unset SHELL
fi

Para que zsh se ejecute automáticamente para un inicio de sesión en modo de texto, invoque desde su .profile. Si desea usarlo .zprofilepara configurar las cosas, conviértalo en un shell de inicio de sesión (pero no obtendrá el mismo entorno en máquinas donde zsh no está presente, por lo que no lo recomiendo). Haga esto solo si se trata de un inicio de sesión interactivo, no cuando .profilese ejecuta mediante un script, durante el inicio de sesión en modo GUI, etc.

if case $- in *i*) true;; *) false;; esac &&  # interactive shell
   [ -z "$ZSH_VERSION" ] &&                   # not running zsh yet
   type zsh >/dev/null 2>/dev/null; then      # zsh is present
  exec zsh
fi

¹ El cliente SSH concatena sus argumentos que no sean opciones con espacios en el medio, y envía la cadena resultante a través de la conexión. Los protocolos SSH definen el comando como una cadena, no una lista de cadenas.

Gilles 'SO- deja de ser malvado'
fuente
Gracias por la explicación detallada. Parece que es el único camino a seguir que no implica la instalación de zsh en la máquina remota, y funciona perfectamente, por lo que me atendré.
Sascha
También sugiero agregar una prueba [ "0$SHLVL" -lt 2 ]en caso de que el shell de inicio de sesión predeterminado sea compatible $SHLVLpara que bash -lse pueda ejecutar otro shell si es necesario (por ejemplo, en caso de que zsh falle por algún motivo). Por ssh -t host bash -llo tanto , ejecutaría un bashshell de inicio de sesión sin ejecutar zsh detrás. Además, reemplazaría exec zshpor exec zsh -lpara que el .zloginarchivo tenga su origen.
vinc17
2

Debe instalar el shell en la máquina especificada si tiene acceso de una manera diferente o solicitarlo a un administrador para que lo haga por usted o cambiar su shell en ldap a un shell que existe en la máquina remota.

(abierto) sshd siempre verificará el shell del usuario y siempre ejecutará ese shell lo que se haya pasado para ejecutar. Si se pasa otro shell para ejecutarlo, lo ejecutará pasándolo como argumento al shell de usuario, por ejemplo, el shell de usuario es '/ bin / sh' y usted pasa como argumento un shell csh que ejecutará "/ bin / sh -c / bin / csh '.

nkms
fuente
Lea el comentario de redfast. openssh le permite omitir el shell predeterminado.
Rui F Ribeiro
@Rui F Ribeiro Si lo hiciera, le quitaría la lógica detrás de configurar el shell en algo como '/ bin / false' o '/ sbin / nologin'. Si te refieres a cambiar el shell después de iniciar sesión, entonces está bien, pero lo hace como escribí anteriormente (sh -c othersh), si no hay '/ bin / sh', entonces no tienes suerte. (Probado en Redhat).
nkms
Es cierto, si passwd tiene un shell que no figura en / etc / shells, no podrá iniciar sesión de todos modos. Pero si puede iniciar sesión, y a menos que sshd_config no lo fuerce a un shell en particular, cualquier comando que el usuario sea capaz de ejecutar es un juego justo. Si hace un par de pruebas más, por ejemplo ssh -l user server "ps ax" | grep bash, es fácil notar que no siempre se invoca el shell predeterminado . Lo que realmente impide que la otra solución funcione es la comprobación de seguridad de que zsh no esté en / etc / shells
Rui F Ribeiro
@Rui F Ribeiro Ejecute strace -f sshd en el lado del servidor. Verá algo como "execve (" / bin / bash ", [" bash "," -c "," ps "] ..." Además, / sbin / nologin es un shell válido en / etc / shells.
nkms
La respuesta de @RuiFRibeiro redfast00 es simplemente errónea. nkms's tiene razón.
Gilles 'SO- deja de ser malvado'