Вопрос: В чем преимущество не выделять терминал в ssh?


Время от времени я буду делать что-то вроде

ssh user@host sudo thing

и мне напомнили, что ssh по умолчанию не выделяет псевдо-tty. Почему не так? Какую пользу я бы проиграл, если бы я стал псевдонимом ssh в ssh -t?


54
2018-05-06 14:06


Источник


> Мне напомнили, что ssh не выделяет psuedo-tty Что происходит? Это обогатило бы вопрос, чтобы понять, в чем проблема. - Air
@Air Нет проблем, которые я пытался исправить. Был выбор в том, как ssh реализуется, что я пытался понять. Вопрос очень ясен, и ответ Эндрю Б отвечает на вопрос красиво. Ответ можно суммировать следующим образом: running ssh -t всегда плохо, потому что это может привести к тому, что некоторые команды сломаются странными способами. Принимая во внимание, что при выполнении команды, которая требует PTY без одного, появляется сообщение об ошибке, в котором вам нужен терминал. - Chas. Owens


Ответы:


Основное различие заключается в интерактивность, Он похож на выполнение команд локально внутри скрипта, а также набирает их самостоятельно. Другое дело в том, что удаленная команда должна выбрать по умолчанию, а неинтерактивная - самая безопасная. (и обычно самый честный)

STDIN

  • Если выделяется PTY, приложения могут обнаружить это и знать, что безопасно запрашивать у пользователя дополнительные данные, не нарушая ничего. Существует много программ, которые пропустят шаг запроса пользователя для ввода, если нет терминала, и это хорошо. Это может привести к тому, что скрипты будут в противном случае зависать.
  • Ваш вход будет отправлен на удаленный сервер на время выполнения команды. Сюда входят контрольные последовательности. Хотя Ctrl-c break обычно приводит к тому, что цикл команды ssh прерывается немедленно, ваши контрольные последовательности будут отправляться на удаленный сервер. Это приводит к необходимости «забивать» нажатие клавиши, чтобы гарантировать, что она поступит, когда управление листья команда ssh, но перед следующей командой ssh.

Я бы предостерег от использования ssh -t в автоматических сценариях, таких как коронки. Неинтерактивная оболочка, запрашивающая удаленную команду для интерактивного ввода данных, запрашивает всевозможные проблемы.

Вы также можете проверить наличие терминала в своих собственных сценариях оболочки. Чтобы проверить STDIN с более новыми версиями bash:

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

STDOUT

  • При сглаживании ssh в ssh -t, вы можете ожидать получить дополнительный возврат каретки в своих концах строки. Это может быть не видно вам, но оно есть; он будет отображаться как ^M при подаче на cat -e, Затем вы должны потратить дополнительные усилия на то, чтобы этот управляющий код не был привязан к вашим переменным, особенно если вы собираетесь вставить этот вывод в базу данных.
  • Существует также риск того, что программы предполагают, что они могут отображать вывод, который не подходит для перенаправления файлов. Обычно, если вы должны перенаправить STDOUT в файл, программа распознает, что ваш STDOUT не является терминалом и не пропускает цветовые коды. Если перенаправление STDOUT происходит от выхода клиент ssh и существует PTY, связанный с удаленным концом клиента, удаленные программы не могут сделать такое различие, и вы получите термальный мусор в своем выходном файле. Перенаправление вывода в файл на удаленный конец соединения должны по-прежнему работать должным образом.

Вот такой же тест bash, как и раньше, но для STDOUT:

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

Хотя можно обойти эти проблемы, вы неизбежно забудете разработать сценарии вокруг них. Мы все в какой-то момент. Члены вашей команды также могут не осознавать / помнить, что этот псевдоним на месте, что, в свою очередь, создает проблемы для вас, когда Oни писать сценарии, которые используют ваш псевдоним.

Aliasing ssh в ssh -t это очень важный случай, когда вы будете нарушать принцип проектирования наименее; люди будут сталкиваться с проблемами, которые они не ожидают, и могут не понимать, что их вызывает.


57
2018-05-06 15:02



Создается впечатление, что я работал над командой, которая сделала это ... - Andrew B


SSH escape-символы и передача двоичных файлов

Одно из преимуществ, которое не было упомянуто в других ответах, заключается в том, что при работе без псевдотерминала, SSH escape-символы такие как ~C находятся не поддерживается; это делает его безопасным для программ для передачи двоичных файлов, которые могут содержать эти последовательности.

Доказательство концепции

Скопируйте двоичный файл с помощью псевдотерминала:

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

Скопируйте двоичный файл без использования псевдотерминала:

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

Эти два файла не совпадают:

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

Тот, который был скопирован с псевдотерминалом, поврежден:

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

а другой - нет:

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

Перенос файлов через SSH

Это особенно важно для таких программ, как scp или rsync которые используют SSH для передачи данных. Эта подробное описание работы протокола SCP объясняет, как протокол SCP состоит из смеси текстовых сообщений протокола и двоичных файлов.


OpenSSH помогает защитить вас от себя

Стоит отметить, что даже если -t используется флаг, OpenSSH ssh клиент отказывается выделять псевдотерминал, если он обнаруживает, что его stdin поток не является терминалом:

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

Вы все равно можете заставить клиента OpenSSH выделить псевдотерминал с помощью -tt:

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

В любом случае, это (разумно) не волнует, если stdout или stderr перенаправляются:

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

22
2018-01-04 16:10



Это был очень интересный момент, который я не рассматривал, спасибо за добавление этого ответа! - Jenny D


На удаленном хосте мы имеем дело с этим параметром:

/etc/sudoers
...
Defaults requiretty

Без sudo

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

И с sudo

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

С помощью sudo мы получаем возврат дополнительной каретки

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

Решение состоит в том, чтобы отключить перевести новую строку в карету return-newline с 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



Приятно, но вывод с отступом /: вы случайно знаете, можете ли вы автоматически перевозить карету (как unix-like)? - Boop


Подумайте о обратной совместимости.

2 основных режима ssh являются интерактивными входами с tty и заданной командой без tty, поскольку это были точные возможности rlogin а также rsh соответственно. ssh необходимо для обеспечения надмножества rlogin/rsh чтобы быть успешными в качестве замены.

Таким образом, дефолты были определены до появления ssh. Комбинации типа «Я хочу указать команду а также получить tty "должен был быть доступен с новыми вариантами. Будьте рады, что по крайней мере мы иметь этот вариант теперь, в отличие от того, когда мы использовали rsh, Мы не использовали никаких полезных функций для получения зашифрованных соединений. У нас есть бонусные функции!


1
2018-05-06 17:24





Из 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.

Это позволяет вам получить «оболочку» на удаленном сервере. Для серверов, которые делают не предоставить доступ к оболочке оболочки, но разрешить SSH (т. е. Github - известный пример для доступа SFTP), использование этого флага приведет к тому, что сервер отклонит ваше соединение.

Оболочка также имеет все ваши переменные окружения (например, $PATH), поэтому выполнение скриптов обычно требует работы tty.


0
2018-05-06 14:45



Это не отвечает на вопрос. Я уже знаю, как выделить псевдо-tty. Я хочу знать, почему я не должен просто выделять его. - Chas. Owens
@ Chas.Owens Потому что, как я указал в ответе, некоторые SSH-серверы делают не разрешить доступ tty, и он отключит соединение, если вы запросите его у сервера. - Nathan C
Я думаю, что вы можете сбить с толку некоторые термины. Это не оболочка просто потому, что с ней связан PTY. Обычно существует три типа оболочки: non-interactive, interactive, а также login, login является дополнительной характеристикой двух других типов оболочек. Перестановки этих трех определяют, какие файлы используются при входе в систему, что в свою очередь влияет на то, как среда будет инициализирована. (переменные, как вы уже упоминали) - Andrew B
@AndrewB Ты прав ... Я тоже кое-что узнал из этого вопроса. :) - Nathan C