在Linux上安装安全的Web服务器并加以维护并非易事。这需要深入了解Linux、Apache和PHP服务器端的选项。主要问题之一是,如何在安全性、生产力和易用性三者之间求得平衡。最好的解决办法取决于项目的具体需求,但是安装的所有服务器都有某些共同的特点。
Linux内核加固。内核是最经常被攻击者盯上的目标。要提升用户的权限,对内核获得访问权是最容易的方法。视操作系统而定,Apache在默认情况下以有限用户nobody(在CentOS等基于红帽的发行版上)或www-data用户(在基于Debian的发行版上,包括Ubuntu)来运行。每个攻击者企图突破有限用户的身份,利用内核存在的某个漏洞来获得访问root的权限。用grsecurity给内核打上补丁可以确保,你处于被保护状态,甚至可以防范零日漏洞。此外,Ksplice可以确保及时打上了所有的内核更新版,最大限度地减小安全风险。
强制性访问控制(MAC)。在正常的Web服务器部署环境下,普通用户不需要访问编译器(gcc)、系统配置文件或者像find这样的实用工具。基于红帽的发行版可以使用名为SELinux的MAC策略软件;Ubuntu管理员可以使用类似的AppArmor。尽管这些MAC工具的功能特性各不一样,但它们都能帮你限制攻击者的破坏行动。说到不利因素,配置不当的MAC工具会削弱Web服务器的功能。这就是为什么所有MAC工具都有非执行模式,那样就可以跟踪误报,并且针对特定环境来重新配置工具。不过,要是觉得MAC工具太过复杂,只要将一些可执行文件的权限改成700,只允许root可以使用它们。
防火墙。必须限制入站流量和出站流量,那样才能防止恶意连接进出服务器。对于各种类型服务器来说,保护入站流量的安全是一种常见做法。然而对于Web服务器来说,限制出站连接以便限制恶意脚本在本地执行所带来的影响,这一点特别重要。为此,最可靠的办法就是将默认iptables链的策略设置成DROP。此外,明确允许所需的入站连接和出站连接。不过在限制出站流量时一定要小心,因为许多Web脚本需要外部资源(RSS和外部应用编程接口)。如果你觉得iptables防火墙工具用起来不习惯,可以使用脚本来帮助生成和维护必要的规则,比如Shorewall和Firestarter。
Apache最佳安全实践
一旦你确保了Linux操作系统的安全,就可以开始处理Apache Web服务器的安全问题了。下列指示专门针对Apache,但可能也适用于其他Web服务器,比如LiteSpeed和nginx。它们之间的差异常常就体现在模块名称或者配置指令上。
要加固Apache,就要完成这些步骤:
安装mod_security,这个Apache模块起到了应用防火墙的作用。它可以过滤Web请求的所有部分,并终结恶意代码。它在Web服务器进行任何实际处理之前发挥作用,因而与Web应用程序无关。Mod_security适用于过滤从SQL注入到XSS攻击的任何恶意流量。它也是保护易受攻击的Web应用程序的最快速、最容易的方法。该软件有众多随时可以使用的规则,但你也很容易自行编写规则。比如设想一下:你有一个过时的Joomla版本,担心会遭到SQL注入攻击。这个简单规则可以过滤含有jos_(Joomla表的默认前缀);SecFilter“jos_”的任何POST和GET内容。
安装mod_evasive,这是另一个重要的Apache模块,可以保护Web应用程序远离拒绝服务(DOS)请求。它的效果受制于这个现实:它是在应用程序层面工作的,这意味着Apache无论如何都接受连接,因而耗用带宽和系统资源。不过,如果是源自少量远程主机的比较弱的DOS攻击,该模块能有所帮助。一旦mod_evasive装入,你需要这样来配置它:
这指示服务器阻止(默认情况下返回HTTP error 403 Forbidden)两次访问同一页面,或者在一秒内(默认的时间间隔)共有30次请求的任何主机。入侵者会在外面被阻挡120秒。
过滤访客的IP地址。这可能被认为是很极端的措施,但结果很好。首先,考虑安装mod_httpbl,这是用Apache实现的Project Honeypot。一旦该模块安装并被启用,它可以阻止有恶意活动"前科"的IP地址。另一个办法是使用mod_geoip,它可以用来允许只有来自某些国家的访客才可以访问接受留言、注册和登录信息等输入内容的页面。它甚至可以阻止和允许来自某些国家的服务器端访客。
其他推荐的Apache选项包括将Timeout(超时)选项设置得低些,比如15秒。这缩短了Web服务器等待某些事件的时间,从而限制了DOS攻击的影响。
PHP安全
PHP是开源领域最流行的服务器端语言。PHP是服务器端,这意味着你需要通过某些指令,比如memory_limit、execution_timeout和disable_functions,对它访问服务器资源设置明确的规则和限制。然而,PHP配置指令可以在各个地方来定义和重新定义,这里作了解释(http://www.php.net/manual/en/ini.list.php)。你在全局范围执行这些规则时,确保已清楚它们的范围。
如果安装了最新版本的PHP,又使用默认设置,环境已经符合还算可以的安全标准。危险的选项在默认情况下已被禁用,比如register_globals和allow_url_include。不过,光这还不够。要考虑调整的最重要的选项之一是disable_functions;顾名思义,它的作用就是禁用PHP函数。
之前为PHP引入额外的安全机制方面有过许多尝试,无论从开发小组里面还是从外面来进行尝试。一个不成功的尝试就是PHP的安全模式(Safe Mode),其主要想法是根据文件的所有者来限制文件的访问权。结果证明,这项功能设计不正确,自PHP 5.3以后就被废弃了。不过一个名为Suhosin的外部安全项目证明了其价值。它与PHP一起捆绑在基于Debian的流行发行版中。
Suhosin有两种安装方法。一种是在PHP实际编译之前给原始的PHP源代码打上补丁。建议采用这种方法,因为它使得Suhosin成为PHP的一个必要组成部分,让Suhosin可以通过其引擎保护功能来保护PHP核心。第二种方法比较容易,就是把它作为普通的PHP扩展来添加。Suhosin的丰富功能适用于许多安全方面,比如会议安全数据加密、请求有效载荷限制,甚至还有SQL注入预防这项试验性功能。
默认情况下,PHP作为Apache模块在Apache用户下运行,这确保了性能最佳、最符合应用程序的需求。然而,如果网站有不止一个虚拟主机(vhost),它可能会带来严重的安全问题,如果虚拟主机属于不同的用户那就更危险了。在这种情况下,来自一个虚拟主机的脚本也许能读取、写入和执行来自其他虚拟主机的脚本,这危及了安全,更不用说危及隐私了。
为了缓解这个问题,可以使用另一个Apache模块:mod_suphp,该模块允许PHP脚本在预先定义的用户下运行。这种模块对于共享的主机托管服务器来说必不可少。如果使用mod_suphp,来自某个虚拟主机的脚本甚至无法读取来自其他虚拟主机的文件,更不用说写入了。禁止读取外来虚拟主机的文件对于配置文件来说极其重要,这就是为什么这类文件必须要有600个文件的许可权。要是不这么设置,你的数据库详细资料很容易被发现,而这是最不想遇到的麻烦。
在mod_suphp的配置文件(默认情况下是/etc/suphp.conf)中,可以使用allow_file_group_writeable、 allow_file_others_writeable、allow_directory_group_writeable和allow_directory_others_writeable等选项,执行全局安全文件的许可策略。在正常情况下,它们都应该被定义为false。执行不遵守这些限制的脚本会得出HTTP Error 500 Internal server error。
为Web服务器保驾护航时,还要考虑下列措施:
把同一台服务器上的不同Web应用程序分隔到不同的虚拟主机上,让它们在不同的用户下运行。
传输密码或信用卡信息等敏感信息时,安装SSL。可以用免费、自己生成的非商业证书来保护管理面板。
不要单单依赖一种方法来限制管理员访问。数量众多的互联网漏洞避开了管理员登录要求。只要限制远程IP地址对管理员区域的访问,并且更改默认的管理员URL或端口,就可以限制这类威胁。
定期对服务器执行安全审查工作。
订阅关于已部署的Web服务和应用程序的安全新闻组。
所有信息充当了确保Web服务器安全的路线图。做好这项工作需要投入大量的时间和精力。如果没有准备好投入这样的时间,最好还是使用共享的主机托管服务器或完全托管的服务器。
|