Я настроил sudo
запуск без пароля, но при попытке ssh 'sudo Foo'
все равно получаю сообщение об ошибке sudo: sorry, you must have a tty to run sudo
.
Почему это происходит и как я могу обойти это?
Это, вероятно, потому что ваш /etc/sudoers
файл (или любой файл, который он включает) имеет:
Defaults requiretty
... что sudo
требует TTY. Известно, что для систем Red Hat (RHEL, Fedora ...) требуется sudoers
файл TTY в файле по умолчанию . Это не дает никакой реальной выгоды для безопасности и может быть безопасно удалено.
Red Hat признала проблему, и она будет устранена в следующих выпусках.
Если изменение конфигурации сервера не является опцией, в качестве обходного пути для этой неправильной конфигурации, вы можете использовать опции -t
или -tt
, к ssh
которым порождается псевдотерминал на удаленной стороне, но остерегайтесь, что у него есть ряд сторон последствия.
-tt
предназначен для интерактивного использования. Он переводит локальный терминал в raw
режим, позволяющий взаимодействовать с удаленным терминалом. Это означает, что если ssh
ввод / вывод не от / к терминалу, это будет иметь побочные эффекты. Так , например, все входные будет эхом, специальные символы (терминальные ^?
, ^C
, ^U
) будет вызывать специальная обработка; на выходе LF
s будет преобразован в CRLF
s ... (см. ответ на вопрос « Почему изменяется этот двоичный файл?») .
Чтобы свести к минимуму влияние, вы можете вызвать его как:
ssh -tt host 'stty raw -echo; sudo ...' < <(cat)
< <(cat)
Позволит избежать настройки локального терминала (если таковые имеются) в raw
режиме. И мы используем, stty raw -echo
чтобы установить дисциплину линии удаленного терминала как проходной (по сути, он ведет себя как канал, который будет использоваться вместо псевдотерминала без него -tt
, хотя это применимо только после запуска этой команды, поэтому вам нужно отложить отправку чего-либо для ввода, пока это не произойдет).
Обратите внимание, что, поскольку выходные данные удаленной команды поступят в терминал, это все равно повлияет на его буферизацию (которая будет основываться на линиях для многих приложений) и эффективность использования полосы пропускания, поскольку TCP_NODELAY
она включена. Также с -tt
, ssh
устанавливает IPQoS lowdelay
в отличие от throughput
. Вы можете обойти оба с:
ssh -o IPQoS=throughput -tt host 'stty raw -echo; sudo cmd | cat' < <(cat)
Кроме того, обратите внимание, что это означает, что удаленная команда не может обнаружить конец файла в своем stdin, а stdout и stderr удаленной команды объединены в один поток.
Так что, не очень хорошая работа в конце концов.
Если у Вас есть есть способ нереста псевдо-терминал на удаленном хосте (например , с expect
, zsh
, socat
, perl
«s IO::Pty
...), то было бы лучше использовать, чтобы создать псевдо-терминал для присоединения sudo
(но не для ввода / вывода), а ssh
без использования -t
.
Например, с expect
:
ssh host 'expect -c "spawn -noecho sh -c {
exec sudo cmd >&4 2>&5 <&6 4>&- 5>&- 6<&-}
exit [lindex [wait] 3]" 4>&1 5>&2 6<&0'
Или с помощью script
(здесь предполагается реализация из util-linux
):
ssh host 'SHELL=/bin/sh script -qec "
sudo cmd <&3 >&4 2>&5 3<&- 4>&- 5>&-
" /dev/null 3<&0 4>&1 5>&2'
(при условии (для обоих), что оболочка входа удаленного пользователя похожа на Bourne).
По умолчанию SUDO настроен на использование TTY. То есть SUDO должен запускаться из оболочки входа в систему. Вы можете отменить это требование, добавив -t
переключатель в ваш вызов SSH:
ssh -t someserver sudo somecommand
Распределение -t
сил псевдо-тты.
Если вы хотите выполнить это глобально, измените, /etc/sudoers
чтобы указать !requiretty
. Это может быть сделано для каждого пользователя, группы или всеобъемлющего уровня.
requiretty
по умолчанию sudoers. Это будет исправлено в более новых выпускахИспользуйте
-t
флагssh
для принудительного распределения tty.источник
-t
чтобы заставить распределение, когдаPseudo-terminal will not be allocated because stdin is not a terminal.
Я столкнулся с этой проблемой, используя Docker и Centos 7. В итоге я сделал следующее:
yum install -y sudo
sed -i -e 's/Defaults requiretty.*/ #Defaults requiretty/g' /etc/sudoers
Я нашел этот взлом на https://hub.docker.com/r/liubin/fluentd-agent/~/dockerfile
источник
Интересной альтернативой является запуск FreeIPA или IdM для централизованного управления пользователями и правилами sudoer. Затем вы можете создать правила sudo и назначить опцию
! requiretty
в правиле. Команда будет запущена, как ожидается. Вы также будете иметь преимущества управления всеми серверами и пользователями из единого набора конфигураций.
источник
Я была такая же проблема. В моем случае решение состояло из двух строк
Объяснение:
Поместите команды, которые вы хотите запустить (включая команды sudo) в скрипт, например "ssh_test.sh".
Прочитайте весь сценарий в переменную с именем «myscript».
Вызовите ssh только с одним ключом -t и передайте переменную вместо команды.
До этого я сталкивался с проблемами при использовании комбинаций чтения из стандартного ввода и использования heredocs
источник
Я нашел этот вопрос, в то время как Google, и я столкнулся с этой ошибкой по совершенно другой причине.
Мое исправление состояло в том, чтобы прекратить вызывать сценарии оболочки ниже по потоку, как
sudo
из моего родительского сценария оболочки, когда родительский сценарий оболочки уже был вызван сsudo
.источник