Por que o cron falha silenciosamente ao executar coisas do sudo no meu script?

30

Eu tenho um script executado a partir do crontab de usuários não privilegiados que chama alguns comandos usando sudo. Exceto que não. O script funciona bem, mas os comandos sudo'ed falham silenciosamente.

  • O script é executado perfeitamente a partir de um shell como o usuário em questão.

  • Sudo não requer uma senha. O usuário em questão tem (root) NOPASSWD: ALLacesso concedido em /etc/sudoers.

  • Cron está executando e executando o script. Adicionar um simples date > /tmp/logproduz saída no momento certo.

  • Não é um problema de permissões. Novamente, o script é executado, mas não os comandos sudo'ed.

  • Não é um problema de caminho. A execução envde dentro do script que está sendo executado mostra a $PATHvariável correta que inclui o caminho para o sudo. Executá-lo usando um caminho completo não ajuda. O comando que está sendo executado recebe o nome completo do caminho.

  • Tentar capturar a saída do comando sudo, incluindo STDERR, não mostra nada de útil. Adicionar sudo echo test 2>&1 > /tmp/logao script produz um log em branco.

  • O próprio binário sudo executa bem e reconhece que possui permissões mesmo quando executado a partir do cron dentro do script. Adicionar sudo -l > /tmp/logao script produz a saída:

    O usuário ec2-user pode executar os seguintes comandos neste host:
    (root) NOPASSWD: ALL

Examinar o código de saída do comando usando $?mostra que ele está retornando um erro (código de saída :) 1, mas nenhum erro parece ser produzido. Um comando tão simples quanto /usr/bin/sudo /bin/echo testretorna o mesmo código de erro.

O que mais poderia estar acontecendo?

Esta é uma máquina virtual criada recentemente, executando a mais recente Amazon Linux AMI. O crontab pertence ao usuário ec2-usere o arquivo sudoers é o padrão de distribuição.

Caleb
fonte
1
Eu ia falar sobre uma solução, mas depois li The user in question has (root) NOPASSWD: ALL access granted in /etc/sudoerse meu cérebro começou a gritar alto demais para continuar lendo.
Shadur
@Shadur: Fale com a mão. Essa também não é a minha maneira de configurar uma máquina, mas essas máquinas são assim que saem da caixa. Mesmo que a máquina seja sua, você não recebe uma senha root, sua chave como o proprietário da caixa entra na conta de usuário ec2 que possui (como observado) acesso total ao sudo. Você não recebe uma senha para o usuário ec2, a menos que você defina uma, é um login apenas com chave.
Caleb
1
Em seguida, a primeira coisa que eu recomendo que você faça é configurar um usuário separado com sudodireitos restritos / somente / para os comandos necessários no script e desativar completamente a capacidade de logon.
Shadur
se você possui root e deseja que o trabalho cron seja executado como root, por que colocá-lo no crontab do usuário ec2? o crontab da raiz não seria mais apropriado? ou / etc / crontab?
cas
@ CraigSanders: Eu não quero que o trabalho cron seja executado como root; na verdade, a maioria deve ser executada como usuário. A questão não é sobre a execução de um trabalho como root, mas sobre um script que tenha acesso especial a uma função através do sudo.
Caleb

Respostas:

40

O Sudo tem algumas opções especiais em seu arquivo de permissões, uma das quais permite uma restrição de uso para os shells que estão sendo executados dentro de um TTY, o que o cron não.

Algumas distribuições, incluindo a Amazon Linux AMI, têm isso ativado por padrão. O /etc/sudoersarquivo terá a seguinte aparência:

# 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

Se você capturasse a saída para STDERR no nível do script shell, em vez do próprio comando sudo, você teria uma mensagem parecida com esta:

desculpe, você deve ter um tty para executar o sudo

A solução é permitir que o sudo seja executado em ambientes não TTY removendo ou comentando estas opções:

#Defaults    requiretty
#Defaults   !visiblepw
Caleb
fonte
1
Posso confirmar que o CentOS possui essas restrições em vigor.
aeu 12/08
Parece que o requiretty foi adicionado no CentOS 7, portanto, embora isso não fosse necessário no CentOS 6, é no CentOS 7+. Na minha experiência, os comandos sudo do cron funcionam no CentOS 6, mesmo que Defaults !visiblepwesteja ativado / não comentado.
kevinmicke