一个安全WEB服务器的安装

发表于:2007-05-25来源:作者:点击数: 标签:
简介 WEB服务器是Internet上最暴露的服务器。为了让客户/目标用户群访问提供的信息,WEB服务器必需是Internet上的任何接入点都可以访问的。与其它诸如DNS和FTP等公共服务相比,WEB对黑客高手更有诱惑力,因为一个成功地侵入一个网站的人可以更改主页从而让别
简介

  WEB服务器是Internet上最暴露的服务器。为了让客户/目标用户群访问提供的信息,WEB服务器必需是Internet上的任何接入点都可以访问的。与其它诸如DNS和FTP等公共服务相比,WEB对黑客高手更有诱惑力,因为一个成功地侵入一个网站的人可以更改主页从而让别人更加意识到他的存在。这些入侵事件能够让一个公司失去客户的信任,尤其是当一些敏感数据(如信用卡详细信息等)被窃取甚至被公开时就更加严重。

  如果说用于防止从Internet对内部网络进行攻击的防火墙是最重要网络安全领域的话,WEB服务器应该说是第二个需要高度安全的领域了。本文的目标就是如何只用45分钟的时间就可以在Linux系统上配置一个安全的WEB服务器。当然,您也可以在其他操作系统上完成同样的事情。下面是基于SuSE Linux 6.4发布的一个例子。

  安全区域

  服务器安全由几个安全区域组成,为了保证允许条件下的最高度的安全保护,安全必需在每个区域都予以一致的实现。

  1. 基础设施区

  基础设施区域定义服务器在网络中的位置。这个区域必需能够防止数据窃听、网络映射和端口扫描等黑客技术的威胁。而且,可以跟踪对一个暴露的WEB服务器的成功入侵,因为被侵入的服务器可能会用来作为攻击其它重要的服务器的基地(这种方式在DoS攻击中最为常见)。

  在这一端,所有提供Internet服务的服务器都通过一个集中部件保护起来并且位于一个隔离的网络是必需的。这个隔离的网络称为非军事区(DMZ)。具有保护功能的组件可能是一个复杂的防火墙或一个简单的路由器(这个路由器配置了具有很强限制的包过滤规则)。因此,仅仅指定的服务器服务才是允许访问的。

  一般DMZ会采用一个具有端口安全和报文洪水保护的转换开关,这种方式可以保证DMZ的高度安全。

  如果您关心物理安全,那么您必需保证服务器安装在一个安全的房间里(或数据处理中心)并且所有的电源、电话线和网线等都必需得到物理上的保护。

  2. 网络协议区

  网络通信一般指的都是TCP/IP通信,操作系统内核对通信负责并且保证一个透明的通信流。然而,一些函数或者协议的易受攻击点可能会被用来发起攻击或破坏行为。因此,内核必需经过必要的配置,以便阻挡这些类型的攻击手段。虽然位于服务器前面的防火墙或路由器可以防止很多类型的攻击,但一些WEB服务器的设置也必需做一些相应的调整。

  防止SYN洪水攻击是很关键的,在所有的操作系统中,Linux提供了一种称为SYNcookies的最有效解决方案。此外,ICMP重定向和对广播地址的ping操作以及IP源路由包也应该被拒绝。适用附加的内核过滤函数可以增加安全级别。

  3. 服务区

  服务区定义需要哪些服务。通过“如果不是指定需要的全部禁止”的安全策略,服务器上仅仅配置完成必要的操作所必需的服务,否则就会为攻击者提供更多的攻击点。

  仅适用可以保证足够安全级的服务:没有充分认证能力的服务(如:rexec)或者传输未经过加密的敏感数据的服务(如telnet、ftp或通过WWW传输信用卡敏感数据)都应该用更安全的相应服务所替代(如SSH、SSLftp或HTTPS)。

  4. 应用区

  为安全起见,每个服务都必需单独配置。一个配置的不好的邮件服务器可能会被用来发送垃圾邮件,配置不好的WEB服务器可以执行所有的系统命令。注意,千万不要创建具有高特权的服务(root)。

  您必需仔细研读您所适用的软件的操作手册中的相关内容才可以更安全地配置您的应用。

  5. 操作系统区

  最后的保护机制是操作系统自身。如果如果应用区的安全方法配置合理的话,即使入侵者成功地进入计算机系统也没有足够的管理权限完成破坏工作。程序的安装,尤其是高特权的程序,应该限制在系统操作的绝对需要范围内。许多高特权的程序可以通过更高级别的认证来限制用户的滥用,因为系统中的标准用户帐号根本不需要使用这些程序。但这还远远不够,万一攻击者成功地进入计算机系统,应该存在一个检测入侵的机制。这被称为“基于主机的入侵检测”。当然,最好还要能够监视和记录系统中的文件操作,以便了解入侵者的真正意图。当然也不能忽视经常性地备份,并且不要丢弃旧的备份文件。这种做法不仅可以用来配置备份服务器和避免数据丢失,它还可以用来跟踪系统中文件的操作情况。如果有几个管理员同时管理一个服务器,那么一个记录谁执行过哪些操作的机制可以在下面提及。

  想定

  Internet需要配置一台自己的WEB服务器,由于没有自己的安全基础设施,应该在WEB服务器前面放一台配置了相应过滤规则的路由器。这台WEB服务器仅仅提供WWW和HTTPS服务,但是,它当然也需要具有远程控制特性。另外,这台WEB服务器最好还能够发送邮件。由于Linux服务器和网页是由三个不同的管理员维护的,所有的管理操作都应该保证在以后进行日志分析是更容易理解。

  实现

  前面段落中说明的安全WEB服务器的需求如何实现呢?下面的例子说明了一种在SuSE Linux 6.4发布的服务器上的实现方法。为了实现上述想定,我们决定选择SSH管理和Apache WEB服务器。

  第一步:配置路由器

  每一个流行的路由器都提供配置过滤列表的功能。您必需配置下面的简单规则:

  +---------------------------------------------------------------+
  |-----------------------过滤规则--------------------------------|
  +------------------+------------------+-------------------------+
  |--------来源------|--------目标------|---------服务------------|
  +------------------+------------------+-------------------------+
  |任何位置----------|web服务器---------|WWW, HTTPS, UDP highport,|
  |------------------|------------------|ICMP types 0 + 3---------|
  +------------------+------------------+-------------------------+
  |管理员------------|web服务器---------|SSH----------------------|
  +------------------+------------------+-------------------------+
  |web服务器---------|任何位置----------|DNS, SMTP----------------|
  +------------------+------------------+-------------------------+
  |web服务器---------|路由器------------|SSH或telnet--------------|
  +------------------+------------------+-------------------------+

  路由器的操作手册会提供如何进行上述配置的详细信息。这里我建议使用Cisco路由器,因为对于这种情况它非常容易配置,并且还在IOS的第12版以后提供了SSH的加密服务。
  第二步:安装Linux服务器

  执行SuSE 6.4的标准安装。处于安全考虑,至少应该为/、/var、/tmp、/home和/usr/local安装5个分区。后面会定义一些mount这些分区的特殊选项,这些选项可以保证系统具有更高的本地安全性能
  现在是选择需要安装哪些程序包的时候了。选择最小系统安装,然后手工加入下面一些必要的程序包:

  在Basis (a)中选择compat
  
  在Applications (ap)中选择sudo
  
  在Network (n)中选择apache, bindutil; 去掉postfix和sendmail
  
  在Security (sec)中选择firewals, hardensuse, mod_ssl, scanlogd, seclearcase/" target="_blank" >ccheck, secumod, tripwire.
  
  其它一些您认为需要的程序包,如数据库和为Apache设计的一些模块。

  然后完成安装。

  第三步:更新

  在配置之前,检查一下是否可以获得这些安装包的更新版本,如果有,需要的话最好进行更新。

  您可以在这里找到SuSE 6.4的更新信息。

  第四步:Linux的本地配置

  在开始真正工作之前,必需首先执行所有的诸如输入服务器名、配置网络接口和设置用户等标准Linux配置。在初始情况下,所有不需要的服务都是非活动状态的。特权程序的授权回收工作并不是必需的,您可以通过harden_suse工具简单地实现这个任务:

   erde#harden_suse yes

  这个命令在很多地方更改了系统的配置,这些更改都记录在/etc/harden_suse.log日志文件中,这些操作可以通过/etc/undo_harden_suse脚本予以恢复。使用其它Linux发布的用户可应使用Bastille脚本或者其它类似的程序。

  随后,所有网络访问服务(除了SSH)都被禁止,仅仅保留了下面的授予特权的suid和sgid程序:

erde# find / -perm -04000 -type f -exec ls -ld {} ;
-rwsr-x--- 1 root trusted 23840 Mar 11 11:26 /bin/ping
-rwsr-x--- 1 root trusted 30750 Mar 11 11:37 /bin/su
-rwsr-x--- 1 root trusted 21268 Mar 11 11:10 /usr/bin/crontab
-rwsr-xr-x 1 man root 85460 Mar 11 11:24 /usr/bin/man
-rwsr-xr-x 1 root root 15308 Mar 11 11:26 /usr/bin/rcp
-rwsr-xr-x 1 root root 11052 Mar 11 11:26 /usr/bin/rlogin
-rwsr-xr-x 1 root root 8104 Mar 11 11:26 /usr/bin/rsh
-rwsr-x--- 1 root shadow 38340 Mar 11 11:50 /usr/bin/gpasswd
-rwsr-x--- 1 root trusted 22184 Mar 11 11:50 /usr/bin/newgrp
-rwsr-xr-x 1 root shadow 27920 Mar 11 11:50 /usr/bin/passwd
-rwsr-x--- 1 root trusted 56600 Mar 11 18:41 /usr/bin/sudo
-rwsr-xr-x 1 root root 20300 Mar 11 11:26 /usr/sbin/traceroute
-rwsr-xr-x 1 root root 6132 Mar 11 09:36 /usr/lib/pt_chown
erde# find / -perm -02000 -type f -exec ls -ld {} ;
-rwxr-sr-x 1 root tty 9452 Mar 11 11:26 /usr/bin/write
-rwxr-sr-x 1 root tty 9796 Mar 11 11:49 /usr/bin/wall

  下一阶段工作是编辑全局配置文件/etc/rc.config,将下面脚本行中的"no"改成"yes":

  START_HTTPD="yes"
  START_FW="yes"
  START_SCANLOGD="yes"

  这样就会保证Apache、Scanlogd和SuSE防火墙在计算机启动时自动执行。现在我们继续配置本地防火墙,将/etc/rc.config.d/firewall.rc.config(个别变量的细节描述在这个文件中可以找到)文件中的对应行改成下面的形式:

  FW_DEV_WORLD="eth0" # query no. 2
  FW_SERVICES_EXTERNAL_TCP="www https" # query no. 9
  FW_SERVICES_TRUSTED_NETS="1.1.1.0/24" # query no. 10 - 1.1.1.0 is the net where the administrators connect from.
  FW_TRUSTED_SERVICES_TCP="ssh" # query no. 10
  /sbin/SuSEfirewall命令可以更新防火墙规则。这些规则会在每个系统启动周期中载入。
  现在我们以下面的形式集成SuSE专用的安全模块:

   erde# cat >> /sbin/init.d/boot.local
   insmod secumod hardlink=1 symlink=1 pipe=1 trace=1 systable=1 logging=1
   ^D

  当系统引导时,这个模块会被加载,它配置用来防止Symlink、Hardlink、Pipe和一些 UNIX特有的攻击形式。

  第五步:配置Apache

  WEB软件和页面时服务器的核心。我们必需确保没有人可以访问未授权的数据或者改变页面。为了这个目的,页面必需进行特殊的防护,然后要给予Apache安全的配置。

  所有的页面都必需由网站管理员统一管理,并且对除他以外的所有人都是本地写保护的。WEB服务器最好以非页面管理员身份运行,这样即使入侵者侵入WEB服务器,他也没有足够的权限更改页面。这样,就需要设置一个用户,还要产生一个cron工作,这个定时工作要保证所有的页面修改权只属于页面管理员并且具有正确的授权。

   erde# useradd -m wwwdocs
   erde# cat > /etc/cron.daily/wwwdocs
   #!/bin/sh
   /bin/chown -R -h wwwdocs /usr/local/httpd/htdocs/*
   /bin/chmod -R go-w /usr/local/httpd/htdocs/*
   /bin/chmod -R a+r /usr/local/httpd/htdocs/*
   ^D
   erde# chmod 700 /etc/cron.daily/wwwdocs

  由于Apache可能已经预先配置好了,所以可能根本不需要进行重新配置。当然,开始的时候/etc/httpd/httpd.conf 文件中的MinSpareServers、MaxSpareServers和StartServers的值应该被正确设置。

  MaxClients选项可以用来避免connect-denial-of-service攻击。应该注意的是:如果这个选项设置的太低,一般访问者的访问也可能会被拒绝;如果太高,管理员在日志跟踪和入侵事件发生时的应对就会显得比较困难。除了自己尝试以外,好象也没有什么确定合适数量的更好建议。

  应该关掉ServerSignature选项,这样访问一个不存在的页面时就不会回应您所使用的软件和版本号信息。但是这样也解决不了多大的问题,因为HTTP头中包含这些——甚至更多——信息。

  应该禁止/hilfe/、/doc/、/cgi-bin-sdb/、/sdb/和/manual/的别名。

  下面显示了标准配置更改后的大概样子:("diff -u0")

   --- httpd.conf.orig Sun Apr 9 19:37:44 2000
   +++ httpd.conf Sun Apr 9 19:42:57 2000
   @@ -141,2 +141,2 @@
   -MinSpareServers 1
   -MaxSpareServers 1
   +MinSpareServers 3
   +MaxSpareServers 10
   @@ -148 +148 @@
   -StartServers 1
   +StartServers 5
   @@ -157 +157 @@
   -MaxClients 150
   +MaxClients 100
   @@ -401 +401 @@
   -ServerAdmin root@localhost
   +ServerAdmin webdocs@echte-domain.de
   @@ -415 +415 @@
   -#ServerName hawking.suse.de
   +ServerName www.echte-domain.de
   @@ -485 +485 @@
   -UserDir public_html
   +#UserDir public_html
   @@ -646 +646 @@
   -ServerSignature On
   +ServerSignature Off
   @@ -665,11 +664,0 @@
   -Alias /hilfe/ /usr/doc/susehilf/
   -Alias /doc/ /usr/doc/
   -Alias /cgi-bin-sdb/ /usr/local/httpd/cgi-bin/
   -Alias /sdb/ /usr/doc/sdb/
   -Alias /manual/ /usr/doc/packages/apache/manual/
   -
   -
   - Options FollowSymLinks
   - AllowOverride None
   -
   -
   @@ -697,9 +685,0 @@
   -# cgi-bin for SuSE help system
   -# using SetHandler
   -
   -
   -AllowOverride None
   -Options +ExecCGI -Includes
   -SetHandler cgi-script
   -
   -
   @@ -981,4 +961,4 @@
   -#
   -# Deny from all
   -# ErrorDocument 403 http://phf.apache.org/phf_abuse_log.cgi
   -#
   +
   + Deny from all
   + ErrorDocument 403 http://phf.apache.org/phf_abuse_log.cgi
   +
  SSL的激活和证书的产生在/usr/doc/packages/apache/README.SuSE文件中描述。

  提示:SSL证书应该 一个密码保护起来,以减少攻击者成功入侵后将其拷贝并滥用的可能性(很少发生!)。

  作为一个一般的规则,应该保证没有在任何地方使用符号符号连接(Symlinks),因此要禁止FollowSymLinks选项。所有的CGI都放在cgi-bin目录下,不允许放在其它任何地方,甚至也不允许在其它目录下执行。为了做到这一点,请不要使用ExecCGI配置选项。

  为了禁止访问某些文件区,应该在这些目录下分别加入一个命名为.htaccess的文件,并在中加入下面的文本行:

  order deny,allow deny from all

  第六步:Step 6: sudo程序与多个管理员

  每一个管理员都应该有一个自己的帐号。如果每个人都使用root身份进行操作,那么就无法知道谁做了些什么。另外,如果使用root口令输入了一个不正确的命令可能对整个系统都产生严重的影响。应该仅仅在绝对需要时才使用具有高授权的操作。先前的harden_suse脚本已经将系统配置进行了必要的修改,它禁止了root用户的直接远程登录。仅仅以加密形式的SSH进行远程登录才可以执行管理任务。下一个需要做的事是配置sudo,这个程序可以帮助管理员记录执行过的命令。这个程序也提供了一个详细的授权结构,例如,象oracle用户一样,用户A可以被授权为可以重新启动数据库和查看root目录下的系统日志文件,但是不能做除此以外的任何事。可用用下面的命令行为每一个管理员设置一个用户:

   erde# adduser -m -g trusted username

  将用户包含在"trusted"用户组是非常关键的,因为根据harden_suse所确定的安全标准,sudo仅能够被trusted组所使用。

  随后,管理员就可以利用visudo程序,在编辑器中加入允许管理员可以做任何他想做的事的脚本行如下:

   username ALL=(ALL) ALL

  "man 5 sudoers" 设置了一个可以限制授权的主机。

  当然,管理员应该使用sudo并且不应该使用"su root"命令转换到root身份,只有这样,才能保证让尽量少的人知道root口令。

  第七步:最后的调整

  完成所有的系统配置之后,应该使用tripwire程序产生一个包含所有文件的校验和的数据库:

   erde# cp /usr/doc/packages/tripwire/tw.conf.example.linux /var/adm/tripwire/tw.config
   erde# /var/adm/tripwire/bin/tripwire -initialize

  在连接Internet之前,产生文件/databases/tw.db_HOSTNAME应该备份到一个安全的存储介质(如CD-ROM)上。

  一旦怀疑有攻击者已经入侵并操作了系统,可以用tripwire跟踪所有的操作。但是,应该隔一段时间就用tripware重新生成一次校验和数据库,因为这是对付高智商的攻击者的最有效方法。

  在连接Internet之间的最后工作是对系统进行备份而后reboot。

  但这些还不够,所有的系统管理员都应该订阅关于WEB安全的最重要的邮件列表:

  suse-security:这是包含安全相关专题和安全公告的SuSE讨论组列表,要订阅这个列表,只需要发送一个空邮件到suse-security-subscribe@suse.com邮箱就可以了;

  suse-security-announce:仅仅包含安全公告,要订阅这个列表,需要发一个空邮件到suse-security-announce-subscribe@suse.com邮箱;

  bugtraq:致力于最新的安全问题的讨论区列表,要订阅这个列表,需要发送一个包含"subscribe bugtraq surname@firstname"内容的空白邮件到:listserv@securityfocus.com邮箱。

  其它选择

  由于没有安装本地入侵检测系统,所以只能从攻击者留下的可以痕迹跟踪成功入侵的黑客行为。对于这种措施,也没有什么现成的解决方案,但是还是有很多人开发了针对这种工作的程序和发布了一些窍门。然而,有关这些方面的细节描述远非本文的主题所能涵盖了。
   如果WEB服务器上的几个文件需要定期更新,scp——cp函数在SSH中的安全版本——就显得不是很好用了。一个更合适的方法是使用SSLftp,它具有FTP的功能并且象SSH一样对数据进行了加密。

  日志数据很重要,所有的从WEB服务器和路由器所记录的重要日志记录都应该送到一个集中管理的日志主机,这个日志主机主要用来监视所有计算机的运行状态。通过这种方法,攻击者就就很难遁形灭迹了。

  另外,将Solar Designer [13]设计的安全内核补丁集成到系统中是个很好的主意,有了这个安全补丁,利用缓冲区溢出做手脚的攻击方式将变得更困难。

  应该剥夺那些suid和sgid程序所具有的没必要的过高特权。这可以通过将那些不再需要具有特权的程序逐个输入到/etc/permissions.local然后手工去掉程序的授权(或启动SuSEconfig)的方法实现。

  这个工作直到没有sgid程序并且仅仅有下面列出的少数几个suid程序时结束:

   -rwsr-xr-x 1 root shadow 27920 Mar 11 11:50 /usr/bin/passwd
   -rwsr-x--- 1 root trusted 56600 Mar 11 18:41 /usr/bin/sudo
   -rwsr-xr-x 1 root root 6132 Mar 11 09:36 /usr/lib/pt_chown

  如果系统由几个分区,通过使用mount选项ro(只读)、nodev(无设备)、nosuid (没有高特权的suid文件)和noexec (没有可执行文件)显著地提高系统的安全级别。

  除此之外,可以使用ext2文件系统标志"append-only"和"immutable" (通过chattr命令设置) 定义内核能力,这样就可以保护日志和引导文件等不被篡改。

  如果服务器需要具有防止本地攻击的能力,必须为LILO引导装载器配备一个口令,这可以通过在/etc/lilo.conf文件的顶端输入下面的脚本行实现:

  password=something_difficult_to_guess
  restricted

  最后,WEB服务器不仅仅只是Apache。通常要包括1到2个数据库,还要引入一些附加的模块和程序,或者需要激活其它一些服务(如DNS服务器)。Linux包过滤(参见第二步中的例子)可以方便有效地提供保护支持。一个称为“隔离间”("compartment":可以从这里获得)的程序支持chroot、特权分配以及Linux能力配置等任务。

  当然,还可以做很多其它的事情,但我所能想到的只有这些了。

  最后的提示

  更新!一个没有采用最新的安全补丁进行更新的系统会很快称为攻击者的目标。

  已经完成配置安全系统所需的所有工作之后,要记住:CGI脚本将是最大的安全隐患。大多数成功的攻击都是通过这些脚本实现的。简明的建议是:最好使用那些公开发布并且已经被不同的网站使用了一段时间的CGI脚本;如果管理员不得已需要写一些CGI脚本程序的话,这些程序应该由其它人对其安全因素进行例行检查。

  结论

  一个非常安全且高可用的WEB服务器——这似乎有些矛盾,但确实是很好的折中——能够在短短45分钟的时间内配置完。当然您可以通过更多的工作以提高系统的安全级别,但是这里配置的系统对大多数应用来说已经足够了。

原文转自:http://www.ltesting.net