HTTP 拒绝服务攻击始终是 Web 服务器面临的一大难题。攻击者借助多种手段,让服务器无法正常响应 HTTP 请求,最直接的后果便是 Apache 对系统资源(CPU 和内存)的需求急剧攀升,最终导致系统运行缓慢甚至完全瘫痪。Apache 服务器最大的弱点恰恰在于它的广泛普及——树大招风,它无时无刻不受到 DoS 攻击的威胁。下面梳理几种常见的攻击类型,然后再探讨如何构建一台相对安全的 Apache 服务器。
常见攻击类型
1. 数据包洪水攻击
中断服务器或本地网络最简单的方式就是数据包洪水攻击,通常使用 ICMP(网络层协议)包或 UDP 包。最初的形式是让服务器或网络负载过重,这意味着攻击者的网络速度必须比目标主机更快。使用 UDP 包的优势在于几乎没有包会返回到攻击者的计算机(UDP 效率比 TCP 高 17 倍);而使用 ICMP 包则能让攻击更具变化性——发送有缺陷的包会扰乱并锁定受害者的网络。目前流行的趋势是攻击者欺骗服务器,让其相信正遭受来自自身的洪水攻击。
2. 磁盘攻击
这是一种极不道德的攻击方式,它不仅影响通信,还会直接破坏硬件。伪造的用户请求利用写命令攻击目标计算机硬盘,使其超出极限并强制关闭,后果相当严重。
3. 路由不可达
许多 DoS 攻击将目标集中在路由器上。攻击者先获取控制权,然后操纵目标机器。一旦能够更改路由表条目,整个网络就会陷入瘫痪。这种攻击非常阴险且隐蔽,因为网络管理员排查网络不通的原因时,往往要面对多种可能性,其中一些原因需要仔细分辨。
4. 分布式拒绝服务攻击(DDoS)
这是最具威胁的 DDoS 攻击,名字很容易理解——简单说就是“群殴”。大量客户端同时攻击一台服务器,你会发现它伤痕累累。Apache 服务器尤其容易受到攻击,无论是 DDoS 还是隐藏来源的攻击,都因为 Apache 无处不在。特别是专为 Apache 打造的病毒(如特选 SSL 蠕虫),潜伏在众多主机上,攻击者通过病毒操纵大量被感染的机器,对特定目标发动一场规模浩大的 DDoS 攻击。通过将蠕虫散播到大量主机,大规模的点对点攻击得以进行。除非你不提供服务,否则几乎无法阻止这样的攻击,这类攻击通常瞄准大型网站。
5. 缓冲区溢出
这种攻击很常见。攻击者利用 CGI 程序编写时的缺陷,使其偏离正常流程。程序使用静态内存分配,攻击者发送一个超长请求就能让缓冲区溢出。例如,一些用 Perl 编写的处理用户请求的网关脚本,一旦缓冲区溢出,攻击者就能执行恶意指令。
6. 非法获取 root 权限
如果 Apache 以 root 权限运行,系统上某些程序的逻辑缺陷或缓冲区溢出漏洞,会让攻击者轻松在本地获取 Linux 服务器上的管理员权限。在远程情况下,攻击者会利用一些以 root 身份执行的有缺陷的系统守护进程来获取 root 权限,或者利用有缺陷的服务进程漏洞获取普通用户权限,然后远程登录,进而控制整个系统。
以上列举了服务器可能遭遇的主要攻击手段。下面进入正题——如何打造一台相对安全的 Apache 服务器。如果你能遵守以下建议,将大大降低安全风险。
一、勤打补丁
这是最有效的手段,没有之一。缓冲区溢出等漏洞都必须通过打补丁来防御。勤快一点,绝对没坏处。在 Apache 官方网站的更新日志中,经常能看到“bug fix”“security bug fix”等字样。作为负责任的系统管理员,要经常关注相关漏洞,及时升级系统并添加补丁。
二、隐藏和伪装 Apache 的版本
打乱攻击者的步骤,给攻击者制造麻烦,相信是每个管理员都乐见其成的。软件的漏洞信息与版本密切相关,在攻击者收集服务软件信息时加以迷惑,是个不错的选择。版本号对攻击者来说,就像 GPS 定位一样重要。默认情况下,系统会把 Apache 版本和模块信息显示在 HTTP 返回头中;如果允许目录列举,还会显示域名信息。去除 Apache 版本号的方法很简单:修改配置文件,找到相关关键字,设置如下:
ServerSignature off
ServerTokens prod
通过分析 Web 服务器类型,大致可以推测出操作系统类型——Windows 通常用 IIS,Linux 则普遍用 Apache。默认的 Apache 配置没有任何信息保护机制,并且允许目录浏览。通过目录浏览,很容易得到类似“Apache/1.3.7 Server at apache.linuxforum.net Port 80”或“Apache/2.0.49 (Unix) PHP/4.3.8”的信息。修改配置文件中的 ServerTokens 参数,可以将 Apache 的相关信息隐藏起来。如果不行,可能是提示信息被编译进了程序,需要修改 Apache 的源代码后重新编译。例如,编辑 ap_release.h 文件,将
#define AP_SERVER_BASEPRODUCT "Apache"
改为
#define AP_SERVER_BASEPRODUCT "Microsoft-IIS/5.0"
编辑 os/unix/os.h 文件,将
#define PLATFORM "Unix"
改为
#define PLATFORM "Win32"
修改完成后,重新编译安装 Apache,再按上述方法修改配置文件。启动后,用工具扫描,会发现提示信息已经显示为 Windows 操作系统了。顺便提一句,有些网站在这方面做得不够严谨,返回的头信息直接暴露了详细的软件版本和模块列表,这等于告诉恶意用户很多有用信息。虽然不算敞开了大门,但相当于告诉别人门在哪里,风险依然很高。
三、建立安全的目录结构
Apache 服务器通常包含四个目录:
- ServerRoot:保存配置文件、二进制文件与其他服务器配置文件
- DocumentRoot:保存 Web 站点内容,包括 HTML 文件和图片等
- ScriptAlias:保存 CGI 脚本
- CustomLog 和 ErrorLog:保存日志
建议的目录结构是让以上目录相互独立,不存在父子逻辑关系。注意权限设置:
- ServerRoot 目录只能由 root 用户访问
- DocumentRoot 目录应能被管理 Web 站点内容的用户访问,同时被 Apache 用户和组访问
- ScriptAlias 目录只能被 CGI 开发人员和 Apache 用户访问
- CustomLog 和 ErrorLog 只能被 root 访问
一个安全的目录结构示例如下:
+-------/etc/
| +----/http (ServerRoot)
| +----/logs (CustomLog 和 ErrorLog)
+-------var/www
+---/cgi-bin (ScriptAlias)
+---/html (DocumentRoot)
这样的结构因为目录之间独立,某个目录权限错误不会影响到其他目录。
四、为 Apache 使用专门的用户和组
按照最小特权原则,需要给 Apache 分配一个合适的权限,使其能完成 Web 服务即可。最小特权原则是系统安全中最基本的原则之一:限制使用者对系统及数据进行存取所需的最小权限,既保证用户能完成任务,又能确保被窃取或异常操作造成的损失最小化。
必须保证 Apache 使用一个专门的用户和组,不要使用系统预定的账户(比如 nobody 用户和 nogroup 组)。只有 root 用户可以运行 Apache,但子进程应该以专用用户运行。假设希望用户“test”在 Web 站点发布内容,并且以 httpd 身份运行 Apache,可以这样设置:
groupadd webteam
usermod -G webteam test
chown -R httpd.webteam /www/html
chmod -R 2570 /www/htdocs
日志文件只允许 root 访问,推荐权限如下:
chown -R root.root /etc/logs
chmod -R 700 /etc/logs
五、Web 目录的访问策略
对于可访问的 Web 目录,要使用相对保守的途径进行访问,不要让用户查看任何目录索引列表。
禁止使用目录索引: Apache 在接到用户对目录的访问请求时,会查找 DirectoryIndex 指令指定的索引文件(默认为 index.html)。如果该文件不存在,Apache 会创建动态列表,显示该目录的内容,这就会暴露 Web 站点结构。因此需要修改配置文件,禁止显示动态目录索引:
Options -Indexes FollowSymLinks
这里 Options 指令中的 -Indexes 表示禁止目录索引,FollowSymLinks 表示允许使用符号链接(但要注意安全风险)。
禁止默认访问: 安全策略必须禁止默认访问,只对指定的目录开放权限。如果允许访问 /var/www/html 目录,使用如下设定:
Order deny,allow
Allow from all
禁止用户重载: 为了禁止用户通过 .htaccess 文件修改目录配置,可以这样设定:
AllowOverride None
六、Apache 服务器访问控制
Apache 的访问控制可以通过 access.conf 文件(或直接写在 httpd.conf 中)设置,实现基于域名和 IP 地址的访问控制。例如,允许 192.168.1.1 到 192.168.1.254 的主机访问:
Order deny,allow
Deny from all
Allow from pair 192.168.1.0/255.255.255.0
七、Apache 服务器的密码保护
.htaccess 文件是 Apache 上的一个设置文件,它是一个文本文件,提供了针对目录改变配置的方法——通过在一个特定的文档目录中放置一个包含一个或多个指令的文件(.htaccess),可以作用于该目录及其子目录。.htaccess 的功能包括:设置网页密码、设置错误页面、改变首页文件名、禁止读取文件、重定向、添加 MIME 类型、禁止目录下的文件访问等。
注意:.htaccess 是一个完整的文件名,不是 ***.htaccess 或其他格式。在 /abc 目录下放置一个 .htaccess 文件,那么 /abc 及其子目录都会被影响,但 /index.html 不会被影响。
.htaccess 的建立和使用比较复杂,这里不展开写。这种保护比某些程序实现的密码保护更安全——那些程序可能通过猜测方式获取密码,而 .htaccess 很难被破解。但文本方式的验证速度较慢,对少量用户没影响,对大量用户就需要使用带数据模块的验证了,这需要在编译源代码时开启相应模块,默认是不开启的。
八、让 Apache 运行在“监牢”中
“监牢”指的是通过 chroot 机制更改某个软件运行时所能看到的根目录。简单说,就是限制软件只能访问指定目录及其子目录,从而保证整个服务器的安全。即使被破坏或侵入,损伤也有限。
以前,Unix/Linux 上的守护进程都以 root 权限启动,这似乎是理所当然的——像 Apache 这样的服务器需要绑定到 80 端口监听请求,而 root 是唯一有这种权限的用户。但攻击手段和强度不断增加,一旦被利用缓冲区溢出漏洞,攻击者就能控制整个系统。现在的服务器设计通常以 root 启动,然后进程放弃 root 权限,改为某个低级的账号运行。这种方式虽然降低了危害,但攻击者仍可能寻找漏洞提升权限,即使无法获得 root 权限,也能删除文件、篡改主页等。
为了进一步提高系统安全性,Linux 内核引入了 chroot 机制。chroot 是一个系统调用,软件可以通过调用 chroot 函数来更改某个进程所能见到的根目录。例如,Apache 安装在 /usr/local/httpd 目录,以 root 启动后,父进程会派生多个以 nobody 权限运行的子进程。父进程监听 80 端口,然后交给某个子进程处理。此时子进程的目录继承父进程,即 /usr/local/httpd 目录。但如果目录权限设定错误,被攻击的 Apache 子进程可以访问 /usr/local、/usr、/tmp 甚至整个文件系统,因为 Apache 进程的根目录仍然是整个文件系统的根目录。如果通过 chroot 将 Apache 限制在 /usr/local/httpd/ 下,那么 Apache 所存取的文件都被限制在该目录下。创建 chroot 监牢的作用就是将进程权限限制在文件目录树下,保证安全。
手动搭建 Apache 的 chroot 监牢非常繁琐,需要牵扯到库文件。可以使用 jail 包来简化实现(具体过程这里不展开)。
九、Apache 服务器防范 DoS
Apache 经常遭遇 DoS 攻击,主要防范手段是通过软件模块。例如 Apache DoS Evasive Maneuvers Module,它是一款 mod_access 的替代软件,可以对抗 DoS 攻击。该模块能快速拒绝来自相同地址对同一 URL 的重复请求,通过查询内部一张各子进程的哈希表来实现。相关工具可以在安全社区找到。
十、减少 CGI 和 SSI 风险
CGI 脚本的漏洞已经成为 Web 服务器的首要安全隐患。通常,程序编写 CGI 脚本时会产生许多漏洞。控制风险的方法除了在编写时注意对输入数据的合法检查、谨慎使用系统调用外,首先应该使用 CGI 程序所有者的 ID 来运行这些程序,这样即使被漏洞利用,危害也仅限于该 ID 能访问的文件,不会对整个系统带来致命影响。因此,必须谨慎使用 CGI 程序。
Apache 1.3 版集成了 suEXEC 程序,可以为 Apache 提供 CGI 程序的控制支持。可以把 suEXEC 看作一个包装器:Apache 接到 CGI 程序的调用请求后,将其交给 suEXEC 完成具体调用,并从 suEXEC 返回结果。suEXEC 能解决一些安全问题,但会影响速度。如果对安全性要求很高,建议使用 suEXEC。此外,还有 CGIWrap 软件,它的安全性比 suEXEC 更高。
减少 SSI 脚本风险:如果使用 exec 等 SSI 命令运行外部程序,也会存在类似 CGI 脚本的风险。除内部调试程序外,应使用以下选项禁止其使用:
Options IncludesNOEXEC
十一、使用 SSL 加固 Apache
使用具有 SSL 功能的服务器,可以提高网站敏感页面的安全性。SSL 工作在 TCP/IP 协议和 HTTP 协议之间,能够加密互联网上传递的数据流,提供身份验证——比如在线购物时不必担心别人窃取信用卡信息。在电子商务和基于 Web 的邮件场景中,SSL 非常重要。SSL 的配置相对复杂,有需要可以查阅相关资料。
