【问题标题】:PHP: Cannot exec() wkhtmltopdf: "sh: /usr/bin/wkhtmltopdf: Permission denied"PHP:无法执行() wkhtmltopdf:“sh:/usr/bin/wkhtmltopdf:权限被拒绝”
【发布时间】:2014-04-28 22:34:07
【问题描述】:

我不是很喜欢 unix,这就是为什么这件事对我来说有点奇怪。

操作系统是 CentOS 6。

我阅读了几乎所有关于 wkhtmltopdf 的主题,但我的问题仍然存在。其实不是wkhtmltopdf问题,而是权限问题。
总结一下:wkhtmltopdf 在命令行中有效,但不适用于 php exec()。
但是 wget 与 php exec() 一起工作正常:

我可以在命令行执行wkhtmltopdf,工作正常:
/usr/bin/wkhtmltopdf "test.de" "/var/www/html/test/test.pdf" 2>&1

我可以用 php 执行 wget,工作正常:
exec('/usr/bin/wget -O /var/www/html/test/test123.txt "test.de" 2>&1', $output, $return_var);

但是我不能用 php 执行 wkhtmltopdf:
exec('/usr/bin/wkhtmltopdf "test.de" "/var/www/html/test/test.pdf" 2>&1', $output, $return_var);

这会导致“sh: /usr/bin/wkhtmltopdf: Permission denied”

我检查了 /usr/bin/wkhtmltopdf 并将其与 /usr/bin/wget 进行了比较。
权限相同:rwxr-xr-x 或 0755
即使我将/usr/bin/wkhtmltopdf的chmod设置为777,并将所有者设置为apache,错误还是一样。

也许是百胜的问题?! 因为我没有通过 yum 和 wkhtmltopdf 安装 wget。这是我能想到的唯一区别。

我使用以下内容安装了 wkhtmltopdf:

tar -vxjf wkhtmltopdf-0.9.9-static-amd64.tar.bz2
mv wkhtmltopdf-amd64 /usr/bin/wkhtmltopdf
chmod +x /usr/bin/wkhtmltopdf

或者这可能是 SELinux 的问题?我对此不太了解,但我阅读了我的研究,“httpd_ssi_exec”和“httpd_execmem”可能会有所帮助,我将两者都设置为“是”,但权限被拒绝问题仍然存在。

所以我想知道为什么 wget 可以与 php 一起使用而 wkhtmltopdf 不可以? 希望有人可以帮助我,我可以停止为此生气;)

最好的问候, 亚历克斯

P.S.:test.de 在我的脚本中是http://test.de,但我不能发布两个以上的链接。

【问题讨论】:

  • 你是如何解决这个问题的?我面临同样的问题,你是对的;我们不应该禁用 SELinux。当涉及到共享目录时,这是一个主要问题。我的情况不同:我是 VPS 上的二级用户,权限有限。通过命令行脚本可以完美运行

标签: php linux permissions exec wkhtmltopdf


【解决方案1】:

你可以使用:

exec('/usr/local/bin/wkhtmltopdf --print-media-type index.html termo590.pdf 2>&1');

【讨论】:

  • 返回错误 - Array ( [0] => sh: /usr/local/bin/wkhtmltopdf: Permission denied ) 126
【解决方案2】:

即使权限是777,命令也会以www用户身份执行。由于www的权限级别非常低,因此会有很多限制。所以请使用setuid File Permission

setuid 表示在执行时设置用户 ID。如果 setuid 位打开了文件,执行该可执行文件的用户将获得拥有该文件的个人或组的权限。因此您可以作为 root/高权限用户执行该命令。

【讨论】:

  • 感谢您的回答,但是如果我设置“chmod u+s /usr/bin/wkhtmltopdf”,它就没有效果。它仍然是权限被拒绝。但我发现,SELinux 阻止了它。如果我将 Enforce-Mode 设置为 permissive,那么我可以使用 wkhtmltopdf 创建 PDF。但我不想禁用 SELinux..
  • 另一种解决方案是使用 Binary wrapper 。它再次需要suid
【解决方案3】:

如果您不想禁用SELinux,另一种方法是使用 cron 运行此命令。/usr/bin/wkhtmltopdf "test.de" "/var/www/html/test/test.pdf" 2>&1

1) 将参数名称从您的 php 程序写入文件。

 $Handle = fopen("myfile", 'w');
 fwrite($Handle, "test.de");
 fclose($Handle);

2) 创建一个 bash 脚本来读取该参数名称并将其转换为 pdf。

#!/bin/sh
arg=$(head -n 1 myfile)   
/usr/bin/wkhtmltopdf arg "/var/www/html/test/test.pdf" 2>&1

另存为 pdf_converter.sh

chmod +x pdf_converter.sh

3)在crontab中配置脚本

crontab -e 并粘贴此

* * * * * pdf_converter.sh

【讨论】:

    【解决方案4】:

    在与 Permission Denied 问题作斗争后,我终于破解了它,所以对于遇到此问题的其他人来说:

    Apache的shell用户(www-data)默认只能访问var/www/内的文件

    Shell 用户根本没有使用 exec() 在其默认目录(在我的例子中为 usr/local/bin)中运行 wkhtmltopdf 的权限。

    我的解决方法是简单地将 wkhtmltopdf 从 /usr/local/bin 复制并粘贴到 /var/www/bin(我创建了 bin 文件夹)并在我的 exec 中定位该文件

    exec('/var/www/bin/wkhtmltopdf file.htm testfile.pdf');
    

    轰隆隆! PDF 的。

    现在这可能不是最安全的做法(我不知道在 var/www 目录中有 bin 文件夹是否存在安全隐患)但我的情况并不重要,因为这是一个测试服务器任何人只是想验证他们的其他代码是否正常工作,它至少应该为您生成一个 test.pdf

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-30
      • 1970-01-01
      • 1970-01-01
      • 2014-04-06
      • 2021-05-21
      • 1970-01-01
      • 1970-01-01
      • 2017-08-22
      相关资源
      最近更新 更多