it-swarm.com.de

Was ist der Vorteil, wenn in ssh kein Terminal zugewiesen wird?

Hin und wieder werde ich so etwas tun

ssh [email protected] Sudo thing

und ich werde daran erinnert, dass ssh standardmäßig keine Pseudo-tty zuweist. Warum nicht? Welche Vorteile würde ich verlieren, wenn ich ssh auf ssh -t?

68
Chas. Owens

Der Hauptunterschied ist das Konzept der Interaktivität . Es ähnelt dem lokalen Ausführen von Befehlen innerhalb eines Skripts, anstatt sie selbst einzugeben. Es unterscheidet sich darin, dass ein Remote-Befehl einen Standard auswählen muss und nicht interaktiv am sichersten ist. (und normalerweise am ehrlichsten)

STDIN

  • Wenn ein PTY zugewiesen ist, können Anwendungen dies erkennen und wissen, dass es sicher ist, den Benutzer zu zusätzlichen Eingaben aufzufordern, ohne die Dinge zu beschädigen. Es gibt viele Programme, die den Schritt überspringen, den Benutzer zur Eingabe aufzufordern, wenn kein Terminal vorhanden ist, und das ist gut so. Andernfalls würden Skripte unnötig hängen bleiben.
  • Ihre Eingabe wird für die Dauer des Befehls an den Remote-Server gesendet. Dies schließt Kontrollsequenzen ein. Während eine Unterbrechung von Ctrl-c Normalerweise dazu führen würde, dass eine Schleife des Befehls ssh sofort unterbrochen wird, werden Ihre Steuersequenzen stattdessen an den Remote-Server gesendet. Dies führt dazu, dass der Tastenanschlag "gehämmert" werden muss, um sicherzustellen, dass er eintrifft, wenn die Steuerung den Befehl ssh verlässt , jedoch bevor der nächste Befehl ssh beginnt.

Ich würde davor warnen, ssh -t In unbeaufsichtigten Skripten wie Cron zu verwenden. Eine nicht interaktive Shell, die einen Remote-Befehl auffordert, sich für Eingaben interaktiv zu verhalten, fordert alle Arten von Problemen an.

Sie können auch das Vorhandensein eines Terminals in Ihren eigenen Shell-Skripten testen. So testen Sie STDIN mit neueren Versionen von bash:

# fd 0 is STDIN
[ -t 0 ]; echo $?

STDOUT

  • Wenn Sie ssh auf ssh -t Aliasen, können Sie damit rechnen, dass Ihre Zeilenenden einen zusätzlichen Wagenrücklauf erhalten. Es mag für Sie nicht sichtbar sein, aber es ist da; Es wird als ^M angezeigt, wenn es an cat -e weitergeleitet wird. Sie müssen dann den zusätzlichen Aufwand aufwenden, um sicherzustellen, dass dieser Steuercode nicht Ihren Variablen zugewiesen wird, insbesondere wenn Sie diese Ausgabe in eine Datenbank einfügen.
  • Es besteht auch das Risiko, dass Programme davon ausgehen, dass sie Ausgaben rendern können, die für die Dateiumleitung nicht geeignet sind. Wenn Sie STDOUT in eine Datei umleiten, erkennt das Programm normalerweise, dass Ihr STDOUT kein Terminal ist, und lässt keine Farbcodes aus. Wenn die STDOUT-Umleitung von der Ausgabe des ssh-Clients stammt und dem Remote-Ende des Clients ein PTY zugeordnet ist, können die Remote-Programme dies nicht tun eine solche Unterscheidung und Sie werden mit Terminal Müll in Ihrer Ausgabedatei enden. Das Umleiten der Ausgabe in eine Datei am Remote-Ende der Verbindung sollte weiterhin wie erwartet funktionieren.

Hier ist der gleiche Bash-Test wie zuvor, jedoch für STDOUT:

# fd 1 is STDOUT
[ -t 1 ]; echo $?

Während es möglich ist, diese Probleme zu umgehen, werden Sie unweigerlich vergessen, Skripte um sie herum zu entwerfen. Wir alle tun es irgendwann. Ihre Teammitglieder können auch nicht erkennen/sich daran erinnern, dass dieser Alias ​​vorhanden ist, was wiederum Probleme für Sie verursacht, wenn sie Skripte schreiben, die Ihren Alias ​​verwenden .

Aliasing ssh auf ssh -t Ist ein Fall, in dem Sie gegen das Designprinzip von am wenigsten überraschend verstoßen. Menschen werden auf Probleme stoßen, die sie nicht erwarten und möglicherweise nicht verstehen, was sie verursacht.

73
Andrew B

SSH-Escapezeichen und Übertragung von Binärdateien

Ein Vorteil, der in den anderen Antworten nicht erwähnt wurde, ist, dass beim Betrieb ohne Pseudo-Terminal die SSH verwendet wird ) Escapezeichen wie ~C werden nicht unterstützt ; Dies macht es für Programme sicher, Binärdateien zu übertragen, die diese Sequenzen enthalten können.

Konzeptioneller Beweiß

Kopieren Sie eine Binärdatei mit einem Pseudo-Terminal:

$ ssh -t [email protected]_Host 'cat /usr/bin/free' > ~/free
Connection to remote_Host closed.

Kopieren Sie eine Binärdatei ohne Verwendung eines Pseudo-Terminals:

$ ssh [email protected]_Host 'cat /usr/bin/free' > ~/free2

Die beiden Dateien sind nicht gleich:

$ diff ~/free*
Binary files /home/anthony/free and /home/anthony/free2 differ

Derjenige, der mit einem Pseudo-Terminal kopiert wurde, ist beschädigt:

$ chmod +x ~/free*
$ ./free
Segmentation fault

während der andere nicht:

$ ./free2
             total       used       free     shared    buffers     cached
Mem:       2065496    1980876      84620          0      48264    1502444
-/+ buffers/cache:     430168    1635328
Swap:      4128760        112    4128648

Übertragen von Dateien über SSH

Dies ist besonders wichtig für Programme wie scp oder rsync, die SSH für die Datenübertragung verwenden. Dieses detaillierte Beschreibung der Funktionsweise des SCP-Protokolls erklärt, wie das SCP-Protokoll aus einer Mischung von Textprotokollnachrichten und Binärdateidaten besteht.


OpenSSH schützt Sie vor sich selbst

Es ist erwähnenswert, dass der OpenSSH ssh-Client die Zuweisung eines Pseudo-Terminals verweigert, selbst wenn das Flag -t Verwendet wird, wenn er feststellt, dass sein stdin-Stream kein Terminal ist ::

$ echo testing | ssh -t [email protected]_Host 'echo $TERM'
Pseudo-terminal will not be allocated because stdin is not a terminal.
dumb

Sie können den OpenSSH-Client weiterhin zwingen, ein Pseudo-Terminal mit -tt Zuzuweisen:

$ echo testing | ssh -tt [email protected]_Host 'echo $TERM'
xterm

In beiden Fällen ist es (vernünftigerweise) egal, ob stdout oder stderr umgeleitet werden:

$ ssh -t [email protected]_Host 'echo $TERM' >| ssh_output
Connection to remote_Host closed.
34

Auf dem Remote-Host haben wir Folgendes zu tun:

/etc/sudoers
...
Defaults requiretty

Ohne Sudo

$ ssh -T [email protected] echo -e 'foo\\nbar' | cat -e
foo$
bar$

Und mit Sudo

$ ssh -T [email protected] Sudo echo -e 'foo\\nbar' | cat -e
Sudo: sorry, you must have a tty to run Sudo

Mit Sudo erhalten wir das extra Wagenrücklauf

$ ssh -t [email protected] Sudo echo -e 'foo\\nbar' | cat -e
foo^M$
      bar^M$
            Connection to localhost closed.

Die Lösung besteht darin, das Newline in Wagenrücklauf-Newline übersetzen mit stty -onlcr Zu deaktivieren.

$ ssh -t [email protected] stty -onlcr\; Sudo echo -e 'foo\\nbar' | cat -e
foo$
    bar$
        Connection to localhost closed.
4

Denken Sie an die Abwärtskompatibilität.

Die beiden Hauptmodi von ssh sind die interaktive Anmeldung mit einem tty und der angegebene Befehl ohne tty, da dies die genauen Funktionen von rlogin bzw. rsh waren. ssh musste eine Obermenge von rlogin/rsh Funktionen bereitstellen, um als Ersatz erfolgreich zu sein.

Die Standardeinstellungen wurden also vor der Geburt von ssh festgelegt. Auf Kombinationen wie "Ich möchte einen Befehl angeben nd get a tty" musste mit neuen Optionen zugegriffen werden. Seien Sie froh, dass zumindest wir diese Option jetzt haben haben, im Gegensatz zu rsh. Wir haben keine nützlichen Funktionen ausgetauscht, um verschlüsselte Verbindungen zu erhalten. Wir haben Bonusfunktionen!

1
user193597

Von man ssh:

 -t      Force pseudo-tty allocation.  This can be used to execute arbi-
         trary screen-based programs on a remote machine, which can be
         very useful, e.g. when implementing menu services.  Multiple -t
         options force tty allocation, even if ssh has no local tty.

Auf diese Weise können Sie eine Art "Shell" auf den Remote-Server übertragen. Bei Servern, die nicht Shell-Zugriff gewähren, aber SSH zulassen (d. H. Github ist ein bekanntes Beispiel für den SFTP-Zugriff), führt die Verwendung dieses Flags dazu, dass der Server Ihre Verbindung ablehnt.

Die Shell enthält auch alle Umgebungsvariablen (wie $PATH) Das Ausführen von Skripten benötigt also im Allgemeinen eine tty, um zu funktionieren.

0
Nathan C