🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# suEXEC支持 **suEXEC**特性使得Apache可以使用与调用web服务器的用户**不同**的用户身份来运行**CGI**和**SSI**程序。而通常情况下,CGI或者SSI程序执行时使用和web服务器相同的用户身份。 正确运用该特性,可以减少很多因为提供用户执行私有CGI或者SSI程序所带来的安全风险。但如果配置不当的话,则可能引起很多问题,使你的计算机产生更多的安全漏洞。如果你对管理 _setuid root_ 程序以及可能导致的安全问题不熟悉的话,我们强烈建议你不要使用suEXEC。 ## 开始之前 在我们开始切入正题之前,你必须明白Apache开发组以及本文档所做的假设。 首先,我们假设你正在使用类UNIX操作系统,只有这类操作系统才具有**setuid**和**setgid**命令。所有的其他命令行的例子也是如此。其他的操作系统平台,即使也支持suEXEC,但是它的配置可能和我们所讲的并不相同。 第二,我们假设你熟悉计算机的安全和管理计算机的一些基本概念。这关系到如何正确理解**setuid/setgid**操作以及对你的系统可能带来的各种影响和不同的安全等级。 第三,我们假设你正在使用源代码**未经修改的**suEXEC版本。所有suEXEC的代码都经过开发者的仔细查验并做过大量测试。在这些代码中,人们采取了各种预防措施,使之简单、健壮、安全。修改这些代码可能会导致预料之外的问题和安全隐患。所以我们强烈地建议你**不要修改**代码,除非你精通安全编程,并愿意和Apache开发组共享成果。 第四,也是最后一点,Apache开发组已经决定**默认不安装**suEXEC。suEXEC的配置需要管理员细致关注各个细节。在仔细考察过关于suEXEC的各种设置方法后,管理员应该使用标准的安装方法来安装suEXEC。设置的参数应该经过仔细推敲,以保证系统的安全运行。Apache开发组希望通过限制suEXEC的安装,仅使那些经过细致理解,并有能力运用它的管理员来使用。 你还想使用suEXEC吗?还想?很好!那我们开始吧! ## suEXEC的安全模型 在我们开始配置和安装suEXEC之前,我们需要先讨论一下它的安全模型。这样,你才能更好的理解suEXEC内部究竟做了些什么事情,以及哪些确保系统安全的预防措施。 **suEXEC**是基于一个setuid的"封装"程序,该程序由"主"Apache web服务器调用。当一个HTTP请求的是管理员指定的、以不同于"主"服务器用户身份运行的CGI或SSI程序时,该封装程序将被调用。处理这样的请求时,Apache将被请求的程序名及其UID和GID提供给suEXEC封装器。 封装器(wrapper)通过处理下面所描述的步骤,来决定封装的成功或失败:如果有任意一个条件为假,程序将把错误情况记录到日志中,退出并返回错误信息。否则继续执行。(以下所说的"程序"均指"CGI/SSI程序") 1. **用户使用了合法的系统账号来执行封装程序了吗?** 确保运行封装器的是一个系统中确实存在的用户。 2. **封装器被调用时,使用的参数个数正确吗?** 封装器仅在使用了正确数量的参数调用时才会执行。Apache web服务器知道正确的参数格式是什么。如果封装器没有收到正确数量的参数,则说明要么被黑客攻击,要么Apache二进制代码中suEXEC的部分出了问题。 3. **这个合法的用户被允许运行封装器吗?** 这个用户是可以运行封装器的用户吗?仅有一个用户(Apache用户)被允许运行封装器。 4. **目标CGI/SSI程序有不安全的分级路径索引吗?** 目标CGI/SSI程序包含了"/"开头或者有".."后向路径索引吗?这些都是不允许的;并且目标程序必须位于suEXEC的文档根目录下。(参见下面的:`--with-suexec-docroot=_DIR_`) 5. **目标程序的所属用户名合法吗?** 目标程序的所属用户名存在吗? 6. **目标程序的所属用户组合法吗?** 目标程序的所属用户组存在吗? 7. **目标程序的所属用户名不是超级用户吗?** 目前,suEXEC不允许root执行CGI/SSI程序。 8. **目标程序所属用户的UID高于最小UID值吗?** 最小UID值是在配置中指定的。你可以指定允许执行CGI/SSI程序的最小UID值,这样可以保证不会和系统账号冲突。 9. **目标程序的所属用户组不是超级用户组吗?** 目前,suEXEC不允许root组用户执行CGI/SSI程序。 10. **目标程序所属用户组的GID高于最小GID值吗?** 最小GID值是在配置中指定的。你可以指定允许执行CGI/SSI程序的最小GID值,这样可以保证不会和系统账号冲突。 11. **封装器能够成功地变为目标用户和组吗?** 这里就是程序变为目标用户和组的关键步骤了。我们是通过调用setuid和setgid来实现的。在组访问列表中,和该用户相关的所有组信息都将被初始化。 12. **能够切换到程序所在的目录吗?** 如果不存在,将无法包含程序文件。如果不能切换一般也表示目录不存在。 13. **这个目录在Apache的网络空间中吗?** 如果是对于服务器的一般请求,那么请求的目录是在suEXEC的根文档目录下吗?如果请求的是一个用户目录,那么该目录是在suEXEC配置的该用户的根目录下吗?(参见:[suEXEC配置选项](#calibre_link-548)) 14. **该目录不具有其他用户可写的权限吗?** 我们不想把目录开放给其他人;只有属主才可以改变该目录中的内容。 15. **目标CGI/SSI程序存在吗?** 如果不存在,当然无法继续运行。 16. **目标CGI/SSI程序不可以被其他用户改写吗?** 我们不想给其他人有修改程序的权限。 17. **目标程序尚未被setuid或者setgid ?** 我们不想要执行的程序被再次改变UID/GID。 18. **目标用户和组与程序的用户和组相同吗?** 用户是这个文件的属主吗? 19. **我们可以成功清除进程的环境变量并保证操作的安全性吗?** suEXEC通过建立一个安全的可执行路径(在配置中定义)来清除该进程的环境变量,同时只传送在安全环境变量列表(配置中定义)中所列出的环境变量。 20. **可以成功的变为目标程序并执行吗?** 这里就是suEXEC结束,并开始运行目标程序的地方了。 这是suEXEC封装器标准操作方式的安全模型。它有些严格,并强加了CGI/SSI设计上的限制。但它是仔细考虑过安全之后一步步发展起来的模型。 更多关于该安全模型如何根据服务器的配置来限制使用者的权限,以及恰当的suEXEC安装步骤能够避免的安全隐患,请参见[警告和举例](#calibre_link-579)部分。 ## 配置和安装suEXEC 继续我们的探险 ... **suEXEC配置选项** `--enable-suexec` 该选项启用默认禁止的suEXEC功能。并同时至少提供一个 `--with-suexec-xxxxx` 选项,以使APACI使用suEXEC功能来处理请求。 `--with-suexec-bin=_PATH_` 出于安全考虑,`suexec`二进制程序的路径必须用这个选项指定并硬编码在服务器里。比如:`--with-suexec-bin=/usr/sbin/suexec` `--with-suexec-caller=_UID_` Apache运行时所用的[UID](#calibre_link-168)。这是唯一允许执行程序的用户。 `--with-suexec-userdir=_DIR_` 定义suEXEC允许访问的用户宿主目录下的子目录。suEXEC将以用户身份执行这个目录下的所有可执行程序,所以这些程序必须是"安全程序"。如果使用"简单的"`UserDir`指令(即不带"*"),则此处应该被设置为相同的值。当`UserDir`指令所指向的目录与"passwd"文件所指定的用户宿主目录不同时,suEXEC将不会正常工作,其默认值是"public_html"。如果所支持的虚拟主机对每个用户有不同的`UserDir` ,则应该把他们集中在同一个父目录下,而用这个参数指向这个父目录。**如果配置不当,"~userdir"下的cgi请求将无效!** `--with-suexec-docroot=_DIR_` 定义Apache的`DocumentRoot`。它是除`UserDir`外suEXEC唯一可以使用的目录。其默认目录是 `--datadir` 值所指定的带有"/htdocs"的后缀的目录,比如:如果配置了"`--datadir=/home/apache`",那么"/home/apache/htdocs"目录将作为suEXEC处理器的文档根目录。 `--with-suexec-uidmin=_UID_` 定义了suEXEC目标用户的最低UID。对大多数系统,一般是500或100。默认值是100 `--with-suexec-gidmin=_GID_` 定义了suEXEC目标组的最低GID。对大多数系统,是100,默认值也是100。 `--with-suexec-logfile=_FILE_` 它定义了suEXEC用于记录所做的事情以及发生的错误的日志文件名(对审核和排错很有用),默认文件名是"suexec_log",并位于标准的日志文件目录中(`--logfiledir`)。 `--with-suexec-safepath=_PATH_` 定义传给CGI程序的一个安全的PATH环境变量的值。默认值是"/usr/local/bin:/usr/bin:/bin" **编译和安装suEXEC处理器** 若用 `--enable-suexec` 打开了suEXEC功能,那么执行`make`命令时(Apache自带的)`suexec`二进制文件就会被自动建立。所有组件编译完毕后执行 `make install` 命令进行安装时,`suexec`文件将被安装在 `--sbindir` 选项指定的目录中,默认为"/usr/local/apache2/sbin/suexec"。 注意,安装过程需要**root权限**。为了使suEXEC处理器可以设置UID,其所有者必须为`_root_` ,并且文件模式中的执行位必须设置为1(允许执行)。 **设置许可权限** 虽然suEXEC包装会检查以确保它的调用者就是`配置选项` `--with-suexec-caller` 所指定的用户。但是总是存在这样的可能性:一个系统或者库在suEXEC执行用户身份检查之前调用它,这样就存在一个可利用的漏洞。通常,避免这种问题的最佳办法是,使用文件系的统权限来确保只有Apache组用户运行的程序才能执行suEXEC。 如果你的web-server是按照如下所示进行配置的: ``` User www Group webgroup ``` 并且`suexec`被安装在"/usr/local/apache2/sbin/suexec"目录,你应当运行以下命令: ``` chgrp webgroup /usr/local/apache2/bin/suexec chmod 4750 /usr/local/apache2/bin/suexec ``` 这将确保只有Apache组用户运行的程序才能执行suEXEC。 ## 启用和禁用suEXEC Apache在启动过程中,会在 `--sbindir` 选项指定的目录(默认为:"/usr/local/apache/sbin/suexec")中寻找`suexec`。如果Apache找到了一个正确配置的suEXEC处理器,会在错误日志中记录以下信息: ``` [notice] suEXEC mechanism enabled (wrapper: <var class="calibre40">/path/to/suexec</var>) ``` 如果服务器启动后没有这个信息,那么很可能是服务器没找到适当的处理器,或者是这个执行程序没有安装_setuid root_。 如果要在Apache服务器运行过程中打开suEXEC功能,则必须停止并重新启动Apache。用一个简单的HUP或USR1信号来重新启动是不够的。 如果要关闭suEXEC功能,应该删除`suexec`文件,并停止和重新启动Apache。 ## 使用suEXEC 对CGI程序的请求仅在下述两种情况下才会调用suEXEC包装:对一个含`SuexecUserGroup`指令的虚拟主机发起请求,或者该请求由`mod_userdir`模块处理。 **虚拟主机:** 使用suEXEC处理器的方法之一是在`VirtualHost`定义中使用`SuexecUserGroup`指令。通过设置这个指令来确定不同于主服务器的UID,所有对CGI资源的请求将以`<VirtualHost>`所定义的_User_和_Group_身份执行。如果`<VirtualHost>`中没有这个指令,则将以主服务器的UID身份执行。 **用户目录:** 由`mod_userdir`处理的请求会调用suEXEC处理器以被请求的用户目录所属的UID执行CGI程序。此功能的唯一要求是,此用户必须有CGI执行权限,并且其脚本符合上述[安全检查](#calibre_link-581)的要求。参见 `--with-suexec-userdir` [编译选项](#calibre_link-548)。 ## 调试suEXEC 如上所述,suEXEC处理器会在 `--with-suexec-logfile` 选项所指定的日志文件中记录信息。如果你感觉配置和安装不正常,可以查看这个日志以及服务器的错误日志。 ## 谨防Jabberwock:警告和举例 **注意!**这部分文档可能还没有完成。查看最新的修订版本,请到Apache开发组的[在线文档](http://httpd.apache.org/docs/2.2/suexec.html)。 以下是有关限制和服务器安装的几个注意事项,在提交任何关于suEXEC的"bugs"以前,请仔细阅读。 * **suEXEC注意事项** * 层次限制 出于安全和效率考虑,所有suEXEC请求必须被限制在虚拟主机或者用户目录的顶层。举例来说,如果你配置了4个虚拟主机,你必须把所有虚拟主机的文档根目录都安置在同一个主Apache目录中,这样才能为虚拟主机启用suEXEC。(例子以后会有的) * suEXEC的PATH环境变量 改变这个变量的值是危险的,必须确保其中每个路径都是**可以信任**的目录。你不会希望谁都可以在你的服务器上安装特洛伊木马。 * 改变suEXEC的代码 重申,如果你不清楚你在干什么就尽量避免,否则会带来**大麻烦**的。