Apache简介
Apache起初由伊利诺伊大学香槟分校的国家超级电脑应用中心(NCSA)开发。此后,Apache Httpd被 开放源代码团体的成员不断的发展和加强。Apache Http网站服务器拥有牢靠可信的美誉,已经在 全球超半数的网站中被使用-特别是几乎所有最热门和访问量最大的网站。比方说,*网站服务器 就是使用Apache的。 刚开始发展时,Apache只是Netscape网页服务器(现在是Sun ONE)之外的开放源代码选择之一。 它开始在功能和速度超越其他基于Unix的HTTP服务器。到了Apache 2.x的时代,实际效率又比 Apache 1.x更快,2.x比1.x能同时服务更多的网页连接数。 1996年4月以来,Apache一直是Internet上最流行的HTTP服务器:1999年5月它在57%的网页服务器上 运行,到了2005年7月这个比例上升到了69%。在2005年11月最风光的时候达到接近70%的市占率, 不过在部分拥有大量域名的主机域名商转换为微软IIS平台后,Apache市占率近年来呈现些微下滑。 同时搜索引擎巨擘Google自己的网页服务器平台GWS推出后(也可说是一种修改版的Apache),再加上 nginx、Lighttpd等轻量化网页服务器软件在市场上有一些能见度,这些因素都反应在整体网页服务 器市占率的消长,Apache的市占率就随之滑落。 根据Netcraft在2009年12月的最新统计数据,Apache的市占率已经降为53.67%,IIS降为18.26%, 谷歌网页服务器13.53%,nginx 8.75%。 尽管如此,Apache及其各种分支版本仍旧是当前互联网市场上,市占率最高的网页服务器软件
Apache站点搭建
Apache的站点搭建相对于IIS而言还是比较简单的,无需过多的配置,只需要安装相应的软件和插件即可。以配置php站点为例,主要分为以下几步:
- 安装httpd服务;
- 安装Mysql、php、配置phpmyadmin;
- 部署php站点;
下面开始详细介绍如何搭建一个完整的Apache站点
环境介绍
操作系统:CentOS release 6.5 (Final) Apache版本:httpd-2.2.15-60.el6.centos.4.x86_64 站点类型:php
搭建步骤
安装httpd服务
整个安装过程还是非常轻松的
yum -y install httpd
service httpd start
有必要的话可以设置其开机启动,顺便安装一些apache拓展
chkconfig httpd on
yum -y install httpd-manual mod_ssl mod_perl mod_auth_mysql
此时去访问localhost或者127.0.0.1或者本机访问本机ip就可以看见熟悉的apache界面
但是由于iptables的缘故,其它主机还是无法访问的,此时有两种方法可以解决:
方法一 iptables -F //直接清除iptables规则,本次开机有效,过于简单粗暴,不推荐 方法二 /sbin/iptables -I INPUT -p tcp --dport 80 -j ACCEPT //添加开启80端口规则 /etc/rc.d/init.d/iptables save //保存配置 /etc/rc.d/init.d/iptables restart //重启iptables /etc/init.d/iptables status //查看开放的端口,出现80 顺便一提,想开启ssh服务也可将22端口如上述方法设置规则
此时其它主机已经可以正常访问
安装Mysql、php、配置phpmyadmin
yum -y install mysql mysql-server mysql-devel //安装mysql和其相关拓展 chkconfig mysqld on //设置其开机启动 service mysqld start //启动mysqld服务 /usr/bin/mysql_secure_installation //设置mysql的一些安全配置 这一步还是很重要的,主要是设置mysql的root密码,是否需要删除匿名账号等等,根据实际需要设置
此时我们可以登录一下mysql
yum -y install php //安装php yum -y install php-mysql gd php-gd gd-devel php-xml php-common yum -y install php-mbstring php-ldap php-pear php-xmlrpc php-imap php-mcrypt //安装php常用拓展 service httpd restart //重启httpd服务,这一步非常重要
完成之后可以简单测试一下,在/var/www/html目录下新建phpinfo.php文件,让其输出一下相关信息
下一步就是安装phpmyadmin,这个其实是可选步骤,只是为了方便图形化管理mysql,下载官网:phpmyadmin下载官网
在官网下载了phpMyAdmin-4.0.10.20-all-languages.tar.gz
下载的是老版本,这个是由于我安装的php版本为5.3.3,低于5.5,一开始下载的4.7.3的版本配置了半天还是显示403比较无语,老版本不会出问题
tar -xvzf phpMyAdmin-4.0.10.20-all-languages.tar.gz mv phpMyAdmin-4.0.10.20-all-languages /var/www/html/phpmyadmin cd /var/www/html/phpmyadmin cp libraries/config.default.php config.inc.php
然后修改一下相关配置vi config.inc.php,一般改这些
$cfg['PmaAbsoluteUri'] = '';这里填写 phpMyAdmin 的访问网址。 $cfg['Servers'][$i]['host'] = 'localhost'; // MySQL hostname or IP address $cfg['Servers'][$i]['port'] = ''; // MySQL port - leave blank for default port $cfg['Servers'][$i]['user'] = 'root'; // 填写 MySQL 访问 phpMyAdmin 使用的 MySQL 用户名,默认为 root。 $cfg['Servers'][$i]['password'] = ''; // 填写对应上述 MySQL 用户名的密码。 $cfg['blowfish_secret'] = '1qaz2wsx3edc';//随意,长度不要太短
实际过程中其实我也只是修改了password一处为我的mysql密码,blowfish_secret其实也可以修改,否则登录后会给个警告,但是不影响使用最后重启一下httpd服务 service httpd restart打开浏览器访问http://localhost/phpmyadmin或者http://ip/phpmyadmin即可
部署php站点
这一步相对而言比较简单,我直接使用了我毕设时制作的php源码包,修改了一下其中的db_config.php,把root密码改成目前设置的,最后访问一下login.php,非常完美
然后登录一下,结果。。。
写了一个小的脚本看一下报的什么错
<?php @ $mysqli = new mysqli($dbConf[host],$dbConf[user], $dbConf[password],$dbConf[dbName],$dbConf[port]); if ($mysqli->connect_errno) { echo "不能连接到数据库<br/>"; echo mysqli_connect_error($mysqli); return; } else {echo "mission success!";} ?>
显示Access denied for user ‘root’@'localhost’ (using password: NO)这个问题非常奇怪,找了半天全是关于终端登录mysql时出现这种问题,看来问题还是出现在我写的db_config.php上,最后根据经验将host从127.0.0.1改成localhost居然好了
仔细查了这个问题发现对于mysql和php这两者还真的不一样,甚至连接方式都不相同
简而言之
当主机填写为localhost时mysql会采用 unix domain socket连接 当主机填写为127.0.0.1时mysql会采用tcp方式连接 这是linux套接字网络的特性,win平台不会有这个问题
Apache日志分析
Apache日志主要分为两类:error_log
和 access_log
,实际排查过程中更常用的是error_log
关于Apache日志文件的位置,详细信息可以查看Apache的配置文件,但是由于Linux发行版的差异和安装方式的不同,其配置文件也不尽相同,下面开始分别介绍:
Apache日志(Debian家族)
常用于Debian,Ubuntu或Linux Mint 测试系统:Ubuntu 16.04 LTS 使用apt-get方式安装 apache2 2.4.18-2ubuntu3.3 此时的配置文件名称为apache2.conf
一般情况下该配置文件路径为/etc/apache2/apache2.conf,如果使用编译安装或者dpkg等方式安装的话路径可能会有不同,此时一般建议使用locate搜索一下apache2.conf
updatedb
locate apache2.conf
日志文件信息就写在该配置文件中
其中使用了变量APACHE_LOG_DIR
指代了前面的路径,而$APACHE_LOG_DIR
到底代表什么,其实这个值是环境变量,一切和apache2环境变量有关的值全在/etc/apache2/envvars中,env为环境缩写,vars为变量缩写,打开后可以发现该值为/var/log/apache2/
拼接一下,完整的error_log路径为
/var/log/apache2/error.log
查看一下/var/log/apache2下的文件,包括access.log
(访问日志)、error.log
(错误日志)、other_vhosts_access.log
(虚拟主机日志)
access.log
我们可以打开access.log文件看一下其中的内容
下面我们详细解释一下吧,首先这个日志格式,仍然来源于配置文件apache2.conf,其中有关于LogFormat的定义
第一个可以不用管它,它是虚拟主机的日志文件格式,本篇不做讨论
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%h %l %u %t \"%r\" %>s %O" common
第二个和第三个分别为组合日志格式(Combined Log Format)和通用日志格式(Common Log Format),本系统中由于Combined在Common之前,因此access_log日志按照Combined Log Format方式记录,解释下各个字段的含义,以下面一行为例:
127.0.0.1 – - [24/May/2017:10:31:39 +0800] “GET / HTTP/1.1″ 200 3525 “-” “Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:53.0) Gecko/20100101 Firefox/53.0″
对应
LogFormat “%h %l %u %t \”%r\” %>s %O \”%{Referer}i\” \”%{User-Agent}i\”" combined
其中:
%h 远端主机 对应127.0.0.1 %l 远端登录名(由identd而来),除非IdentityCheck设为"On",否则将得到一个"-" %u 远程用户名(根据验证信息而来),若不存在得到一个"-" %t 时间,用普通日志时间格式(标准英语格式) 对应[24/May/2017:10:31:39 +0800] \"%r\" 请求头的第一行,\用于转移双引号,对应 "GET / HTTP/1.1" %>s 该请求最后的状态码,对应200 %O 发送的字节数,包括请求头的数据,并且不能为零,对应3525 \"%{Referer}i\"该请求来源页面,此处对应"-" \"%{User-Agent}i\"该请求使用的浏览器信息,对应"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:53.0) Gecko/20100101 Firefox/53.0"
第四个和第五个类似,补充一条
%U 请求的URL路径,不包含查询字符串。
关于Apache日志完整字段内容可以参考以下文章apache日志 LogFormat参数说明
error.log
相对于access.log日志文件,apache的error.log要简单一些,首先在apache2.conf文件中定义了其路径(ErrorLog)及记录等级(LogLevel)
类似于Linux的syslog,只记录等级在配置文件中规定及以上的信息,如上图所示,error.log中只记录等级在warn以上的信息,以下为错误信息等级排序:
查看一下error.log中到底记录了什么吧
其实这张图不是特别好,居然记录的全是notice的信息,而notice的等级在warn之下,为什么会被记录?
注意:当错误日志是一个单独分开的正式文件的时候(如本例中就是单独的/var/log/apache2/error.log文件),notice级别的消息总是会被记录下来,而不能被屏蔽。但是,当使用syslog来记录时就没有这个问题。
以上图片还表明了apache错误日志记录的格式为
[日期和时间] [错误等级] 错误消息
关于日志文件的更多内容可以查阅该网站Apache的日志文件
Apache日志(RedHat家族)
常用于CentOS,Fedora或RHEL 测试系统:CentOS release 6.5 使用yum方式安装 Apache/2.2.15 (Unix) 此时的配置文件名称为httpd.conf
一般情况下该配置文件路径为/etc/httpd/conf/httpd.conf,如果使用编译安装或者rpm等方式安装的话路径可能会有不同,此时一般建议使用locate搜索一下httpd.conf,还有更简便的方法,后面会介绍
updatedb locate httpd.conf
日志文件信息就写在该配置文件中
典型的相对路径的写法,还要找一下路径的起始位置,可以搜索一下ServerRoot
拼接一下,完整的error_log路径为
/etc/httpd/logs/error.log
与此同时,我们还可以在/var/log/httpd/目录下找到相同的error.log文件,这是怎么回事呢?
显而易见,/etc/httpd/logs/目录是/var/log/httpd的一个软链接
更简单的查看方法,可以使用以下命令
httpd -V
指出了httpd的根目录为/etc/httpd,错误日志目录为/etc/httpd/+logs/error_log,配置文件目录为/etc/httpd/+conf/httpd.conf
查看一下/etc/httpd/logs下的文件,包括 access.log
(访问日志)、error.log
(错误日志)、ssl_access_log
(https访问日志)、ssl_error_log
(https错误日志)、ssl_request_log
(https请求日志)
access.log
我们可以打开access.log文件看一下其中的内容
下面我们详细解释一下吧,首先这个日志格式,仍然来源于配置文件httpd.conf,其中有关于LogFormat的定义
这个和Debian家族的apache2.conf中的定义是一样的,此处就不详细展开了,有一点不同之处:httpd.conf中的access.log指定了日志格式为Combined Log Format,而apache2.conf中并未提及,只是按照顺序选择了Combined Log Format
error.log
这个和Debian家族的error.log基本上是相同的,httpd中同样记录了LogLevel为Warn
注意:当错误日志是一个单独分开的正式文件的时候(如本例中就是单独的/var/log/apache2/error.log文件),notice级别的消息总是会被记录下来,而不能被屏蔽。但是,当使用syslog来记录时就没有这个问题。
以上图片还表明了apache错误日志记录的格式为
[日期和时间] [错误等级] 错误消息
查看该日志我们可以发现一个问题:php的access.log和error.log直接记录在了httpd的日志路径下,难道php的日志不会记录在自己的相关目录下吗?
这个问题可以在/etc/php.ini(php配置文件默认路径)中得到答案
php的错误日志文件可以自定义输出路径,也可以输出到syslog中,但是在该文件中均被分号注释了,因此日志文件默认通过web中间件进行存储
Apache日志分析Web攻击行为
Apache日志有一个重要作用就是分析Web攻击行为
sql注入攻击
下面使用Apache日志分析sqlmap对网站进行sql注入攻击。
首先还是找一处注入点
打开access.log文件可以看见非常多的访问记录,包括IP、访问时间、UA以及sqlmap的攻击payload等信息
xss攻击
下面使用Apache日志分析burp suite对网站进行xss跨站攻击。
首先使用burp suite随意拦截一处网址url,并在dcbid字段标记,使用xss-fuzzing攻击
由于这个站点设置过XSS过滤,因此以上payload没有成功
但是查看日志文件,同样可以看见大量的xss攻击记录
post方式访问
Apache的日志能否记录POST请求数据呢?我们使用burp suite将GET请求更改为POST,并添加内容为hello qingteng~~
去日志文件中查看,可以发现对于此次的POST 请求,日志中是有记录的,但并未记录POST提交的内容
那么apache中如何让日志文件记录POST提交的信息呢?
-
apache加载dumpio模块。这个需要在httpd.conf文件中进行设置,apache默认不启用该模块,找到下面一行,去掉最前方的#号
# LoadModule dumpio_module modules/mod_dumpio.so`
-
配置日志告警级别。将原先的LogLevel注释掉,添加DumpIO模块的记录
LogLevel debug
DumpIOInput On
DumpIOOutput On
DumpIOLogLevel debug
3.重启apache
测试一下,还是POST方式传入hello qingteng~~,此时在error.log(特别注意不是access.log)中,我们可以看见POST传入的值
补充知识点
1. 如何修改apache默认端口号?
这个问题非常简单,打开httpd.conf文件,
找到Listen 80 一行,将80修改为想要设置的端口号,保存,重启httpd即可
测试时在本机浏览器输入http://127.0.0.1:新端口号 即可
注:外网主机此时可能无法通过http://IP:新端口号 方式访问,记得修改iptables,添加新端口号规则。
2. 以root身份启动apache,该服务以什么用户运行?
使用ps aux|grep httpd|grep -v grep查看一下
第一列中既有root,又有apache,其中第一行为httpd主进程,自第二行起为httpd子进程,这个是由于apache默认端口为80(http)和443(https),而Linux中启动小于1024的端口,必须使用root权限。
如果配置文件中的Listen directive设置了默认端口为80(或者是其它的值,但要小于1024),接下来apache httpd就需要root权限来启动apache,这是因为在将应用进程绑定在(1-1024)这个保留端口范围内的时候,需要root权限。
当 server一旦启动并且执行了些许初步动作,比如打开log日志文件,接下来server会装载执行指定数目的child processes,这些process是用来复杂监听端口,处理来自client的请求并且返回响应。
而主httpd process仍然以root权限继续运行,但是这些child processes会以较低的权限运行,而这些行为都可以通过选择Multi-processing Module来进行控制。