6.3 配置一个安全的Apache服务器
合理的网络配置能够保护Apache服务器免遭许多攻击。
6.3.1 勤打补丁在上最新的changelog中都写着:bug fix、security bug fix的字样。所以,Linux网管员要经常关注相关网站的缺陷,及时升级系统或添加补丁。使用最高和最新的安全版本对于加强Apache Web服务器的安全是至关重要的。将你的OpenSSL升级到0.9.6e或者更高版本,伪造的密钥将起不了任何作用,也不能渗透到系统里。一些反病毒程序能发现并杀死SSL蠕虫,但是蠕虫可能产生变体,从而逃脱反病毒软件的追捕。重启Apache可以杀死这样的病毒,但是对防止将来的感染没有任何意义。
6.3.2 隐藏和伪装Apache的版本通常,软件的漏洞信息和特定版本是相关的,因此,版本号对黑客来说是最有价值的。
默认情况下,系统会把Apache版本模块都显示出来(http返回头)。如果列举目录的话,会显示域名信息(文件列表正文),去除Apache版本号的方法是修改配置文件/etc/httpd.conf。找到关键字ServerSignature,将其设定为:
ServerSignature Off
ServerTokens Prod
然后重新启动Apache服务器。
通过分析Web服务器的类型,大致可以推测出操作系统的类型,比如,Windows使用IIS来提供HTTP服务,而Linux中最常见的是Apache。
默认的Apache配置里没有任何信息保护机制,并且允许目录浏览。通过目录浏览,通常可以获得类似“Apache/1.3.27 Server at apache.linuxforum.net Port 80”或“Apache/2.0.49 (Unix) PHP/4.3.8”的信息。
通过修改配置文件中的ServerTokens参数,可以将Apache的相关信息隐藏起来。但是,Red Hat Linux运行的Apache是编译好的程序,提示信息被编译在程序里,要隐藏这些信息需要修改Apache的源代码,然后,重新编译安装程序,以替换里面的提示内容。
以Apache 2.0.50为例,编辑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。
Apache安装完成后,修改httpd.conf配置文件,将“ServerTokens Full”改为“ServerTokens Prod”;将“ServerSignature On”改为“ServerSignature Off”,然后存盘退出。重新启动Apache后,用工具进行扫描,发现提示信息中已经显示操作系统为Windows。
6.3.3 建立一个安全的目录结构Apache服务器包括以下四个主要目录。
— ServerRoot:保存配置文件(conf子目录)、二进制文件和其他服务器配置文件。
— DocumentRoot:保存Web站点的内容,包括HTML文件和图片等。
— ScripAlias:保存CGI脚本。
— Customlog和Errorlog:保存访问日志和错误日志。
建议设定这样一个目录结构,以上四个主要目录相互独立并且不存在父子逻辑关系。
提示 ServerRoot目录应该被配置为只能由root用户访问;DocumentRoot应该能够被管理Web站点内容的用户访问和使用Apache服务器的Apache用户和Apache用户组访问;ScriptAlias目录应该只能被CGI开发人员和Apache用户访问;只有root用户可以访问日志目录。
下面是一个安全目录结构,如图6-3所示。
图6-3 安全目录结构
这样的目录结构是比较安全的,因为目录之间是独立的,某个目录的权限错误不会影响到其他目录。
6.3.4 为Apache使用专门的用户和用户组按照最小特权原则,需要给Apache分配一个合适的权限,让其能够完成Web服务。
提示
最小特权原则是系统安全中最基本的原则之一,它限制了使用者对系统及数据进行存取所需要的最小权限,既保证了用户能够完成所操作的任务,同时也确保非法用户或异常操作所造成的损失最小。必须保证Apache使用一个专门的用户和用户组,不要使用系统预定义的账号,比如nobody用户和nogroup用户组。
因为只有root用户可以运行Apache,DocumentRoot应该能够被管理Web站点内容的用户访问和使用Apache服务器的Apache用户和Apache用户组访问。所以,如果希望“cao”用户在Web站点发布内容,并且可以以httpd身份运行Apache服务器,通常可以这样:
groupadd webteam
usermod -G webteam cao
chown -R httpd.webteam /www/html
chmod -R 2570 /www/htdocs
只有root用户访问日志目录,这个目录的推荐权限:
chown -R root.root /etc/logs
chmod -R 700 /etc/logs
6.3.5 Web目录的访问策略对于可以访问的Web目录,要使用相对保守的途径进行访问,不要让用户查看任何目录索引列表。
1.禁止使用目录索引Apache服务器在接收到用户对一个目录的访问时,会查找Directorylndex指令指定的目录索引文件,默认情况下该文件是index.html。如果该文件不存在,那么Apache会创建动态列表为用户显示该目录的内容。通常这样的设置会暴露Web站点结构,因此需要修改配置文件禁止显示动态目录索引。
修改配置文件httpd.conf:
Options -Indexes FollowSymLinks
Options指令通知Apache禁止使用目录索引。FollowSymLinks表示不允许使用符号链接。
2.禁止默认访问一个好的安全策略要禁止默认访问的存在,只对指定的目录开启访问权限,如果允许访问/var/www/html目录,使用如下设定:
Order deny,allow
Allow from all
3.禁止用户重载为了禁止用户对目录配置文件(.htaccess)进行重载(修改),可以这样设定:
AllowOverride None
6.3.6 Apache服务器访问控制方法Apache的access.conf文件负责设置文件的访问权限,可以实现互联网域名和IP地址的访问控制。它包含一些指令,控制允许什么用户访问Apache目录。应该把deny from all设为初始化指令,再使用allow from指令打开访问权限。如果允许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
6.3.7 管理Apache服务器访问日志 1.相关配置文件说明一个优秀的Linux网络管理员会密切关注服务器日志系统,这些日志可以提供异常访问的线索。Apache可以记录所有的访问请求,同样,错误的请求也会记录。Apache配置文件中,需要关心的和日志相关的配置文件有两个:
$ CustomLog /www/logs/access_log common #记录对Web站点的每个进入请求#
$ ErrorLog /www/logs/error_log #记录产生错误状态的请求#
CustomLog用来指示Apache的访问日志存放的位置(这里保存在/www/logs/access_log中)和格式(这里为common);ErrorLog用来指示Apache的错误信息日志存放的位置。对于不配置虚拟主机的服务器来说,只需直接在httpd.conf中查找CustomLog配置进行修改即可。而对于具有多个虚拟服务器的Web服务器来说,需分离各个虚拟服务器的访问日志,以便对各个虚拟服务器进行访问统计和分析,因此,需要在虚拟服务器配置中进行独立的日志配置。
2.Web服务器日志轮循Web服务器日志轮循比较好的方式有三种:第一种方法是利用Linux系统自身的日志文件轮循机制logrotate;第二种方法是利用Apache自带的日志轮循程序rotatelogs;第三种是使用在Apache的FAQ中发展已经比较成熟的日志轮循工具cronolog。对于大型的Web服务器来说,往往使用负载均衡技术提高Web站点的服务能力,这样后台有多个服务器提供Web服务,大大方便了服务的分布规划和扩展。如果有多个服务器,需要对日志进行合并,统一进行统计分析。因此为了保证统计的精确性,需要严格按照每天的时段来自动生成日志。
(1)用logrotate实现日志轮循
首先讨论采用Linux系统自身的日志文件轮循机制logrotate的方法。logrotate是Linux系统自身带的一个日志轮循程序,是专门对各种系统日志(syslog、mail)进行轮循的程序。该程序是由运行程序的服务crond每天凌晨4:02运行的。在/etc/cron.daily目录下可以看到logrotate文件:
#!/bin/sh/
$ usr/sbin/logrotate /etc/logrotate.conf
每天凌晨crond都会启动/etc/cron.daily目录下的logrotate脚本来进行日志轮循。在/etc/logrorate. conf中可以看到如下内容:
# see "man logrotate" for details
# rotate log files weekly
weekly
# keep 4 weeks worth of backlogs
rotate 4
# create new (empty) log files after rotating old ones
create
# uncomment this if you want your log files compressed
#compress
# RPM packages drop log rotation information into this directory
include /etc/logrotate.d
# no packages own wtmp -- we'll rotate them here
/var/log/wtmp {
monthly
create 0664 root utmp
rotate 1
}
# system-specific logs may be also be configured here.
从logrotate的配置文件中可以看到,除了wtmp以外,需要滚动的日志的配置都保存在/etc/logroate.d目录下。因此只需要在该目录下创建一个名为apache的配置文件,来指示logrotate如何轮循Web服务器的日志文件即可。这种方法的优点是不需要其他第三方工具就可以实现日志轮循。但是对于重负载的服务器和使用负载均衡技术的Web服务器来说,这种方法不是很实用,因为它是对相应服务进程发出一个“-HUP”重启命令来实现日志的截断归档的,这样会影响服务的连续性。
(2)用rotatelogs实现日志轮循
Apache提供了不把日志直接写入文件,而是通过管道发送给另外一个程序的能力。这样就大大加强了对日志进行处理的能力。这个通过管道得到的程序可以是任意程序,如日志分析、压缩日志等。要实现将日志写到管道的操作,只需要将配置中日志文件部分的内容替换为“|程序名”即可,例如:
# compressed logs
$ CustomLog "|/usr/bin/gzip -c >> /var/log/access_log.gz" common
这样就可以使用Apache自带的轮循工具rotatelogs来对日志文件进行轮循。rotatelogs基本是按时间或大小来控制日志的。
$ CustomLog "|/www/bin/rotatelogs /www/logs/secfocus/access_log 86400" common
上面内容表示,Apache访问日志被发送给程序rotatelogs;rotatelogs将日志写入/www/logs/ secfocus/access_log,并每隔86 400秒(1天)对日志进行一次轮循。轮循以后的文件名为/www/logs/ secfocus/access_log.nnn,这里nnn是开始记录日志的时间。因此,为了将日志按天对齐需要在凌晨00:00启动服务,使得每天轮循得到的日志刚好是完整一天的日志,以提供给访问统计分析程序进行处理。如果是00:00开始生成新的日志,那么轮循得到的日志就是access_log.0000。
(3)用cronolog实现日志轮循
首先需要下载和安装cronolog,可以到下载最新版本的cronolog。下载完毕以后,解压安装即可。这样就完成了cronolog的配置和安装,默认情况下,cronolog安装在/usr/local/sbin下。修改Apache日志配置命令如下所示:
$ CustomLog "|/usr/local/sbin/cronolog /www/logs/secfocus/%w/access_log" combined
这里%w表示按照日期在不同的目录下保存日志,这种方式会保存一周的日志。为了进行日志分析,需要每天将该日志文件复制(或移动,如果不希望保存一周的日志)到一个固定的位置,以方便日志分析统计文件进行处理(使用crontab -e)。添加定时任务如下:
$ 5 0 * * * /bin/mv /www/logs/secfocus/`date -v-1d +\%w`/access_log
/www/logs/secfocus/access_log_yesterday
再使用日志统计分析程序,对文件access_log_yesterday进行处理。对于这种情况,各个服务器定义或移动日志文件时就不能使用access_log_yesterday了,而应该带上服务器编号(例如服务器IP地址等信息)加以区分。然后在各个服务器上运行网站镜像和备份服务rsyncd,再将每个服务器每天的安装配置文件通过rsyncd下载到专门进行访问统计分析的服务器上进行合并。合并多个服务器的日志文件(如log1、log2、log3),并输出到log_all中的方法是:
$ sort -m -t " " -k 4 -o log_all log1 log2 log3
-m表示使用merge优化算法;-k 4表示根据时间进行排序;-o表示将排序结果存放到指定的文件中。
3.使用php MyVisites分析Apache日志(1)Apache日志分析的原理
网站服务器日志记录了Web服务器接收处理请求及运行时的错误等各种原始信息。通过对日志进行统计、分析和综合,就能有效地掌握服务器的运行状况、发现和排除错误、了解客户访问分布等,更好地加强系统的维护和管理。Web访问机制非常简单,如图6-4所示。
图6-4 Web访问机制
① 客户端(浏览器)和Web服务器建立TCP连接,连接建立以后,向Web服务器发出访问请求(如get)。根据HTTP协议,该请求中包含了客户端的IP地址、浏览器的类型、请求的URL等一系列信息。
② Web服务器收到请求后,将客户端要求的页面内容返回到客户端。如果出现错误,那么返回错误代码。
③ 服务器将访问信息和错误信息记录到日志文件里。
日志在实际的Web服务器中有更多的用途,比较典型的是进行网站的流量统计和安全分析。在Web日志中找出攻击Web服务器的蛛丝马迹并不是非常容易的一件事,因为日志中条目繁多,这需要分析访问者的源IP地址和请求的页面,猜测访问者的企图,他是在进行站点镜像还是CGI漏洞扫描,进而做有针对性的查缺补漏。用户更关注的是Web服务器的性能,但对于商务网站来说,不能只在乎用户的要求,不能把精力全放在减少用户访问延迟和提高并发访问数目上。还要关注访问用户的地理分布、时间分布和某个页面的点击率。通过分析用户群和他们的访问行为,有助于对网站页面做出有针对性的改善,帮助商家提高网站质量,更好地为用户服务。日志可以帮你完成流量分析,给出上述关注内容的统计数字。直接去读日志文件仅适用于查找某一特定内容的情况,更多时候,我们要借助专用的日志分析工具。比较著名的工具有AWStats、Webalizer和phpMyVisites等,它们都是开源软件。它们不仅可以进行简单的基于访问时间和IP地址来源的分析,还可以发现自己的网站与搜索引擎的关系。
phpMyVisites具有以下一些特性:
— phpMyVisites是一个用PHP/MySQL技术开发,采用Gnu GPL.方式发布的关于网站访问量统计的开源软件,所以它具有很高的运行效率。在主频为800MHz的机器上,每秒钟可以分析100 000条记录,所以分析一个400M大小的日志文件只需要25秒。
— 可以支持多种语言,也可以自己进行本地化工作。
— 支持多种平台,比如UNIX, Linux, Windows和MacOS等。
相对于另外一个优秀的开放源代码的日志分析工具Webalizer,phpMyVisites的优势在于:
— 界面友好,可以根据浏览器直接调用相应的语言界面(有简体中文版)。
— 基于PHP,并且很好地解决了跨平台问题,系统本身可以运行在GNU/Linux上或Windows上(安装了PHP后);分析的日志直接支持Apache格式(combined)和IIS格式(需要修改)。Webalizer虽然也有Windows平台版,但目前已经缺乏维护;phpMyVisites可以完全实现用一套系统完成对自身站点不同Web服务器,如GNU/Linux/Apache和Windows/IIS服务器的统一统计。
— 效率比较高,phpMyVisites输出的统计项目比Webalizer丰富了很多,速度仍可以达到Webalizer的1/2左右,对于一个日访问量百万级的站点,这个速度是足够的。
— 配置/定制方便,系统提供了足够灵活但默认也很合理的配置规则,而且修改和扩展的插件也比较多;使用简单,不用再看让人头晕的Log日志,提供柱状图分析报表,形象生动。
— 提供强大的IP库支持,了解访问用户的地区。
(2)安装使用phpMyVisites
phpMyVisites的官方网站是,最新版本为2.1。
1)phpMyVisites软件下载。
#cd var/www/html
wegt ?part=download&lg=en
#unzip phpmyvisites_2_1.zip "建立一个目录"
#mv phpmyvisites_2 phpmy2
2)为phpmy2建立数据库。
# mysql –u root –p
Enter password: xxxxxxxxx
Your Mysql connection id is 3 to server version: 4.11
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
Mysql> create database phpmy2 ; "为phpbb2建立数据库"
Query OK, 1 row affected (0.01 sec)
Mysql>grant all privileges on phpmyv2.* to phpmy2@localhost identified by '76543981' ; "将建立的 bblog 权限给bblog 账号,并且设定密码"
mysql>quit
Bye
3)开始安装phpMyVisites。
安装前需要说明的是,MySQL服务器名称为localhost,这个是MySQL的服务器名称,不是Linux的服务器名称。MySQL数据库名称为phpmy2,MySQL账号为phpmy2,且密码为上面设定值。
#cd /var/www/html/phpmy2 "进入到Apache 服务器的默认目录中"
#chmod 777 install #赋予安装文件和目录的可以执行权限#
4)网络安装设定。
网络安装一共九个步骤。
①“Welcome!”:欢迎设定语言。
网络安装非常简单,打开Linux的Firefox(火狐浏览器)在地址栏直接输入“主机名/phpmy2/ install/install.php”后,首先是语言设定,选择“Simplified Chinese”即可,如图6-5所示。
图6-5 安装首页和管理员页面语言设定
②“System Requirements”:系统检测。
系统会自动检测MySQL、PHP、GD库是否设定完成,所有选项显示绿色表示通过。
③“Database Setup”:MySQL数据库设定。
第3部分最为关键,如图6-6所示。
④“Table Creation”:数据库表设定。
选择默认设置即可。
图6-6 MySQL数据库设定界面
⑤“General Setup”:常规设定。
主要设定管理员登录密码和管理员电子邮件,如图6-7所示。
图6-7 常规设定界面
⑥“Create Config File”:生成配置文件。
选择默认设置即可。
⑦“Add First Website”:首页显示设定。
请根据爱好设定。
⑧“Display Javascript code”:javascript代码设定。
选择默认设置即可。
⑨“Finished!”:安装结束。
系统如果出现如图6-8所示界面表示安装成功。
图6-8 安装成功页面
测试成功后系统提醒你出于安全考虑,删除安装文件(防止他人使用这些文件修改系统信息)。
// rm –rf install ; // rm –rf install.Php
⑩ 管理员���录首页。
用鼠标点击图6-8页面的链接“Go to phpMyVisites”,然后使用管理员权限和密码登录首页即可。首页界面如图6-9所示。
图6-9 phpMyVisites的首页界面
图6-10是管理员控制面板。
图6-10 管理员控制面板
phpMyVisites可以分析下列信息:
— 访问情况统计
— 时间段汇总
— 图示统计汇总
— Graph to show long term statistics summary 图示某时间段内访问者的访问量
— 图示每小时服务器的访问量
— 图示每小时访问者的访问量
— Frequency
— 统计
— New vs Returning visits
— Graph to show New vs Returning visits
— Graph to show number of visits per visitor
— 浏览页
— 页浏览
— Time by page
— 图示每页的访问量
— 访问轨迹
— 入口页
— 退出页
— Single Pages visits
— 访问来源
— 世界地图
— 访问国家汇总
— Internet服务提供商
图6-11是phpMyVisites的工作界面。
图6-11 phpMyVisites的工作界面
6.3.8 Apache服务器的密码保护.htaccess文件是Apache服务器上的一个设置文件。它是一个文本文件,可以使用任何文本编辑器进行编写。.htaccess文件提供了针对目录改变配置的方法,即通过在一个特定的文档目录中放置一个包含一个或多个指令的文件(.htaccess文件),以作用于此目录及其所有子目录。.htaccess的功能包括设置网页密码、设置发生错误时出现的文件、改变首页的文件名(如index.html)、禁止读取文件名、重新导向文件、加上MIME类别、禁止列目录下的文件等。注意,.htaccess是一个完整的文件名,不是***.htaccess或其他格式(当然也有管理员把其设置成其他名字,但一般都是使用.htaccess)。另外,上传.htaccess文件时,必须使用ASCII模式,并使用chmod命令改变权限为644(RW__R__R__)。每一个放置.htaccess的目录和其子目录都会被.htaccess影响。例如,在/abc/目录下放置了一个. htaccess文件,那么/abc/和/abc/def/内所有的文件都会被它影响,但/index.html不会被它影响,这一点是很重要的。
1.建立.htpasswd文件首先在设置存取控制的目录(如htdocs)下建立一个文件,文件名可以自行设定,一般服务器都会设置为.htpasswd,该文件是不能由HTTP读取的。.htpasswd文件中的每一行代表一个使用者,使用者的名字及经过加密的密码以冒号“:”分隔。
2..htaccess文件实现保护.htaccess文件的内容如下:
authtype basic
authuserfile /usr/home/***/htdocs/.abcname1
authgroupfile /usr/home/***/htdocs/.abcname2
authname information
<limit get post>
require valid-user
</limit>
其中第二行和第三行中的***可以改为个人的FTP登录名。.abcname1和.abcname2可以是任意的文件名,如.htpasswd, .htpass,但不能是.htaccess。将.htaccess上传到要进行密码保护的目录(如htdocs)中。
.htaccess文件最后的“require”告诉服务器哪些用户可以进入。require valid-user是指只要是.htpasswd中的任何一个都可以进入。也可以指定名单上的某人或某几个人可以通过,使用“require user username”或“require user username1 username2 username3”。还可以指定某组人可以通过,使用“require group groupname”。
3.增加新的许可用户进入htdocs目录,在命令行状态输入以下命令生成.abcname1文件。
echo > .abcname1
/var/www/bin/htpasswd .abcname1 abc
abc表示要增加的用户名。输入此命令后,系统会提示输入此用户密码,这样该用户名就生效了。以后如要再增加用户,运行第二行的命令时换一个用户名即可。如果这个用户名存在,则会提示修改密码。
4.建立允许访问的组组的设置方法是建立一个名为.htgroup的文本文件,内容如下:
groupname1: username1 username2 username3
groupname2: username1 username3 username4
并在.htaccess中加上“AuthGroupFile /absolute/path/.htgroup”。以ASCII模式上传所有文件后,该目录中的所有文件都会被保护起来。
5.禁止读取文件如果将某些内容如密码,存放在一个文件中,那么别人只需知道该文件的对应位置,就可以一目了然,这样太不安全。其实完全可以不改变其他设置,也不用将文件移到其他地方就可解决这个问题,只需在.htaccess文件中加入以下几行:
<files filename.ext>
order allow,deny
deny from all
</files>
如果系统安装的是Apache 1.3以后的版本,更可以支持regular expression的filesmatch。
<filesmatch "\.tmp">
order allow,deny
deny from all
</filesmatch>
files和filesmatch表示只对符合要求的部分文件生效。“order deny,allow”表示先找出禁止(deny)的,然后去找许可的(allow)。如果将它们的顺序颠倒“order allow,deny”则表示先找出许可的,然后才去找禁止的。“deny from all”则表示全部IP地址都不许可。相对地,“allow from all”表示全部都允许。可以如下设置:
order allow,deny
allow from all
deny from 111.222
deny from 111.222是指禁止所有以111.222开始的IP地址(如111.222.0.1)。除了设置IP地址外,也可以设置成hostname(如***.com)。“files”和“filesmatch”的用途很多,不但可以设置deny,也可以设置个别文件的密码,如:
<files 123>
require user 123
</files>
<files abc>
require user abc
</files>
总的来说,通过.htaccess来保护网站更为方便和安全。因为它不像利用程序实现密码保护时,有可能通过猜测的方法获取密码。利用.htaccess文件实现密码保护,一般是很难破解的。上述方案中有一个特点,那就是它使用普通的文本文件来存储验证信息,这就使得查询信息的效率受到了限制。而由于HTTP是无状态的,因此每一次内容被请求时,都要被验证,即使所请求的用户不存在也是如此。当然这对于用户比较少的站点来说根本不是什么问题,因此上述方案适用于用户数量比较少的站点。对于用户数量非常庞大的站点来说,就应该使用带数据模块的方案了。因为在默认情况下,Apache在编译时并不包含数据库模块,所以需要自己来编译和安装Apache服务器。
注意 在Red Hat默认安装和自己编译安装两种情况下,配置文件的位置及其中的一些参数值是不尽相同的,在下面的配置过程中就不一一说明了
此外,在进行编译前,应该删除已有的安装。方法是使用下面的命令查询出所安装的软件包:
rpm -qa|grep httpd
然后使用rpm -e命令进行删除。
下面就来进行配置过程:从站点下载最新的Apache,本节采用当时的最新版本2.2.45。将下载文件复制至/tmp目录中,运行下面命令:
tar zxvf httpd-2.2.45.tar.gz
解压缩后切换至目录httpd-2.2.45中。运行下面命令:
./configure -enable-module=auth_db
这就是声明在编译时要包含数据库模块,这个过程要花费一些时间。
6.3.9 减少CGI和SSI风险CGI脚本的漏洞已经成为Web服务器的首要安全隐患,通常是程序编写CGI脚本中产生了许多漏洞。控制CGI脚本的漏洞除了在编写时需要注意对输入数据的合法性检查、对系统调用的谨慎使用等因素外,首先使用CGI程序所有者的UID来运行这些程序。这些CGI程序即使存在某些漏洞,那么其危害也仅限于该UID所能够访问的文件。也就是说,这样只能伤害用户的文件,而不会对整个系统带来致命的影响。
通过安装和使用suEXEC的应用程序,可以为Apache服务器提供CGI程序的控制支持(从Apache l.3版以后,suEXEC已经作为Apache服务器的一部分),可以把suEXEC看作一个包装器,在Apache接到对CGI程序的调用请求后,它将这个调用请求交给suEXEC来负责完成具体的调用,并且从suEXEC获得返回的结果。
suEXEC能解决一些安全问题,但也会降低服务性能,因为它只能运行在CGI版本的PHP上,而CGI版本比模块版本运行速度慢。原因是模块版本使用了线程,而使用CGI版本的是进程。在不同线程之间的环境转换和访问公用的存储区域显然要比在不同的进程之间要快得多。
建议在对安全性能要求比较高时使用suEXEC,为此还要以牺牲速度为代价。此外,可以尝试另外一个软件CGIWrap,它的安全性能高于suEXEC。官方网址为ftp://ftp.cc.umr.edu/pub/cgi/cgiwrap。
减少SSI脚本的风险,如果用exec等SSI命令运行外部程序,也会存在类似CGI脚本程序的危险,除了内部调试程序时都应当可以使用Option命令禁止其使用。
Options IncludesNOEXEC
6.3.10 让Apache服务器在“监牢”中运行所谓的“监牢”是指通过chroot机制来更改某个软件运行时所能看到的根目录,即将某软件运行限制在指定目录中,保证该软件只能对该目录及其子目录的文件有所动作,从而保证整个服务器的安全。这样即使被破坏或侵入,所受的损伤也不大。
将软件chroot化的一个问题是该软件运行时需要的所有程序、配置文件和库文件都必须事先安装到chroot目录中,通常称这个目录为chroot jail(chroot“监牢”)。如果要在“监牢”中运行Apache,而事实上根本看不到文件系统中那个真正的目录,就需要事先创建目录,并将httpd复制到其中。同时,httpd需要库文件,可以使用LDD(Library Dependency Display)命令查看,LDD的作用是显示一个可执行程序必须使用的共享库。这意味着还需要在“监牢”中创建lib目录,并将库文件复制到其中。手工完成这一工作是非常麻烦的,此时可以用jail软件包来帮助简化chroot“监牢”建立的过程。jail官方网站是:,最新版本为1.9a。
以前,UNIX/Linux上的daemon都是以root权限启动的。当时,这似乎是一件理所当然的事情,因为像Apache这样的服务器软件需要绑定到“众所周知”的端口上(小于1024)来监听HTTP请求,而root是唯一有这种权限的用户。但是,随着攻击者活动的日益频繁,尤其是缓冲区溢出漏洞数量的激增,使服务器安全受到了更大的威胁。一旦某个网络服务存在漏洞,攻击者就能够访问并控制整个系统。因此,为了减小这种攻击所带来的负面影响,现在的服务器软件通常设计为以root权限启动,然后服务器进程自行放弃root权限,再以某个低权限的系统账号来运行进程。这种方式的好处在于一旦该服务被攻击者利用漏洞入侵,由于进程权限很低,攻击者得到的访问权限又是基于这个较低权限的,对系统造成的危害比以前减轻了许多。
有些攻击者会试��找到系统其他的漏洞来提升权限,直至达到root权限。由于本地安全性远低于远程安全性,因此攻击者很有可能在系统中找到可以提升权限的东西。即使没有找到本地漏洞,攻击者也可能会制造其他损害,如删除文件、涂改主页等。
为了进一步提高系统安全性,Linux内核引入了chroot机制。chroot是内核中的一个系统调用,软件可以通过调用库函数chroot,来更改某个进程所能见到的根目录。比如,Apache软件安装在/usr/local/httpd/目录下,以root用户(或具有相同权限的其他账号)启动Apache,这个root权限的父进程会派生数个以nobody权限运行的子进程,具体情况取决于个人设置。父进程监听来自80端口的TCP数据流,然后根据内部算法将这个请求分配给某个子进程来处理。这时Apache子进程所处的目录继承父进程,即/usr/local/httpd/。但是,一旦目录权限设定失误,被攻击的Apache子进程可以访问/usr/local、/usr、/tmp,甚至整个文件系统,因为Apache进程所处的根目录仍是整个文件系统的根。如果能够利用chroot将Apache限制在/usr/local/httpd/,那么,Apache所能存取的文件都是/usr/local/httpd/下的文件或其子目录下的文件。创建chroot“监牢”的作用就是将进程权限限制在文件系统目录树中的某一子树中。
1.编译和安装jail在网站上可以下载到jail的最新版本,它是由jail chroot项目小组开发的。该软件包包含了帮助自动创建chroot“监牢”的C程序、Perl程序和Bash脚本。
首先将jail.tar.gz置于任意目录,然后执行命令:
#tar xzvf jail.tar.gz && cd jail/src
按照个人实际情况修改makefile文件,尤其是安装路径(默认安装路径是/usr/local)、体系结构(jail支持Linux, FreeBSD, IRIX和Solaris),以及编译选项等。最后执行命令:
#make && make install
为jail创建chroot“监牢”。
现在创建一个目录作为chroot“监牢”,以/var/chroot/为例。执行下面的命令为chroot“监牢”创建环境:
#/usr/local/bin/mkjailenv /var/chroot
这样“监牢”就建好了。jail软件包提供了几个Perl脚本作为其核心命令,包括mkjailenv、addjailuser和addjailsw。addjailsw会从真实文件系统中复制二进制可执行文件及其相关的其他文件(包括库文件、辅助性文件和设备文件)到该“监牢”中。
2.为jail“监牢”添加软件接下来需要为这个“监牢”增加一些软件,以便让它运行起来。执行以下命令安装一些基本的软件,包括ls、cat、cp等程序和ld-linux.so.2等库文件。
#/usr/local/bin/addjailsw /var/chroot
事实上仅有这些基本软件是不够的,还需要把一些真正有用的东西加进来。以Apache服务器软件为例:
#addjailsw /var/chroot/ -P /usr/local/httpd/bin/httpd
addjailsw
A component of Jail (version 1.9 for linux)
Juan M. Casillas <juanm.casillas@jmcresearch.com>
Guessing /usr/local/httpd/bin/httpd args(0)
Warning: file /var/chroot//lib/libssl.so.4 exists. Overwritting it
Warning: file /var/chroot//lib/libcrypto.so.4 exists. Overwritting it
Warning: file /var/chroot//lib/libresolv.so.2 exists. Overwritting it
……
Done.
不用在意那些告警信息,因为jail会调用LDD检查httpd用到的库文件。而几乎所有基于共享库的二进制可执行文件都需要上述的几个库文件。接下来将Apache的相关文件复制到“监牢”中:
#cp -a /usr/local/httpd/ /var/chroot/usr/local/
可根据个人情况依次将Apache需要的文件复制到“监牢”中。
3.“监禁”用户有时候需要为chroot“监牢”创建新的用户,比如Apache要求创建nobody用户作为子进程用户。鉴于可能有其他进程使用nobody,还可以使用另一用户——httpd。首先需要在真实系统中创建httpd用户:
#useradd -d /var/chroot -s /usr/local/bin/jail httpd
然后执行以下命令在chroot“监牢”中创建httpd用户:
#/usr/local/bin/addjailuser /var/chroot /usr/local/httpd /usr/sbin/httpd httpd
接下来修改/var/chroot/usr/local/httpd/conf/httpd.conf,将User nobody替换为User httpd。由于chroot后Apache将以httpd身份启动进程,只有root有权将Apache绑定在低端口上(通常为80),因此还需要修改端口值,该值必须大于1024(假设为8080)。这个修改要应用到Apache的所有配置文件中,包括虚拟主机的配置。至于Apache的其他设置,与在真实文件系统中一样配置即可。
接下来需要复制一些其他的文件。启动Apache,最常见的方式就是调用apachectl,这是个Bash脚本。查看这个文件,会发现如下行:
HTTPD='/usr/local/httpd/bin/httpd'
LYNX="lynx -dump"
ULIMIT_MAX_FILES="ulimit -S -n `ulimit -H -n`"
ARGV="-h"
$HTTPD -k $ARGV
$HTTPD -k start -DSSL
$HTTPD -t
$LYNX $STATUSURL | awk ' /process$/ { print; exit } { print } '
其中ulimit、lynx和awk是辅助性的程序。另外需要注意的是,程序使用不同的参数时,可能会使用不同的库文件,因此,为了让Apache完整运行,使用下面的命令来跟踪所有可能的文件:
///usr/local/bin/addjailsw /var/chroot -P httpd "-k start -DSSL"
用上述的参数替换引号中的参数,完成全部的工作。
最后,让Apache成功运行起来:
//su - httpd &
打开浏览器进行测试,访问Web服务器时记住加上8080端口号。
6.3.11 使用SSL加固Apache使用具有SSL功能的Web服务器,可以提高网站的安全性能。SSL协议工作在Linux TCP/IP协议和HTTP协议之间,其关系如图6-12所示。
SSL使用加密方法来保护Web服务器和浏览器之间的信息流。SSL不仅用于加密在互联网上传递的数据流,而且还提供双方身份验证。这样就可以安全地在线购物而不必担心别人窃取信用卡的信息。这种特性使得SSL适用于那些交换重要信息的地方,像电子商务和基于Web的邮件。
图6-12 SSL协议与Linux TCP/IP协议和HTTP协议之间关系
SSL使用公共密钥加密技术,服务器在连接结束时给客户端发送公用密钥用来加密信息,而加密的信息只有服务器用它自己持有的专用密钥才能解开。客户端用公用密钥加密数据,并且发送给服务器自己的密钥,以唯一确定自己,防止在系统两端之间有人冒充服务器或客户端进行欺骗。加密的HTTP连接用443端口号代替80端口号,以区别于普通的不加密的HTTP。客户端使用加密HTTP连接时会自动使用443端口而不是80端口,这使得服务器更容易做出相应的响应。SSL验证和加密的具体过程如下:
① 用户使用浏览器,访问Web服务器站点,发出SSL握手信号;
② Web服务器发出回应,并出示服务器证书(公钥),显示系统Web服务器站点身份;
③ 浏览器验证服务器证书,并生成一个随机的会话密钥,密钥长度达到128位;
④ 浏览器用Web服务器的公钥加密该会话密钥;
⑤ 浏览器将会话密钥的加密结果发送Web服务器;
⑥ Web服务器用自己的私钥解密得出真正的会话密钥;
⑦ 现在浏览器和Web服务器都拥有同样的会话密钥,双方可以放心使用这个会话密钥来加密通信内容;
⑧ 安全通信通道建立成功。
Apache服务器使用SSL时通常有两种选择,即主服务器或虚拟Web站点。
如果使用的是RHEL 3.0~4.0,那么可以直接使用命令“rpm -qa | grep mod_ssl”检查,如果没有安装,可以以root的身份登录系统,输入命令“system-config-packages”。利用GUI套件管理工具的网页服务器,点选“详细信息”,然后勾选“mod_ssl”,提示放入适当的光盘,便可完成安装工作,如图6-13所示。
图6-13 安装mod_ssl软件包
下面产生SSL凭证,使用以下命令可以产生.key和.csr档:
# openssl genrsa -out server.key 1024
Generating RSA private key, 1024 bit long modulus
......++++++
........++++++
e is 65537 (0x10001)
# chmod 600 server.key
# openssl req -new -key server.key -out server.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 City
Organization Name (eg, company) [My Company Ltd]:x41
Organizational Unit Name (eg, section) []:x41
Common Name (eg, your name or your server's hostname) []:localhost
Email Address []:goodcjh@2911.net
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:goodcjh
An optional company name []:goodcjh
注意 黑体部分是需要手工输入的。下面要自行签署才有效,然后再让使用者汇入你的凭证才行。
以下将示范如何自己签署金钥:
openssl x509 -req -days 365 –in server.csr -signkey server.key -out server.crt
完成之后,你应该就会产生三个文件:server.csr, server.key, server.crt。将它们复制到ca存放的目录/etc/httpd/conf/ca,然后修改Apache配置文件httpd.conf,添加以下两行:
SSLCertificateFile /etc/httpd/conf/ca/server.crt
SSLCertificateKeyFile /etc/httpd/conf/ca/server.key
重新启动Apache:
apachectl stop
apachectl startssl
使用浏览器访问Apache服务器的首页,输入“https://localhost”,此时出现屏幕提示,如图6-14所示。
点击“确定”按钮,即可进入加密显示的Apache首页,注意浏览器的位置栏和右下角的标志,如图6-15所示。
图6-14 HTTPS安全性提示的界面
如果使用的Linux发行版本没有包括mod_ssl软件,可以使用APT命令添加。Debian GNU/Linux 是APT(Advanced Package Tool)的缔造者。其初衷是利用工具来解决软件安装时的依赖性问题。工作原理大致为:用户安装APT客户端工具,查寻APT服务器的资料库(repositories)上的RPM软件包信息,并分析软件包之间的依赖性,然后下载并进行安装。APT 除了可以让你很方便且快速地安装 RPM 软件外,你也可以用它来更新系统。虽然APT是基于Debian的软件包管理工具,但是已经被一个巴西公司Conectiva移植到基于RPM的系统上。因此,对于基于RPM软件包管理的平台,如 Red Hat、TurboLinux、SUSE、Mandrake等Linux发行版本,APT是一个非常优秀的软件管理工具。
图6-15 加密显示的Apache首页
运行APT之前需要确认服务器上Apache是否已经可以提供WWW服务,并且/var分区是否有足够的空间。
# wget Fedora/linux/3/apt/apt-0.5.15cnc6- 1.1.fc3.fr.i386.rpm
# wget 15cnc6-1.1.fc3.fr.i386.rpm
# rpm -ivh apt-devel-0.5.15cnc6-1.1.fc3.fr.i386.rpm
# rpm -ivh apt-0.5.15cnc6-1.1.fc3.fr.i386.rpm
接着需要加入freshrpms.net的公共密钥GPG-KEY,然后在/etc/apt下建立一个/gpg文件夹,将GPG-KEY保存在那里,以便日后管理。
# rpm --import
安装图形界面,freshrpms.net站点提供了一个图形界面的apt-rpm接口Synaptic,使用图形界面的APT更加方便,可以直接利用APT安装Synaptic:
# apt-get install synaptic
在几行提示之后Synaptic就安装好了,进入X Window后,Synaptic会出现在“系统设置”菜单里面。界面如图6-16所示。
图6-16 APT图形化接口Synaptic
APT系统主要包括以下命令,如表6-1所示。
表6-1 APT系统的主要命令
命 令 描 述 apt-get update 更新apt-get的本地数据库,使其与服务器的pkglist文件同步。在升级以前一般都要执行本命令实现与服务器的一致 apt-get check 验证本地系统的完整性 apt-get dist-upgrade 安装所有的基础软件包,升级一切软件包,并在需要时安装新软件包 apt-get remove package_name 删除该软件包,同时会删除依赖于它的软件包 apt-get install package_name 安装某个软件包及其相关软件包 apt-get source package_name 下载软件包的source rpm apt-get clean 删除保存在缓存目录下(/var/cache/apt/archives)的被下载的软件包 apt-get upgrade package_name 升级指定的软件包,并升级其依赖的软件包 apt-cdrom add 自动安装光盘并建立列表 apt-cache depends package_name 显示软件包的依赖性关系 apt-cache package_name 在网络上搜索指定的软件包 apt-config dump 显示目前的配置信息
其中用户使用最多的就是apt-get命令。
# apt-get install openssl
# apt-get install libapache-mod-ssl
# apache-modconf apache enable mod_ssl
然后产生认证文件。方法和上面相似。
# cd /etc/apache/ssl.key/
# openssl genrsa -out server.key 1024
# chmod 600 server.key
# openssl genrsa -des3 -out server.key 1 024
# cd ../ssl.csr/
# openssl req -new -key ../ssl.key/server.key -out server.csr
# cd ../ssl.crt/
# openssl req new -x509 -nodes -sha1 -days 365 -key /ssl.key/server.key -out server.crt
如果使用的是虚拟主机,还要修改Apache配置文件:
Listen *:443
<VirtualHost *:443>
ServerName secure.example.org
DocumentRoot /home/username/public_html/
User username
Group groupname
DirectoryIndex index.php index.html index.htm
SSLEngine On
SSLCertificateKeyFile /etc/apache/ssl.key/server.key
SSLCertificateFile /etc/apache/ssl.crt/server.crt
SSLCACertificateFile /etc/apache/ssl.crt/ca.crt
</VirtualHost>
6.3.12 Apache服务器防范DoSApache服务器对拒绝服务攻击的防范主要通过软件Apache DoS Evasive Maneuvers Module 来实现。它是一款mod_access的替代软件,可以对抗DoS攻击。该软件可以快速拒绝来自相同地址对同一URL的重复请求,通过查询内部一张各子进程的哈希表来实现。到网站 securityfocus.com/data/tools/dospatch.tar.gz上下载软件。软件安装的配置可以查看Linux中文主页上的Apache性能和安全指南,过程比较简单,限于篇幅这里就不介绍了。
同时可以使用Linux系统强大的命令手段防范Dos攻击。
netstat -an | grep -i “服务器IP地址:80” | awk '{print $6}' | sort | uniq -c | sort -n
这个命令会自动统计TCP连接的各个状态的数量,如果syn_recv很高的话,就不能排除有基于TCP协议的拒绝服务攻击的可能。于是需要打开tcp_syncookies:
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
如果没有 /proc/sys/net/ipv4/tcp_syncookies,说明内核不支持syncookies,需要重新编译内核,同时降低SYN重试次数。
echo “1” > /proc/sys/net/ipv4/tcp_syn_retries
echo “1” > /proc/sys/net/ipv4/tcp_synack_retries
同时加大syn_backlog,以保证用户的访问:
echo “2048” > /proc/sys/net/ipv4/tcp_max_syn_backlog
6.3.13 利用LDAP对Apache进行认证建立测试网页。
# #mkdir /var/www/html/ldap
#echo “LDAP Auth Test Page” > /var/www/html/ldap/index.html
安装mod_authz_ldap模块。
要让Apache服务器可以存取LDAP服务器上的资料,必须利用mod_authz_ldap模块作为Apache和LDAP服务器之间认证的接口,所以必须安装mod_authz_ldap模块。
# rpm -ivh mod_authz_ldap*.rpm
修改/etc/httpd/conf.d/auth_mysql.conf。若之前曾安装mod_auth_mysql认证模块,则必须将mod_auth_mysql模块功能关闭。
#LoadModule mysql_auth_module modules/mod_auth_mysql.so
修改/etc/httpd/conf.d/authz_ldap.conf。
# <IfModule mod_authz_ldap.c>
# <Location /private>
# AuthzLDAPEngine on
# AuthzLDAPServer localhost
# AuthzLDAPUserBase ou=People,dc=example,dc=com
# AuthzLDAPUserKey uid
# AuthzLDAPUserScope base
# AuthType basic
# AuthName "ldap@example.com"
# require valid-user
# </Location>
</IfModule>
修改为以下文字:
# LoadModule authz_ldap_module modules/mod_authz_ldap.so
<IfModule mod_authz_ldap.c>
<Directory /var/www/html/ldap>
AuthzLDAPServer localhost
AuthzLDAPUserBase ou=People,dc=example,dc=com
AuthzLDAPUserKey uid
AuthzLDAPUserScope base
AuthType basic
AuthName "ldap@example.com"
require valid-user
</Directory>
</IfModule>
重新启动Apache服务器。# #service httpd restart
停止 httpd: [ 确定 ]
启动 httpd: [ 确定 ]
6.3.14 其他安全工具使用tcp_wrappers和AIDE可以为系统提供额外的保护。使用tcp_wrappers可以进一部控制访问权限。AIDE是一个数据完整性检测工具,可以帮助系统管理员监视系统是否被改动过,你可以在AIDE的配置文件中编制特定的策略,监视Web服务器的配置文件、数据和CGI文件是否被修改。另外Selinux也可以保护Apache服务器(第16章将会介绍)。如果对目录服务比较熟悉,还可以使用LDAP服务器对Apache服务器进行访问认证。
在Apache配置文件中,有一些安全相关的指令可以使用。这些指令的详细用法可以参考 apache.org/docs/mod/directives.html。
使用以下指令可以帮助你减小拒绝服务攻击的威胁。
— LimitRequestbody:数字参数,控制HTTP请求的大小。
— LimitRequestFields:数字参数,控制请求头的数目。
— KeepAlive:设置连接的生存期。
— KeepAliveTimeout:限制等待请求的时间。
使用以下指令可以帮助你减少缓冲区溢出的危险。
— LimitRequestFieldSize:限制每个请求头的大小。
— LimitRequestLine:限制每个请求行的大小。
实际上,大部分Web站点被破坏者恶意攻击是因为应用程序或脚本中的漏洞。Web安全专家认为,运行在Web服务器上的脚本或应用程序是最大的危险因素。因为CGI脚本通常产生动态内容,它们经常导致很大损害。对于大部分Web服务器来说,首先应该考虑如何加强安全配置。