Зачем мне tty запускать sudo, если я могу sudo без пароля?

Я настроил sudo для запуска без пароля, но когда я пытаюсь выполнить ssh 'sudo Foo', я все равно получаю сообщение об ошибке sudo: sorry , вы должны иметь tty для запуска sudo.

Почему это происходит и как я могу обойти его?

202 голоса | спросил merlin2011 1 PMpTue, 01 Apr 2014 23:12:55 +040012Tuesday 2014, 23:12:55

6 ответов


269

Вероятно, потому, что ваш файл /etc /sudoers (или любой файл, который он содержит) имеет:

Defaults requiretty

..., в результате чего sudo требуется TTY. Известно, что для систем Red Hat (RHEL, Fedora ...) требуется TTY в файле sudoers по умолчанию. Это не обеспечивает реальной безопасности и может быть безопасно удалено.

Red Hat подтвердила проблему и будет удалена в будущих версиях .

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

-tt предназначен для интерактивного использования. Он помещает локальный терминал в режим raw, чтобы вы взаимодействовали с удаленным терминалом. Это означает, что если ssh ввода /вывода не принадлежит /к терминалу, это будет иметь побочные эффекты. Например, все входные данные будут отозваны обратно, специальные символы терминала (^? , ^ C, ^ U)) вызовут специальную обработку; на выходе LF s будет преобразован в CRLF s ... (см. этот ответ на Зачем этот бинарный файл изменен? для более подробной информации.

Чтобы свести к минимуму воздействие, вы можете вызвать его как:

ssh -tt host 'stty raw -echo; sudo ... '<& Л; (кат)

<<(cat) будет избегать установки локального терминала (если есть) в режиме raw. И мы используем stty raw -echo, чтобы установить линейную дисциплину удаленного терминала как пропускную (фактически так, чтобы вести себя как канал, который будет использоваться вместо псевдотерминала без -tt, хотя это применяется только после выполнения этой команды, поэтому вам нужно отложить отправку чего-либо для ввода до тех пор, пока это не произойдет).

Обратите внимание, что поскольку выход удаленной команды перейдет к терминалу, это все равно повлияет на его буферизацию (которая будет линейной для многих приложений) и эффективность полосы пропускания, поскольку TCP_NODELAY включен. Также с -tt, ssh устанавливает IPQoS в lowdelay в отличие от пропускной способности. Вы можете обойти оба с помощью:

ssh -o IPQoS = пропускная способность -tt host 'stty raw -echo; sudo cmd | cat <& Л; (кат)

Также обратите внимание, что это означает, что удаленная команда не может обнаружить конец файла на своем stdin, а stdout и stderr удаленной команды объединяются в один поток.

Итак, не очень хорошая работа в конце концов.

Если у вас есть способ создать псевдотерминал на удаленном хосте (например, с помощью expect, zsh, socat , perl 'IO :: Pty ...), тогда было бы лучше использовать это для создания псевдотерминала для присоединения sudo to (но не для ввода-вывода) и используйте ssh без -t.

Например, при expect:

ssh host 'expect -c "spawn -noecho sh -c {
     exec sudo cmd> 4 2 & 5 & 6> & -> & - <& -}
 exit [lindex [wait] 3] "4 & 1> & 2 <& 0 '

Или с помощью script (здесь предполагается реализация из util-linux):

ssh host 'SHELL = /bin /sh script -qec "
              sudo cmd & & amp; 4> & 5 <& & amp; & amp; -> &
            "/dev /null 3 <& 0> <1> & 2 '

(предполагая (для обоих), что оболочка входа удаленного пользователя похожа на Bourne).

ответил Stéphane Chazelas 2 AMpWed, 02 Apr 2014 00:32:00 +040032Wednesday 2014, 00:32:00
25

По умолчанию SUDO настроен на требование TTY. То есть ожидается, что SUDO будет запущен из оболочки входа. Вы можете победить это требование, добавив переключатель -t к вашему вызову SSH:

ssh -t someserver sudo somecommand

-t принудительно выделяет псевдо-tty.

Если вы хотите выполнить это глобально, измените /etc /sudoers, чтобы указать ! requiretty. Это может быть сделано для каждого пользователя, на группу или всеохватывающий уровень.

ответил JRFerguson 1 PMpTue, 01 Apr 2014 23:25:43 +040025Tuesday 2014, 23:25:43
16

Используйте флаг -t для ssh, чтобы принудительно выделить tty.

$ ssh luci tty
не tty
$ ssh luci -t tty
/DEV /ttys003
$
ответил Kyle Jones 1 PMpTue, 01 Apr 2014 23:23:31 +040023Tuesday 2014, 23:23:31
10

Я столкнулся с этой проблемой, используя 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-агент /~ /dockerfile

ответил Martin Tapp 21 MarpmMon, 21 Mar 2016 16:07:29 +03002016-03-21T16:07:29+03:0004 2016, 16:07:29
1

Интересной альтернативой является запуск FreeIPA или IdM для управления пользователями и правилами sudoer централизованно. Затем вы можете создать правила sudo и назначить опцию

! Requiretty

в правиле. Затем команда будет выполняться, как ожидалось. У вас также будут преимущества управления всеми серверами и пользователями из одного набора конфигураций.

ответил strtluge 6 J0000006Europe/Moscow 2016, 05:41:35
-1

Я нашел этот вопрос, в то время как мы с Гуглинг и я столкнулись с этой ошибкой по совершенно другой причине.

Мое решение состояло в том, чтобы перестать вызывать сценарии оболочки ниже, как sudo из моего родительского сценария оболочки, когда сценарий родительской оболочки уже был вызван с помощью sudo.

ответил entpnerd 13 12017vEurope/Moscow11bEurope/MoscowMon, 13 Nov 2017 22:58:12 +0300 2017, 22:58:12

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132