开源 Apache 服务器安全防护技术精要及实战

jopen 11年前

Apache 一直是世界上使用率排名前三的 Web 服务器软件。企业使用其构建 Web 应用,从很大程度上都需要对其安全性进行综合考虑,以保证能够应对拒绝服务攻击、流量窃听、数据泄漏等网络威胁,从而保证企业门户网站的安全。除了使用业 界流行的防火墙、IDS/IPS(入侵检测系统 / 入侵防御系统)、WAF(Web 应用防火墙)、UTM(统一威胁管理)等外部安全设备对 Apache 服务进行安全防护外,作为一种优秀的开源服务器软件,Apache 本身就具有很多优秀的特性可以为服务器管理员提供安全配置,以防范各种网络攻击。因此,充分、高效地挖掘 Apache 服务器的自身安全能力也是企业安全工作者一个必备的技能。基于此,本文将通过大量的实例,从服务器安全设置、运行环境安全保障、安全模块保护、日志管理等 6 个方面详细剖析 Apache 服务器的安全防护要点。

Apache 服务简介

Web 服务器也称为 WWW 服务器或 HTTP 服务器 (HTTP Server),它是 Internet 上最常见也是使用最频繁的服务器之一,Web 服务器能够为用户提供网页浏览、论坛访问等等服务。

由于用户在通过 Web 浏览器访问信息资源的过程中,无须再关心一些技术性的细节,而且界面非常友好,因而 Web 在 Internet 上一推出就得到了爆炸性的发展。现在 Web 服务器已经成为 Internet 上最大的计算机群,Web 文档之多、链接的网络之广,也令人难以想像。因此,Web 服务器软件的数量也开始增加,Web 服务器软件市场的竞争也越来越激烈。本文所讨论的就是一款最常用的 Web 服务器软件—— Apache。

Apache 是一个免费的软件,用户可以免费从 Apache 的官方网站下载。任何人都可以参加其组成部分的开发。Apache 允许世界各地的人对其提供新特性。当新代码提交到 Apache Group 后,Apache Group 对其具体内容进行审查并测试和质量检查。如果他们满意,该代码就会被集成到 Apache 的主要发行版本中。

Apache 的其他主要特征有:

  • 支持最新的 HTTP 协议:是最先支持 HTTP1.1 的 Web 服务器之一,其与新的 HTTP 协议完全兼容,同时与 HTTP1.0、HTTP1.1 向后兼容。Apache 还为支持新协议做好了准备。
  • 简单而强大的基于文件的配置:该服务器没有为管理员提供图形用户界面,提供了三个简单但是功能异常强大的配置文件。用户可以根据需要用这三个文件随心所欲地完成自己希望的 Apache 配置。
  • 支持通用网关接口(CGI):采用 mod_cgi 模块支持 CGI。Apache 支持 CGI/1.1 标准,并且提供了一些扩充。
  • 支持虚拟主机:是首批既支持 IP 虚拟主机又支持命名虚拟主机的 Web 服务器之一。
  • 支持 HTTP 认证:支持基于 Web 的基本认证。它还有望支持基于消息摘要的认证。
  • 内部集成 Perl:Perl 是 CGI 脚本编程的事实标准。Apache 对 Perl 提供了良好的支持,通过使用其 mod_perl 模块,还可以将 Perl 的脚本装入内存。
  • 集成代理服务器:用户还可以选择 Apache 作为代理服务器。
  • 支持 SSL:由于版本法和美国法律在进出口方面的限制,Apache 本身不支持 SSL。但是用户可以通过安装 Apache 的补丁程序集合(Apache-SSL)使得 Apache 支持 SSL。
  • 支持 HTTP Cookie:通过支持 Cookie,可以对用户浏览 Web 站点进行跟踪。

Apache 服务面临的网络威胁

一般说来,Apache 服务器主要面临如下几种网络威胁:

  1. 使用 HTTP 协议进行的拒绝服务攻击:攻击者会通过某些手段使服务器拒绝对 HTIP 应答。这样会使 Apache 对系统资源(CPU 时间和内存)需求巨增,造成 Apache 系统变慢甚至完全瘫痪,从而引起 HTTP 服务的中断或者合法用户的合法请求得不到及时地响应;
  2. 缓冲区溢出攻击:由于 Apache 源代码完全开放,攻击者就可以利用程序编写的一些缺陷,使程序偏离正常流程。程序使用静态分配的内存保存请求数据,攻击者就可以发送一个超长请求使缓冲区溢出,从而导致缓冲区溢出攻击;
  3. 被攻击者获得 root 权限,威胁系统安全:由于 Apache 服务器一般以 root 权限运行,攻击者通过它获得 root 权限,进而控制整个 Apache 系统;
  4. Apache 服务器与客户端通信安全:如果采用明文传输,则服务器与客户端的敏感通信信息将有可能被黑客或者不法用户获取;
  5. 由于 Apache 配置文件设置不当引起的安全问题:恶意者可以随意下载或修改删除系统文件。这主要涉及到对访问者的内容和权限的限制。

要应对上述这些安全威胁,要从 Apache 服务器端配置、运行环境、通信链路安全保障、安全模块使用、日志管理等各方面、全方位的进行保障,下面将进行分门别类的详细介绍。

Apache 服务器端安全设置

限制 root 用户运行 Apache 服务器

一般情况下,在 Linux 下启动 Apache 服务器的进程 httpd 需要 root 权限。由于 root 权限太大,存在许多潜在的对系统的安全威胁。一些管理员为了安全的原因,认为 httpd 服务器不可能没有安全漏洞,因而更愿意使用普通用户的权限来启动服务器。http.conf 主配置文件里面有如下 2 个配置是 Apache 的安全保证,Apache 在启动之后,就将其本身设置为这两个选项设置的用户和组权限进行运行,这样就降低了服务器的危险性。

User apache

Group apache

需要特别指出的是:以上 2 个配置在主配置文件里面是默认选项,当采用 root 用户身份运行 httpd 进程后,系统将自动将该进程的用户组和权限改为 apache,这样,httpd 进程的权限就被限制在 apache 用户和组范围内,因而保证了安全。

向客户端隐藏 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. 错误情况下未设定安全选项前示意
开源 Apache 服务器安全防护技术精要及实战
图 2. 操作情况下使用安全设定后的对比

开源 Apache 服务器安全防护技术精要及实战

设置虚拟目录和目录权限

要从主目录以外的其他目录中进行发布,就必须创建虚拟目录。虚拟目录是一个位于 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″

如果需要对其进行权限设置,可以加入如下语句:

    AllowOverride None    Options Indexes    Order allow,deny    Allow from all   

设置该虚拟目录和目录权限后,可以使用客户端浏览器进行测试验证,采用别名对该目录中的文件进行访问,浏览结果如图 3 所示。

图 3. 使用虚拟目录的测试结果

开源 Apache 服务器安全防护技术精要及实战

限制 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       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       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

启用 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 才能实现相应的访问控制和通信加密功能。

Apache 访问控制策略设置

在开启了相应的安全模块后,还需要对 Apache 的访问控制策略进行设定。

认证和授权指令

目前,有两种常见的认证类型,基本认证和摘要认证:

(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。

管理认证口令文件和认证组文件

要实现用户认证功能,首先要建立保存用户名和口令的文件。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

认证和授权使用实例

配置指令

Apache 实现访问控制的配置指令包括如下三种:

(1)order 指令:用于指定执行允许访问控制规则或者拒绝访问控制规则的顺序。order 只能设置为 Order allow,deny 或 Order deny,allow,分别用来表明用户先设置允许的访问地址还是先设置禁止访问的地址。Order 选项用于定义缺省的访问权限与 Allow 和 Deny 语句的处理顺序。Allow 和 Deny 语句可以针对客户机的域名或 IP 地址进行设置,以决定哪些客户机能够访问服务器。Order 语句设置的两种值的具体含义如下:

  • allow, deny:缺省禁止所有客户机的访问,且 Allow 语句在 Deny 语句之前被匹配。如果某条件既匹配 Deny 语句又匹配 Allow 语句,则 Deny 语句会起作用(因为 Deny 语句覆盖了 Allow 语句)。
  • deny, allow:缺省允许所有客户机的访问,且 Deny 语句在 Allow 语句之前被匹配。如果某条件既匹配 Deny 语句又匹配 Allow 语句,则 Allow 语句会起作用(因为 Allow 语句覆盖了 Deny 语句)。

(2)allow 指令:指明允许访问的地址或地址序列。如 allow from all 指令表明允许所有 IP 来的访问请求。

(3)deny 指令:指明禁止访问的地址或地址序列。如 deny from all 指令表明禁止所有 IP 来的访问请求。

应用实例

下面举几个简单的例子对上述 order、allow 和 deny 命令的使用进行示范。

(1)在下面的例子中,admin.org 域中所有主机都允许访问网站,而其他非该域中的任何主机访问都被拒绝,因为 Deny 在前,Allow 在后,Allow 语句覆盖了 Deny 语句:

Order Deny,Allow   Deny from all   Allow from admin.org
(2)下面例子中,admin.org 域中所有主机,除了 db.admin.org 子域包含的主机被拒绝访问以外,都允许访问。而所有不在 admin.org 域中的主机都不允许访问,因为缺省状态是拒绝对服务器的访问(Allow 在前,Deny 在后,Deny 语句覆盖了 Allow 语句):
Order Allow,Deny   Allow from admin.org   Deny from db.admin.org

使用主配置文件配置用户认证及授权

在本例子中,用户可以在 Apache 的主配置文件 httpd.conf 中加入以下语句建立对目录 /var/www/html/rhel5 访问的用户认证和授权机制:

    AllowOverride None   AuthType Basic   AuthName "rhel5"   AuthUserFile /etc/httpd/passwd_auth   Require user rhel5 testuser   

在上述例子中,使用了如下指令:

  • 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

使用 .htaccess 文件配置用户认证和授权

在本例子中,为了完成如上述例子同样的功能,需要先在主配置文件中加入如下语句:

    AllowOverride AuthConfig   
上述语句中的 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

保证 Apache 服务通信安全

Apache 中 SSL 原理

在 SSL 通信中,首先采用非对称加密交换信息,使得服务器获得浏览器端提供的对称加密的密钥,然后利用该密钥进行通信过程中信息的加密和解密。为了保证消息在传递 过程中没有被篡改,可以加密 Hash 编码来确保信息的完整性。服务器数字证书主要颁发给 Web 站点或其他需要安全鉴别的服务器,证明服务器的身份信息,同样客户端数字证书用于证明客户端的身份。

使用公用密钥的方式可以保证数据传输没有问题,但如果浏览器客户访问的站点被假冒,这也是一个严重的安全问题。这个问题不属于加密本身,而是要保证密钥本 身的正确性问题。要保证所获得的其他站点公用密钥为其正确的密钥,而非假冒站点的密钥,就必须通过一个认证机制,能对站点的密钥进行认证。当然即使没有经 过认证,仍然可以保证信息传输安全,只是客户不能确信访问的服务器没有被假冒。如果不是为了提供电子商务等方面对安全性要求很高的服务,一般不需要如此严 格的考虑

下面给出使用 SSL 进行通信的过程(参见图 4):

(1)客户端向服务器端发起对话,协商传送加密算法。例如:对称加密算法有 DES、RC5,密钥交换算法有 RSA 和 DH,摘要算法有 MD5 和 SHA。

(2)服务器向客户端发送服务器数字证书。比如:使用 DES-RSA-MD5 这对组合进行通信。客户端可以验证服务器的身份,决定是否需要建立通信。

(3)客户端向服务器传送本次对话的密钥。在检查服务器的数字证书是否正确,通过 CA 机构颁发的证书验证了服务器证书的真实有效性之后,客户端生成利用服务器的公钥加密的本次对话的密钥发送给服务器。

(4)服务器用自己的私钥解密获取本次通信的密钥。

(5)双方的通信正式开始。

图 4. SSL 通信流程示意
开源 Apache 服务器安全防护技术精要及实战
在一般情况下,当客户端是保密信息的传递者时,他不需要数字证书验证自己身份的真实性,如用户通常使用的网上银行交易活动,客户需要将自己的隐秘信息—— 账号和密码发送给银行,因此银行的服务器需要安装数字证书来表明自己身份的有效性,否则将会使得信息泄露。当然,在某些安全性要求极高的 B2B(Business to Business)应用,服务器端也需要对客户端的身份进行验证,这时客户端也需要安装数字证书以保证通信时服务器可以辨别出客户端的身份,验证过程类似 于服务器身份的验证过程。另外,在一些电子商务的应用中,可能还会使用到电子签名,或者为了信息交换的更加安全,会增加电子签名和消息校验码(MAC)。 而在通常情况下,浏览器都会通过交互的方式来完成上述的通信过程,下面在 Linux 中对 Apache 采用 SSL 也会作详细地介绍。

安装和启动 SSL

安装 SSL

虽然 Apache 服务器不支持 SSL,但 Apache 服务器有两个可以自由使用的支持 SSL 的相关计划,一个为 Apache-SSL,它集成了 Apache 服务器和 SSL,另一个为 Apache+mod_ssl,它是通过可动态加载的模块 mod_ssl 来支持 SSL,其中后一个是由前一个分化出的,并由于使用模块,易用性很好,因此使用范围更为广泛。还有一些基于 Apache 并集成了 SSL 能力的商业 Web 服务器,然而使用这些商业 Web 服务器主要是北美,这是因为在那里 SSL 使用的公开密钥的算法具备专利权,不能用于商业目的,其他的国家不必考虑这个专利问题,而可以自由使用 SSL。

Apache+mod_ssl 依赖于另外一个软件:OpenSSL,它是一个可以自由使用的 SSL 实现,首先需要安装这个软件。用户可以从网站 http://www.openssl.org/source/ 上下载 Linux 下 OpenSSL 的最新稳定版本:openssl-1.0.1c.tar.gz。

下载源代码安装包后,使用如下的步骤安装即可:

(1)用 openssl-1.0.1c.tar.gz 软件包安装 OpenSSL 之前,首先须要对该软件包进行解压缩和解包。用以下命令完成软件包的解压缩和解包:

#tar xvfz openssl-1.0.1c.tar.gz

(2)解压缩后,进入源码的目录 openssl-1.0.1c ,并使用配置脚本进行环境的设置。相应的命令为:

// 改变当前目录为 openssl-1.0.1c 目录   #cd openssl-1.0.1c          // 执行该目录下配置脚本程序   #./configure
(3)在执行 ./configure 之后,配置脚本会自动生成 Makefile。如果在设置的过程中没有任何的错误,就可以开始编译源码了。相应的命令及其显示结果如下:
</div>
#make & make install

安装好 OpenSSL 之后,就可以安装使用 Apache+mod_ssl 了。然而为了安装完全正确,需要清除原先安装的 Apache 服务器的其他版本,并且还要清除所有的设置文件及其缺省设置文件,以避免出现安装问题。最好也删除 /usr/local/www 目录(或更名),以便安装程序能建立正确的初始文档目录。如果是一台没有安装过 Apache 服务器的新系统,就可以忽略这个步骤,而直接安装 Apache+mod_ssl 了。

启动和关闭 SSL

启动和关闭该服务器的命令如下所示:

  • #apachectl start:启动 apache。
  • #apachectl startssl:启动 apache ssl。
  • #apachectl stop:停止 apache。
  • #apachectl restart:重新启动 apache。
  • #apachectl status:显示 apache 的状态。
  • #apachectl configtest:测试 httpd.conf 配置是否正确。
  • # /usr/local/sbin/apachectl startssl

此时使用 start 参数为仅仅启动普通 Apache 的 httpd 守护进程,而不启动其 SSL 能力,而 startssl 才能启动 Apache 的 SSL 能力。如果之前 Apache 的守护进程正在运行,便需要使用 stop 参数先停止服务器运行。

为 OpenSSL 产生证书

在采用 OpenSSL 进行 Apache 通信加密前,需要先产生与加密相关的认证凭证(也就是证书),如下步骤所示:

# openssl genrsa -out apache.key 1024   Generating RSA private key, 1024 bit long modulus   ..........................................++++++   .....................++++++   e is 65537 (0x10001)      # openssl req -new -key apache.key -out apache.csr   You are about to be asked to enter information that will be incorporated   into your certificate request.   What you are about to enter is what is called a Distinguished Name or a DN.   There are quite a few fields but you can leave some blank   For some fields there will be a default value,   If you enter '.', the field will be left blank.   -----   Country Name (2 letter code) [GB]:CN   State or Province Name (full name) [Berkshire]:China   Locality Name (eg, city) [Newbury]:Beijing   Organization Name (eg, company) [My Company Ltd]:CSO   Organizational Unit Name (eg, section) []:CSO   Common Name (eg, your name or your server's hostname) []:localhost   Email Address []:CSO@ittf.org.cn      Please enter the following 'extra' attributes   to be sent with your certificate request   A challenge password []:apacheserver   An optional company name []:apacheserver      # openssl x509 -req -days 365 -in apache.csr -signkey apache.key -out apache.crt   Signature ok   subject=/C=CN/ST=China/L=Beijing/O=CSO/OU=CSO/CN=localhost/emailAddress=CSO@ittf.org.cn   Getting Private key

经过上述步骤后,将会产生三个文件 apache.csr, apache.key 和 apache.crt,然后把这三个文件拷贝到 /etc/httpd/conf/ca 目录下即可。

然后,就可以启动 Mozilla、IE 或其他支持 SSL 的浏览器,输入 URL 为:https://ssl_server/来查看服务器是否有相应,https 使用的缺省端口为 443,如果一切正常,服务器将会返回给客户端证书,由客户端进行验证并且判断,是否接受该证书并进行下一步的通信过程。

下面以 Linux 下的 Mozilla Firefox 浏览器为例,来简要说明使用 Apache+SSL 服务器的过程。首先,图 5 给出了查看和验证该证书的相关提示;最后,图 6 则给出了证书验证成功后,采用 SSL 进行保密传输的具体界面示意:

图 5. 验证证书示意

开源 Apache 服务器安全防护技术精要及实战

图 6. 证书通过验证,正常通信开始

开源 Apache 服务器安全防护技术精要及实战

Apache 日志管理

日志管理分类

日志文件是用户管理和监控 Apache 安全的非常好的第一手资料,它清晰地记录了客户端访问 Apache 服务器资源的每一条记录,以及在访问中出现的错误信息,可以这样说,Apache 可以记录 Web 访问中感兴趣的几乎所有信息。

当运行 Apache 服务器时生成 4 个标准的日志文件:

  • 错误日志
  • 访问日志
  • 传输日志
  • Cookie 日志

其中比较常见的是访问日志(access_log)和错误日志(error_log),其中传输日志和 cookie 日志被 Apache 2.0 以上的版本丢弃,所以本文不讨论这两种日志。当然,如果使用 SSL 服务的话,还可能存在 ssl_access_log、ssl_error_log 和 ssl_request_log 三种日志文件。

另外,值得注意的是:上述几种日志文件如果长度过大,还可能生成注入 access_log.1,error_log.2 等的额外文件,其格式与含义与上述几种文件相同,只不过系统自动为其进行命名而已。

日志相关的配置指令

Apache 中提供如下 4 条与日志相关的配置指令:

  • ErrorLog 指令:用于指定错误日志的存放路径,使用语法为:ErrorLog 文件名;
  • LogLevel:用于指定错误日志的错误登记,使用语法为:Loglevel 等级;
  • LogFormat:用于为日志记录格式命名,使用语法为:LogFormat 记录格式说明字符串 格式称谓;
  • CustomLog:用于指定访问日志存放路径和记录格式,指定访问日志由指定的程序生成并指定日志的记录格式,使用语法为:CustomLog 日志文件名 格式称谓。

在上述几个文件当中,除了 error_log 和 ssl_error_log 之外,所有日志文件以由 CustomLog 和 LogFormat 指令指定的格式生成。这些指令在 httpd.conf 文件中出现。使用 LogFormat 指令可以定义新的日志文件格式:

LogFormat “%h  %l  %u  %t  \ “%> %s %b “common

假定使用的是 common 日志格式或者 combined 日志格式,这两种格式都在默认的配置文件中定义。表 1 列出了 LogFormat 语句可以使用的变量:

表 1. LogFormat 语句的变量

变 量 含 义
%b 发送字节,不包括 HTTP 标题
%f 文件名
%{VARIABLE}e 环境变量 VARIABLE 的内容
%h 远程主机
%a 远程 IP 地址
%{HEADER}i HEADER 内容;发送到服务器的请求的标题行
%l 远程登录名(如果提供该值,则从 identd 获得)
%{NOTE}n 来自另一个模块的 NOTE 通知的内容
%{HEADER}o HEADER 的内容,回复中的标题行
%p 服务器服务于请求的规范端口
%P 服务于请求的子进程的 ID
%r 请求的第一行
%s 状态。对于内部重定向的请求,该状态为初始请求—最后是 %>s
%t 时间,格式为 common 日志格式中的时间格式
%{format}t 时间,格式由 format 给出。可以是 strftime(3)格式
%T 服务请求花费的时间,以秒计
%u 来自 auth 的远程用户;如果返回的状态(%s)为 401 则可能是假的
%U 请求的 URL 路径
%v 服务于该请求的服务器的规范 ServerName
在每个变量中,可以在前面设置一个条件,决定是否显示该变量。如果不显示,则显示 -。这些条件是数值返回值列表的形式。另外,还可以使用 CustomLog 指令指定日志文件的位置和格式。如果没有指定日志文件的绝对路径,则日志文件的位置假定为相对于 ServerRoot。下面是 httpd.conf 文件中指定日志文件的语句:
//   // The location and format of the access logfile(Common Logfile Format).   // If you do not define any access logfiles within a   // container, they will be logged here.  Contrariwise, if you *do*   // define per- access logfiles, transactions will be   // logged therein and *not* in this file.   //   CustomLog logs/access_log common      ErrorLog logs/error_log

日志记录等级和分类

一般说来,Apache 中的错误日志记录等级有如表 2 所示的八类:

表 2. 错误日志记录的等级

紧急性 等级 解释
1 Emerg 出现紧急状况使得系统不可用
2 Alert 需要立即引起注意的状况
3 Crit 危险情况的警告
4 Error 除上述 3 种情况之外的其他错误
5 Warn 警告信息
6 Notice 需要引起注意的情况,不如第 4 和第 5 类重要
7 Info 需要报告的一般消息
8 Debug 运行于 debug 模式的程序产生的消息

另外,在 Apache 中,将访问日志分为如下 4 类:

  • 普通日志格式(common log format,CLF):大多数日志分析软件都支持这种格式,其在 LogFormat 指定中定义的昵称为 common;
  • 参考日志格式(referer log format):记录客户访问站点的用户身份,其在 LogFormat 指定中定义的昵称为 referer;
  • 代理日志格式(agent log format):记录请求的用户代理,其在 LogFormat 指定中定义的昵称为 agent;
  • 综合日志格式(combined log format):即结合上述三种格式的日志信息,其在 LogFormat 指定中定义的昵称为 combined。

在实际的使用过程中,由于综合日志格式有效地结合了其他 3 种日志格式和信息,所以在配制访问日志时,可以有两种方式:

(1)分别使用 3 个文件进行分别记录,相应配置示例如下:

LogFormat “%h %l %u %t \ “%r\” %>s %b” common   LogFormat “%{Referer}i->%U” referer   LogFormat “%{Apache User-agent}i” agent   CustomLog logs/access_log common   CustomLog logs/referer_log referer   CustomLog logs/agent_log agent
(2)使用一个综合文件进行记录,相应配置示例如下:
LogFormat “%h %l %u %t \ “%r\” %>s %b \”%{Referer}i\” \    “%{Apache User-Agent}i\””combined  CustomLog logs/access_log combined