Почему cron молча не запускает sudo в моем скрипте?

30

У меня есть скрипт, запускаемый из crontab непривилегированных пользователей, который вызывает некоторые команды, используя sudo. За исключением того, что это не так. Скрипт работает нормально, но команды sudo'а молча терпят неудачу.

  • Скрипт отлично запускается из оболочки как пользователь, о котором идет речь.

  • Sudo не требует пароля. У данного пользователя есть (root) NOPASSWD: ALLдоступ, предоставленный в /etc/sudoers.

  • Cron запускает и выполняет скрипт. Добавление простого date > /tmp/logпроизводит вывод в нужное время.

  • Это не проблема с разрешениями. Снова выполняется скрипт, но не команды sudo.

  • Это не проблема пути. Запуск envизнутри запускаемого скрипта показывает правильную $PATHпеременную, которая включает путь к sudo. Запуск по полному пути не помогает. Выполняемой команде дается полный путь.

  • Попытка перехватить вывод команды sudo, включая STDERR, не дает ничего полезного. Добавление sudo echo test 2>&1 > /tmp/logв скрипт приводит к пустому логу.

  • Сам двоичный файл sudo выполняется нормально и распознает, что у него есть разрешения, даже если он запускается из cron внутри скрипта. Добавление sudo -l > /tmp/logк сценарию приводит к выводу:

    Пользователь ec2-пользователь может запускать следующие команды на этом хосте:
    (root) NOPASSWD: ALL

Изучение кода завершения команды с использованием $?показывает, что она возвращает ошибку (код выхода:) 1, но, похоже, ошибки не возникает. Такая простая команда /usr/bin/sudo /bin/echo testвозвращает тот же код ошибки.

Что еще может происходить?

Это недавно созданная виртуальная машина с последней версией Amazon Linux AMI. Crontab принадлежит пользователю, ec2-userа файл sudoers является дистрибутивом по умолчанию.

Калеб
источник
1
Я собирался поговорить о решении, но потом я прочитал, The user in question has (root) NOPASSWD: ALL access granted in /etc/sudoersи мой мозг начал кричать слишком громко, чтобы продолжать читать.
Шадур
@Shadur: поговорите с рукой. Это не мой способ настройки машины, но эти машины выходят из коробки. Даже если машина принадлежит вам, вы не получите пароль root, ваш ключ как владелец ящика входит в учетную запись пользователя ec2, которая имеет (как уже было отмечено) полный доступ sudo. Вы также не получите пароль для пользователя ec2, если только вы его не установите, это только ключ входа в систему.
Калеб
1
Тогда первое, что я бы порекомендовал вам сделать, - это настроить отдельного пользователя с ограниченными sudoправами / только / для команд, которые вам нужны в сценарии, и полностью отключить его возможность входа в систему.
Шадур
если у вас есть root и вы хотите, чтобы задание cron запускалось от имени root, то зачем помещать его в crontab пользователя ec2? не будет ли уместнее crontab от root? или / etc / crontab?
Cas
@CraigSanders: я не хочу, чтобы задание cron запускалось от имени пользователя root, на самом деле большая его часть должна выполняться от имени пользователя. Вопрос не в том, чтобы запустить задание от имени пользователя root, а в том, что скрипт имеет специальный доступ к одной функции через sudo.
Калеб

Ответы:

40

В файле разрешений Sudo есть несколько специальных опций, одна из которых позволяет ограничить его использование для оболочек, которые работают внутри TTY, а cron - нет.

В некоторых дистрибутивах, включая Amazon Linux AMI, эта опция включена по умолчанию. /etc/sudoersФайл будет выглядеть следующим образом :

# Disable "ssh hostname sudo <cmd>", because it will show the password in clear.
#         You have to run "ssh -t hostname sudo <cmd>".
#
Defaults    requiretty

#
# Refuse to run if unable to disable echo on the tty. This setting should also be
# changed in order to be able to use sudo without a tty. See requiretty above.
#
Defaults   !visiblepw

Если бы вы захватили вывод в STDERR на уровне сценария оболочки, а не самой команды sudo, вы бы выглядели примерно так:

извини, ты должен иметь tty для запуска sudo

Решение состоит в том, чтобы разрешить выполнение sudo в средах без TTY, удалив или закомментировав эти параметры:

#Defaults    requiretty
#Defaults   !visiblepw
Калеб
источник
1
Я могу подтвердить, что CentOS действительно имеет эти ограничения.
AEU
Похоже, что requiretty была добавлена ​​в CentOS 7, поэтому в CentOS 6 этого не требовалось, но в CentOS 7+. По моему опыту, команды sudo из cron работают на CentOS 6, даже если они Defaults !visiblepwвключены / не закомментированы.
Кевинмике