Apache常见功能实战详解

Apache 是一款使用量排名第一的 web 服务器,LAMP 中的 A 指的就是它。因为其开源、稳定、安全等特性而被普遍使用。前边的一篇文章中已经记录过如何搭建 LAMP 架构,搭建仅是第一步,其中最为重要的就是 Apache 服务,也是 LAMP 的核心。下边记录了使用 Apache 以来常常用到的功能。javascript

1、Apache的三种工做模式

Apache 一共有3种稳定的 MPM 模式(多进程处理模块),它们分别是 prefork、worker、event。http-2.2版本的httpd默认的mpm工做模式为prefork,2.4版本的httpd默认是event工做模式。能够经过 httpd -V 来查看。php

[root@linuxblogs ~]# httpd -V | grep -i "server mpm" Server MPM: Prefork

编译的时候,能够经过 configure 的参数来指定:css

--with-mpm=prefork|worker|event

一、prefork 工做模式html

Apache在启动之初,就预先fork一些子进程,而后等待请求进来。之因此这样作,是为了减小频繁建立和销毁进程的开销。每一个子进程只有一个线程,在一个时间点内,只能处理一个请求。java

优势:成熟稳定,兼容全部新老模块。同时,不须要担忧线程安全的问题。
缺点:一个进程相对占用更多的系统资源,消耗更多的内存。并且,它并不擅长处理高并发请求。linux

二、worker 工做模式web

使用了多进程和多线程的混合模式。它也预先fork了几个子进程(数量比较少),而后每一个子进程建立一些线程,同时包括一个监听线程。每一个请求过来,会被分配到1个线程来服务。线程比起进程会更轻量,由于线程一般会共享父进程的内存空间,所以,内存的占用会减小一些。在高并发的场景下,由于比起prefork有更多的可用线程,表现会更优秀一些。chrome

优势:占据更少的内存,高并发下表现更优秀。
缺点:必须考虑线程安全的问题。apache

三、event 工做模式vim

它和worker模式很像,最大的区别在于,它解决了keep-alive场景下,长期被占用的线程的资源浪费问题。event MPM中,会有一个专门的线程来管理这些keep-alive类型的线程,当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又容许它释放。这样加强了高并发场景下的请求处理能力。

HTTP采用keepalive方式减小TCP链接数量,可是因为须要与服务器线程或进程进行绑定,致使一个繁忙的服务器会消耗完全部的线程。Event MPM是解决这个问题的一种新模型,它把服务进程从链接中分离出来。在服务器处理速度很快,同时具备很是高的点击率时,可用的线程数量就是关键的资源限 制,此时Event MPM方式是最有效的,但不能在HTTPS访问下工做。

 

2、Apache的用户认证

有时候,咱们须要给一些特殊的访问设置一个用户认证机制,增长安全。好比咱们的我的网站,通常都是有一个管理后台的,虽然管理后台自己就有密码,但咱们为了更加安全,能够再设置一层用户认证。

一、编辑配置文件

vim /usr/local/apache2/conf/extra/httpd-vhosts.conf

在对应的虚拟主机配置中加入以下配置:(加粗部分是添加内容)

<VirtualHost *:80> DocumentRoot "/usr/local/apache2/htdocs" ServerName www.123.com ServerAlias www.abc.com <Directory /usr/local/apache2/htdocs/admin.php> AllowOverride AuthConfig AuthName "Please input you acount." AuthType Basic AuthUserFile /usr/local/apache2/htdocs/.htpasswd require valid-user </Directory>
</VirtualHost>

说明:首先指定要对哪一个目录进行验证,AuthName自定义,AuthUserFile指定用户密码文件在哪里。

二、建立加密用的用户名和密码文件

htpasswd -c /usr/local/apache2/htdocs/.htpasswd liwei htpasswd -m /usr/local/apache2/htdocs/.htpasswd admin

建立第一个用户时-c选项建立.htpasswd文件,-m选项增长用户,根据提示输入密码。

三、重启apache服务

apachectl -t apachectl graceful

先检查配置是否正确,而后用graceful至关因而reload配置,不用重启apache服务,效果同样。测试,经过浏览器输入 www.123.com/admin.php 提示输入密码。

 

3、设置默认虚拟主机

默认虚拟主机就是配置文件里的第一个虚拟主机。关于默认虚拟主机有个特色,凡是解析到这台服务器的域名,无论是什么域名,只要在配置文件中没有配置,那么都会访问到这个主机上来。若是咱们直接用IP访问,会访问到这个站点上来。为了不别人乱解析,因此应该把默认也就是第一个虚拟主机给禁止掉。咱们使用allow,deny语句,已经禁止掉了。

一、配置默认虚拟主机

vim /usr/local/apache2/conf/extra/httpd-vhosts.conf

添加一个虚拟主机的记录:

<VirtualHost *:80> DocumentRoot "/var/123" ServerName xxxxx.com.cn <Directory /var/123> Order allow,deny Deny from all </Directory>
</VirtualHost>

建立/var/123目录,而且设置600权限,daemon用户没法访问:

mkdir /var/123
chmod -R 600 /var/123

二、重启apache服务器

apachectl -t apachectl graceful

若是用IP或其它解析的域名访问,发现提示:

Forbidden
You don't have permission to access / on this server.

 

4、域名301跳转

一个站点不免会有多个域名,而多个域名总得有一个主次,好比个人网站能够用两个域名访问:www.itepub.cnwww.linuxblogs.cn 但你们发现无论我用哪一个域名访问,最终都会跳转到 www.linuxblogs.cn 上来。这个行为就叫作域名跳转,这里的301只是一个状态码,跳转除了301还有302,301是永久跳转,302是临时跳转,网站上必定要设置为301,这样对搜索引擎是比较友好的。

一、配置域名跳转

# vim /usr/local/apache2/conf/extra/httpd-vhosts.conf <IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{HTTP_HOST} ^www.abc.com$ RewriteRule ^/(.*)$ http://www.123.com/$1 [R=301,L]
</IfModule>

配置为:当访问aaa时,跳转到123的网站。

二、配置多个域名跳转

<IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{HTTP_HOST} ^www.abc.com$ [OR] RewriteCond %{HTTP_HOST} ^www.abcd.com$ RewriteRule ^/(.*)$ http://www.123.com/$1 [R=301,L]
</IfModule>

三、重启服务器并测试

apachectl -t apachectl graceful

测试:

# curl -x192.168.0.8:80 www.abc.com -I HTTP/1.1 301 Moved Permanently Date: Tue, 25 Oct 2016 15:48:10 GMT Server: Apache/2.2.31 (Unix) PHP/5.5.38 Location: http://www.123.com/
Content-Type: text/html; charset=iso-8859-1
# curl -x192.168.0.8:80 www.abcd.com -I HTTP/1.1 301 Moved Permanently Date: Tue, 25 Oct 2016 15:48:49 GMT Server: Apache/2.2.31 (Unix) PHP/5.5.38 Location: http://www.123.com/
Content-Type: text/html; charset=iso-8859-1

经过上述测试,发现不管是abc或abcd均可以跳转到 www.123.com 域名上来,经过浏览器访问也同样。

 

5、Apache日志切割

咱们每访问一次网站,那么就会记录若干条日志。固然前提是已经设置了日志,日志不去管理,时间长了日志文件会愈来愈大,如何避免产生这么大的日志文件?其实apache有相关的配置,使日志按照咱们的需求进行归档,好比天天一个新日志,或者每小时一个新的日志。

一、首先简单设置日志的路径名称

vim /usr/local/apache2/conf/extra/httpd-vhosts.conf

编辑添加内容以下:

ErrorLog "logs/error.log" CustomLog "logs/access.log" combined

指定了日志存放在/usr/local/apache2/logs目录下分别为error.log和access.log,combined为日志显示的格式,日志格式能够参考配置文件httpd.conf中格式的指定,以下:

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%h %l %u %t \"%r\" %>s %b" common

二、设置apache日志分割

一样编辑配置文件httpd-vhosts.conf

ErrorLog "|/usr/local/apache2/bin/rotatelogs -l /usr/local/apache2/logs/aaa-error_%Y%m%d.log 86400" CustomLog "|/usr/local/apache2/bin/rotatelogs -l /usr/local/apache2/logs/aaa-access_%Y%m%d.log 86400" combined

ErrorLog是错误日志,CustomLog是访问日志。|就是管道符,意思是把产生的日志交给rotatelog这个工具,而这个工具就是apache自带的切割日志的工具。-l的做用是校准时区为UTC,也就是北京时间。86400,单位是秒,正好是一天,那么日志会天天切割一次。而最后面的combined为日志的格式,在httpd.conf中有定义。

 

6、不记录指定文件类型的日志

若是一个网站访问量特别大,那么访问日志就会不少,但有一些访问日志咱们实际上是能够忽略掉的,好比网站的一些图片,还有js、css等静态对象。而这些文件的访问每每是巨量的,并且即便记录这些日志也没有什么用,那么如何忽略不记录这些日志呢?

一、配置日志不记录图片的访问

vim /usr/local/apache2/conf/extra/httpd-vhosts.conf

相关配置为:

SetEnvIf Request_URI ".*\.gif$" image-request SetEnvIf Request_URI ".*\.jpg$" image-request SetEnvIf Request_URI ".*\.png$" image-request SetEnvIf Request_URI ".*\.bmp$" image-request SetEnvIf Request_URI ".*\.swf$" image-request SetEnvIf Request_URI ".*\.js$"  image-request SetEnvIf Request_URI ".*\.css$" image-request CustomLog "|/usr/local ... _%Y%m%d.log 86400" combined env=!image-request

说明:在原来日志配置基础上,增长了一些image-request的定义,好比把gif、jpg、bmp、swf、js、css等结尾的全标记为image-request,而后在配置日志后加一个标记env=!image-request,表示取反。

 

7、Apache配置静态缓存

所说的静态文件指的是图片、js、css等文件,用户访问一个站点,其实大多数元素都是图片、js、css等,这些静态文件实际上是会被客户端的浏览器缓存到本地电脑上的,目的就是为了下次再请求时再也不去服务器上下载,这样就加快了速度,提升了用户体验。但这些静态文件总不能一直缓存,它总有一些时效性,那么就得设置这个过时时间。

一、配置静态缓存

# vim /usr/local/apache2/conf/extra/httpd-vhosts.conf <IfModule mod_expires.c> ExpiresActive on ExpiresByType image/gif "access plus 1 days" ExpiresByType image/jpeg "access plus 24 hours" ExpiresByType image/png "access plus 24 hours" ExpiresByType text/css "now plus 2 hour" ExpiresByType application/x-javascript "now plus 2 hours" ExpiresByType application/javascript "now plus 2 hours" ExpiresByType application/x-shockwave-flash "now plus 2 hours" ExpiresDefault "now plus 0 min"
</IfModule>

或者使用 mod_headers 模块实现:

<IfModule mod_headers.c> # htm,html,txt 类的文件缓存一个小时 <filesmatch "\.(html|htm|txt)$"> header set cache-control "max-age=3600"
    </filesmatch> # css, js, swf 类的文件缓存一个星期 <filesmatch "\.(css|js|swf)$"> header set cache-control "max-age=604800"
    </filesmatch> # jpg,gif,jpeg,png,ico,flv,pdf 等文件缓存一年 <filesmatch "\.(ico|gif|jpg|jpeg|png|flv|pdf)$"> header set cache-control "max-age=29030400"
    </filesmatch>
</IfModule>

说明:这里的时间单位能够 days、 hours 甚至是 min,两种不一样的方法,上面使用的是mod_expires,而下面用的是 mod_headers,要想使用这些模块,必需要事先已经支持。如何查看是否支持,使用命令:

# /usr/local/apache2/bin/apachectl -M

二、重启服务器并验证

apachectl -t apachectl graceful

验证:

# curl -x127.0.0.1:80 'http://www.123.com/static/image/common/online_admin.gif' -I HTTP/1.1 200 OK Date: Wed, 26 Oct 2016 03:51:26 GMT Server: Apache/2.2.31 (Unix) PHP/5.5.38 Last-Modified: Tue, 31 May 2016 03:08:36 GMT ETag: "46891b-16b-5341ab0597500" Accept-Ranges: bytes Content-Length: 363 Cache-Control: max-age=86400 Expires: Thu, 27 Oct 2016 03:51:26 GMT Content-Type: image/gif

 

8、Apache配置防盗链

若是你的网站有不少漂亮的图片,好比你网站域名 www.123.com,图片地址为 www.123.com/image/111.jpg,那么其它人就能够直接把这个地址放到他本身的网站上,他的用户能够直接从他网站查看这张图片,而实际图片是从你的网站访问的,所产生的带宽消耗对你没有任何意义,应该对这些图片限制一下,凡是在第三方站点上,严禁访问你站点的图片,如何配置呢?

一、配置防盗链

# vim /usr/local/apache2/conf/extra/httpd-vhosts.conf SetEnvIfNoCase Referer "^http://.*\.123\.com" local_ref SetEnvIfNoCase Referer ".*\.abc\.com" local_ref SetEnvIfNoCase Referer "^$" local_ref <filesmatch "\.(txt|doc|mp3|zip|rar|jpg|gif)"> Order Allow,Deny Allow from env=local_ref </filesmatch>

说明:在这段配置中涉及到一个名词referer,其实就是上次访问的网站连接。配置referer是根据来源连接作限制的,若是来源连接不是咱们想要的,就直接拒绝,这就是防盗链的原理。固然不止是图片,mp三、rar、zip等文件一样支持。上述配置中默认是除了定义的列表中的referer,其它都拒绝。

 

9、Apache访问控制

其实咱们能够对apache的访问进行控制,能够设置白名单或黑名单。前面更改httpd.conf时候就已经看到了allow,deny这两个关键词,先来看看allow和deny的规则。

一、举例1

Order deny,allow deny from all allow from 127.0.0.1

咱们的判断依据是这样的:

  • 看Order后面的,哪一个在前,哪一个在后
  • 若是deny在前,那么就须要看deny from这句,而后看allow from这句
  • 规则是一条一条匹配的,无论是deny在前仍是allow在前,都会生效的。

二、举例2

Order allow,deny deny from all allow from 127.0.0.1

这个就会deny全部了,127.0.0.1也会被deny。由于顺序是先allow而后deny,虽然开始allow了127,可是后面又拒绝了它。

三、举例3

Order allow,deny
deny from all

上面的规则就表示,所有都不能经过。

四、举例4

Order deny,allow
deny from all
上面的规则表示,所有都不能通。

Order deny,allow
只有顺序,没有具体规则,表示所有均可以通行(默认的),由于allow在最后了。

Order allow,deny
这个表示,所有都不能通行(默认的),由于deny在最后。

五、针对某个目录限制

好比这个目录很重要,只容许咱们公司的IP访问,固然这个目录能够是网站根目录,也就是整个站点。

<Directory /usr/local/apache2/htdocs> Order deny,allow Deny from all Allow from 127.0.0.1
</Directory>

六、针对请求的URL去限制

<filesmatch "(.*)admin(.*)"> Order deny,allow Deny from all Allow from 127.0.0.1
</filesmatch>

这里用到了filesmatch语法,表示匹配的意思。

七、验证

# curl -x192.168.0.8:80 www.123.com/admin.php -I HTTP/1.1 403 Forbidden Date: Wed, 26 Oct 2016 06:24:54 GMT Server: Apache/2.2.31 (Unix) PHP/5.5.38 Content-Type: text/html; charset=iso-8859-1
# curl -x127.0.0.1:80 www.123.com/admin.php -I HTTP/1.1 401 Authorization Required Date: Wed, 26 Oct 2016 06:25:03 GMT Server: Apache/2.2.31 (Unix) PHP/5.5.38 WWW-Authenticate: Basic realm="Please input you acount." Content-Type: text/html; charset=iso-8859-1

 

10、禁止解析PHP

某个目录下禁止解析PHP,这个颇有做用,咱们作网站安全的时候,这个用的不少,好比某些目录能够上传文件,为了不上传的文件有木马,因此咱们禁止这个目录下面的访问解析PHP。

一、配置禁止解析php

<Directory /usr/local/apache2/htdocs/data> php_admin_flag engine off <filesmatch "(.*)php"> Order deny,allow Deny from all </filesmatch>
</Directory>

说明:php_admin_flag engine off这个语句就是禁止解析php的控制语句,但只这样配置还不够,由于这样配置后用户依然能够访问php文件,只不过不解析了,但能够下载,用户下载php文件也是不合适的,因此有必要再禁止一下。

 

11、禁止指定user_agent

user_agent叫作浏览器标识,目前主流的浏览器有IE、chrome、Firefox、360、iphone的Safari、Android手机上的、百度搜索引擎、google搜索引擎等不少,每一种浏览器都有对应的user_agent。为了不一些无用的搜索引擎或机器爬虫之类引发的带宽的无辜消耗。

<IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{HTTP_HOST} ^www.abc.com$ [OR] RewriteCond %{HTTP_HOST} ^www.abcd.com$ RewriteRule ^/(.*)$ http://www.123.com/$1 [R=301,L]
 RewriteCond %{HTTP_USER_AGENT} ".*Firefox.*" [NC,OR] RewriteCond %{HTTP_USER_AGENT} ".*Tomato Bot.*" [NC] RewriteRule .* - [F] </IfModule>

一样是使用rewrite模块来实现限制指定user_agent。本例中,RewriteRule .* - [F]能够直接禁止访问,rewritecond用user_agent来匹配,NC表示不区分大小写,OR表示或者,链接下一个条件。假如咱们要把百度的搜索引擎限制掉,能够加一条这样的规则:

RewriteCond %{HTTP_USER_AGENT} ^.*Baiduspider/2.0.* [NC] RewriteRule .* - [F]

 

12、限制某个目录

咱们能够allow和deny去如今网站根目录下的某个子目录,固然这个rewrite也能够实现,配置以下:

<IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{REQUEST_URI} ^.*/tmp/* [NC] RewriteRule .* - [F] </IfModule>

这段配置,会把只要是包含 /tmp/ 字样的请求都限制了。

^_^...... 差很少到这里就要结束了,之后有新的经常使用功能再来更新。

相关文章
相关标签/搜索