He configurado sudo
para ejecutar sin contraseña, pero cuando intento ssh 'sudo Foo'
, sigo recibiendo el mensaje de error sudo: sorry, you must have a tty to run sudo
.
¿Por qué sucede esto y cómo puedo solucionarlo?
Respuesta aceptada:
Probablemente se deba a que su /etc/sudoers
El archivo (o cualquier archivo que incluya) tiene:
Defaults requiretty
…lo que hace que sudo
requieren un TTY. Se sabe que los sistemas Red Hat (RHEL, Fedora...) requieren un TTY en los sudoers
predeterminados. expediente. Eso no proporciona ningún beneficio de seguridad real y se puede eliminar de forma segura.
Red Hat ha reconocido el problema y se eliminará en futuras versiones.
Si cambiar la configuración del servidor no es una opción, como una solución para esa configuración incorrecta, puede usar -t
o -tt
opciones para ssh
que genera una pseudo-terminal en el lado remoto, pero tenga en cuenta que tiene una serie de efectos secundarios.
-tt
está diseñado para uso interactivo. Pone la terminal local en raw
para que interactúes con el terminal remoto. Eso significa que si ssh
La E/S no es desde/hacia un terminal, eso tendrá efectos secundarios. Por ejemplo, toda la entrada se repetirá, caracteres terminales especiales (^?
, ^C
, ^U
) causará un procesamiento especial; en la salida, LF
s se convertirán a CRLF
s… (vea esta respuesta a ¿Por qué se está cambiando este archivo binario? para más detalles.
Para minimizar el impacto, puede invocarlo como:
ssh -tt host 'stty raw -echo; sudo ...' < <(cat)
El < <(cat)
evitará la configuración del terminal local (si lo hay) en raw
modo. Y estamos usando stty raw -echo
para establecer la disciplina de línea del terminal remoto como paso a través (efectivamente para que se comporte como la tubería que se usaría en lugar de un pseudo-terminal sin -tt
, aunque eso solo se aplica después de que se ejecuta ese comando, por lo que debe retrasar el envío de algo para la entrada hasta que eso suceda).
Tenga en cuenta que dado que la salida del comando remoto irá a un terminal, eso aún afectará su almacenamiento en búfer (que estará basado en línea para muchas aplicaciones) y la eficiencia del ancho de banda ya que TCP_NODELAY
Está encendido. También con -tt
, ssh
establece IPQoS en lowdelay
a diferencia de throughput
. Podría solucionar ambos con:
ssh -o IPQoS=throughput -tt host 'stty raw -echo; sudo cmd | cat' < <(cat)
Además, tenga en cuenta que significa que el comando remoto no puede detectar el final del archivo en su stdin y la salida estándar y la stderr del comando remoto se fusionan en una sola secuencia.
Relacionado:Debian:¿eliminar usuario y contraseña al iniciar sesión en Debian 9 Stretch?Por lo tanto, no es una solución tan buena después de todo.
Si tiene una forma de generar un pseudo-terminal en el host remoto (como con expect
, zsh
, socat
, perl
's IO::Pty
…), entonces sería mejor usar eso para crear el pseudo-terminal para adjuntar sudo
(pero no para E/S), y use ssh
sin -t
.
Por ejemplo, con expect
:
ssh host 'expect -c "spawn -noecho sh -c {
exec sudo cmd >&4 2>&5 <&6 4>&- 5>&- 6<&-}
exit [lindex [wait] 3]" 4>&1 5>&2 6<&0'
O con script
(aquí asumiendo la implementación de util-linux
):
ssh host 'SHELL=/bin/sh script -qec "
sudo cmd <&3 >&4 2>&5 3<&- 4>&- 5>&-
" /dev/null 3<&0 4>&1 5>&2'
(asumiendo (para ambos) que el shell de inicio de sesión del usuario remoto es similar a Bourne).