Apache一直是世界上使用率排名前三的Web服务器软件。企业使用其构建Web应用,从很大程度上都需要对其安全性进行综合考虑,以保证能够应对拒绝服务攻击、流量窃听、数据泄漏等网络威胁,从而保证企业门户网站的安全。
除了使用业界流行的防火墙、IDS/IPS(入侵检测系统/入侵防御系统)、WAF(Web应用防火墙)、UTM(统一威胁管理)等外部安全设备对Apache服务进行安全防护外,作为一种优秀的开源服务器软件,Apache本身就具有很多优秀的特性可以为服务器管理员提供安全配置,以防范各种网络攻击。因此,充分、高效地挖掘Apache服务器的自身安全能力也是企业安全工作者一个必备的技能。基于此,本文将从4个方面详细剖析Apache服务器的安全防护要点。
策略一:服务器端安全设置
1.限制root用户运行Apache服务器
一般情况下,在Linux下启动Apache服务器的进程httpd需要root权限。由于root权限太大,存在许多潜在的安全威胁。一些管理员为了安全起见,认为httpd服务器不可能没有安全漏洞,因而更愿意使用普通用户的权限来启动服务器。http.conf主配置文件里面有如下两个配置是Apache的安全保证,Apache在启动后,就将其本身设置为这两个选项设置的用户和组权限进行运行,降低了服务器的危险性。
User apache
Group apache
需要特别指出的是:以上两个配置在主配置文件里面是默认选项,当采用root用户身份运行httpd进程后,系统将自动将该进程的用户组和权限改为apache,这样,httpd进程的权限就被限制在apache用户和组范围内,因而保证了安全。
2.向客户端隐藏Apache服务器的相关信息
Apache服务器的版本号可作为黑客入侵的重要信息被利用,通常他们在获得版本号后,通过网上搜索针对该版本服务器的漏洞,从而使用相应的技术和工具有针对性的入侵,这也是渗透测试的一个关键步骤。因此,为了避免一些不必要的麻烦和安全隐患,可以通过主配置文件httpd.conf下的如下两个选项进行:
(1)ServerTokens:该选项用于控制服务器是否响应来自客户端的请求,向客户端输出服务器系统类型或者相应的内置模块等重要信息。Red Hat Enterprise Linux 5操作系统在主配置文件中提供全局默认控制阈值为OS,即ServerTokens OS。它们将向客户端公开操作系统信息和相关敏感信息,所以保证安全情况下需要在该选项后使用“ProductOnly”,即ServerTokens ProductOnly。
(2)ServerSignature:该选项控制由系统生成的页面(错误信息等)。默认情况下为off,即ServerSignature off,该情况下不输出任何页面信息。另一情况为on,即ServerSignature on,该情况下输出一行关于版本号等相关信息。安全情况下应该将其状态设为off。
图1和图2为安全设定这两个选项前后正常情况下和错误情况下的输出页面(通过Rhel5中的Mozilla Firefox浏览器访问Rhel5中的Apache服务器)的详细对比。可以清楚看到,安全设定选项后,可以充分地向客户端用户隐藏Linux操作系统信息和Apache服务器版本信息。
图1 错误情况下未设定安全选项前示意
图2 操作情况下使用安全设定后的对比
3.设置虚拟目录和目录权限
要从主目录以外的其他目录中进行发布,就必须创建虚拟目录。虚拟目录是一个位于Apache的主目录外的目录,它不包含在Apache的主目录中,但在访问Web站点的用户看来,它与主目录中的子目录是一样的。每个虚拟目录都有一个别名,用户Web浏览器中可以通过此别名来访问虚拟目录,如http://服务器IP地址/别名/文件名,就可以访问虚拟目录下面的任何文件了。
使用Alias选项可以创建虚拟目录。在主配置文件中,Apache默认已经创建了两个虚拟目录。这两条语句分别建立了“/icons/”和“/manual”两个虚拟目录,它们对应的物理路径分别是“/var/www/icons/”和“/var/www/manual”。在主配置文件中,用户可以看到如下配置语句:
Alias /icons/ "/var/www/icons/"
Alias /manual "/var/www/manual"
在实际使用过程中,用户可以自己创建虚拟目录。比如,创建名为/user的虚拟目录,它所对应的路径为上面几个例子中常用的/var/www/html/rhel5:
Alias /test "/var/www/html/rhel5"
如果需要对其进行权限设置,可以加入如下语句:
<Directory “/var/www/html/rhel5”>
AllowOverride None
Options Indexes
Order allow,deny
Allow from all
</Directory>
设置该虚拟目录和目录权限后,可以使用客户端浏览器进行测试验证,采用别名对该目录中的文件进行访问,浏览结果如图3所示。
图3 使用虚拟目录的测试结果
#p#副标题#e#
策略二:限制Apache服务的运行环境
Apache服务器需要绑定到80端口上来监听请求,而root是唯一有这种权限的用户,随着攻击手段和强度的增加,服务器受到相当大的威胁,一旦缓冲区溢出漏洞被利用,就可以控制整个系统。为了进一步提高系统安全性,Linux内核引入chroot机制,chroot是内核中的一个系统调用,软件可以通过调用函数库的chroot 函数,来更改某个进程所能见到的根目录。
chroot机制是将某软件运行限制在指定目录中,保证该软件只能对该目录及其子目录的文件有所动作,从而保证整个服务器的安全。在这种情况下,即使出现黑客或者不法用户通过该软件破坏或侵入系统,Linux系统所受的损坏也仅限于该设定的根目录,而不会影响到系统的其他部分。
将软件chroot化的一个问题是该软件运行时需要的所有程序、配置文件和库文件都必须事先安装到chroot目录中,通常称这个目录为chroot“监牢”。如果在“监牢”中运行httpd,那么用户根本看不到Linux文件系统中那个真正的目录,从而保证了Linux系统的安全。
在使用该技术的时候,一般情况下需要事先创建目录,并将守护进程的可执行文件httpd复制到其中。同时,由于httpd需要几个库文件,所以需要把httpd程序依赖的几个lib文件同时也拷贝到同一个目录下,因此手工完成这一工作是非常麻烦的。幸运的是,用户可以通过使用开源的jail软件包来帮助简化chroot“监牢”建立的过程,具体步骤如下所示:
Jail官方网站是:http://www.jmcresearch.com/projects/。首先将其下载,然后执行如下命令进行源代码包的编译和安装:
#tar xzvf jail_1.9a.tar.gz
#cd jail/src
#make
jail软件包提供了几个Perl脚本作为其核心命令,包括mkjailenv、addjailuser和addjailsw,他们位于解压后的目录jail/bin中。这几个命令的基本用途如下所示:
•mkjailenv:用于创建chroot“监牢”目录,并且从真实文件系统中拷贝基本的软件环境。
•addjailsw:用于从真实文件系统中拷贝二进制可执行文件及其相关的其它文件(包括库文件、辅助性文件和设备文件)到该“监牢”中。
•addjailuser:创建新的chroot“监牢”用户。
采用jail创建监牢的步骤如下所示;
(1)首先需要停止目前运行的httpd服务,然后建立chroot目录,命令如下所示。该命令将chroot目录建立在路径/root/chroot/httpd下:
# service httpd stop
# mkjailenv /root/chroot/httpd
kjailenv
A component of Jail (version 1.9 for linux)
http://www.gsyc.inf.uc3m.es/~assman/jail/
Juan M. Casillas <assman@gsyc.inf.uc3m.es>
Making chrooted environment into /root/chroot/httpd
Doing preinstall()
Doing special_devices()
Doing gen_template_password()
Doing postinstall()
Done.
(2)为“监牢”添加httpd程序,命令如下:
# ./addjailsw /root/chroot/httpd/ -P /usr/sbin/httpd
addjailsw
A component of Jail (version 1.9 for linux)
http://www.gsyc.inf.uc3m.es/~assman/jail/
Juan M. Casillas <assman@gsyc.inf.uc3m.es>
Guessing /usr/sbin/httpd args(0)
Warning: can't create /proc/mounts from the /proc filesystem
Done.
在上述过程中,用户不需要在意那些警告信息,因为jail会调用ldd检查httpd用到的库文件。而几乎所有基于共享库的二进制可执行文件都需要上述的几个库文件。
(3)然后,将httpd的相关文件拷贝到“监牢”的相关目录中,命令如下所示:
# mkdir -p /root/chroot/httpd/etc
# cp –a /etc/httpd /root/chroot/httpd/etc/
。。。。。。
添加后的目录结构如下所示:
# ll
总计 56
drwxr-xr-x 2 root root 4096 03-23 13:44 dev
drwxr-xr-x 3 root root 4096 03-23 13:46 etc
drwxr-xr-x 2 root root 4096 03-23 13:46 lib
drwxr-xr-x 2 root root 4096 03-23 13:46 selinux
drwsrwxrwx 2 root root 4096 03-23 13:46 tmp
drwxr-xr-x 4 root root 4096 03-23 13:46 usr
drwxr-xr-x 3 root root 4096 03-23 13:46 var
(4)重新启动httpd,并使用ps命令检查httpd进程,发现该进程已经运行在监牢中,如下所示:
# ps -aux | grep httpd
Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.7/FAQ
root 3546 0.6 0.3 3828 1712 pts/2 S 13:57 0:00 /usr/sbin/nss_pcache off /etc/httpd/alias
root 3550 14.2 3.6 49388 17788 ? Rsl 13:57 0:00 /root/chroot/httpd/httpd
apache 3559 0.2 1.4 49388 6888 ? S 13:57 0:00 /root/chroot/httpd/httpd
apache 3560 0.2 1.4 49388 6888 ? S 13:57 0:00 /root/chroot/httpd/httpd
apache 3561 0.2 1.4 49388 6888 ? S 13:57 0:00 /root/chroot/httpd/httpd
apache 3562 0.2 1.4 49388 6888 ? S 13:57 0:00 /root/chroot/httpd/httpd
apache 3563 0.2 1.4 49388 6888 ? S 13:57 0:00 /root/chroot/httpd/httpd
apache 3564 0.2 1.4 49388 6888 ? S 13:57 0:00 /root/chroot/httpd/httpd
apache 3565 0.2 1.4 49388 6888 ? S 13:57 0:00 /root/chroot/httpd/httpd
apache 3566 0.2 1.4 49388 6888 ? S 13:57 0:00 /root/chroot/httpd/httpd
root 3568 0.0 0.1 4124 668 pts/2 R+ 13:57 0:00 grep httpd
#p#副标题#e#
策略三:启用Apache自带安全模块保护
Apache的一个优势便是其灵活的模块结构,其设计思想也是围绕模块(module)概念而展开的。安全模块是Apache Server中的极其重要的组成部分。这些安全模块负责提供Apache server的访问控制和认证,授权等一系列至关重要的安全服务。
Apache下有如下几类与安全相关的模块:
•mod_access模块能够根据访问者的IP地址(或域名,主机名等)来控制对Apache服务器的访问,称之为基于主机的访问控制。
•mod_auth模块用来控制用户和组的认证授权(Authentication)。用户名和口令存于纯文本文件中。
•mod_auth_db和mod_auth_dbm模块则分别将用户信息(如名称、组属和口令等)存于Berkeley-DB及DBM型的小型数据库中,便于管理及提高应用效率。
•mod_auth_digest模块则采用MD5数字签名的方式来进行用户的认证,但它相应的需要客户端的支持。
•mod_auth_anon模块的功能和mod_auth的功能类似,只是它允许匿名登录,将用户输入的E-mail地址作为口令。
•mod_ssl被Apache用于支持安全套接字层协议,提供Internet上安全交易服务,如电子商务中的一项安全措施。通过对通信字节流加密来防止敏感信息的泄漏。但是,Apache这种支持是建立在对Apache的API扩展来实现的,相当于一个外部模块,通过与第三方程序(如openssl)的结合提供安全的网上交易支持。
为了能够使用模块功能,模块通常以DSO(Dynamic Shared Object)的方式构建,用户应该在httpd.conf文件中使用LoadModule指令,使得能够在使用前获得模块的功能。下面是主配置文件中各个模块的情况,开启安全模块非常简单,即去掉在各安全模块所在行前的“#”符号即可,如下所示:
LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule auth_digest_module modules/mod_auth_digest.so
LoadModule authn_file_module modules/mod_authn_file.so
LoadModule authn_alias_module modules/mod_authn_alias.so
。。。。。。
只有将上述安全模块进行开启后,Apache才能实现相应的访问控制和通信加密功能。
#p#副标题#e#
策略四:访问控制策略设置
在开启了相应的安全模块后,还需要对Apache的访问控制策略进行设定。
1.认证和授权指令
目前,有两种常见的认证类型,基本认证和摘要认证:
(1)基本认证(Basic):使用最基本的用户名和密码方式进行用户认证。
(2)摘要认证(Digest):该认证方式比基本认证要安全得多,在认证过程中额外使用了一个针对客户端的挑战(challenge)信息,可以有效地避免基本认证方式可能遇到的“重放攻击”。值得注意的是:目前并非所有的浏览器都支持摘要认证方式。
所有的认证配置指令既可以出现在主配置文件httpd.conf中的Directory容器中,也可以出现在单独的.htaccess文件中,这个可以由用户灵活地选择使用。在认证配置过程中,需要用到如下指令选项:
•AuthName:用于定义受保护区域的名称。
•AuthType:用于指定使用的认证方式,包括上面所述的Basic和Digest两种方式。
•AuthGroupFile:用于指定认证组文件的位置。
•AuthUserFile:用户指定认证口令文件的位置。
使用上述的认证指令配置认证后,需要为Apache服务器的访问对象,也就是指定的用户和组进行相应的授权,以便于他们对Apache服务器提供的目录和文件进行访问。为用户和组进行授权需要使用Require指令,主要可以使用以下三种方式进行授权:
•授权给指定的一个或者多个用户:使用Require user 用户名1 用户名2 …。
•授权给指定的一个或者多个组:使用Require group 用户名1 用户名2 …。
•授权给指定口令文件中的所有用户:使用Require valid-user。
2.管理认证口令文件和认证组文件
要实现用户认证功能,首先要建立保存用户名和口令的文件。Apache自带的htpasswd命令提供了建立和更新存储用户名、密码的文本文件的功能。需要注意的是,这个文件必须放在不能被网络访问的位置,以避免被下载和信息泄漏。建议将口令文件放在/etc/httpd/目录或者其子目录下。
下面的例子在/etc/httpd目录下创建一个文件名为passwd_auth的口令文件,并将用户rhel5添加入认证口令文件。使用以下命令建立口令文件(过程中还会提示输入该用户的口令):
# touch passwd_auth
# htpasswd -c /etc/httpd/passwd_auth rhel5
New password:
Re-type new password:
Adding password for user rhel5
命令执行的过程中系统会要求用户为rhel5用户输入密码。上述命令中的-c选项表示无论口令文件是否已经存在,都会重新写入文件并删去原有内容。所以在添加第2个用户到口令文件时,就不需要使用-c选项了,如下命令所示
# htpasswd /etc/httpd/passwd_auth testuser
3.认证和授权使用实例
(1)使用主配置文件配置用户认证及授权
在本例子中,用户可以在Apache的主配置文件httpd.conf中加入以下语句建立对目录/var/www/html/rhel5访问的用户认证和授权机制:
<Directory "/var/www/html/rhel5">
AllowOverride None
AuthType Basic
AuthName "rhel5"
AuthUserFile /etc/httpd/passwd_auth
Require user rhel5 testuser
</Directory>
在上述例子中,使用了如下指令:
•AllowOverride:该选项定义了不使用.htaccess文件。
•AuthType Basic:AuthType选项定义了对用户实施认证的类型,最常用的是由mod_auth提供的Basic。
•AuthName:定义了Web浏览器显示输入用户/密码对话框时的领域内容。
•AuthUserFile:定义了口令文件的路径,即使用htpasswd建立的口令文件。
•Require user:定义了允许哪些用户访问,各用户之间用空格分开。
需要注意的是:在AuthUserFile选项定义中,还需要使用如下语句事先建立认证用户patterson和testuser,该选项中的定义才能生效:
#htpasswd -c /etc/httpd/passwd_auth rhel5
#htpasswd /etc/httpd/passwd_auth testuser
(2)使用.htaccess文件配置用户认证和授权
在本例子中,为了完成如上述例子同样的功能,需要先在主配置文件中加入如下语句:
<Directory “/var/www/html/rhel5”>
AllowOverride AuthConfig
</Directory>
上述语句中的AllowOverride选项允许在.htaccess文件中使用认证和授权指令。
然后,在.htaccess文件中添加如下语句即可:
AuthType Basic
AuthName "Please Login:"
AuthUserFile /etc/httpd/passwd_auth
Require user rhel5 testuser
同理,在AuthUserFile选项定义中,还需要使用如下语句事先建立认证用户patterson和testuser,该选项中的定义才能生效:
#htpasswd -c /etc/httpd/passwd_auth rhel5
#htpasswd /etc/httpd/passwd_auth testuser