问题是:我有一个脚本定期通过cron 作为root运行 ,但是我想通过网页给人们一种asynchronous启动的方式。 (脚本将被写入,以确保它不会运行重叠的实例等。)
我不需要用户login或有一个帐户,他们只需点击一个button,如果脚本准备好运行它将运行。 用户可以为脚本select参数(大量过滤为input),但为了简单起见,我们会说他们只是有button来select按下。
作为一个简单的testing,我已经在cgi-bin中创build了一个Python脚本。 将它chown到root:root,然后将“chmod ug +”应用到它没有得到所需的结果:它仍然认为它有Web服务器帐户的有效组…从我可以告诉这不是允许。
我读过用一个编译好的cgi程序包装它会做这个工作,所以我创build了一个调用我的脚本(它的权限恢复正常)的C包装器,并给了可执行文件根权限和setuid位。 这工作…脚本运行,就像根运行它。
我的主要问题是,这是正常的(需要二进制包装完成工作),这是做到这一点的安全方式? 这不是面向世界的,但我仍然想学习最佳实践。
更广泛地说,我经常想知道为什么编译后的二进制文件在实践中比脚本更“可信”呢? 我想你会相信一个文件是一个神秘的二进制可读的文件。 如果攻击者可以编辑一个文件,那么你已经遇到了麻烦,如果是一个你不能轻易检查的文件。 简而言之,我希望这是在这个基础上的另一种方式。 你的想法?
首先:不要这样做,或者至less不要让任何参数从Web传递到根运行的应用程序。
现在到你的实际问题:当你写一个脚本(在你的情况下,Python),它被解释器执行。 所以为了能够以root身份运行脚本,您需要设置python解释器suid-root,但是您确实不希望这样做。 这是因为你的脚本不是可执行文件,而只是解释器的一套规则。 当你用二进制可执行文件包装你的脚本时,你现在再次拥有一个获得root权限的可执行文件,并且从可执行文件调用的python解释器也具有root权限。 有关这方面的更多信息,请参阅无法在Shell脚本上设置UID和http://www.diablotin.com/librairie/networking/puis/ch05_05.htm
这就是说,通过sudo作为@SvenW提示脚本应该可以正常工作。
另一个答案,因为这是一个完全不同(更通用)的方法。 人们可以争辩说,这是做这种事情的规范方法:)
把你的apache用户(但是它的名字,我假设www-data )进入sudoers文件(与visudo )与一个非常具体的行,只允许他只运行yourscript.py并从本地机器( hostname ),没有密码。 像这样的东西:
www-data hostname=(root)NOPASSWD:/path/to/yourscript.py
然后,您的CGI脚本可以通过调用sudo /path/to/yourscript.py来启动该脚本。
当然,你必须确保你可能用于这个脚本的参数完全限制在允许的值上 – 最好来自cgi wrapper脚本和yourscript.py 。
恕我直言,最简单(也是相当安全)的方式是间接的:如果用户点击button,使网页创build一个文件,并修改脚本,只有当文件存在,然后删除它才运行。 然后每分钟从一个cron作业运行这个脚本。 你甚至可以用这个文件为脚本提供参数(这当然需要特别注意)。
这留下了改进的余地(多个用户同时点击是一个),但我已经多次使用这种方法进行清理和一次性操作。