Запустить скрипт как другой пользователь из корневого скрипта без tty stdin

Используя CentOs, я хочу запустить скрипт как "обучение" пользователя как системный сервис. Я использую daemontools для мониторинга процесса, для которого нужен скрипт запуска, запускаемый от имени root и не имеющий стандарта tty.

Ниже я приведу пять разных попыток, которые все провалились.

  1. :

    #!/bin/bash
    exec >> /var/log/training_service.log 2>&1
    setuidgid training training_command
    

    Эта последняя строка недостаточно хороша, так как для training_command нам нужна среда для настройки trqaining пользователя.

  2. :

    su - training -c 'training_command' 
    

    Это выглядит так ( Запустите скрипт оболочки от имени другого пользователя), но выдает:standard in must be tty'убедившись, что tty присутствует, чтобы принять пароль. Я знаю, что могу сделать это, изменив /etc/sudoers (а-ля https://superuser.com/questions/119376/bash-su-script-giving-an-error-standard-in-must-be-a-tty) но я неохотно и не уверен в последствиях.

  3. :

    sudo -u training -i bash -c 'source $HOME/.bashrc; training_command'
    

    Вариация на ту же тему:sudo: sorry, you must have a tty to run sudo'

  4. :

    runuser - training -c 'training_command'  
    

    Этот дает runuser: cannot set groups: Connection refused, Я не нашел смысла или разрешения этой ошибки.

  5. :

    ssh -p100 training@localhost 'source $HOME/.bashrc; training_command'
    

    Это больше шутка, чтобы показать отчаяние. Даже этот не с Host key verification failed. (ключ хоста находится в known_hosts и т. д.).

Примечание: все 2,3,4 работают должным образом, если я запускаю скрипт-обертку из корневой оболочки. проблемы возникают только в том случае, если монитор системного сервиса (daemontools) запускает его (нет терминала tty, я думаю).

Я застрял. Это так трудно достичь?

Я ценю все понимание и руководство для наилучшей практики.

(это также было опубликовано на суперпользователя: https://superuser.com/questions/434235/script-calling-script-as-other-user)

8 ответов

Вам нужно будет отключить requiretty установка в /etc/sudoers за root, Добавьте следующую строку через visudo:

Defaults:root !requiretty

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

root ALL=(ALL) ALL

Тогда вы можете сделать следующее:

sudo -u training /path/to/training_command

По-видимому, это, по сути, частный случай этого вопроса; мы можем использовать script -c подделать Tty. Единственная проблема в том, что я не могу заставить этот трюк работать напрямую с su по какой-то причине и sudo немного некрасиво, если вы действительно должны исходить ~/.bashrc до training_command, Пытаться:

echo password | script -c "sudo su - training -c training_command" 

Запустите вашу команду с SSH.

  1. сделать конфигурацию ключа SSH для входа без пароля для другого пользователя. Вот учебник для этой цели: https://www.digitalocean.com/community/tutorials/how-to-set-up-ssh-keys--2

  2. Запустите команду с помощью команды ssh: ssh -l training -i key_file "training_command"

Плагиат мой ответ здесь: Запуск сценария от имени другого пользователя

Вы можете использовать start-stop-daemon что-то вроде этого:

/sbin/start-stop-daemon --background --start --exec /path/to/training.sh --user training --pidfile=/path/to/training.pid --make-pidfile

где training.sh примерно так:

#!/bin/sh
exec >> /var/log/training_service.log 2>&1
source /home/training/.bashrc
training_command

Под SSH вы можете запустить команду foo.sh у обычного пользователя:

$ ssh [email protected] bash /path/to/foo.sh

если один из foo.shКоманде нужны права суперпользователя, например, netstatоберните это внутри su команда как это (заменить оригинал netstat -tunple):

su -c "netstat -tunpl" root

и беги foo.sh как это:

$ ssh -t [email protected] bash /path/to/foo.sh

Это предложит пароль для буксировки, первый для normal_user, а второй для root,

Выберите первый и установите необходимые переменные среды.

Если вы уже используете daemontools, вы не создаете и не связываетесь с файлами журналов вручную. Daemontools делает эту работу за вас.

Это скрипт для запуска приложения

#!/bin/bash
exec 2>&1
exec setuidgid training sh -c 'YOURVARIABLE=yourvalue exec training_command'

Затем вы создаете log сценарий запуска каталога со своим собственным сценарием выполнения.

Обратитесь к этой записи для настройки журнала: http://cr.yp.to/daemontools/faq/create.html

Классика (простые команды)

su user -c "commands" 

Выполните команды для указанного пользователя, НО это не заботится о переменной окружения, которая особенно необходима, если ваши команды воспроизводят звук или запускают графический интерфейс.

Advanced (для звука, графического интерфейса и т. Д.)

su user -c "export DISPLAY=:0; export XDG_RUNTIME_DIR='/run/user/1000'; xhost local:root; commands" 

Замените использованное значение в соответствии с вашим целевым пользователем

Попробуй это:

#!/bin/bash
sudo -u training training_command > /var/log/training_service.log 2>&1

Если это не помогло, пожалуйста, опубликуйте вывод /var/log/training_service.log.

Другие вопросы по тегам