Ich habe sudo
die Ausführung ohne Passwort konfiguriert , aber wenn ich es versuche ssh 'sudo Foo'
, erhalte ich immer noch die Fehlermeldung sudo: sorry, you must have a tty to run sudo
.
Warum passiert das und wie kann ich das umgehen?
Ich habe sudo
die Ausführung ohne Passwort konfiguriert , aber wenn ich es versuche ssh 'sudo Foo'
, erhalte ich immer noch die Fehlermeldung sudo: sorry, you must have a tty to run sudo
.
Warum passiert das und wie kann ich das umgehen?
Antworten:
Das liegt wahrscheinlich daran, dass Ihre /etc/sudoers
Datei (oder eine beliebige darin enthaltene Datei) Folgendes enthält:
Defaults requiretty
... was sudo
ein TTY erforderlich macht . Es ist bekannt, dass Red Hat-Systeme (RHEL, Fedora ...) ein TTY in der Standarddatei erfordern sudoers
. Das bietet keinen wirklichen Sicherheitsvorteil und kann sicher entfernt werden.
Red Hat hat das Problem erkannt und es wird in zukünftigen Versionen entfernt.
Wenn das Ändern der Serverkonfiguration keine Option ist, können Sie zur Umgehung dieser Fehlkonfiguration die Optionen -t
oder verwenden -tt
, mit ssh
denen ein Pseudoterminal auf der Remote-Seite erstellt wird. Achten Sie jedoch darauf, dass es mehrere Seiten hat Auswirkungen.
-tt
ist für den interaktiven Gebrauch gedacht. Dadurch wird das lokale Terminal in den raw
Modus versetzt, sodass Sie mit dem Remote-Terminal interagieren können. Das bedeutet, dass, wenn ssh
E / A nicht von / zu einem Terminal ausgeführt wird, dies Nebenwirkungen hat. Beispielsweise können alle so wird der Eingang zurück, Sonderklemme Zeichen Echo werden ( ^?
, ^C
, ^U
) bewirkt , dass eine spezielle Verarbeitung; Bei der Ausgabe wird LF
s in CRLF
s konvertiert. ( Weitere Informationen finden Sie in der Antwort unter Warum wird diese Binärdatei geändert ? .)
Um die Auswirkungen zu minimieren, können Sie sie folgendermaßen aufrufen:
ssh -tt host 'stty raw -echo; sudo ...' < <(cat)
Dadurch < <(cat)
wird die Einstellung des lokalen Terminals (falls vorhanden) im raw
Modus vermieden. Und wir verwenden stty raw -echo
, um die Leitungsdisziplin des Remote-Terminals als Durchgang festzulegen (effektiv verhält es sich so wie die Pipe, die anstelle eines Pseudo-Terminals ohne verwendet wird -tt
, obwohl dies nur gilt, nachdem dieser Befehl ausgeführt wurde um das Senden von Eingaben zu verzögern).
Da die Ausgabe des Remote-Befehls an ein Terminal geht, wirkt sich dies nach wie vor auf die Pufferung (die für viele Anwendungen zeilenbasiert TCP_NODELAY
ist ) und die Bandbreiteneffizienz aus, da sie aktiviert ist. Auch mit -tt
, ssh
setzt die IPQoS lowdelay
im Gegensatz zu throughput
. Sie könnten beide umgehen mit:
ssh -o IPQoS=throughput -tt host 'stty raw -echo; sudo cmd | cat' < <(cat)
Beachten Sie außerdem, dass der Remote-Befehl das Dateiende in seiner Standard-ID nicht erkennen kann und die Standard-ID und die Standard-ID des Remote-Befehls zu einem einzigen Stream zusammengeführt werden.
Also doch keine so gute Arbeit.
Wenn Sie ein bekommen eine Art und Weise habe einen Pseudo-Terminal auf dem entfernten Rechner zum Laichen (wie mit expect
, zsh
, socat
, perl
‚s IO::Pty
...), dann wäre es besser, dass die Verwendung des Pseudo-Terminal zu schaffen , zu befestigen sudo
(aber nicht für I / O) und ssh
ohne -t
.
Zum Beispiel mit 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'
Oder mit script
(hier unter der Annahme der Implementierung von 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'
(vorausgesetzt (für beide), dass die Anmeldeshell des Remotebenutzers Bourne-ähnlich ist).
Standardmäßig ist SUDO so konfiguriert, dass ein TTY erforderlich ist. Das heißt, SUDO wird voraussichtlich über eine Anmeldeshell ausgeführt. Sie können diese Anforderung umgehen, indem Sie den -t
Schalter zu Ihrem SSH-Aufruf hinzufügen :
ssh -t someserver sudo somecommand
Die -t
Zwangszuordnung einer Pseudotty.
Wenn Sie dies global ausführen möchten, ändern Sie es, um /etc/sudoers
es anzugeben !requiretty
. Dies kann pro Benutzer, pro Gruppe oder auf allen Ebenen erfolgen.
Verwenden Sie das -t
Flag, ssh
um die Tty-Zuordnung zu erzwingen.
$ ssh luci tty
not a tty
$ ssh luci -t tty
/dev/ttys003
$
-t
, um die Zuordnung zu erzwingen, wennPseudo-terminal will not be allocated because stdin is not a terminal.
Ich bin mit Docker und Centos 7 auf dieses Problem gestoßen. Am Ende habe ich Folgendes getan:
yum install -y sudo
sed -i -e 's/Defaults requiretty.*/ #Defaults requiretty/g' /etc/sudoers
Ich habe diesen Hack unter https://hub.docker.com/r/liubin/fluentd-agent/~/dockerfile gefunden
Eine interessante Alternative ist das Ausführen von FreeIPA oder IdM, um Ihre Benutzer und Sudoer-Regeln zentral zu verwalten. Sie können dann Sudo-Regeln erstellen und die Option zuweisen
! requiretty
in der Regel. Der Befehl wird dann wie erwartet ausgeführt. Sie haben auch die Vorteile, alle Server und Benutzer von einer einzigen Konfiguration aus zu verwalten.
Ich hatte das gleiche Problem. In meinem Fall bestand die Lösung aus zwei Zeilen
myscript=$(cat ssh_test.sh)
ssh -t user@host "$myscript"
Erläuterung:
Fügen Sie die Befehle, die Sie ausführen möchten (einschließlich sudo-Befehle), in ein Skript ein, z. B. "ssh_test.sh".
Lesen Sie das gesamte Skript in eine Variable namens "myscript".
Rufen Sie ssh mit nur einem -t auf und geben Sie die Variable anstelle eines Befehls an.
Zuvor hatte ich Probleme mit der Verwendung von Kombinationen aus stdin und heredocs
Ich habe diese Frage beim Googeln gefunden und bin auf diesen Fehler aus einem ganz anderen Grund gestoßen.
Mein Fix bestand darin, den Aufruf von Downstream-Shell-Skripten zu beenden, wie dies sudo
bei meinem übergeordneten Shell-Skript der Fall war, als das übergeordnete Shell-Skript bereits mit aufgerufen wurde sudo
.
requiretty
Red Hat- Distribution von sudo, die in den Standard-Sudoern enthalten ist. Es wird in neueren Versionen behoben