it-swarm-es.tech

¿Por qué necesito un tty para ejecutar Sudo si puedo Sudo sin contraseña?

He configurado Sudo para que se ejecute 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?

229
merlin2011

Eso es probablemente porque su archivo /etc/sudoers (O cualquier archivo que incluya) tiene:

Defaults requiretty

... lo que hace que Sudo requiera un TTY. Se sabe que los sistemas Red Hat (RHEL, Fedora ...) requieren un TTY en el archivo sudoers predeterminado. 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 solución alternativa para esa configuración incorrecta, puede usar las opciones -t O -tt A ssh que genera un pseudo terminal en el lado remoto, pero tenga en cuenta que tiene una serie de efectos secundarios.

-tt Está destinado para uso interactivo. Pone el terminal local en modo raw para que pueda interactuar con el terminal remoto. Eso significa que si ssh I/O no es de/a una terminal, eso tendrá efectos secundarios. Por ejemplo, toda la entrada se repetirá, los caracteres de terminal especiales (^?, ^C, ^U) Causarán un procesamiento especial; en la salida, LFs se convertirá en CRLFs ... (vea esta respuesta a ¿Por qué se cambia este archivo binario? para más detalles.

Para minimizar el impacto, puede invocarlo como:

ssh -tt Host 'stty raw -echo; Sudo ...' < <(cat)

La < <(cat) evitará la configuración del terminal local (si existe) en el modo raw. Y estamos usando stty raw -echo Para establecer la disciplina de línea del terminal remoto a medida que pasa (efectivamente, de modo que se comporta como la tubería que se usaría en lugar de un pseudo terminal sin -tt eso solo se aplica después de ejecutar ese comando, por lo que debe retrasar el envío de algo para la entrada hasta que eso ocurra.

Tenga en cuenta que dado que la salida del comando remoto irá a un terminal, eso afectará su almacenamiento en búfer (que estará basado en líneas para muchas aplicaciones) y la eficiencia del ancho de banda ya que TCP_NODELAY Está activado. También con -tt, ssh establece el IPQoS en lowdelay en lugar de throughput. Podrías evitar 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 que stdout y stderr del comando remoto se fusionan en una sola secuencia.

Entonces, no es un buen trabajo después de todo.

Si tiene una manera 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 a (pero no para E/S), y usar 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'

(suponiendo (para ambos) que el Shell de inicio de sesión del usuario remoto es similar a Bourne).

294

Por defecto, Sudo está configurado para requerir un TTY. Es decir, se espera que Sudo se ejecute desde un Shell de inicio de sesión. Puede vencer este requisito agregando -t cambie a su invocación SSH:

ssh -t someserver Sudo somecommand

Los -t fuerza la asignación de un pseudo-tty.

Si desea realizar esto globalmente, modifique /etc/sudoers para especificar !requiretty. Esto se puede hacer a por usuario, por grupo o nivel global.

30
JRFerguson

Utilizar el -t marca a ssh para forzar la asignación de tty.

$ ssh luci tty
not a tty
$ ssh luci -t tty
/dev/ttys003
$
18
Kyle Jones

Me encontré con este problema usando Docker y Centos 7. Terminé haciendo lo siguiente:

yum install -y Sudo

sed -i -e 's/Defaults requiretty.*/ #Defaults requiretty/g' /etc/sudoers

Encontré este truco en https://hub.docker.com/r/liubin/fluentd-agent/~/dockerfile

11
Martin Tapp

Una alternativa interesante es ejecutar FreeIPA o IdM para administrar sus usuarios y reglas de sudoer de forma centralizada. Luego puede crear reglas de Sudo y asignar la opción

! requiretty

en la regla El comando se ejecutará como se esperaba. También tendrá los beneficios de administrar todos los servidores y usuarios desde un único conjunto de configuraciones.

1
strtluge

Tuve el mismo problema. En mi caso, la solución fue dos líneas.

myscript=$(cat ssh_test.sh)
ssh -t [email protected] "$myscript"

Explicación:

  • Coloque los comandos que desea ejecutar (incluidos los comandos de Sudo) en un script, p. "ssh_test.sh".

  • Lea todo el script en una variable llamada "myscript".

  • Invoque ssh con solo uno -t y proporcione la variable en lugar de un comando.

Antes de esto, me encontré con problemas al usar combinaciones de lectura de stdin y usar heredocs

0
Gerry Hickman