Подтвердить что ты не робот

Команда "su" в Docker возвращает "должна быть запущена из терминала"

Я разрабатываю среду докеров для обучения и должен иметь возможность переключать пользователей внутри докеров.

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

Я получаю это, если я пытаюсь выполнить ssh в докер, а также выдавая команды через php-оболочку (служба apache выполняется на экземпляре Docker).

Любая помощь очень ценится.

4b9b3361

Ответ 1

Когда вы заходите или проходите через php, ваш сеанс не выделяется pty. Я использовал каждое из следующих решений:

ANSWER 1: используйте ssh -t или ssh -tt, чтобы получить pty при входе в систему, используя ssh:

Мне было очень весело получать команды для запуска справа из-за pty при выполнении таких сеансов: jenkins shell → ssh driver → ssh test → docker exec. Хороший ответ здесь: https://unix.stackexchange.com/questions/105422/command-must-be-run-from-a-terminal

"Попробуйте параметр -t для ssh. Если это не работает, попробуйте -tt."

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

ANSWER 2: использовать docker run -t... и docker exec -it

Используйте параметры -t и -it для размещения pty в сеансе exec docker.

Также с помощью docker exec вы можете просто использовать опцию -u для входа в контейнер в качестве разных пользователей и избегать использования su. например

$ docker exec -u root -it small_hypatia bash

Здесь есть хороший вопрос и ответ: https://github.com/docker/docker/issues/8631

ANSWER 3: используйте python для создания pty в вашей оболочке

Довольно милый взлом:)

[email protected]:~$ su -
su: must be run from a terminal

$ echo "import pty; pty.spawn('/bin/bash')" > /tmp/asdf.py
$ python /tmp/asdf.py

$ su -
Password: 

[email protected]:~# 

Ответ 2

Это решение работает с помощью команды "script" из пакета "bsdutiles", который устанавливает pty (терминал). Команда "sleep" предназначена для предотвращения отправки пароля до того, как команда "su" готова к чтению. Команда "tail" удаляет входную строку "Пароль:", выданную "su".

 sh -c "sleep 1; echo rootpassword" | script -qc 'su -c whoami - root' | tail -n +2

Помните, что rootpassword можно увидеть разными способами (история, ps,/proc/и т.д.). Запустите команду с пространством, чтобы избежать записи истории.

Ответ 3

Если вы используете su-exec вместо su, проблема с tty полностью исчезает, поскольку она вызывает execvp напрямую, а не forking как su делает.

Gosu - еще одна аналогичная альтернатива.