我注意到 Stack Overflow 上的几个问题,比如这个,关于使用 PHP 以 root 权限执行命令。建议添加该行的答案
www-data ALL=(ALL) NOPASSWD: ALL
到/etc/sudoers.d
文件。
这是解决问题的安全方法吗?它会产生漏洞吗?
我注意到 Stack Overflow 上的几个问题,比如这个,关于使用 PHP 以 root 权限执行命令。建议添加该行的答案
www-data ALL=(ALL) NOPASSWD: ALL
到/etc/sudoers.d
文件。
这是解决问题的安全方法吗?它会产生漏洞吗?
这……太惨了。以非 root 用户身份运行 Web 事物的全部意义在于损害遏制:万一 Web 服务器进程通过某些漏洞被劫持,至少攻击者不会获得对机器的完全控制,因为他将受到限制非root账户的限制www-data
。但是,如果您提供www-data
一种方法来运行它希望运行的每个命令,并且具有任何用户(包括root
)的权限,并且无需任何进一步的身份验证,那么您就失去了该损害遏制功能。
公平地说,www-data
+ sudo 比简单地运行所有东西都稍微好一点root
,因为 go-to-root 必须是明确的;因此,像 PHP 脚本在不正确的位置写入文件这样的常见缺陷将更难被利用。但是,让www-data
sudoers 的成员看起来仍然是个糟糕的主意。
在考虑某物的安全性时,您应该假设攻击者能够以您的 www-data 用户身份登录,并拥有一个 shell。这并不意味着你的攻击者真的可以得到一个 shell,但攻击者可以有很多方法可以执行任意 shell 命令;它们可能是诸如 shellshock 之类的库错误或代码中的疏忽的结果。
最好的方法是,就像@AlexeyVesnin 所说的那样,使用专门的流程来完成这项工作。让这个进程在一个(unix 域,因此无法从网络访问)套接字上侦听,从所述套接字读取其输入,清理输入(!),完成工作,并将一些结果返回到套接字,从哪里Web 服务器脚本读取结果。任何授权(用户需要在网站上输入一些密码才能被允许这样做)都应该在该过程中处理,并且 www-data 用户不应该能够读取任何授权数据。
如果您的预算或技能无法使这种最佳方法可行,则使用 sudo 方法并非完全错误,但您应该将 sudo 权限限制在您实际需要的最低限度。例如,假设您想在您的网站上显示当前磁盘 I/O 数据,您需要为此调用iotop
:
制作一个脚本,在这个例子中/var/www/bin/get-disk-io
,提取你需要的数据:
/usr/sbin/iotop -b -n 1 | /usr/bin/head -2
$1
, $2
, ... , $*
,$@
/etc/sudoers
env_reset
在 sudoers 文件的默认策略中请注意,这仍然比 suid 程序更安全,因为(a)您可以限制谁可以执行它,因此获得在不同用户下执行程序的能力的攻击者将无法使用它,(b)您不能将任意参数传递给它,(c)环境由 清理sudo
,并且(d)您可以在命令执行时制作 sudo 日志,因此您有一个 suid 程序没有给您的审计跟踪。
注意:除非您知道自己在做什么,否则不要这样做。如果您在 stackexchange 上询问或阅读此问题,您可能不会。所以不要这样做。
如果您将可执行文件的所有者设置为某个用户(chown user /my/executable/file
),然后设置 suid 位(chmod u+s /my/executable/file
),那么该程序每次执行时都会在该用户的权限下运行。因此,例如,chown root /bin/cat; chmod u+s /bin/cat
将cat
使用 root 权限运行每个调用,这意味着您可以独立于其访问权限读取系统上的每个文件。不要在连接到网络的系统上尝试此操作,甚至不要在 5 分钟内“检查它是否有效”。
strace
,则该s
位无效Linux 有一个功能系统,其工作方式几乎与 suid 类似,但粒度要细得多。例如,如果您需要一个进程能够使用低于 1024 的端口号,在经典的 unix 系统中,您需要以 root 身份运行该命令,这通常意味着您需要执行上述操作chown/chmod u+s
,这允许使用这些端口号,但是还授予对文件系统的访问权限。Linux 允许您在没有 root 附带的所有其他内容的情况下提供端口功能:
setcap cap_net_bind_service+EP /path/to/my/program
做man 7 capabilities
以了解更多。如果您认真考虑将 suid 赋予程序,请三思而后行,如果设置功能不是一个更好的主意。
每次ALL=(ALL) NOPASSWD: ALL
,当您在文件中看到时,无一例外,都/etc/sudoers
应该被解雇。基本上,您有第二个 root 用户。
安全吗?一定不行。它会产生漏洞吗?当然好。
您可以使用 sudo 安全地授予非 root 用户(包括 www-data)特权执行,但它应该始终尽可能具体。如果您/usr/bin/my_system_tool +x /var/cache/my_cache
出于某种原因需要以 root 身份运行,则该确切的命令(包括参数)应该在/etc/sudoers
文件中。
我最近做了一些研究并找到了一些方法来做到这一点,但正如@tom-leek 所说,它绝不会是 100% 一致的,只是一种不那么不安全的方法。
但是有一种方法我相信即使对于像我这样没有经验的专业人士来说也很容易!
最好的安全方法是使用 crontab。
将所有命令保存在数据库中(mysql whateaver)
创建一个 cronjob 来读取这些 mysql 条目并通过exec()
or执行shell_exec();
将这些行添加到 cron
crontab -e
我更喜欢每 5 秒检查一次,但您可以根据自己的喜好每 10 分钟检查一次。
PHP 将值放入 db 表中,一个具有 1 个值的简单表对我有用,就是它! $domain_name kkk
root 用户检查表并获取记录,生成证书并删除$domain_name
表。
您可以使用 acme.sh,我更喜欢 Lego,但无论如何。
如果您的系统被黑客入侵,您将永远不会失去您的 root 访问权限,并且可以快速修复它!
我在这篇文章中发现了这个好主意: https ://sanjaykumarns.blogspot.com/p/how-to-execute-root-level-privileged.html
killProcess.php 从数据库中获取进程 ID 并通过 php 函数 shell_exec() 执行 kill linux 命令(或根据您的要求的任何其他 linux 命令)。
由于 cronjob 条目被配置为 root 用户,因此指定的脚本具有与 root 用户相同的所有权限集。