Pourquoi cron échoue-t-il silencieusement à exécuter des trucs sudo dans mon script?

30

J'ai un script exécuté à partir de la crontab d'un utilisateur non privilégié qui appelle certaines commandes à l'aide sudo. Sauf que non. Le script s'exécute correctement mais les commandes sudo'ed échouent silencieusement.

  • Le script fonctionne parfaitement à partir d'un shell en tant qu'utilisateur en question.

  • Sudo n'a pas besoin de mot de passe. L'utilisateur en question dispose d'un (root) NOPASSWD: ALLaccès autorisé dans /etc/sudoers.

  • Cron exécute et exécute le script. L'ajout d'une date > /tmp/logsortie simple produit au bon moment.

  • Ce n'est pas un problème d'autorisations. Encore une fois, le script est exécuté, mais pas les commandes sudo'ed.

  • Ce n'est pas un problème de chemin. L'exécution envdepuis l'intérieur du script en cours d'exécution affiche la $PATHvariable correcte qui inclut le chemin vers sudo. L'exécuter en utilisant un chemin complet n'aide pas. La commande en cours d'exécution reçoit le nom de chemin complet.

  • Essayer de capturer la sortie de la commande sudo, y compris STDERR, n'affiche rien d'utile. L'ajout sudo echo test 2>&1 > /tmp/logau script produit un journal vide.

  • Le binaire sudo lui-même s'exécute correctement et reconnaît qu'il dispose d'autorisations même lorsqu'il est exécuté à partir de cron à l'intérieur du script. L'ajout sudo -l > /tmp/logau script produit la sortie:

    L'utilisateur ec2-user peut exécuter les commandes suivantes sur cet hôte:
    (root) NOPASSWD: ALL

L'examen du code de sortie de la commande à l'aide $?montre qu'elle renvoie une erreur (code de sortie:) 1, mais aucune erreur ne semble se produire. Une commande aussi simple que /usr/bin/sudo /bin/echo testrenvoie le même code d'erreur.

Que pourrait-il se passer d'autre?

Il s'agit d'une machine virtuelle récemment créée exécutant la dernière AMI Amazon Linux. La crontab appartient à l'utilisateur ec2-useret le fichier sudoers est la distribution par défaut.

Caleb
la source
1
J'allais parler d'une solution mais ensuite j'ai lu The user in question has (root) NOPASSWD: ALL access granted in /etc/sudoerset mon cerveau a commencé à crier trop fort pour continuer à lire.
Shadur
@Shadur: Parlez à la main. Ce n'est pas ma façon de configurer une machine non plus, mais ces machines sortent de cette boîte. Même si la machine est à vous, vous n'obtenez pas de mot de passe root, votre clé en tant que propriétaire de la boîte va dans le compte utilisateur ec2 qui a (comme indiqué) un accès sudo complet. Vous n'obtenez pas non plus de mot de passe pour ec2-user, sauf si vous en avez défini un, il s'agit uniquement d'une clé de connexion.
Caleb
1
Ensuite, la première chose que je vous recommanderais de faire est de configurer un utilisateur distinct avec des sudodroits restreints / uniquement / pour les commandes dont vous avez besoin dans le script et de désactiver complètement leur capacité de connexion.
Shadur
si vous avez root et que vous voulez que le travail cron s'exécute en tant que root, alors pourquoi le mettre dans la crontab d'ec2-user? le crontab de root ne serait-il pas plus approprié? ou / etc / crontab?
cas
@CraigSanders: Je ne veux pas que le travail cron soit exécuté en tant que root, en fait, la plupart devrait être exécuté en tant qu'utilisateur. La question n'est pas d'exécuter un travail en tant que root, mais d'un script ayant spécialement accès à une fonction via sudo.
Caleb

Réponses:

40

Sudo a des options spéciales dans son fichier d'autorisations, dont l'une permet une restriction de son utilisation aux shells qui s'exécutent à l'intérieur d'un ATS, ce qui n'est pas le cas.

Certaines distributions, y compris l'AMI Amazon Linux, ont cette option activée par défaut. Le /etc/sudoersfichier ressemblera à ceci:

# 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

Si vous aviez capturé la sortie vers STDERR au niveau du script shell plutôt que la commande sudo elle-même, vous auriez semblé un message quelque chose comme ceci:

désolé, vous devez avoir un tty pour exécuter sudo

La solution consiste à permettre à sudo de s'exécuter dans des environnements non TTY en supprimant ou en commentant ces options:

#Defaults    requiretty
#Defaults   !visiblepw
Caleb
la source
1
Je peux confirmer que CentOS a ces restrictions en place.
aeu
Il semble que requireetty ait été ajouté dans CentOS 7, donc bien que cela n'ait pas été nécessaire avec CentOS 6, c'est avec CentOS 7+. D'après mon expérience, les commandes sudo du cron fonctionnent sur CentOS 6 même si le Defaults !visiblepwest activé / non commenté.
kevinmicke