Vraag Wat is het voordeel van het niet toewijzen van een terminal in ssh?


Af en toe zal ik zoiets doen

ssh user@host sudo thing

en ik herinner me dat ssh standaard geen pseudo-tty toewijst. Waarom niet? Welke voordelen zou ik verliezen als ik een alias zou hebben ssh naar ssh -t?


56
2018-05-06 14:06


oorsprong


> Ik herinner me dat ssh geen psuedo-tty toewijst. Wat gebeurt er? Het zou de vraag verrijken om te begrijpen wat het probleem is. - Air
@Air Er is geen probleem dat ik probeerde op te lossen. Er was een keuze in hoe ssh wordt geïmplementeerd dat ik probeerde te begrijpen. De vraag is heel duidelijk en het antwoord van Andrew B behandelt de vraag mooi. Het antwoord kan als volgt worden samengevat: hardlopen ssh -t is altijd slecht omdat sommige commando's op rare manieren kunnen breken. Terwijl het uitvoeren van een opdracht die een PTY zonder heeft, resulteert in een duidelijk foutbericht dat u een terminal nodig hebt. - Chas. Owens


antwoorden:


Het belangrijkste verschil is het concept van interactiviteit. Het is vergelijkbaar met het uitvoeren van opdrachten lokaal in een script, of zelf uit te typen. Anders is dat een opdracht op afstand een standaardinstelling moet kiezen en niet-interactief het veiligst is. (en meestal het meest eerlijk)

STDIN

  • Als een PTY wordt toegewezen, kunnen toepassingen dit detecteren en weten dat het veilig is om de gebruiker om extra invoer te vragen zonder dingen te verbreken. Er zijn veel programma's die de stap overslaan om de gebruiker om invoer te vragen als er geen terminal aanwezig is, en dat is maar goed ook. Hierdoor zouden scripts onnodig onnodig hangen.
  • Uw invoer wordt gedurende de duur van de opdracht naar de externe server verzonden. Dit omvat controlesequenties. Terwijl een Ctrl-c break zou normaal een lus op de ssh-opdracht veroorzaken om onmiddellijk te breken, uw controlesequenties worden in plaats daarvan naar de externe server verzonden. Dit resulteert in de noodzaak om de toetsaanslag te "hameren" om ervoor te zorgen dat deze bij de besturing arriveert bladeren de opdracht ssh, maar voordat de volgende opdracht ssh begint.

Ik zou waarschuwen voor gebruik ssh -t in onbewaakte scripts, zoals crons. Een niet-interactieve shell die een opdracht op afstand vraagt ​​om zich interactief voor invoer te gedragen, vraagt ​​om allerlei soorten problemen.

Je kunt ook testen op de aanwezigheid van een terminal in je eigen shell-scripts. STDIN testen met nieuwere versies van bash:

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

STDOUT

  • Bij aliasing ssh naar ssh -t, je kunt verwachten dat je een extra rijder return krijgt in je lijn eindigt. Het is misschien niet zichtbaar voor u, maar het is er; het zal verschijnen als ^M wanneer doorgesluisd naar cat -e. U moet dan extra moeite doen om ervoor te zorgen dat deze controlecode niet aan uw variabelen wordt toegewezen, vooral als u die uitvoer in een database invoegt.
  • Er bestaat ook het risico dat programma's aannemen dat ze uitvoer kunnen genereren die niet vriendelijk is voor bestandsomleiding. Normaal gesproken zou u, als u STDOUT naar een bestand zou doorverwijzen, herkennen dat uw STDOUT geen terminal is en geen kleurcodes weglaat. Als de STDOUT-omleiding afkomstig is van de uitvoer van de ssh-client en er is een PTY gekoppeld aan het externe einde van de client, de programma's op afstand kunnen zo'n onderscheid niet maken en je zult eindigen met terminal-garbage in je uitvoerbestand. Omleiden van uitvoer naar een bestand op de afgelegen einde van de verbinding moet nog steeds werken zoals verwacht.

Hier is dezelfde bash-test als eerder, maar voor STDOUT:

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

Hoewel het mogelijk is om deze problemen te omzeilen, zult u onvermijdelijk vergeten om scripts om hen heen te ontwerpen. We doen allemaal op een gegeven moment. Uw teamleden kunnen zich ook niet realiseren / onthouden dat deze alias aanwezig is, wat op zijn beurt weer problemen voor u zal veroorzaken wanneer ze schrijf scripts die uw alias gebruiken.

aliasing ssh naar ssh -t is zeer een geval waarin je het ontwerpprincipe van minste verrassing; mensen zullen problemen tegenkomen die ze niet verwachten en zullen misschien niet begrijpen waardoor ze worden veroorzaakt.


62
2018-05-06 15:02



Je krijgt bijna de indruk dat ik heb gewerkt aan een team dat dit heeft gedaan ... - Andrew B


SSH-escape-tekens en overdracht van binaire bestanden

Een voordeel dat niet is genoemd in de andere antwoorden is dat bij bediening zonder een pseudo-terminal, de SSH ontsnapping karakters zoals ~C zijn niet ondersteund; dit maakt het veilig voor programma's om binaire bestanden over te zetten die deze sequenties kunnen bevatten.

Bewijs van concept

Kopieer een binair bestand met behulp van een pseudo-terminal:

$ ssh -t anthony@remote_host 'cat /usr/bin/free' > ~/free
Connection to remote_host closed.

Kopieer een binair bestand zonder een pseudo-terminal te gebruiken:

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

De twee bestanden zijn niet hetzelfde:

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

Degene die is gekopieerd met een pseudo-terminal is beschadigd:

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

terwijl de andere niet is:

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

Bestanden overzetten via SSH

Dit is vooral belangrijk voor programma's zoals scp of rsync die SSH gebruiken voor gegevensoverdracht. Deze gedetailleerde beschrijving van hoe het SCP-protocol werkt legt uit hoe het SCP-protocol bestaat uit een combinatie van tekstuele protocolberichten en binaire bestandsgegevens.


OpenSSH helpt je beschermen tegen jezelf

Het is vermeldenswaard dat zelfs als het -t vlag wordt gebruikt, de OpenSSH ssh cliënt zal weigeren een pseudo-terminal toe te wijzen als het detecteert dat het stdin stream is geen terminal:

$ echo testing | ssh -t anthony@remote_host 'echo $TERM'
Pseudo-terminal will not be allocated because stdin is not a terminal.
dumb

Je kunt de OpenSSH-client nog steeds dwingen om een ​​pseudo-terminal toe te wijzen -tt:

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

In beide gevallen maakt het (verstandig) niet uit of stdout of stderr worden omgeleid:

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

24
2018-01-04 16:10



Dat was een heel interessant punt dat ik niet had overwogen, bedankt voor het toevoegen van dit antwoord! - Jenny D


Op remote host hebben we te maken met deze instelling:

/etc/sudoers
...
Defaults requiretty

Zonder sudo

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

En met sudo

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

Met sudo krijgen we de extra carriage return

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

De oplossing is het uitschakelen van de vertaal newline naar carriage return-newline met 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



Leuk, maar de uitvoer is ingesprongen /: weet je toevallig of je het auto-carriage-return (unix-achtig) kunt geven? - Boop


Denk aan achterwaartse compatibiliteit.

De 2 primaire modi van ssh zijn interactief inloggen met een tty en gespecificeerd commando zonder een tty, omdat dit de exacte mogelijkheden waren van rlogin en rsh respectievelijk. ssh moest een superset van bieden rlogin/rsh functies om succesvol te zijn als vervanging.

Dus de standaardwaarden werden bepaald voordat ssh werd geboren. Combinaties zoals "Ik wil een commando specificeren en krijg een tty "moest worden geopend met nieuwe opties. Wees blij dat we tenminste hebben die optie nu, in tegenstelling tot toen we gebruikten rsh. We ruilden geen nuttige functies in om versleutelde verbindingen te krijgen. We hebben bonusfuncties!


1
2018-05-06 17:24





Van 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.

Hiermee kunt u een "shell" van soorten naar de externe server krijgen. Voor servers die dat wel doen niet shell-toegang verlenen maar SSH toestaan ​​(dat wil zeggen, Github is een bekend voorbeeld voor SFTP-toegang), met behulp van deze vlag zal de server uw verbinding weigeren.

De schaal heeft ook al je omgevingsvariabelen (zoals $PATH) dus het uitvoeren van scripts heeft meestal een tty nodig om te werken.


0
2018-05-06 14:45



Dit geeft geen antwoord op de vraag. Ik weet al hoe ik een pseudo-tty moet toewijzen. Ik wil weten waarom ik er niet één moet toewijzen. - Chas. Owens
@ Chas.Owens Omdat, zoals ik in het antwoord al zei, sommige SSH-servers dat doen niet laat tty-toegang toe en het verliest de verbinding als je er een aanvraag van de server aanvraagt. - Nathan C
Ik denk dat je een deel van je terminologie in de war raakt. Het is geen shell, simpelweg omdat er een PTY aan is gekoppeld. Er zijn over het algemeen drie soorten shell: non-interactive, interactive, en login. login is een extra kenmerk van de andere twee schaaltypen. De permutaties van deze drie bepalen welke bestanden bij het inloggen worden betrokken, wat op zijn beurt invloed heeft op hoe de omgeving wordt geïnitialiseerd. (variabelen, zoals je al zei) - Andrew B
@AndrewB Je hebt gelijk ... ik heb ook iets van deze vraag geleerd. :) - Nathan C