什么是suEXEC?

suEXEC自Apache 1.2版本开始引入,负责处理CGI和SSI程序的请求,确保网页使用者能以该目录或程序的用户ID来执行远程程序。在正常情况下,所有CGI或SSI程序都必需由程序拥有者,透过Apache执行。

在suEXEC使用正确的情况下,使用CGI/SSI程序的用户ID来执行程序,能强制阻止其它用户胡乱执行,从而提高网络的安全性。相反,假若网管 人员未能正确设定suEXEC,suEXEC将会为你带来多个无可预知的系统保安漏洞,若你不熟识控制及设定ID的程序及其安全问题,我们强烈建议你不使 用suEXEC。

用前准备

在阅读正式说明文件前,请细看及留意Apache Group的要求及假设。

第一,Apache Group假定你的操作系统为任何一种UNIX系统,并拥有setuid及setgid功能,所有suEXEC设置例子都需在这大前提下才能正常运作。而在其它支持suEXEC的作业平台中,suEXEC的设置亦有可能和UNIX不同。

第二,你必需有系统保安及管理的基本概念,这些概念包括setuid/setgid的运作原理及其对系统的冲击,和清楚知道这些运作所产生的保安漏洞。

第三,在你没有更改suEXEC程序代码的情况下,Apache Group才能保证suEXEC的风险已减到最低,suEXEC的程序代码经开发者及测试者审慎测试,已加入预防错误的程序代码以保证suEXEC不会产 生错 误,更改原有程序代码会引起无法预知的系统漏洞。除非你已精通系统安全编程,及你愿意和Apache Group分享你的开发成果,不则我们绝不建议更改suEXEC的程序代码。

第四,在Apache Group考虑过后,suEXEC已豁出Apache的预设安装之外。因此,网管人员在安装suEXEC时需特别注意suEXEC的细节,几经考虑了 suEXEC的各项设置后,网管人员可从预设的安装方法嵌入suEXEC至Apache中,suEXEC的设置参数必需谨慎决定。由于suEXEC需网管 人员有周密的计划,故Apache Group谨希望审慎及细心的网管人员使用。

suEXEC安全模型

在设定及安装suEXEC之前,我们先讨论suEXEC的安全模型,这样你可详细地了解suEXEC的运作状况及其系统保安措施。

suEXEC是Apache的「包装程序」,这包装程序有setuid权限,当有CGI或SSI执行请求时,suEXEC就会把执行用户更改为程序的拥有者后才执行。

包装程序其后会根据以下步骤检查「包装过程」是否正常,若以下有其中一个检查失败,suEXEC会把错误写入记录,并拒绝执行请求:

传入包装程序的参数不足 。包装程序只会在传入足够参数时才会执行,而这些参数必需乎合Apache的内部格式,如果包装程序接收不到足够的参数,那代表suEXEC被人破坏,或你suEXEC的Binary版本出现问题。

执行包装程序的是否合法用户? 这检查确保执行程序的用户是系统中合法的用户。

执行用户有没有权使用包装程序?只有唯一一个用户(Apache用户)可执行这个程序。

被执行的程序有不安全的相对目录参照字符?所有程序文件名开头含有「/」或「..」都不获处理,程序需存在Apache分配的目录中。

执行用户是否合法用户? 执行用户必需是系统中已存在用户。

执行工作组是否合法工作组?执行工作组必需是系统中已存在工作组。

执行用户是否超级用户? 目前Apache仍不允许「root」执行CGI/SSI程序。 CGI/SSI programs.

执行用户ID是否低于Apache的最低容许ID? 最低允许ID值在设定档中找到,用来控制哪个值以上的ID才可执行包装程序,这功能可过滤系统内设用户。

程序所属的工作组是否超级用户工作组? 目前suEXEC仍不允许「root」工作组执行CGI/SSI程序

程序工作组是否低于Apache最低容许ID? 最低允许ID值在设定档中找到,用来控制哪个值以上的GID才可执行包装程序,这功能可过滤系统内设工作组。

包装程序可否更改执行用户及其工作组? 成功与否在于将CGI/SSI程序SETUID及SETGID的过程,工作组使用列表

载有该程序的目录是否存在? 若果该目录并不存在,要执行的程序也不会存在。

载有程序的目录是否在Apache所设置的网页空间内? 若执行请求发生于Apache常规部分,该目录应在Apache的根目录;若请求发生于一般UserDir,该目录应在用户的Document Root中。

载有程序的目录是否拒绝任何人写入? 其它用户不能存取这个目录,只有目录拥有者才能更改目录里的内容。

要执行的程序存在吗? 不可能执行不存在的程序。

程序是否不能被更改或更新? 除了程序拥有者外,任何人都没有权限更改该程序。

你的程序是否setuid或setgid程序? suEXEC不会处理会更改现时UID/GID的程序。

程序拥有者是否就是suEXEC所包装的用户? 只有把请求包装成程序拥有者权限才能执行该程序。

可否清除程序环境以确保程序能顺利行? suEXEC利用安全执行目录来清除程序环境,所有页面传递变量均会清除(在设置suEXEC时已设定)。

我们能否成为被执行的程序? execute? suEXEC已完了,是被执行的程序的开始。

以上就是suEXEC包装程序的标准运作安全模型,这严谨的模型引入了CGI/SSI程序的限制及程序设计指导,但设计时当然要在脑海中一步步实行。

如欲获取更多关于安全模型如何限制服务器的设定,以及知道如何避免suEXEC所产生的系统漏洞,请参看Beware the Jabberwock。

设定及安装suEXEC

我们正式开始把suEXEC嵌入Apache中,如果你正使用Apache 1.2或是Apache 1.3的src/Configure的话,你需修改suEXEC的头档(Header File)及人手安装Binary版本至正确位置,安装过程可在suEXEC附加文件找到。以下几节将会描述Apache 1.3,透过AutoConf-Style Interface(APACI)的设定及安装过程。

suEXEC APACI设定选项

--enable-suexec

代表安装suEXEC至Apache中,加入这选项后,必需额外设置最少有一个 --suexec-xxxxx 选项,让APACI知道suEXEC该如何设定。

--suexec-caller=UID

在Apache能呼叫suEXEC的用户名称,这是执行Apache子程序的用户,只有这个用户才可呼叫suEXEC。

--suexec-docroot=DIR

设定网页文件存放位置,只有这目录及其子目录内的程序才可使用suEXEC,预设的目录为 --datadir 加上「/htdocs」,例如你将datadir设为--datadir=/home/apache,那么「/home/apache/htdocs」就 是允许使用suEXEC包装程序的目录。

--suexec-logfile=FILE

设定记录文件的文件名称,所有suEXEC的执行记录及错误均会记入此档(方便检查及除错),默认值为「suexec_log」,而预设目录设在--logfiledir中。

--suexec-userdir=DIR

设定用户存放网页的目录,所有suEXEC包装都必需在这个目录内进行,以确定这个程序是用户亲自允许执行的,若你只简单地键入绝对路径(i.e. 没有万用字符「*」),那么UserDir和允许使用suEXEC的地方就应设定为同一个目录,若suEXEC的UserDir并不包括用户存放网页的目 录,那么这些网页就因不乎合密码文件的记录而不能使用suEXEC。UserDir的默认值为「public_html」,若你设定Virtual Host时其UserDir在suEXEC目录之外,那么你就需要把suEXEC的UserDir设定为这堆目录的父目录。若你不正确设定 UserDir,所有「~userdir」的CGI请求均会失败。

--suexec-uidmin=UID

设定使用suEXEC的最大允许用户ID,默认值为100,一般系统是500或者100。

--suexec-gidmin=GID

设定使用suEXEC的最大允许用户组ID,默认值为100。

--suexec-safepath=PATH

设定suEXEC的安全目录,这安全目录允许执行CGI程序,默认值为「/usr/local/bin:/usr/bin:/bin」。

检查suEXEC的设定

在编译及安装suEXEC包装程序之前,你可利用--layout选项检查你目前各设定选项:

输出例子:

suEXEC setup:

suexec binary: /usr/local/apache/sbin/suexec

document root: /usr/local/apache/share/htdocs

userdir suffix: public_html

logfile: /usr/local/apache/var/log/suexec_log

safe path: /usr/local/bin:/usr/bin:/bin

caller ID: www

minimum user ID: 100

minimum group ID: 100

编译及安装suEXEC包装程序

若你透过--enable-suexec选项,在Binary版本中决定使用suEXEC的话,按「make」后就会自动把suEXEC嵌入Apache中。

执行「make install」安装所有Apache组件后,suEXEC会放置在由--sbindir选项决定的目录中,预设目录为 「/usr/local/apache/sbin/suexec」。请留意,你需要成为超级用户方可完成安装过程,为了让suEXEC有setuid的权 力,你必需把suEXEC拥有者转为「root」及加入setuid权限至suEXEC程序。

启动及关闭suEXEC

在启动Apache之前,Apache主程序会寻找「sbin」里的「suexec」程序文件(默认值为 「/usr/local/apache/sbin/suexec」,若Apache能找到正确的suexec檔,Apache将会把suEXEC启动记录 写入错误日志中:

[notice] suEXEC mechanism enabled (wrapper: /path/to/suexec)

若在Apache启动后在错误日志中找不到以上讯息,即代表Apache服务器找不到包装程序,又或者该包装程序文件没有setuid权限。

你不可以中途加入suEXEC至运行中的Apache,你必先关闭并重新启动Apache服务器,纯粹使用「HUP」或「USR1」是没效的;若你想关掉suEXEC,你亦需同样把Apache服务器关闭并重开,但在重开之前你需移除suexec程序文件

使用suEXEC

虚拟主机:

透过User和Group可让虚拟主机自设suEXEC的用户及用户组,设定后所有CGI请求都会依照User和Group的设定值来执行,若在宣告虚拟主机时没有设定User和Group,Apache会使用主服器的用户及用户组

使用者目录:

suEXEC包装程序亦会接受以个别设定的用户权限来执行CGI程序,只要把「~」加在用户ID之前把主服务器目录导向至用户之网页目录即可,所有乎合suEXEC安全模型的CGI程序及请求都可用这个方法以特定用户执行CGI程序。

suEXEC除错

所有suEXEC的执行过程都会写入日志档案,日志文件名称可于--suexec-logfile选项中设定,若你已确定自己设置无误,但仍有不明的suEXEC错误的话,可参看suEXEC的error_log。

suEXEC注意事项

目录阶层限制

在系统安全及效率的大前提下,所有在虚拟主机的网页及个别用户的suEXEC请求都必需在根目录里执行,例如你设定了四个虚拟主机,你必需把这些虚拟主机的根目录归纳在一个Apache主文件目录中,以乎合suEXEC需要在特定安全目录下执行这个条件。

执行环境中的suEXEC路径

更改suEXEC执行目录有可能产生系统保安漏洞,请确定suEXEC的执行目录为可信任的目录,让不可靠的目录设定为suEXEC的执行目录有可能被任何人以木马程序攻击计算机系统。

更改suEXEC的程序代码

若你不清楚suEXEC程序代码的意义就自行更改其内容,可引起庞大的程序错误,请尽量不要更改suEXEC的程序代码。