Web中间件学习篇
本篇主要从IIS、Apache、Nginx、Tomcat四种常见中间件的Nginx入手,介绍相关安全知识,遵循“中间件简介→如何搭建网站→安全配置分析→安全日志分析”的顺序进行学习,旨在梳理常见Web中间件的知识点,为Web安全学习打好基础。
Nginx简介
代码语言:javascript复制Nginx(发音同engine x)是一个网页服务器,它能反向代理HTTP, HTTPS, SMTP, POP3,IMAP的协议链接,以及一个负载均衡器和一个HTTP缓存。 Nginx是一款面向性能设计的HTTP服务器,相较于Apache、lighttpd具有占有内存少,稳定性高等优势。与旧版本(<=2.2)的Apache不同,nginx不采用每客户机一线程的设计模型,而是充分使用异步逻辑,削减了上下文调度开销,所以并发服务能力更强。 起初是供俄国大型的门户网站及搜索引擎Rambler(俄语:Рамблер)使用。此软件BSD-like协议下发行,可以在UNIX、GNU/Linux、BSD、Mac OS X、Solaris,以及Microsoft Windows等操作系统中运行。
Nginx站点搭建
Nginx站点的搭建其难点在于安装Nginx,不同于Apache可以直接使用yum或者apt-get的方式安装,Nginx不在系统标准源中,因此常见的安装方式主要有两个:编译安装和第三方yum源安装。由于编译安装Nginx需要安装的拓展比较多,此次我们使用第三方yum源方式安装Nginx,同时以此为基础,搭建Linux Nginx Mysql Php的站点,分为以下几步:
- 配置第三方yum源;
- 安装Nginx;
- 安装Mysql、php、配置phpmyadmin;
- 部署php站点;
下面开始详细介绍如何搭建一个完整的Nginx站点:
环境介绍
代码语言:javascript复制操作系统:CentOS release 6.5 (Final)Nginx版本: nginx-1.6.2-23.el6.art.x86_64站点类型:php
搭建步骤
配置第三方yum源
由于CentOS标准yum源中不提供Nginx的安装包,所以需要第三方yum源来补充一下,而第三方源的选择同样需要谨慎,不仅要保证软件要兼容本系统同时版本较新,最重要的是要保证安全,否则安装的软件可能都带着后门。此次我们选择的是Atomic源
Atomic支持哪些软件可以到这个地址查看:http://www.atomicorp.com/channels/atomic/ 最常见的有php、mysql、nginx、openvas、memcached、php-zend-guard-loader等软件。
配置步骤如下:
代码语言:javascript复制wget <a href="http://www.atomicorp.com/installers/atomic">http://www.atomicorp.com/installers/atomic</a>sh ./atomicyum check-update
其中在sh ./atomic一步,一路yes即可,同时安装相关拓展和依赖
代码语言:javascript复制yum -y install ntp make openssl openssl-devel pcre pcre-devel libpnglibpng-devel libjpeg-6b libjpeg-devel-6b freetype freetype-devel gd gd-devel zlib zlib-develgcc gcc-c libXpm libXpm-devel ncurses ncurses-devel libmcrypt libmcrypt-devel libxml2libxml2-devel imake autoconf automake screen sysstat compat-libstdc -33 curl curl-devel
如果之前有安装过mysql、apache、php,需要先全部卸载
代码语言:javascript复制yum remove httpdyum remove phpyum remove mysql
安装Nginx
配置了第三方yum源后,安装就方便了很多
代码语言:javascript复制yum install nginxservice nginx startchkconfig --levels 235 nginx on ////设置2、3、5级别开机启动
此时去访问localhost或者127.0.0.1或者本机访问本机ip就可以看见nginx界面
由于Atomic源的软件不是特别新,该版本是2014年4月发行,但是也足够使用了
此时其他主机还是无法通过ip的方式访问该主机的,和apache类似,需要开启80端口的访问规则
代码语言:javascript复制/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
此时其它主机已经可以正常访问
安装Mysql、php、配置phpmyadmin
这些其实和apache是基本相同的
代码语言:javascript复制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
代码语言:javascript复制yum -y install php //安装phpyum -y install php-mysql gd php-gd gd-devel php-xml php-commonyum -y install php-mbstring php-ldap php-pear php-xmlrpc php-imap php-mcrypt//安装php常用拓展yum install php-tidy php-common php-devel php-fpm //安装php-fpmservice php-fpm start //启动php-fpmchkconfig --levels 235 php-fpm on //设置php-fpm2、3、5级别开机启动service nginx restart //重启nginx服务,这一步非常重要
完成之后可以简单测试一下,在/usr/share/nginx/html/目录下新建phpinfo.php文件内容为phpinfo(),让其输出一下相关信息,然后发现。。。现在还是无法解析php文件,访问的话会直接下载该文件
因此我们需要配置一下Nginx支持解析php,配置文件名称为nginx.conf,具体路径的寻找方式有多种方法:
代码语言:javascript复制方法一:updatedblocate nginx.conf方法二:ps aux |grep nginx
还有更简单的配置文件路径的查看方法,会在日志篇进行详细说明
具体的配置步骤如下:
代码语言:javascript复制mv /etc/nginx/nginx.conf /etc/nginx/nginx.confbak//将配置文件改为备份文件 cp /etc/nginx/nginx.conf.default /etc/nginx/nginx.conf//由于原配置文件要自己去写因此可以使用默认的配置文件作为配置文件 //修改nginx配置文件,添加fastcgi支持vi /etc/nginx/nginx.confindex index.php index.html index.htm;//加入index.php,大约在45行左右 location ~ .php$ {root /usr/share/nginx/html;fastcgi_pass 127.0.0.1:9000;fastcgi_index index.php;fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html$fastcgi_script_name;include fastcgi_params;}//将65行--71行处关于.php文件规则的注释符号删去
代码语言:javascript复制//配置/etc/php.ini,在文件末尾添加cgi.fix_pathinfo = 1
代码语言:javascript复制最后重启nginx和php-fpmservice nginx restartservice php-fpm restart
此时再访问/usr/share/nginx/html/目录下的phpinfo.php,可以正常显示服务器信息
下一步就是安装phpmyadmin,这个其实是可选步骤,只是为了方便图形化管理mysql,下载官网:phpmyadmin下载官网
在官网下载了phpMyAdmin-4.0.10.20-all-languages.tar.gz
和Apache一样,由于安装的php版本为5.4.45,低于php5.5,因此安装低版本的phpMyAdmin
代码语言:javascript复制tar -xvzf phpMyAdmin-4.0.10.20-all-languages.tar.gzmv phpMyAdmin-4.0.10.20-all-languages /usr/share/nginx/html/phpmyadmincd /usr/share/nginx/html/phpmyadmincp libraries/config.default.php config.inc.php
然后修改一下相关配置vi config.inc.php,一般改这些
代码语言:javascript复制$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其实也可以修改,否则登录后会给个警告,但是不影响使用最后重启一下nginx和php-fpm服务
代码语言:javascript复制service nginx restartservice php-fpm restart
打开浏览器访问http://localhost/phpmyadmin 或者 http://ip/phpmyadmin
部署Php站点
还是将apache中配置好的php源码包直接拿来使用,和apache不同,此时的db_config.php文件,主机host使用127.0.0.1不会报错
但是登录页面login.php显示乱码,登录成功后的页面index.php正常,这个很显然是编码的问题
于是在login.php的<?php下发第一行添加
代码语言:javascript复制header("Content-Type: text/html;charset=utf-8");
重启一下nginx和php-fpm,再次访问,可以登录,一切正常,至此nginx下的php站点搭建完成
Nginx日志分析
和apache非常类似,nginx的主要日志也是access.log和error.log,那么该如何确认详细的路径?
执行以下命令即可
代码语言:javascript复制nginx -V
其实里面有很多详细的路径信息,可以在其中查到,同时顺便一提,关于一些配置信息可以查看phpinfo界面,不要忽略它
根据上图,我们可以得到访问日志和错误日志的具体路径
access.log=/var/log/nginx/access.log error.log=/var/log/nginx/error.log
在打开这两种日志前,我们还是去配置文件/etc/nginx/nginx.conf里看看关于nginx日志的配置情况,直接搜索关键字log_format
,结果…
看起来比apache详细多了,而且还解释了各个字段的含义。但是…所有和日志有关的内容全被注释了…所以日志是怎么记录的?难道虽然被注释了,但是还是生效的?打开/var/log/nginx/access.log看一下
这个完全和apache的日志一样啊,根本没有什么http_x_forward_for
字段嘛,这个问题我困惑了很久,找了半天才发现原因:
也就是说:nginx默认使用了和apache相同的组合日志格式(Combined Log Format),但是它省略了,这个就比较坑了
其实一般情况下nginx日志记录格式会如上图所示,不会注释,但是可能是我安装的方式使用第三方yum源,有些配置被修改了
如果想自定义日志的不同字段,可以参考这篇文章:nginx系列-04-nginx日志配置
同时error.log的格式在nginx.conf中若未定义,同样使用apache对于错误日志的记录级别,该句亦省略
error_log /var/log/nginx/error.log warn;
还有一点很重要:查看一下/var/log/nginx下的文件
可以看见访问日志和错误日志均会按照天压缩成.gz文件,这个在nginx.conf中并未定义,是在哪里设置的?
其实类似这种log分片压缩成不同文件的,往往由logrotate完成 logratate根据不同应用生成多个log配置文件,路径在/etc/logrotate.d/目录下
两处关键点:
- daily 代表log按照天划分;
- compress 代表日志以gzip压缩转储以后的日志(.gz文本文件亦可直接使用vim打开)
如果对logrotate中nginx的配置比较感兴趣,可以看这篇文章:Nginx日志切割之Logrotate篇
Nginx日志分析Web攻击行为
Nginx日志同样可以用于分析Web攻击行为,本次使用AWVS扫描搭建的站点,然后查看日志情况
一切使用默认配置即可,稍等片刻即可完成扫描
打开日志看一下,内容挺多的,这次和IIS和Apache的web日志分析不同,这次主动查找AWVS的常用攻击行为
sql注入攻击
直接在access日志中搜索关键字“SELECT”
典型的GET型sql注入攻击,目的是获取数据库中所有的表
xss攻击
也非常简单,直接在access日志中搜索关键字“script”
如图所示,以上4处xss均为dom-xss,且添加测试字段均为wvstest
shellshock漏洞攻击
这个发现的比较偶然,自己之前甚至不怎么留意,因为在access日志中发现了一处16进制编码payload
配合前面的echo -e ,基本可以判断这是一处测试RCE漏洞的payload,于是乎想看看这个payload的原文
代码语言:javascript复制echo -e x22x5C0141x5C0143x5C0165x5C0156x5C0145x5C0164x5C0151x5C0170x5C0163x5C0150x5C0145x5C0154x5C0154x5C0163x5C0150x5C0157x5C0143x5C0153x22
x是典型的16进制,x22是双引号"的16进制,5C是反斜杠的16进制,所以转换一下上述字符串就是
代码语言:javascript复制echo -e” 141 143 165 156 145 164 151 170 163 150 145 154 154 163 150 157 143 153″