Frage Was ist der Vorteil, kein Terminal in ssh zuzuweisen?


Ab und zu werde ich etwas tun

ssh user@host sudo thing

und ich werde daran erinnert, dass ssh standardmäßig kein Pseudo-tty vergibt. Warum nicht? Welche Vorteile würde ich verlieren, wenn ich Alias ​​nenne ssh zu ssh -t?


56
2018-05-06 14:06


Ursprung


> Ich werde daran erinnert, dass ssh kein Pseudo-tty zuweist Was passiert? Es würde die Frage bereichern, um zu verstehen, was das Problem ist. - Air
@Air Es gibt kein Problem, das ich beheben wollte. Es gab eine Wahl, wie ssh implementiert wird, die ich zu verstehen versuchte. Die Frage ist sehr klar und die Antwort von Andrew B geht die Frage gut an. Die Antwort kann wie folgt zusammengefasst werden: Laufen ssh -t ist immer schlecht, weil es dazu führen kann, dass einige Befehle auf seltsame Weise unterbrochen werden. Während das Ausführen eines Befehls, der ein PTY ohne eine benötigt, führt zu einer klaren Fehlermeldung, dass Sie ein Terminal benötigen. - Chas. Owens


Antworten:


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

STDIN

  • Wenn ein PTY zugewiesen wird, können Anwendungen dies erkennen und wissen, dass es sicher ist, den Benutzer für zusätzliche Eingaben aufzufordern, ohne die Dinge zu stören. Es gibt viele Programme, die den Schritt überspringen, den Benutzer zur Eingabe aufzufordern, wenn kein Terminal vorhanden ist, und das ist eine gute Sache. Es würde dazu führen, dass Skripts andernfalls unnötig hängen.
  • Ihre Eingabe wird für die Dauer des Befehls an den Remote-Server gesendet. Dies beinhaltet Kontrollsequenzen. Während ein Ctrl-c break würde normalerweise dazu führen, dass eine Schleife im ssh-Befehl sofort bricht, Ihre Kontrollsequenzen werden stattdessen an den Remote-Server gesendet. Dies führt dazu, dass der Tastendruck "hämmert", um sicherzustellen, dass er bei der Steuerung ankommt Blätter der Befehl ssh, aber bevor der nächste Befehl ssh beginnt.

Ich warne vor der Verwendung ssh -t in unbeaufsichtigten Skripts, z. B. Crons. Eine nicht-interaktive Shell, die einen Remote-Befehl auffordert, sich interaktiv für Eingaben zu verhalten, verlangt nach allen Arten von Problemen.

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

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

STDOUT

  • Beim Aliasing ssh zu ssh -t, können Sie erwarten, eine zusätzliche Wagenrücklauf in Ihren Zeilenenden zu erhalten. Es ist vielleicht nicht für dich sichtbar, aber es ist da; es wird als angezeigt ^M wenn geleitet zu cat -e. 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 möchten.
  • Es besteht auch das Risiko, dass Programme davon ausgehen, dass sie Ausgaben ausgeben können, die nicht für die Dateiumleitung geeignet sind. Normalerweise würde das Programm, wenn Sie STDOUT in eine Datei umleiten würden, erkennen, dass Ihr STDOUT kein Terminal ist und Farbcodes weglassen. Wenn die STDOUT-Umleitung vom Ausgang des SSH-Client und da es ein PTY gibt, das dem entfernten Ende des Clients zugeordnet ist, können die entfernten Programme diese Unterscheidung nicht treffen, und Sie werden mit Terminal-Müll in Ihrer Ausgabedatei enden. Umleiten der Ausgabe in eine Datei auf der Remote-Ende der Verbindung sollte immer noch wie erwartet funktionieren.

Hier ist der gleiche Bashtest wie zuvor, aber für STDOUT:

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

Während es möglich ist, diese Probleme zu umgehen, werden Sie zwangsläufig vergessen, Skripte um sie herum zu entwickeln. Wir alle machen irgendwann. Möglicherweise merken Ihre Teammitglieder auch nicht, dass dieser Alias ​​vorhanden ist, was wiederum zu Problemen führen wird Sie Schreiben Sie Skripte, die Ihren Alias ​​verwenden.

Aliasing ssh zu ssh -t ist ein Fall, in dem Sie gegen das Designprinzip verstoßen Wenigstens Überraschung; Menschen werden auf Probleme stoßen, die sie nicht erwarten, und verstehen vielleicht nicht, was sie verursacht.


62
2018-05-06 15:02



Man hat fast den Eindruck, dass ich an einem Team gearbeitet habe, das das gemacht hat ... - Andrew B


SSH-Escape-Zeichen und Übertragung von Binärdateien

Ein Vorteil, der in den anderen Antworten nicht erwähnt wurde, ist der Betrieb ohne Pseudo-Terminal, der SSH Escape-Zeichen sowie ~C sind 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 anthony@remote_host 'cat /usr/bin/free' > ~/free
Connection to remote_host closed.

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

$ ssh anthony@remote_host 'cat /usr/bin/free' > ~/free2

Die zwei Dateien sind nicht identisch:

$ 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 ist:

$ ./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. Diese detaillierte Beschreibung, wie das SCP-Protokoll funktioniert 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 selbst wenn -t Flag wird verwendet, die OpenSSH ssh Der Client wird sich weigern, ein Pseudo-Terminal zuzuweisen, wenn er dies erkennt stdin Stream ist kein Terminal:

$ echo testing | ssh -t anthony@remote_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 zuzuordnen -tt:

$ echo testing | ssh -tt anthony@remote_host 'echo $TERM'
xterm

In jedem Fall ist es (vernünftig) egal, ob stdout oder stderr werden umgeleitet:

$ ssh -t anthony@remote_host 'echo $TERM' >| ssh_output
Connection to remote_host closed.

24
2018-01-04 16:10



Das war ein sehr interessanter Punkt, den ich nicht bedacht hatte, danke, dass Sie diese Antwort hinzugefügt haben! - Jenny D


Auf Remote-Host haben wir mit dieser Einstellung zu tun:

/etc/sudoers
...
Defaults requiretty

Ohne Sudo

$ ssh -T user@host echo -e 'foo\\nbar' | cat -e
foo$
bar$

Und mit Sudo

$ ssh -T user@host sudo echo -e 'foo\\nbar' | cat -e
sudo: sorry, you must have a tty to run sudo

Mit Sudo bekommen wir das zusätzlicher Wagenrücklauf

$ ssh -t user@host sudo echo -e 'foo\\nbar' | cat -e
foo^M$
      bar^M$
            Connection to localhost closed.

Die Lösung ist das Deaktivieren der übersetzen Sie Newline in Carriage Return-Newline mit stty -onlcr

$ ssh -t user@host stty -onlcr\; sudo echo -e 'foo\\nbar' | cat -e
foo$
    bar$
        Connection to localhost closed.

3
2017-08-01 12:51



Schön, aber die Ausgabe ist eingerückt /: Wissen Sie zufällig, ob Sie Auto-Carriage-Return (Unix-Like) können? - Boop


Denken Sie über Rückwärtskompatibilität nach.

Die 2 primären Modi von ssh sind interactive-login mit einem tty und specified-command ohne tty, denn das waren die genauen Fähigkeiten von rlogin und rsh beziehungsweise. ssh musste eine Obermenge von rlogin/rsh Features, um als Ersatz erfolgreich zu sein.

Also wurden die Standardeinstellungen vor der Geburt von ssh festgelegt. Kombinationen wie "Ich möchte einen Befehl angeben und get a tty "musste mit neuen Optionen erreicht werden. Sei froh, dass wir zumindest haben diese Option jetzt, anders als bei uns rsh. Wir haben keine nützlichen Funktionen eingetauscht, um verschlüsselte Verbindungen zu erhalten. Wir haben Bonus Features!


1
2018-05-06 17:24





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" für den Remote-Server erstellen. Für Server, die das tun nicht Shell-Zugriff gewähren, aber SSH zulassen (d. h. Github ist ein bekanntes Beispiel für SFTP-Zugriff). Wenn Sie dieses Flag verwenden, wird der Server Ihre Verbindung ablehnen.

Die Shell hat auch alle Umgebungsvariablen (wie $PATH) Damit Skripte ausgeführt werden können, ist in der Regel ein Tty erforderlich.


0
2018-05-06 14:45



Dies beantwortet die Frage nicht. Ich weiß schon, wie man einen Pseudo-Tty zuweist. Ich möchte wissen, warum ich nicht immer nur einen vergeben sollte. - Chas. Owens
@ Chas.Owens Weil, wie ich in der Antwort darauf hingewiesen habe einige SSH-Server tun nicht tty Zugriff erlauben und es wird die Verbindung fallen lassen, wenn Sie eine vom Server anfordern. - Nathan C
Ich glaube, Sie könnten etwas von Ihrer Terminologie durcheinander bringen. Es ist keine Shell, nur weil ein PTY damit verbunden ist. Es gibt im Allgemeinen drei Arten von Shell: non-interactive, interactive, und login. login ist ein zusätzliches Merkmal der anderen beiden Shell-Typen. Die Permutationen dieser drei bestimmen, welche Dateien bei der Anmeldung stammen, was wiederum beeinflusst, wie die Umgebung initialisiert wird. (Variablen, wie Sie erwähnt haben) - Andrew B
@AndrewB Du hast Recht ... Ich habe auch etwas aus dieser Frage gelernt. :) - Nathan C