为什么crond无法在alpine linux上运行非root crontab?

时间:2017-07-05 19:46:04

标签: linux docker cron alpine

我在Alpine Linux上运行非root crontab文件时感到讨厌。

我已经通过其他两个与cron相关的帖子而且我没有答案:

https://askubuntu.com/questions/23009/why-crontab-scripts-are-not-working

https://serverfault.com/questions/449651/why-is-my-crontab-not-working-and-how-can-i-troubleshoot-it

这是设置。

我的crontab看起来像这样:

FROM alpine:3.5

# DEPENDENCY TO ALLOW USERS TO RUN crontab -e
RUN apk add --update busybox-suid

# I LIKE BASH
RUN apk --no-cache add bash bash-doc
RUN apk --no-cache add util-linux pciutils usbutils coreutils binutils findutils grep

#... lots of custom stuff ...    

# CREATE USER
RUN adduser -S robuser && \
    mkdir -p /home/robuser

# ADD ENTRY POINT
ADD src/entrypoint.sh /home/robuser/entrypoint.sh

# GIVE MY USER ACCESS
RUN mkdir /etc/cron.d
RUN echo "robuser" > /etc/cron.allow
RUN echo "" >> /etc/cron.allow
RUN chmod -R 644 /etc/cron.d

# ADD MY CRONTAB
RUN mkdir -p /var/spool/cron/crontabs
ADD ./src/crontab.conf /tmp/cloudwatch/crontab.conf
RUN crontab -u robuser /tmp/cloudwatch/crontab.conf

# DEBUG... GIVE MY USER ACCESS TO EVERYTHING
RUN chown -R robuser /etc/cron.d
RUN chmod -R 755 /etc/cron.d
RUN chown -R robuser /var/spool/cron
RUN chmod -R 744 /var/spool/cron
RUN chown robuser /var/spool/cron/crontabs
RUN chmod 744 /var/spool/cron/crontabs
RUN chown -R robuser /etc/crontabs
RUN chmod -R 744 /etc/crontabs
RUN chown robuser /etc/crontabs/robuser
RUN chmod -R 744 /etc/crontabs/robuser
RUN chmod 600 /var/spool/cron/crontabs/robuser

# ADD MY MONITORING PROGRAM
RUN mkdir -p /opt/monitor
ADD src/monitor /opt/monitor
RUN mkdir -p /opt/monitor/.tmp && \
    chown -R robuser /opt/monitor && \
    chmod -R 700 /opt/monitor

RUN touch /var/log/entrypoint.log && \
    touch /var/log/monitor.log && \
    touch /var/log/cron.log && \
    touch /var/log/awslogs.log && \
    chown -R robuser /var/log

USER robuser

ENTRYPOINT /home/robuser/entrypoint.sh

我的Dockerfile现在有点乱,但只是因为我一直在拼命想解决这个问题。它看起来像这样。简而言之,我为crontab -e添加SUID以作为其他用户工作,我创建我的用户,导入我的crontab文件,然后我提供我能想到的所有权限。

#!/bin/bash

crond -b -l 0 -L /var/log/cron.log

#... lots of other startup stuff ...

同时,我的entrypoint.sh在其中的某个地方。我将cron守护进程作为后台服务启动并详细登录到cron.log。我也试过指定-d 0来获得更多的调试,但是没有真正为输出添加任何东西。

crond: crond (busybox 1.25.1) started, log level 0
crond: wakeup dt=45
crond: wakeup dt=60
crond: wakeup dt=60

重点:如果我没有切换到 robuser ,那么一切都可以正常工作

如果我查看 cron.log ,它就是空的:

PATH=/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/opt/aws/bin:/home/ec2-user/bin
SHELL=/bin/bash

* * * * * touch /tmp/test.txt

同时,/ var / log / monitor.log完全为空(请参阅帖子开头的crontab)。

所以crond没有打印任何错误。

我已经尝试了所有我能想到的调试方法。没有错误消息。它只是运行,从不打印。一个很好的建议只是我的crontab ..但这也没有用:

#!/usr/bin/python
#!/usr/bin/python2.3
#!/usr/bin/python2.4
#!c:\Python24\python.exe
#!c:\Python25\python.exe

我已经尝试过寻找其他使用非根cron的高山容器,但是大多数人都没有经历让他们的高山容器无法运行的麻烦。

有没有人有任何进一步的建议来帮助调试这个?

2 个答案:

答案 0 :(得分:1)

无论您要使用哪个用户来运行作业,

cron本身都应该以{{1​​}}运行。

确实,当你跑步时:

root

这将为用户RUN crontab -u robuser /tmp/cloudwatch/crontab.conf 安装crontab。当robuser执行来自此特定cron的作业时,它会自动将用户切换为crontab但是,robuser如果用户未按cron运行,则无法切换此类用户,这就是您需要以root身份运行root的原因。

因此,要使cron在此工作,您需要从Dockerfile中删除此指令:

cron

请注意,一旦解决了这个问题,您可能无法摆脱困境:如果您正在使用环境变量将AWS凭据传递给监控脚本(您似乎正在使用AWS这不会起作用,因为USER robuser 会在切换用户之前将其删除。这主要是cron中的一项安全功能,可以避免向非特权用户泄露环境变量。

顺便说一句:我写了一个开源的crontab运行程序Supercronic,专门为容器用例而设计,它修复了这个问题(你可以像非特权用户一样运行它)。如果你对常规cron感到沮丧,你总是可以试一试。

答案 1 :(得分:0)

将修补程序编码为以非root身份运行crond,基本上crond是在busybox代码库中实现的,它调用了函数“ change_identity”,该函数调用syscall setgroups(通常需要linux CAP_SETGID功能)来切换将工作特权转换为普通用户/组特权,与​​用户的工作相同,因此crond进程必须以root用户身份运行,相反,我对docker选项--cap-add setgid并没有感到失望

我将打补丁的高山推到docker hub上

geekidea/alpine-cron:3.7
geekidea/alpine-cron:3.8
geekidea/alpine-cron:3.9

一个示例dockerfile:

FROM geekidea/alpine-cron:3.9
RUN mkdir /tmp/crontabs \
    && echo 'SHELL=/bin/sh' > /tmp/crontabs/nobody \
    && echo '* * * * * /tmp/nobody.sh' >> /tmp/crontabs/nobody \
    && echo 'echo "$(date) blahblahblah nobody" >> /tmp/nb-cron.log' > /tmp/nobody.sh \
    && chmod 0755 /tmp/nobody.sh \
    && chown -R nobody.nobody /tmp/crontabs/nobody

USER nobody
CMD ["crond", "-c", "/tmp/crontabs", "-l", "0", "-d", "0", "-f"]

查看更多:https://github.com/inter169/systs/blob/master/alpine/crond/README.md