【发布时间】:2014-09-16 12:01:03
【问题描述】:
我有一个 Perl CGI,它应该允许用户从文件系统中选择一些文件,然后通过 Rsync 将它们发送到远程服务器。所有的 HTML 都是由 Perl 脚本生成的,我使用查询字符串和临时文件来产生有状态事务的错觉。 Rsync 部分是一个单独的 shell 脚本,它以文件名作为参数调用(该脚本还发送电子邮件和一堆其他东西,这就是为什么我没有将它移到 Perl 脚本中的原因)。我想在没有密码的情况下使用 sudo,我设置了 sudoers 以允许 apache 用户在没有密码的情况下运行脚本并禁用了 requiretty,但我仍然在日志中收到关于 no tty 的错误。然后我尝试使用 su -c scriptname,但这也失败了。
TD;DR 使用 Perl CGI 脚本通过 sudo 调用 Bash 脚本是一种糟糕的做法,您如何处理 Perl CGI 脚本的权限提升? Linux 2.6 内核上的 Perl 5.10。
相关代码:(LFILE是一个文件,包含文件系统中所有文件数组的索引)
elsif ( $ENV{QUERY_STRING} =~ 'yes' ) {
my @CMDLINE = qw(/bin/su -c /bin/scriptname.sh);
print $q->start_html;
open('TFILE', '<', "/tmp/LFILE");
print'<ul>';
foreach(<TFILE>) {
$FILES[$_] =~ s/\/.*\///g;
print "Running command @CMDLINE $FILES[$_]";
print $q->h1("Sending File: $FILES[$_]") ; `@CMDLINE $FILES[$_]` or print $q->h1("Problem: $?);
【问题讨论】:
-
“使用 Perl CGI 脚本通过 sudo 调用 Bash 脚本是不是很糟糕……” 是的。改为为 非 root 用户 设置 SSH 密钥。
-
我的问题的答案是 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no
-
这不是一个很好的解决方案,因为它使您容易受到中间人攻击,因为您不再检查您要连接的主机是否是您认为的主机它是。通过 sudo 授予您的网络服务器用户超级用户权限也是一个非常糟糕的主意 (TM)。
-
由于没有 tty,当 CGI 通过反引号或 system() 调用它们时,我无法让 scp/rsync 等工作。这个问题的正确解决方案是什么?
-
一种选择是使用排队系统。您的 CGI 所做的只是将作业添加到队列中;另一个以特权用户身份运行的(非 CGI)程序将作业从队列中拉出并运行它们。这可以解决很多安全问题。请注意,大多数排队系统通过网络工作,因此执行作业的程序可以在远程系统上运行。有关其他建议,请参阅 this similar question。