一、环境的搭建
实验环境:
操作系统:Centos 7.4
[root@xuegod70 ~]# ls apr-1.6.3.tar.gz apr-util-1.6.1.tar.bz2 httpd-2.4.33.tar.gz pcre-8.41.tar.gz #主要的按照包,下面是具体的安装操作 [root@xuegod70 ~]# yum install -y bzip2 [root@xuegod70 ~]# tar xf apr-1.6.3.tar.gz [root@xuegod70 ~]# ls apr-1.6.3 apr-1.6.3.tar.gz apr-util-1.6.1.tar.bz2 httpd-2.4.33.tar.gz pcre-8.41.tar.gz [root@xuegod70 ~]# cd apr-1.6.3 [root@xuegod70 apr-1.6.3]# yum install -y gcc gcc-c++ #安装依赖包 [root@xuegod70 apr-1.6.3]# ./configure --prefix=/usr/local/apr [root@xuegod70 apr-1.6.3]# make && make install [root@xuegod70 ~]# tar xf apr-util-1.6.1.tar.bz2 [root@xuegod70 ~]# cd apr-util-1.6.1 [root@xuegod70 apr-util-1.6.1]# ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr/bin/apr-1-config [root@xuegod70 apr-util-1.6.1]# yum install expat-devel -y #安装依赖包 [root@xuegod70 apr-util-1.6.1]# make && make install [root@xuegod70 ~]# tar xf pcre-8.41.tar.gz [root@xuegod70 ~]# cd pcre-8.41 [root@xuegod70 pcre-8.41]# ./configure --prefix=/usr/local/pcre [root@xuegod70 pcre-8.41]# make && make install
二、隐藏Apache版本信息
1. 屏蔽apache版本等敏感信息
#查看apache版本信息: [root@xuegod63 ~]# curl -I 192.168.1.63 HTTP/1.1 200 OK Date: Sun, 15 Nov 2015 12:40:59 GMT Server: Apache/2.4.33 (Unix) mod_ssl/2.4.33 OpenSSL/1.0.0-fips PHP/5.4.14 X-Powered-By: PHP/5.4.14 Content-Type: text/html [root@xuegod63 ~]# curl -I www.baidu.com HTTP/1.1 200 OK Accept-Ranges: bytes Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform Connection: Keep-Alive Content-Length: 277 Content-Type: text/html Date: Mon, 16 Jul 2018 08:32:29 GMT Etag: "575e1f71-115" Last-Modified: Mon, 13 Jun 2016 02:50:25 GMT Pragma: no-cache Server: bfe/1.0.8.18 [root@xuegod63 ~]# curl -I www.tencent.com HTTP/1.1 200 OK Server: NWS_UGC_HY Connection: keep-alive Date: Mon, 16 Jul 2018 08:32:58 GMT Cache-Control: max-age=600 Expires: Mon, 16 Jul 2018 08:42:58 GMT Last-Modified: Fri, 17 Feb 2017 02:11:37 GMT Content-Type: text/html Content-Length: 189 X-NWS-LOG-UUID: 0f1c8273-b0fa-4d9c-87ae-f6d9c5c8ca99 989f50f8bc1bbda11f966c017556085f X-Cache-Lookup: Hit From Disktank [root@xuegod63 ~]# curl -I www.taobao.com HTTP/1.1 302 Found Server: Tengine Date: Mon, 16 Jul 2018 08:33:17 GMT Content-Type: text/html Content-Length: 258 Connection: keep-alive Location: https://www.taobao.com/ Set-Cookie: thw=cn; Path=/; Domain=.taobao.com; Expires=Tue, 16-Jul-19 08:33:17 GMT; Strict-Transport-Security: max-age=31536000 1、我们在apache主配置文件httpd.conf中,找到包含httpd-default.conf的行,并解开注释 [root@xuegod63 ~]# vim /usr/local/httpd/conf/httpd.conf 486 #Include conf/extra/httpd-default.conf 为: 486 Include conf/extra/httpd-default.conf 注意:编译安装的情况下,只有此行解开注释了,后面的修改才能生效。 2)打开httpd-default.conf文件,修改如下两个地方 [root@xuegod63 ~]# vim /usr/local/httpd/conf/extra/httpd-default.conf #修改如下行 改: 55 ServerTokens Full 65 ServerSignature On 为: ServerTokens Prod ServerSignature Off 注: 服务器标记产品 服务器签名 重启服务: [root@xuegod63 ~]# /etc/init.d/apachectl restart 测试: [root@xuegod63 ~]# curl -I 192.168.1.63 HTTP/1.1 200 OK Date: Sat, 29 Aug 2015 09:07:00 GMT Server: Apache X-Powered-By: PHP/5.4.14 Content-Type: text/html 注:还是会出现信息:Server: Apache
2. 提升:彻底让版本等敏感信息消失
要彻底将版本之类的信息进行改头换面,需要在编译之前做准备或者进行重新编译了。在重新编译时,修改源码包下include目录下的ap_release.h文件
[root@xuegod63 httpd-2.4.33]# pwd /usr/src [root@xuegod63 src]# rm -rf httpd-2.4.33 [root@xuegod63 src]# tar zxf httpd-2.4.33.tar.gz [root@xuegod63 src]# cd httpd-2.4.33 [root@xuegod63 httpd-2.4.33]# vim include/ap_release.h 改: 42 #define AP_SERVER_BASEVENDOR "Apache Software Foundation" 43 #define AP_SERVER_BASEPROJECT "Apache HTTP Server" 44 #define AP_SERVER_BASEPRODUCT "Apache" 45 46 #define AP_SERVER_MAJORVERSION_NUMBER 2 47 #define AP_SERVER_MINORVERSION_NUMBER 2 48 #define AP_SERVER_PATCHLEVEL_NUMBER 25 49 #define AP_SERVER_DEVBUILD_BOOLEAN 0 为: #define AP_SERVER_BASEVENDOR "xuegod" #define AP_SERVER_BASEPROJECT "web server" #define AP_SERVER_BASEPRODUCT "web" #define AP_SERVER_MAJORVERSION_NUMBER 8 #define AP_SERVER_MINORVERSION_NUMBER 1 #define AP_SERVER_PATCHLEVEL_NUMBER 2 #define AP_SERVER_DEVBUILD_BOOLEAN 3 注释: #define AP_SERVER_BASEVENDOR "Apache Software Foundation" #服务的供应商名称 #define AP_SERVER_BASEPROJECT "Apache HTTP Server" #服务的项目名称 #define AP_SERVER_BASEPRODUCT "Apache" #服务的产品名 #define AP_SERVER_MAJORVERSION_NUMBER 2 #主要版本号 #define AP_SERVER_MINORVERSION_NUMBER 4 #小版本号 #define AP_SERVER_PATCHLEVEL_NUMBER 6 #补丁级别 #define AP_SERVER_DEVBUILD_BOOLEAN 0 # 注:上述列出的行,大家可以修改成自己想要的,然后编译安装之后,再对httpd-default.conf文件进行修改,对方就彻底不知道你的版本号了。
3.源码编译安装apache
[root@xuegod63 httpd-2.4.33]# pwd /usr/local/src/httpd-2.4.33 [root@xuegod63 httpd-2.4.33]# yum install openssl* openssl-devel [root@xuegod63 httpd-2.4.33]# ./configure --prefix=/usr/local/httpd --enable-so --enable-rewrite --enable-ssl --with-apr=/usr/local/apr
--with-apr-util=/usr/local/apr-util/ --with-pcre=/usr/local/pcre #检查安装环境并生成Makefile文件 #配置参数用途: --prefix=/usr/local/httpd #指定安装路径 --enable-so # 支持动态加载模块 --enable-rewrite # 支持网站地址重写 --enable-ssl # 支持ssl加密 #配置参数用途: --prefix=: 指定安装目录 --enable-so: 支持动态加载模块 --enable-rewrite: 支持网站地址重写 --enable-cgi: 支持CGI程序脚本 --enable-ssl: 支持SSL加密 --enable-charset-lite:支持多语言编码 #编译:安装: [root@xuegod63 httpd-2.4.33]# make -j 4 [root@xuegod63 httpd-2.4.33]# make install #查看配置文件: [root@xuegod63 httpd-2.4.33]# ls /usr/local/httpd/conf/httpd.conf /usr/local/httpd/conf/httpd.conf #存放网站的根目录: [root@xuegod63 httpd-2.4.33]# ls /usr/local/httpd/htdocs/ index.html #修改默认首页内容: [root@xuegod63 httpd-2.4.33]# echo apache-xuegod >> /usr/local/httpd/htdocs/index.html #启动apache: #配置apache 可以开机启动并且可以使用service 命令启动apache服务器 [root@xuegod63 httpd-2.4.33]# cp /usr/local/httpd/bin/apachectl /etc/init.d/apachectl [root@xuegod63 httpd-2.4.33]# vim /etc/init.d/apachectl #第一行后添加两行 #!/bin/sh # chkconfig: 2345 11 88 # description: Web Site …… [root@xuegod63 httpd-2.4.33]# ll !$ ll /etc/init.d/apachectl-xuegod -rwxr-xr-x 1 root root 3455 Aug 29 17:38 /etc/init.d/apachectl [root@xuegod63 httpd-2.4.33]# /etc/init.d/apachectl stop #关闭源来的apache包。 #设置开机自动启动: [root@xuegod63 httpd-2.4.33]# chkconfig --add apachectl [root@xuegod63 httpd-2.4.33]# chkconfig --list apachectl apachectl-xuegod 0:off 1:off 2:on 3:on 4:on 5:on 6:off #启动apache: [root@xuegod63 httpd-2.4.33]# /etc/init.d/apachectl start
4. 测试
[root@xuegod63 ~]# curl -I 192.168.1.63 #看不到apache版本相关内容了 HTTP/1.1 200 OK Date: Sat, 29 Aug 2015 09:43:44 GMT Server: web/8.1.2-dev (Unix) mod_ssl/8.1.2-dev OpenSSL/1.0.0-fips Last-Modified: Sat, 29 Aug 2015 09:37:36 GMT ETag: "6d086-3a-51e6ff35dba19" Accept-Ranges: bytes Content-Length: 58 Content-Type: text/html #接下来再次修改: [root@xuegod63 ~]# vim /usr/local/httpd/conf/httpd.conf 486 #Include conf/extra/httpd-default.conf 为: Include conf/extra/httpd-default.conf 2、打开httpd-default.conf文件,修改如下两个地方 [root@xuegod63 ~]# vim /usr/local/httpd/conf/extra/httpd-default.conf 改: 55 ServerTokens Full 65 ServerSignature Off 为: ServerTokens Prod ServerSignature On #重启服务: [root@xuegod63 ~]# /etc/init.d/apachectl restart #测试: [root@xuegod63 ~]# curl -I http://192.168.1.63/ HTTP/1.1 200 OK Date: Sat, 29 Aug 2015 09:55:31 GMT Server: web Last-Modified: Sat, 29 Aug 2015 09:37:36 GMT ETag: "6d086-3a-51e6ff35dba19" Accept-Ranges: bytes Content-Length: 58 Content-Type: text/html
5.查看运行apache的默认用户
我们通过更改apache的默认用户,可以提升apache的安全性。这样,即使apache服务被攻破,黑客拿到apache普通用户也不会对系统和其他应用造成破坏。
这里创建的apache用户,将用于对子进程和线程的控制。
注:默认使用daemon用户是安全的。
[root@xuegod63 ~]# ps -axu | grep httpd [root@xuegod63 ~]# id daemon uid=2(daemon) gid=2(daemon) groups=2(daemon),1(bin),4(adm),7(lp) [root@xuegod63 ~]# grep daemon /etc/passwd daemon:x:2:2:daemon:/sbin:/sbin/nologin [root@c64-web /]# useradd -M -s /sbin/nologin apache 创建apache用户 -M:不要自动建立用户的登入目录。 编辑apache配置文件,修改默认的用户。 [root@c64-web /]# vim /usr/local/apache/conf/httpd.conf 66 User daemon 67 Group daemon 为: User apache Group apache
6.apache目录及文件权限设置, 不能给777权限
在生产环境的网站架构中,我们应把资源文件的权限做好配置。
例:用户上传的图片及附件等和程序做好分离。这样才能更方便我们做好授权,保证apache服务和整个服务器安全。
这里我们设置apache的网站目录属主和属组是daemon:
[root@xuegod63 ~]# ll -sd /usr/local/apache2.2-xuegod/htdocs/ 4 drwxr-xr-x 2 root root 4096 Jun 29 2013 /usr/local/apache2.2-xuegod/htdocs/ [root@xuegod63 ~]# chown daemon:daemon /usr/local/apache2.2-xuegod/htdocs/ -R [root@xuegod63 ~]# ll -sd /usr/local/apache2.2-xuegod/htdocs/ 4 drwxr-xr-x 2 daemon daemon 4096 Jun 29 2013 /usr/local/apache2.2-xuegod/htdocs/ #网页目录文件权限快速恢复: [root@localhost httpd]# find ./htdocs/ -type f -exec chmod 644 {} ; [root@localhost httpd]# find ./htdocs/ -type d -exec chmod 755 {} ;
网页目录下,所有的目录应该为755, 所有的文件应该为644
如果某个目录用来上传文件的, 属主属组应该为apache, 其他的应该是root.apache
7.保护apache日志
设置好apache日志文件权限
#对日志的授权,我们要将属主和属组都设置为root: [root@xuegod63 ~]# ll -sd /usr/local/apache2.2-xuegod/logs/ 4 drwxr-xr-x 2 root root 4096 Aug 29 17:49 /usr/local/apache2.2-xuegod/logs/ [root@xuegod63 ~]# ll /usr/local/apache2.2-xuegod/logs/ total 12 -rw-r--r-- 1 root root 702 Aug 29 17:55 access_log -rw-r--r-- 1 root root 1590 Aug 29 17:55 error_log -rw-r--r-- 1 root root 6 Aug 29 17:55 httpd.pid -rw-r--r-- 1 root root 0 Aug 29 17:49 ssl_request_log 注:由于apache日志的记录是由apache的主进程进行操作的,而apache的主进程又是root用户启动的,所以这样不影响日志的输出。这也是日志记录的最安全的方法。
8.配置apache使用cronolog
由于实验用的apache开启了虚拟主机功能,所以以下范例配置都在虚拟主机中进行。
[root@sunsky cronolog-1.6.2]# vim /usr/local/apache/conf/extra/httpd-vhosts.conf #将配置文件中的CustomLog和ErrorLog替换为下面的(由于我们要对多站点,所以这里要替换两个虚拟主机的,并且将日志存放名字做有效的区分才好) CustomLog "|/usr/local/sbin/cronolog /app/logs/sunsky_access_%Y%m%d.log" combined ErrorLog "|/usr/local/sbin/cronolog /app/logs/sunsky_error_%Y%m%d.log" #更多日志格式参考: #按天轮询(生产环境常见用法,推荐使用): CustomLog "|/usr/local/sbin/cronolog /app/logs/access_www_%Y%m%d.log" combined #按小时轮询(生产环境较常见用法): CustomLog "|/usr/local/sbin/cronolog /app/logs /access_www_ %Y%m%d%H.log" combined
三、设置错误页面、开启压缩和缓存功能
1.错误页面优雅显示
为了提升网站的用户体验,避免404,403之类的丑陋的默认错误提示出现。我们需要对错误页面进行优化,让他们变的漂亮一点。错误页面不仅在于告诉用户访问出现了问题,而且需要引导用户到正确的页面。
错误页面优雅化显示的实现方式主要有两种,下面我们主要以404错误为例:
#方法一: [root@xuegod63 ~]# vim /usr/local/httpd/conf/httpd.conf #在根目录的标签中添加以下红色标记内容。 132 <Directory "/usr/local/apache2.2-xuegod/htdocs"> 。。。 159 ErrorDocument 404 /404.html 160 </Directory> 注:#将404错误跳转到/usr/local/httpd/htdocs下的404.html页面上 #创建404测试页: [root@xuegod63 ~]# echo "404 go to home" > /usr/local/httpd/htdocs/404.html #重启: [root@xuegod63 ~]# /etc/init.d/apachectl restart 方法二: #在apache的虚拟主机配置文件httpd-vhost.conf中的<VirtualHost*:80></VirtualHost>中添加ErrorDocument配置。 [root@xuegod63 ~]# vim /usr/local/httpd/conf/extra/httpd-vhosts.conf #添加以下内容 <VirtualHost *:80> ServerAdmin 888@qq.com DocumentRoot "/www/html" ServerName www.xuegod.cn ServerAlias xuegod.cn CustomLog "|/usr/local/sbin/cronolog /app/logs/www_access_%Y%m%d.log" combined ErrorLog "|/usr/local/sbin/cronolog /app/logs/www_error_%Y%m%d.log" ErrorDocument 404 http://www.xuegod.cn #将404错误跳转到http://www.xuegod.cn页面上 </VirtualHost>
总结:ErrorDocument的命令格式如下:
ErrorDocument 错误代码跳转到的页面或文件
另外这里需要注意,你若设置跳转到文件,必须要有这个文件才行。另外文件必须在站点目录内,不然会报错。
在跳转到文件的测试中,我用全路径和别名路径进行测试,当把404错误页面跳转文件放到其他目录的时候,不报错,但是页面跳转不过去。
2.启用压缩模块mod_deflate
Deflate [dɪˈfleɪt] 压缩,紧缩
网站随着用户访问量的增加和内容量的增加,网站的带宽会不断的增加,随之就是网站成本的增加。并且当内容量增大的时候,客户端如果带宽小,就会影响用户的体验。因此从这两方面考虑,网站的某些内容必须经过压缩之后再传给用户,然后在用户客户端进行解压,来实现双方共赢的效果。
apache的压缩要用到mod_deflate模块,该模块提供了DEFLATE输出过滤器,允许服务器在将输出内容发送到客户端以前进行压缩,以节约带宽。它的核心思想就是把文件先在服务器进行压缩,然后再进行传输,这样可以显著减少文件传输的大小。当传输完毕后,客户端游览器会重新对压缩过的内容进行解压缩。如果没特殊情况的话,所有的文本内容都应该能被gzip压缩,例如:html(php),js,css,xml,txt等。特殊情况就是像一些首页上有很多广告投放的js代码,由于需要每次加载进而进行来访信息统计,所以这些广告代码拥有者网站的js不会经过gzip压缩,
a)编译时安装方法
编译的时候跟上--enable-deflate即可实现安装
b)DSO方式安装。
扩展:DSO: Dynamic shared object动态共享对象 。DSO模块可以在编译服务器之后编译,也可以用Apache扩展工具(apxs)编译并增加
使用DSO方式安装,/usr/local/apache2.2-xuegod/bin/apxs后跟的参数详解
-c 此选项表明需要执行编译操作。
-i 此选项表示需要执行安装操作,以安装一个或多个动态共享对象到服务器的modules目录。
-a 此选项自动增加一个LoadModule行到httpd.conf文件中,以激活此模块,或者,如果此行已经存在,则启用之。
[root@xuegod63 filters]#cd /usr/local/src/httpd-2.4.33/modules/filters #切到apache源码包mod_deflate所在的目录下 [root@xuegod63 filters]# /usr/local/httpd/bin/apxs -c -i -a /usr/local/src/httpd-2.4.33/modules/filters/mod_deflate.c #以dso的方式编译安装到apache中 [root@xuegod63 filters]# ll /usr/local/httpd/modules/mod_deflate.so -rwxr-xr-x 1 root root 61912 Aug 31 09:05 /usr/local/apache2.2-xuegod/modules/mod_deflate.so #检查mod_deflate是否安装,成功安装这里会显示出该文件
3.压缩模块配置
#配置压缩参数 [root@xuegod63 ~]# vim /usr/local/httpd/conf/httpd.conf #确认下面这一行是打开的。默认是打开的。 LoadFile /usr/lib64/libz.so LoadModule deflate_module modules/mod_deflate.so #此行解锁后再进行下面操作,不然下面的操作会报错。 [root@xuegod63 ~]# vim /usr/local/httpd/conf/httpd.conf #在以下内容后,插入: 57 <IfModule !mpm_netware_module> 58 <IfModule !mpm_winnt_module> <ifmodule mod_deflate.c> DeflateCompressionLevel 9 SetOutputFilter DEFLATE DeflateFilterNote Input instream DeflateFilterNote Output outstream DeflateFilterNote Ratio ratio AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css application/javascript </ifmodule> 注释: <ifmodule mod_deflate.c> DeflateCompressionLevel 9 #压缩等级,越大效率越高,消耗CPU也越高。 DeflateCompressionLevel 9 #是指压缩程度的等级,从1到9,9是最高等级。据了解,这样做最高可以减少8成大小的传输量(看档案内容而定),最少也能够节省一半。 DeflateCompressionLevel #预设可以采用 6 这个数值,以维持耗用处理器效能与网页压缩质量的平衡。 注:一般压缩等级使用6或8 SetOutputFilter DEFLATE #启用压缩 DeflateFilterNote Input instream #声明输入流的byte数量 DeflateFilterNote Output outstream #声明输出流的byte数量 DeflateFilterNote Ratio ratio #声明压缩的百分比 #LogFormat '"%r" %{outstream}n/%{instream}n (%{ratio}n%%)' deflate #声明日志类型 #CustomLog logs/deflate_log.log deflate #声明日志类型 AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css application/javascript #仅压缩,限制特定的MIME类型文件 </ifmodule> 注: 1、如果是虚拟机,需要在<VirtualHost*:80></VirtualHost>中添加配置即可实现压缩 2、图片和视频本身就是压缩格式,一般不需要压缩的。有些小图片和视频压缩后还会变大。 #执行上面的添加后,我们对apache进行优雅重启 restart #粗人, 直接断开连接 [root@xuegod63 ~]# /etc/init.d/apachectl graceful # graceful 重新启动Apache服务器,但不会中断原有的连接。用于修改了配置文件后进行重新读取配置文件。 # 相当于nginx中的 -s reload 创建测试文件: [root@xuegod63 ~]# cp /etc/passwd /usr/local/httpd/htdocs/passwd.html
总结:我们在企业生产环境中时,在启用mod_deflate时,一定要注意,对于太小的文件和某些格式的图片不要对它们进行压缩,有可能越压越大。
扩展:AddOutputFilterByTypeDEFLATE后跟的所有的压缩文件类型,后期可以参照选择。
text/plain text/html text/php text/xml text/css text/javascript
application/xhtml+xml application/xml application/rss+xml application/atom_xml application/x-javascript application/x-httpd-php image/svg+xml image/gif image/png image/jpe image/swf image/jpeg image/bmp
4.mod_expires: 设置网页缓存时间
expire [ɪkˈspaɪə(r)] 到期
虽然我们上面通过mod_deflate模块启用了压缩,从很大程度上节约了企业带宽,降低了企业成本。可是由于现在越来越多的图片、脚本、css和flash被嵌入到页面中,当客户访问站点势必会做很多次的http请求,因此我们还可以通过mod_expires缓存模块来设置ExpiresHeader来缓存这些文件。
Expires是通过header报文来指定特定类型的文件在游览器中的缓存时间的。平时,我们大多数的图片,flash在发布之后都是不需要经常修改的,因此做了缓存之后,游览器第一次从服务器下载之后,就不需要再从服务器下载这些文件而是直接从游览器缓存中读取了。这样客户访问页面的速度就会大大加快,企业的带宽压力也得到了缓解。
安装了的话,就可以直接进行压缩配置了,如果没有安装,下面为安装方法 a)编译方式安装 编译的时候跟上--enable-expires即可实现安装 b)DSO方式安装 [root@xuegod63 ~]# cd /usr/local/src/httpd-2.4.33/modules/metadata/ #切到apache源码包mod_expires所在的目录下 [root@xuegod63 metadata]# ls mod_expires.c mod_expires.c #以dso的方式编译安装到apache中 [root@xuegod63 metadata]# /usr/local/httpd/bin/apxs -c -i -a /usr/local/src/httpd-2.4.33/modules/metadata/mod_expires.c #检查mod_deflate是否安装,成功安装这里会显示出该文件 [root@xuegod63 metadata]# ll /usr/local/httpd/modules/mod_expires.so -rwxr-xr-x 1 root root 37438 Aug 31 15:03 /usr/local/httpd/modules/mod_expires.so
5.配置缓存参数
注意如果我们是编译安装时已经编译进去的,要先解锁以下行,再进行下面操作,不然会报错。
[root@xuegod63 ~]# vim /usr/local/httpd/conf/httpd.conf #确认这一行是开启的。 55 LoadModule expires_module modules/mod_expires.so
缓存的用法有3种,分别问对全局,对目录,对虚拟主机。
1、对全局
对全局的配置就是在apache主配置文件httpd.conf的末尾加入如下参数即可
[root@xuegod63 ~]# vim /usr/local/httpd/conf/httpd.conf #在最后添加以下内容: 在57 <IfModule !mpm_netware_module> 58 <IfModule !mpm_winnt_module> 之后添加如下: <IfModule mod_expires.c> ExpiresActive on ExpiresDefault "access plus 12 month" ExpiresByType text/html "access plus 12 months" ExpiresByType text/css "access plus 12 months" ExpiresByType image/gif "access plus 12 months" ExpiresByType image/jpeg "access plus 12 months" ExpiresByType image/jpg "access plus 12 months" ExpiresByType image/png "access plus 12 months" EXpiresByType application/x-shockwave-flash "access plus 12 months" EXpiresByType application/x-javascript "access plus 12 months" ExpiresByType video/x-flv "access plus 12 months" </IfModule> #重启服务: [root@xuegod63 ~]# /etc/init.d/apachectl restart
2、对目录
对目录的配置就是在apache主配置文件中<Directory></Directory>标签内,最后加入如下参数即可
[root@xuegod63 ~]# vim /usr/local/httpd/conf/httpd.conf 133 <Directory "/usr/local/apache2.2-xuegod/htdocs"> <IfModule mod_expires.c> ExpiresActive on ExpiresDefault "access plus 12 month" ExpiresByType text/html "access plus 12 months" ExpiresByType text/css "access plus 12 months" ExpiresByType image/gif "access plus 12 months" ExpiresByType image/jpeg "access plus 12 months" ExpiresByType image/jpg "access plus 12 months" ExpiresByType image/png "access plus 12 months" EXpiresByType application/x-shockwave-flash "access plus 12 months" EXpiresByType application/x-javascript "access plus 12 months" ExpiresByType video/x-flv "access plus 12 months" </IfModule> </Directory>
3、对虚拟主机
对虚拟主机的配置就是在apache的虚拟主机配置文件httpd-vhost.conf中添加如下参数即可
[root@xuegod63 ~]# vim /usr/local/httpd/conf/httpd.conf <VirtualHost *:80> ServerAdmin 888@qq.com DocumentRoot "/www/html" ServerName www.sunsky.pw ServerAlias sunsky.pw CustomLog "|/usr/local/sbin/cronolog /app/logs/www_access_%Y%m%d.log" combined ErrorLog "|/usr/local/sbin/cronolog /app/logs/www_error_%Y%m%d.log" <IfModule mod_expires.c> ExpiresActive on ExpiresDefault "access plus 12 month" ExpiresByType text/html "access plus 12 months" ExpiresByType text/css "access plus 12 months" ExpiresByType image/gif "access plus 12 months" ExpiresByType image/jpeg "access plus 12 months" ExpiresByType image/jpg "access plus 12 months" ExpiresByType image/png "access plus 12 months" EXpiresByType application/x-shockwave-flash "access plus 12 months" EXpiresByType application/x-javascript "access plus 12 months" ExpiresByType video/x-flv "access plus 12 months" </IfModule> </VirtualHost>
以上三种配置任何一种配置之后,对apache服务器进行优化重启,然后用火狐或者google游览器的
测试:
上传一张图片a.jpg 到/usr/local/httpd/htdocs下:
[root@xuegod63 ~]# cp a.jpg /usr/local/httpd/htdocs
6.扩展:expires模块的语法
expires模块用到了ExpiresDefault和EXpiresByType两个指令,下面是这两个指令的语法。
ExpiresDefault “<base> [plus] {<num><type>}*”
EXpiresByType type/encoding "<base> [plus] {<num><type>}"
其中<base>的参数有3个:access,now(等价于‘access’),modification
modification [ˌmɒdɪfɪˈkeɪʃn] 改性,修正
plus关键字是可选的。 plus [plʌs] 加上
<num>必须是整数,确保可以atoi()所接收。(atoi可以把字符串转换成长整型数)
<type>参数类型:years,months,weeks,days,hours,minutes,seconds
例如:下面3个指令都表示文档默认的有效期是一个月
ExpiresDefault "access plus 1 month"
ExpiresDefault "access plus 4 weeks"
ExpiresDefault "access plus 30 days"
有效期可以通过增加“<num><type>”子句进一步调整
ExpiresByType text/html "access plus 1 month 15 days 2 hours"
ExpiresByType image/gif "modification plus 5 hours 3 minutes"
注意:如果你使用基于最后修改日期的设置,“Expires”头将不会被添加到那些并非来自于硬盘文件的内容,这是因为这些内容并不存在“最后修改时间”的属性。
基准时刻可以是源文件的最后修改时刻或者客户端对源文件的访问时刻,至于使用那一个则由<code>指定。“M”表示源文件的最后修改时刻,“A”表示客户端对源文件的访问时刻,需要注意的是<code>和seconds之间没有空格。
这两个基准的差别是很微妙的。如果使用“M”,所有当前缓存中的文档副本都将在同一时刻过期,这个可能对定期更新的URL(比如位于同一位置的每周通告)很有好处。如果使用“A”,则每个客户端所得到的有效期是不一样的,这个可能对那些几乎不更新的图片很有好处,特别是对于一组都引用相同图片的相关文档。
缓存优化对企业来说是至关重要了的,不同的业务类型,对于缓存的类型和时间又各不相同,大家具体可以用YSlow对淘宝,京东,新浪,谷歌等站点进行测试,看看他们的缓存时间是多少,并思考下为什么那样设置。
查看天猫缓存时间:
注:天猫解决被缓存文件及时更新的方法:对缓存的对象改名
虽然缓存的设置有如下优点
- 1. 缩短服务的响应时间
- 2. 减轻服务器负担
- 3. 减少网络带宽使用量,降低企业成本
但是他的缺点也是显而易见的,由于使用了缓存设置,导致被缓存的内容更新了,但是客户看到的却还是旧的。
如何解决被缓存文件及时更新这个问题呢?
- 第一种:缩短缓存时间例如:1天,不彻底牺牲性能
- 第二种:对缓存的对象改名。
参数:
<IfModule expires_module>
#打开缓存
ExpiresActive on
#css文件缓存7200000/3600/24=83天
ExpiresByType text/css A7200000
#js文件缓存7200000/3600/24=83天
ExpiresByType application/x-javascript A7200000
ExpiresByType application/javascript A7200000
#html文件缓存7200000/3600/24=83天
ExpiresByType text/html A7200000
#图片文件缓存7200000/3600/24=83天
ExpiresByType image/jpeg A7200000
ExpiresByType image/gif A7200000
ExpiresByType image/png A7200000
ExpiresByType image/x-icon A7200000
</IfModule>
三、开启长连接功能
KeepAlive Off/On 保持连接,会减少三次握手,但是会消耗内存,是否打开,取决于单位时间内是否进行多次连接(三次握手),一个连接有多次请求的,建议打开,并适当调整KeepAliveTimeout时间
在APACHE的httpd.conf中,KeepAlive指的是保持连接活跃,如果将KeepAlive设置为On,那么来自同一客户端的请求就不需要再一次连接,避免每次请求都要新建一个连接而加重服务器的负担。
KeepAlive的连接活跃时间当然是受KeepAliveTimeOut限制的。如果第二次请求和第一次请求之间超过KeepAliveTimeOut的时间的话,第一次连接就会中断,再新建第二个连接。所以,一般情况下,图片较多的网站应该把KeepAlive设为On。但是KeepAliveTimeOut应该设置为多少秒就是一个值得讨论的问题了。 如果KeepAliveTimeOut设置的时间过短,例如设置为1秒,那么APACHE就会频繁的建立新连接,当然会耗费不少的资源;反过来,如果KeepAliveTimeOut设置的时间过长,例如设置为300秒,那么APACHE中肯定有很多无用的连接会占用服务器的资源,也不是一件好事。
所以,到底要把KeepAliveTimeOut设置为多少,要看网站的流量、服务器的配置而定。
以下是我的配置: [root@xuegod63 ~]# vim /usr/local/httpd/conf/httpd.conf 改: #Include conf/extra/httpd-default.conf 为:Include conf/extra/httpd-default.conf # vim /usr/local/httpd/conf/extra/httpd-default.conf 修改: KeepAlive On KeepAliveTimeout 30
注:如果配置文件中这两项,就自己修改一下。源码编译的有时没有这两个参数。
考虑到我的网站上有不少的图片,所以将KeepAlive设为On,一般的页面两次请求间隔不会超过30秒,所以这样设置,至尽运行状况良好。如果是艺术品网站, 需要看的时间长,那么就设置长一些。
MaxKeepAliveRequests 默认:100
一个建立好的Keep-Alive连接,允许发送的请求的个数。一旦建立连接,要么就是个数达到了断开,要么就是等KeepAliveTimeout时间到了断开连接。
MaxKeepAliveRequests指令限制了当启用KeepAlive时,每个连接允许的请求数量。如果将此值设为"0",将不限制请求的数目。我们建议最好将此值设为一个比较大的值,以确保最优的服务器性能。
这个数字的设置,必须考虑在一个时间段内,同一个用户访问你的服务会发多少请求。要结合KeepAliveTimeout参数来考虑。
举个例子,用户需要间隔时间不大于KeepAliveTimeout的时间内,连续请求10个文件,那么这个参数就应该设置成10,如果用户在连续时间里不断请求访问,则这个数值得设置得更多。否则就重新建立连接下载。一旦用户连续进行了10个请求后,并且这个用户肯定在完成这些请求后的5秒内不会再请求,甚至要在之后的很长时间后请求,那么这个KeepAliveTimeout时间就可以设置得很短,以便尽早断开这种用户,把资源让个其他用户。
TimeOut 默认:300 秒
TimeOut指令用于设置Apache等待以下三种事件的时间长度:
- 1. 接受一个GET请求耗费的总时间。
- 2. POST或PUT请求时,接受两个TCP包之间的时间。
- 3. 应答时TCP包传输中两个ACK包之间的时间。
比如:apache需要把jsp文件传给后端tomcat服务器,而tomcat服务器关了,这时这个链接需要等待的超时时间,由TimeOut控制。
注:计时器在1.2版本之前的默认值为1200,而现在已经设置为300了,但对于绝大多数情况来说仍是足够的。
案例分析:
假设 KeepAlive 的超时时间为 10 秒钟,服务器每秒处理 50 个独立用户访问,那么系统中Apache的总进程数就是 10 * 50 = 500 个,如果一个进程占用 4M 内存,那么总共会消耗2G内存,所以可以看出,在这种配置中,相当消耗内存,但好处是系统只处理了 50次 TCP 的握手和关闭操作。
如果关闭 KeepAlive,如果还是每秒50个用户访问,如果用户每秒的并发请求数为3个,那么 Apache 的总进程数就是 50 * 3 = 150 个,如果还是每个进程占用 4M 内存,那么总的内存消耗为600M,这种配置能节省大量内存,但是,系统处理了 150 次 TCP 的握手和关闭的操作,因此又会多消耗一些 CPU 资源。
总结:
- 1、如果内存和CPU都足够,开启和关闭KeepAlive对性能影响不大。
- 2、如果考虑服务器压力,如果同一个客户端对服务器会经常访问,建议开启KeepAlive。
参考数值:
KeepAlive On
KeepAliveTimeout 30
MaxKeepAliveRequests 100 #这个值一般不需要配置。
四、apache运行模式调优
Web服务器Apache目前一共有三种稳定的MPM(Multi-Processing Module,多进程处理模块)模式。
- Prefork:进程模式
- worker:线程模式
- Event : 事件模式(2.4版本后开始稳定)
1. prefork运行模式详解
Prefork MPM : Prefork MPM实现了一个非线程的、预派生的web服务器。它在Apache启动之初,就先预派生一些子进程,然后等待连接;可以减少频繁创建和销毁进程的开销,每个子进程只有一个线程,在一个时间点内,只能处理一个请求。这是一个成熟稳定,可以兼容新老模块,也不需要担心线程安全问题,但是一个进程相对占用资源,消耗大量内存,不擅长处理高并发的场景。
最重要的是将MaxClients设置为一个足够大的数值以处理潜在的请求高峰,同时又不能太大,以致需要使用的内存超出物理内存的大小。
注: Prefork 是基于多进程的模式。
优点:因为每个进程使用独立的内存空间,所以比较安全。一个进程坏了,不会影响其他进程。
缺点:占用的内存比较大。
实战2: Apache prefork调优
案例场景: 当用户访问网站时,在客户端浏览器输入网址后长时间无响应,而一旦连接上之后,页面很快就打开了(因为配置了持久连接)。
排查:登录上linux服务器后,使用netstat观察最大连接数稳定在257,查看apache配置文件中,prefork模式中,maxclients为 257, 这因为apache连接数明显不够用。
#先查看apache的运行模式 [root@xuegod63 ~]# /usr/local/httpd/bin/httpd -l | grep prefork #查看命令 prefork.c #看到这个,说明是prefork多进程模式 注:使用httpd -l来确定当前使用的MPM,应该会看到prefork.c,如果看到worker.c说明使用的是worker MPM。 或: [root@xuegod63 src]# /usr/local/httpd/bin/httpd -V Server version: Apache/2.4.33 (Unix) Server built: Oct 24 2017 20:29:35 Server's Module Magic Number: 20051115:33 Server loaded: APR 1.4.8, APR-Util 1.5.2 Compiled using: APR 1.4.8, APR-Util 1.5.2 Architecture: 64-bit Server MPM: Prefork 注:如果使用rpm安装的httpd,直接执行: [root@xuegod63 ~]# httpd -l Compiled in modules: core.c prefork.c http_core.c mod_so.c [root@xuegod63 ~]# rpm -qf `which httpd` #httpd命令是apache服务器软件包安装的 httpd-2.2.15-15.el6.x86_64