Jaka jest korzyść z nieprzydzielenia terminala w ssh?


66

Co jakiś czas robię coś takiego

ssh user@host sudo thing

i przypomina mi się, że ssh domyślnie nie przydziela pseudo-tty. Dlaczego nie Jakie korzyści będę tracić gdybym aliasem sshdo ssh -t?


1
> Przypomina mi się, że ssh nie przyznaje psuedo-tty Co się dzieje? Wzbogaci to pytanie, aby zrozumieć, na czym polega problem.
Air

5
@ Air Nie ma problemu, który próbowałem naprawić. Próbowałem zrozumieć sposób implementacji ssh. Pytanie jest bardzo jasne, a odpowiedź Andrew B. ładnie na nie odpowiada. Odpowiedź można podsumować tak: działa ssh -tzawsze jest złe, ponieważ może to spowodować pewne polecenia złamać w dziwnych sposobów. Natomiast uruchomienie polecenia, które wymaga PTY bez niego, powoduje wyświetlenie wyraźnego komunikatu o błędzie, że potrzebujesz terminala.
Chas. Owens

Odpowiedzi:


73

Podstawową różnicą jest koncepcja interaktywności . Jest to podobne do uruchamiania poleceń lokalnie w skrypcie, w przeciwieństwie do samodzielnego wpisywania ich. Różni się tym, że komenda zdalna musi wybrać domyślną, a nieinteraktywna jest najbezpieczniejsza. (i zazwyczaj najbardziej uczciwy)

STDIN

  • Jeśli przydzielono PTY, aplikacje mogą to wykryć i wiedzieć, że można bezpiecznie poprosić użytkownika o dodatkowe dane wejściowe bez niszczenia elementów. Istnieje wiele programów, które pomijają etap monitowania użytkownika o wprowadzenie danych, jeśli nie ma terminalu, i to dobrze. W przeciwnym razie skrypty zawieszałyby się niepotrzebnie.
  • Twoje dane wejściowe zostaną przesłane do zdalnego serwera na czas trwania polecenia. Obejmuje to sekwencje kontrolne. Podczas gdy Ctrl-cnormalnie przerwa spowodowałaby natychmiastowe przerwanie pętli polecenia ssh, sekwencje kontrolne zostaną zamiast tego wysłane na zdalny serwer. Powoduje to konieczność „uderzenia” klawisza, aby upewnić się, że dotrze on, gdy sterowanie opuści polecenie ssh, ale przed rozpoczęciem następnego polecenia ssh.

ssh -tPrzestrzegałbym przed użyciem w nienadzorowanych skryptach, takich jak crons. Nieinteraktywna powłoka pytająca zdalne polecenie, aby zachowywała się interaktywnie podczas wprowadzania, prosi o wszelkiego rodzaju problemy.

Możesz także przetestować obecność terminala we własnych skryptach powłoki. Aby przetestować STDIN z nowszymi wersjami bash:

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

STDOUT

  • W przypadku aliasu sshdo ssh -tmożesz oczekiwać dodatkowego zwrotu karetki na końcach linii. To może nie być dla ciebie widoczne, ale jest tam; pokaże się jak ^Mpo przesłaniu do cat -e. Następnie musisz poświęcić dodatkowy wysiłek, aby upewnić się, że ten kod kontrolny nie zostanie przypisany do zmiennych, szczególnie jeśli zamierzasz wstawić dane wyjściowe do bazy danych.
  • Istnieje również ryzyko, że programy założą, że mogą renderować dane wyjściowe, które nie są przyjazne dla przekierowania plików. Zwykle jeśli przekierujesz STDOUT do pliku, program rozpozna, że ​​twój STDOUT nie jest terminalem i pominie wszelkie kody kolorów. Jeśli przekierowanie STDOUT pochodzi z danych wyjściowych klienta ssh, a PTY jest powiązany ze zdalnym końcem klienta, programy zdalne nie mogą wprowadzić takiego rozróżnienia, a skończysz na śmieciach końcowych w pliku wyjściowym. Przekierowanie wyjścia do pliku na zdalnym końcu połączenia powinno nadal działać zgodnie z oczekiwaniami.

Oto ten sam test bash, co wcześniej, ale dla STDOUT:

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

Chociaż można obejść te problemy, nieuchronnie zapomnisz zaprojektować wokół nich skrypty. W pewnym momencie wszyscy to robimy. Członkowie zespołu mogą nie zdawać sobie sprawy / pamiętać, że ten alias jest na swoim miejscu, co z kolei powodować problemy dla Ciebie, kiedy oni pisać skrypty, które wykorzystują swój alias.

Aliasing sshdo ssh -tjest bardzo przypadkiem, w którym będziesz naruszał zasadę najmniejszego zaskoczenia ; ludzie będą mieli problemy, których się nie spodziewają i mogą nie rozumieć, co ich powoduje.


9
Można odnieść wrażenie, że pracowałem nad zespołem, który to zrobił ...
Andrew B

W zakresie objętym tą odpowiedzią jest świetny. Ale pytanie miało szerszy zakres, zasadniczo chcąc poznać WSZYSTKIE różnice (czego się spodziewać). Informacje dodatkowe: Na poziomie procesu -t najpierw przydzieli tty, a następnie uruchomi powłokę (po drodze, sourcing / etc / profile i ~ / .bash_profile), a następnie uruchom polecenie. Bez -t, ssh ZAINSTALUJE źródła różnych plików env (/etc/bash.bashrc, następnie ~ / .bashrc), a następnie uruchomi twoje polecenie. Oznacza to, że możesz zaobserwować bardzo różne zachowanie w każdym: krótsza ŚCIEŻKA $, może bash „jednoznaczny” błąd, ponieważ zakładany ENV var nie istnieje ...
Scott Prive

@ Crossfit W komentarzach do innej odpowiedzi omawialiśmy temat powłok logowania a nie non, ale nie doszliśmy do wyczerpującego podziału różnic środowiskowych, ponieważ PO rozważał już odpowiedź na pytanie dotyczące ich szczególnych potrzeb. Możesz dodać szczegóły w miejscu, w którym widzisz miejsce, aby to zrobić, ponieważ może to pomóc innym osobom, które natrafią na to pytanie.
Andrew B,

33

Znaki specjalne SSH i przesyłanie plików binarnych

Jedną z zalet, o której nie wspomniano w innych odpowiedziach, jest to, że podczas działania bez pseudoterminalu znaki specjalne SSH, takie jak nie~Cobsługiwane ; dzięki temu programy mogą bezpiecznie przesyłać pliki binarne, które mogą zawierać te sekwencje.

Dowód koncepcji

Skopiuj plik binarny za pomocą pseudo-terminala:

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

Skopiuj plik binarny bez użycia pseudo-terminala:

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

Dwa pliki nie są takie same:

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

Ten, który został skopiowany z pseudo-terminalem, jest uszkodzony:

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

podczas gdy drugi nie jest:

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

Przesyłanie plików przez SSH

Jest to szczególnie ważne w przypadku programów takich jak scplub rsyncwykorzystujących SSH do przesyłania danych. Ten szczegółowy opis działania protokołu SCP wyjaśnia, w jaki sposób protokół SCP składa się z mieszanki komunikatów protokołu tekstowego i danych pliku binarnego.


OpenSSH pomaga chronić cię przed sobą

Warto zauważyć, że nawet jeśli -tużywana jest flaga, sshklient OpenSSH odmówi przydzielenia pseudo-terminala, jeśli wykryje, że jego stdinstrumień nie jest terminalem:

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

Nadal możesz zmusić klienta OpenSSH do przydzielenia pseudo-terminala za pomocą -tt:

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

W obu przypadkach (rozsądnie) nie ma znaczenia, stdoutczy nastąpi stderrprzekierowanie:

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

2
To był bardzo interesujący punkt, którego nie wziąłem pod uwagę, dziękuję za dodanie tej odpowiedzi!
Jenny D.

4

Na zdalnym hoście mamy do czynienia z tym ustawieniem:

/etc/sudoers
...
Defaults requiretty

Bez sudo

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

I z sudo

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

Dzięki sudo otrzymujemy dodatkowy zwrot karetki

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

Rozwiązaniem jest wyłączenie translacji nowej linii na znak powrotu nowej linii za pomocąstty -onlcr

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

1
Fajnie, ale wynik jest wcięty /: Czy wiesz, czy możesz automatycznie zwrócić karetkę (jak w Uniksie)?
Boop,

1

Pomyśl o kompatybilności wstecznej.

W 2 podstawowe tryby ssh są interaktywne-login z terminala, a określony, polecenie bez tty, ponieważ to były dokładne możliwości rlogini rshodpowiednio. ssh potrzebował dostarczyć superset funkcji rlogin/, rshaby odnieść sukces jako zamiennik.

Tak więc domyślne zostały ustalone przed narodzinami ssh. Kombinacje takie jak „Chcę podać polecenie i uzyskać tty” musiały być dostępne z nowymi opcjami. Ciesz się, że przynajmniej teraz mamy tę opcję, w przeciwieństwie do tego, kiedy korzystaliśmy rsh. Nie wymieniliśmy żadnych przydatnych funkcji, aby uzyskać szyfrowane połączenia. Mamy dodatkowe funkcje!


0

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

Pozwala to uzyskać „powłokę” na zdalnym serwerze. W przypadku serwerów, które nie udzielają dostępu do powłoki, ale zezwalają na SSH (tj. Github jest znanym przykładem dostępu SFTP), użycie tej flagi spowoduje, że serwer odrzuci twoje połączenie.

Powłoka ma również wszystkie zmienne środowiskowe (np. $PATH), Więc wykonywanie skryptów zazwyczaj wymaga tty do pracy.


1
To nie odpowiada na pytanie. Wiem już, jak przydzielić pseudo-tty. Chcę wiedzieć, dlaczego nie zawsze powinienem przydzielić jeden.
Chas. Owens

1
@ Chas.Owens Ponieważ, jak wskazałem w odpowiedzi, niektóre serwery SSH nie zezwalają na dostęp do tty, a połączenie zostanie przerwane, jeśli poprosisz o to z serwera.
Nathan C

5
Myślę, że możesz wprowadzać w błąd niektóre z terminologii. To nie jest powłoka, ponieważ PTY jest z nią związane. Są generalnie trzy rodzaje muszli: non-interactive, interactive, i login. loginjest dodatkową cechą pozostałych dwóch rodzajów powłok. Permutacje tych trzech elementów decydują o tym, które pliki są pobierane podczas logowania, co z kolei wpływa na sposób inicjalizacji środowiska. (zmienne, jak wspomniałeś)
Andrew B

3
@AndrewB Masz rację ... Nauczyłem się również z tego pytania. :)
Nathan C
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.