Apache运维中常用功能配置笔记梳理
Apache 是一款使用量排名第一的 web 服务器,LAMP 中的 A 指的就是它。由于其开源、稳定、安全等特性而被广泛使用。下边记录了使用 Apache 以来经常用到的功能,做此梳理,作为日常运维笔记所用。
一、Apache的工作模式
Apache 目前一共有三种MPM 模式(多进程处理模块),它们分别是prefork、worker、enent,主要用到前两种工作模式,且默认的工作模式是prefork。可以通过 httpd -V 来查看。
|
1
2
|
[root@uatweb01 ~]# /usr/local/apache/bin/httpd -V | grep -i "server mpm" Server MPM: prefork |
编译的时候,可以通过 configure 的参数来指定:
|
1
|
--with-mpm=prefork|worker|event |
1)prefork 工作模式
Apache在启动之初,就预先fork一些子进程,然后等待请求进来。之所以这样做,是为了减少频繁创建和销毁进程的开销。每个子进程只有一个线程,在一个时间点内,只能处理一个请求。
优点:成熟稳定,兼容所有新老模块。同时,不需要担心线程安全的问题。
缺点:一个进程相对占用更多的系统资源,消耗更多的内存。而且,它并不擅长处理高并发请求。
2)worker 工作模式
使用了多进程和多线程的混合模式。它也预先fork了几个子进程(数量比较少),然后每个子进程创建一些线程,同时包括一个监听线程。每个请求过来,会被分配到1个线程来服务。线程比起进程会更轻量,因为线程通常会共享父进程的内存空间,因此,内存的占用会减少一些。在高并发的场景下,因为比起prefork有更多的可用线程,表现会更优秀一些。
优点:占据更少的内存,高并发下表现更优秀。
缺点:必须考虑线程安全的问题。
3)event 工作模式
它和worker模式很像,最大的区别在于,它解决了keep-alive场景下,长期被占用的线程的资源浪费问题。event MPM中,会有一个专门的线程来管理这些keep-alive类型的线程,当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放。这样增强了高并发场景下的请求处理能力。
HTTP采用keepalive方式减少TCP连接数量,但是由于需要与服务器线程或进程进行绑定,导致一个繁忙的服务器会消耗完所有的线程。Event MPM是解决这个问题的一种新模型,它把服务进程从连接中分离出来。在服务器处理速度很快,同时具有非常高的点击率时,可用的线程数量就是关键的资源限 制,此时Event MPM方式是最有效的,但不能在HTTPS访问下工作。
二、Apache的用户认证
有时候,需要给apache一些特殊的访问设置一个用户认证机制,增加安全。比如公司网站,一般都是有一个管理后台的,虽然管理后台本身就有密码,但为了更加安全,可以再设置一层用户认证。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
1)编辑配置文件)# vim /usr/local/apache2/conf/extra/httpd-vhosts.conf 在对应的虚拟主机配置中加入如下配置:<VirtualHost *:80> DocumentRoot "/usr/local/apache2/htdocs"ServerName www.kevin.comServerAlias www.bobo.com <Directory /usr/local/apache2/htdocs/> AllowOverride AuthConfig AuthName "Please input you acount." AuthType Basic AuthUserFile /usr/local/apache2/htdocs/.htpasswd require valid-user </Directory></VirtualHost> 说明:首先指定要对哪个目录进行验证,AuthName自定义,AuthUserFile指定用户密码文件在哪里。 2)创建加密用的用户名和密码文件)# htpasswd -c /usr/local/apache2/htdocs/.htpasswd liwei# htpasswd -m /usr/local/apache2/htdocs/.htpasswd admin 创建第一个用户时-c选项创建.htpasswd文件,-m选项增加用户,根据提示输入密码。 3)重启apache服务# apachectl -t# apachectl graceful 先检查配置是否正确,然后用graceful相当于是reload配置,不用重启apache服务,效果一样。如上配置后,通过浏览器输入网址,访问就会提示输入密码。========================================================在子目录中放宽安全限制也就是说,比如我们现在已经在/usr/local/apache2/htdocs/这个目录上加上了用户名和密码的认证。但如果想在/usr/local/apache2/htdocs/php这个目录中不需要认证,使用户可以直接访问。要达到上面的要求,就需要在配置文件中加入: <Directory "/usr/local/apache2/htdocs/php">Satisfy AnyOrder Deny,AllowAllow from all</Directory> 或者: 在/usr/local/apache2/htdocs/php目录下建立.htaccess文件,把Satisfy AnyOrder Deny,AllowAllow from all=================================================如果已经限制了一个目录的访问,需要用户名和密码,但想要放开这个目录中的其中一个文件(例如:back.html)的权限,使其可以任意访问,在配置文件中添加: <Files back.html>Satisfy AnyOrder Deny,AllowAllow from all</Files>=================================================查看通过验证的用户名称:可以查看REMOTE_USER环境变更。在access_log中也可以看到。=================================================禁止通过代理服务器访问特定的URL<Directory proxy:http://192.168.10.10/music/>Order Allow,DenyDeny from allSatisfy All</Directory> 上述方法都无法满足要求时,可以使用正则表达式的方式,使用Rewrite指令。================================================想拒绝所有对目录中文件的访问,除了特殊指定扩展名的文件(比如.html文件)<Directory "/usr/local/apache2/htdocs/test">Satisfy allOrder Allow,DenyDeny from all <Files *.html> Order Deny,Allow Allow from all Satisfy any </Files></Directory> 以上指令,使得test目录及其子目录下的所有非.html文件无法访问,只有.html的文件可以访问。 |
三、设置默认虚拟主机
默认虚拟主机就是配置文件里的第一个虚拟主机。关于默认虚拟主机有个特点,凡是解析到这台服务器的域名,不管是什么域名,只要在配置文件中没有配置,那么都会访问到这个主机上来。如果直接用IP访问,会访问到这个站点上来。为了避免别人乱解析,所以应该把默认也就是第一个虚拟主机给禁止掉。使用allow,deny语句就可以禁止掉了。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
1)配置默认虚拟主机# vim /usr/local/apache2/conf/extra/httpd-vhosts.conf 添加一个虚拟主机的记录:<VirtualHost *:80> DocumentRoot "/data/www" ServerName www.kevin.com <Directory /data/www> Order allow,deny Deny from all </Directory></VirtualHost> 创建/data/www目录,并且设置600权限,daemon用户无法访问: # mkdir /data/www# chmod -R 600 /data/www 2)重启apache服务器# apachectl -t# apachectl graceful 如果用IP或其它解析的域名访问,发现提示:ForbiddenYou don't have permission to access / on this server.=================================================只有一个IP,但想在系统上支持多个网站: NameVirtualHost *<VirtualHost *:80> ServerAdmin webmaster@www.kevin.com DocumentRoot /www/docs/www.kevin.com ServerName www.kevin.com ServerAlias www.bobo.com ######p这条指令可对虚拟主机设定多个名称 ErrorLog logs/www.kevin.com-error_log CustomLog logs/www.kevin.com-access_log common</VirtualHost> 其中:"*" 表示所设定的主机可在所有的地址上运行。对于只有单一地址的机器,这表示会在该地址上运行,同时也会在loopback地址上运行。如果NameVirtualHost 后面放置主机名称可能会在启动服务器时停用虚拟主机的机制。虚拟主机会使用户无法再访问配置文件中的主服务器。如果想让主服务器成为默认服务器,则必须在虚拟主机区块中先将它列出。对于每个虚拟主机名称,还需要在DNS中添加相关记录。=================================================# /usr/local/apache2/bin/httpd -S 显示虚拟主机的配置=================================================ErrorDocument 404 /err.html 这个指令可以让没有打到指定网页的时候,不显示404错误,而是err.html页面。错误号可以是其它的号码,如403、500等 例如:<VirtualHost *> ServerAdmin webmaster@www.kevin.com DocumentRoot /www/docs/kevin.com ServerName kevin.com ErrorLog logs/kevin.com-error_log CustomLog logs/kevin.com-access_log combined ErrorDocument 404 /err.html</VirtualHost> 根据以上配置,访问kevin.com/index.html时,如果/www/docs/kevin.com目录下没有index.html文件时,则会显示/www/docs/kevin.com目录下的err.html文件=================================================如果是有多个IP的情况下,想在每个地址上支持一个网站: NameVirtualHost 127.0.0.1<VirtualHost 172.16.50.230> ServerAdmin webmaster@www.kevin.com DocumentRoot /www/docs/bobo.bobo.com ServerName bobo.bobo.com ErrorLog logs/bobo.bobo.com-error_log CustomLog logs/bobo.bobo.com-access_log combined</VirtualHost><VirtualHost 172.16.50.231> ServerAdmin webmaster@www.kevin.com DocumentRoot /www/docs/kevin.com ServerName kevin.com ErrorLog logs/kevin.com-error_log CustomLog logs/kevin.com-access_log combined</VirtualHost> 以上配置根据所访问的IP地址不同,会访问不同的虚拟主机。如果服务器上还有其它的IP地址,但是没有在配置文件的虚拟主机区块列出来时,这时访问这个其它的IP地址,请求会被送至在配置文件主设定区的虚拟主机=================================================建立以IP寻址的默认虚拟主机,以配置文件中加入下面代码: <VirtualHost _default_> DocumentRoot /www/htdocs ErrorDocument 404 /err.html</VirtualHost> 加入以上代码后,如果访问本地的IP,但是该IP确没有在配置文件中配置时,则会访问以上代码指定的页面=================================================混用以IP寻址及以名称寻址虚拟主机: ServerName 127.0.0.1NameVirtualHost 172.16.50.10NameVirtualHost 172.16.50.230<VirtualHost 172.16.50.10> ################此处不同 ServerAdmin webmaster@www.kevin.com DocumentRoot /www/docs/kevin.com ServerName kevin.com ################此处不同 ErrorLog logs/kevin.com-error_log CustomLog logs/kevin.com-access_log combined</VirtualHost><VirtualHost 172.16.50.230> ################此处不同 ServerAdmin webmaster@www.kevin.com DocumentRoot /www/docs/kevin.com ServerName kevin.bobo.com ################此处不同 ErrorLog logs/kevin.bobo.com-error_log CustomLog logs/kevin.bobo.com-access_log combined</VirtualHost><VirtualHost 172.16.50.230> ################此处不同 ServerAdmin webmaster@www.kevin.com DocumentRoot /www/docs/kevin.com ServerName bobo.bobo.com ################此处不同 ErrorLog logs/bobo.bobo.com-error_log CustomLog logs/bobo.bobo.com-access_log combined</VirtualHost>=================================================mod_vhost_alias 模块可以建立大量的虚拟主机=================================================将URL对应至特定目录。比如说:访问http://172.16.50.10/bobo,如果不想让它访问/usr/local/apache2/htdocs/bobo,而是让它访问其它的目录中的内容,可以在配置文件中加入如下:Alias /bobo /home/bobo/apache_bobo 然后还要把指定的目录加入到配置文件中,以让apache可以访问,默认情况下apache是不访问DocumentRoot以外的目录的。<Directory "/home/bobo/apache_bobo"> Order allow,deny Allow from all</Directory> 这种用Alias的目录指定,其实是用Alias的第二个参数去替换第一个参数。本例中就是用/home/bobo/apache_bobo去替换/bobo因此,我们访问http://172.16.50.10/bobo其实上是访问http://172.16.50.10/home/bobo/apache_bobo 这种方法对"/"符号要求非常严格,如果上例我们写成Alias /bobo/ /home/bobo/apache_bobo,而我们在访问http://172.16.50.10/bobo/index.html,其实是访问http://172.16.50.10/home/bobo/apache_boboindex.html,这是错误的,因为/home/bobo/apache_bobo替换的是/bobo/,注意,这里把最后的“/”也替换了,所以转换后就是前面所说那样错误的URL。 Alias也可以为现有的网页内容创建新的URL,例如要想原来http://172.16.50.10/php/phpinfo.php内容,通过http://172.16.50.10/newphp/phpinfo.php也可以访问,只要在配置文件中加入如下一行:Alias /newphp /usr/local/apache2/htdocs/php Alias只影响本地URI,不会影响URL的主机名部分。 |
四、域名301跳转
一个站点难免会有多个域名,而多个域名总得有一个主次,比如我的网站可以用两个域名访问:www.kevin.cn 和 www.bobo.cn 但大家发现不管我用哪个域名访问,最终都会跳转到www.bobo.con 上来。这个行为就叫做域名跳转,这里的301只是一个状态码,跳转除了301还有302,301是永久跳转,302是临时跳转,网站上一定要设置为301,这样对搜索引擎是比较友好的。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
1)配置域名跳转# 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>配置为:当访问abc时,跳转到123的网站。2)配置多个域名跳转<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>3)重启服务器并测试# apachectl -t# apachectl graceful4)测试:# curl -x 192.168.0.8:80 www.abc.com -IHTTP/1.1 301 Moved PermanentlyDate: Tue, 25 Oct 2016 15:48:10 GMTServer: Apache/2.2.31 (Unix) PHP/5.5.38Location: http://www.123.com/Content-Type: text/html; charset=iso-8859-1# curl -x 192.168.0.8:80 www.abcd.com -IHTTP/1.1 301 Moved PermanentlyDate: Tue, 25 Oct 2016 15:48:49 GMTServer: Apache/2.2.31 (Unix) PHP/5.5.38Location: http://www.123.com/Content-Type: text/html; charset=iso-8859-1通过上述测试,发现无论是abc或abcd都可以跳转到 www.123.com 域名上来,通过浏览器访问也一样。 |
五、Apache日志
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
指定日志记录格式,组合日志格式(combined)或通用日志格式(common),修改配置文件:CustomLog logs/access_log combined 组合日志格式CustomLog logs/access_log common 通用日志格式通用日志格式与组合日志格式的"%h"控制符表示远程请求用户的身份,依据HostNameLookups指令的设定值,可能是主机名也可能是IP地址。如果想永远记录IP地址,则使用“%a”控制符。记录从客户端收到的cookieCustomLog logs/cookies_in.log "%{UNIQUE_ID}e %{Cookie}i"CustomLog logs/cookies2_in.log "%{UNIQUE_ID}e %{Cookie2}i" 记录由服务器设定并传送给客户端的cookie值:CustomLog logs/cookies_out.log "%{UNIQUE_ID}e %{Set-Cookie}o"CustomLog logs/cookies2_out.log "%{UNIQUE_ID}e %{Set-Cookie2}o"不记录来自本机网页的图像请求:<FilesMatch \.(jpg|gif|png$)>SetEnvIfNoCase Referrer "^http://www.kevin.com/" local_referrer=1</FilesMatch>Customlog logs/access_log combined env=!local_referrer按照日或小时来记录请求:CustomLog "| /usr/local/apache2/bin/rotatelogs /usr/local/apache2/logs/access_log.%Y-%m-%d 86400" combined 其中:rotatelogs的第一个参数是主日志文件名如果有%字符,则表示日志文件名中时间的格式,如果没有指定时间格式,则是以秒为单位,从1970.1.1日算起的秒数第二个参数是产生新日志的间隔是多少秒。也可以是大小如果把上例中的86400换成5M,则表时日志达到5M时,就会产生一个新的日志,日志的名字是access_log.%Y-%m-%d格式的logresolve 将日志中记录的IP地址解析为主机名例如:# logresolve -c < /usr/local/apache2/logs/access_log.raw > access_log.resolved 也可以让apache在处理过程中使用IP地址,然后在记录日志时,以管道方式的日志记录进程来解析,修改配置文件:HostnameLookups offCustomLog "|/usr/local/apache2/bin/logresolve -c >> /usr/local/apache2/logs/access_log.resolved" combined |
Apache日志切割
每访问一次网站,那么就会记录若干条日志。当然前提是已经设置了日志,日志不去管理,时间长了日志文件会越来越大,如何避免产生这么大的日志文件?其实apache有相关的配置,使日志按照我们的需求进行归档,比如每天一个新日志,或者每小时一个新的日志。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
1)首先简单设置日志的路径名称# vim /usr/local/apache2/conf/extra/httpd-vhosts.confErrorLog "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\"" combinedLogFormat "%h %l %u %t \"%r\" %>s %b" common 2)设置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中有定义。 |
Apache不记录指定文件类型的日志
如果一个网站访问量特别大,那么访问日志就会很多,但有一些访问日志我们其实是可以忽略掉的,比如网站的一些图片,还有js、css等静态对象。而这些文件的访问往往是巨量的,而且即使记录这些日志也没有什么用,那么如何过滤掉(不记录)这些日志呢?
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
配置日志不记录图片的访问# vim /usr/local/apache2/conf/extra/httpd-vhosts.conf 相关配置为:SetEnvIf Request_URI ".*\.gif$" image-requestSetEnvIf Request_URI ".*\.jpg$" image-requestSetEnvIf Request_URI ".*\.png$" image-requestSetEnvIf Request_URI ".*\.bmp$" image-requestSetEnvIf Request_URI ".*\.swf$" image-requestSetEnvIf Request_URI ".*\.js$" image-requestSetEnvIf Request_URI ".*\.css$" image-requestCustomLog "|/usr/local ... _%Y%m%d.log 86400" combined env=!image-request 说明:在原来日志配置基础上,增加了一些image-request的定义,比如把gif、jpg、bmp、swf、js、css等结尾的全标记为image-request,然后在配置日志后加一个标记env=!image-request,表示取反。 |
六、Apache配置静态缓存
所说的静态文件指的是图片、js、css等文件,用户访问一个站点,其实大多数元素都是图片、js、css等,这些静态文件其实是会被客户端的浏览器缓存到本地电脑上的,目的就是为了下次再请求时不再去服务器上下载,这样就加快了速度,提高了用户体验。但这些静态文件总不能一直缓存,它总有一些时效性,那么就得设置这个过期时间。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
1)配置静态缓存# 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 -M2)重启服务器并验证# apachectl -t# apachectl graceful3)验证:# curl -x127.0.0.1:80 'http://www.kevin.com/static/image/common/online_admin.gif' -IHTTP/1.1 200 OKDate: Wed, 26 Oct 2016 03:51:26 GMTServer: Apache/2.2.31 (Unix) PHP/5.5.38Last-Modified: Tue, 31 May 2016 03:08:36 GMTETag: "46891b-16b-5341ab0597500"Accept-Ranges: bytesContent-Length: 363Cache-Control: max-age=86400Expires: Thu, 27 Oct 2016 03:51:26 GMTContent-Type: image/gif |
七、Apache配置防盗链
盗链,全称是盗取链接,假如我们的网站有很多好看的图片,别人可以查看我们网站图片的链接,然后应用在他的网站上,这样的话,去访问他的网站,实际上消耗的是我们的流量(因为实际链接在我们这里),这样我们就不得不去配置防盗链,使得别人不能复制我们图片的链接。
防盗链的实现原理就不得不从HTTP协议说起,在HTTP协议中,有一个表头字段叫referer,采用URL的格式来表示从哪儿链接到当前的网页或文件。换句话说,通过referer,网站可以检测目标网页访问的来源网页,如果是资源文件,则可以跟踪到显示它的网页地址。有了referer跟踪来源就好办了,
这时就可以通过技术手段来进行处理,一旦检测到来源不是本站即进行阻止或者返回指定的页面。
如果想对自己的网站进行防盗链保护,则需要针对不同的情况进行区别对待。如果网站服务器用的是apache,那么使用apache自带的Url Rewrite功能可以很轻松地防止各种盗链,其原理是检查refer,如果refer的信息来自其他网站则重定向到指定图片或网页上。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
如果网站有很多漂亮的图片,比如网站域名 www.kevin.com,图片地址为 www.kevin.com/image/111.jpg,那么其它人就可以直接把这个地址放到他自己的网站上,他的用户可以直接从他网站查看这张图片,而实际图片是从你的网站访问的,所产生的带宽消耗对你没有任何意义,应该对这些图片限制一下,凡是在第三方站点上,严禁访问你站点的图片,如何配置呢?# vim /usr/local/apache2/conf/extra/httpd-vhosts.confSetEnvIfNoCase Referer "^http://.*\.kevin\.com" local_refSetEnvIfNoCase Referer ".*\.abc\.com" local_refSetEnvIfNoCase Referer "^$" local_ref<filesmatch "\.(txt|doc|mp3|zip|rar|jpg|gif)"> Order Allow,Deny Allow from env=local_ref</filesmatch> 说明:在这段配置中涉及到一个名词referer,其实就是上次访问的网站链接。配置referer是根据来源链接做限制的,如果来源链接不是我们想要的,就直接拒绝,这就是防盗链的原理。当然不止是图片,mp3、rar、zip等文件同样支持。上述配置中默认是除了定义的列表中的referer,其它都拒绝。Directory表示指定哪个目录,我们设置防盗链肯定是针对本站点,所以直接写站点。SetEnv开头的是referer的白名单local_ref 表示空的Referfilesmatch开头的指的后面这些格式的文件不设置白名单,(就是说针对这些文件做防盗链)order定义访问控制的,order定义顺序,是先允许还是先拒绝。allow一行的意思是把上面末尾带有local_ref的白名单referer做一个允许。其他的使用上一行的order给deny掉然后保存检查错误,然后重启。# apachectl -t# apachectl graceful再看之前用到的一例:<Directory /data/wwwroot/boke> SetEnvIfNoCase Referer "http://kevin.com"; local_ref SetEnvIfNoCase Referer "http://xiaobo.com"; local_ref SetEnvIfNoCase Referer "^$" local_ref <filesmatch "\.(txt|doc|mp3|zip|rar|jpg|gif)"> Order Allow,Deny Allow from env=local_ref </filesmatch> </Directory>来做一个测试,测试一下http://kevin.com/ai.png浏览器看看能不能打开,或者把它以超链接的形式发到论坛,然后点开。发现点开后出现"Forbidden"的报错页面,这种情况就是空referer,就是防盗链起了作用! |
八、Apache访问控制
其实可以对apache的访问进行控制,可以设置白名单或黑名单(通过allow和deny的规则来配置)。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
1)示例一Order deny,allowdeny from allallow from 127.0.0.1 判断依据是这样的:看Order后面的,哪个在前,哪个在后如果deny在前,那么就需要看deny from这句,然后看allow from这句规则是一条一条匹配的,不管是deny在前还是allow在前,都会生效的。 2)示例二Order allow,denydeny from allallow from 127.0.0.1 这个就会deny所有了,127.0.0.1也会被deny。因为顺序是先allow然后deny,虽然开始allow了127,但是后面又拒绝了它。 3)示例三Order allow,denydeny from all 上面的规则就表示,全部都不能通过。 4)示例四Order deny,allowdeny from all 上面的规则表示,全部都不能通。 Order deny,allow只有顺序,没有具体规则,表示全部都可以通行(默认的),因为allow在最后了。 Order allow,deny这个表示,全部都不能通行(默认的),因为deny在最后。 5)针对某个目录限制比如这个目录很重要,只允许我们公司的IP访问,当然这个目录可以是网站根目录,也就是整个站点。<Directory /usr/local/apache2/htdocs> Order deny,allow Deny from all Allow from 127.0.0.1</Directory> 6)针对请求的URL去限制<filesmatch "(.*)admin(.*)"> Order deny,allow Deny from all Allow from 127.0.0.1</filesmatch> 这里用到了filesmatch语法,表示匹配的意思。 验证# curl -x 192.168.0.8:80 www.kevin.com/admin.php -IHTTP/1.1 403 ForbiddenDate: Wed, 26 Oct 2016 06:24:54 GMTServer: Apache/2.2.31 (Unix) PHP/5.5.38Content-Type: text/html; charset=iso-8859-1 # curl -x 127.0.0.1:80 www.kevin.com/admin.php -IHTTP/1.1 401 Authorization RequiredDate: Wed, 26 Oct 2016 06:25:03 GMTServer: Apache/2.2.31 (Unix) PHP/5.5.38WWW-Authenticate: Basic realm="Please input you acount."Content-Type: text/html; charset=iso-8859-17)Apache防盗链主要是防止本网站的链接被别人盗用。可以使用Apache访问控制,禁用来源IP访问# vim /usr/local/apache2/conf/extra/httpd-vhosts.conf<VirtualHost *:80>........... <Directory "/data/www"> AllowOverride None Options None Order allow,deny Allow from all #允许所有访问 Deny from 127.0.0.1 #禁用127.0.0.1访问 </Directory>...........</VirtualHost>测试# curl -x 127.0.0.1:80 -I www.kevin.com #127.0.0.1被禁止访问HTTP/1.1 403 ForbiddenDate: Wed, 02 Oct 2018 02:47:23 GMTServer: Apache/2.2.31 (Unix) PHP/5.4.45Content-Type: text/html; charset=iso-8859-1# curl -x 192.168.101.230:80 -I www.kevin.com #192.168.101.230正常访问HTTP/1.1 301 Moved PermanentlyDate: Wed, 02 Oct 2018 02:47:42 GMTServer: Apache/2.2.31 (Unix) PHP/5.4.45X-Powered-By: PHP/5.4.45location: forum.phpCache-Control: max-age=0Expires: Wed, 02 Oct 2018 02:47:42 GMTContent-Type: text/html# curl -x 192.168.101.230:80 -I www.kevin.com/forum.php #正常访问HTTP/1.1 200 OK8)如果希望白名单限制管理员登录网页URI:http://www.kevin.com/xiaobo.php,怎么做?)<VirtualHost *:80>........ <filesmatch "(.*)xiaobo(.*)"> Order deny,allow Deny from all #禁用所有访问 Allow from 127.0.0.1 #允许127.0.0.1访问 Allow from 192.168.101.230 </filesmatch>...........</VirtualHost>重启Apache服务后,用PC机器(192.168.101.175)访问http://www.kevin.com/xiaobo.php,报错403Forbidden。# curl -x 192.168.101.230:80 -I http://www.kevin.com/xiaobo.phpHTTP/1.1 200 OK 200,但是192.168.101.230可以正常访问 |
九、禁止解析PHP
某个目录下禁止解析PHP,这个很有作用,我们做网站安全的时候,这个用的很多,比如某些目录可以上传文件,为了避免上传的文件有木马,所以我们禁止这个目录下面的访问解析PHP。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
配置禁止解析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文件也是不合适的,所以有必要再禁止一下。 |
十、禁止指定user_agent
user_agent叫做浏览器标识,目前主流的浏览器有IE、chrome、Firefox、360、iphone的Safari、Android手机上的、百度搜索引擎、google搜索引擎等很多,每一种浏览器都有对应的user_agent。为了避免一些无用的搜索引擎或机器爬虫之类引起的带宽的无辜消耗。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{HTTP_HOST} ^www.kevin.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] |
十一、限制某个目录
可以allow和deny去现在网站根目录下的某个子目录,当然这个rewrite也可以实现。
|
1
2
3
4
5
6
7
|
<IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{REQUEST_URI} ^.*/shibo/* [NC] RewriteRule .* - [F]</IfModule>这段配置,会把只要是包含 /shibo/ 字样的请求都限制了。 |
十二、让Apache服务器的用户都有自己的URL,有自己的网页空间
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
配置文件里添加下面一行内容:UserDir public_html 配置文件中有这行指令后,再在用户主目录下创建public_html目录,里面放入网页就可以了。访问的URL,以kevin这个用户为例:http://192.168.10.10/~kevin/还要将配置文件中一段注释去掉:#<Directory /home/*/public_html># AllowOverride FileInfo AuthConfig Limit Indexes# Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec# <Limit GET POST OPTIONS PROPFIND># Order allow,deny# Allow from all# </Limit># <LimitExcept GET POST OPTIONS PROPFIND># Order deny,allow# Deny from all# </LimitExcept>#</Directory> 以配置访问权限。另一种方式是在配置文件中添加下面一行内容:UserDir /www/user/*/htdocs这种方法后的参数是完整的路径名,把用户的页面文件都放在了统一的目录下(/www/usr/下),后面的*号是用户名命名的目录。访问方法和上面第一种方法一样。 |
十三、Apache的.htaccess文件配置说明
.htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过对.htaccess文件进行设置,可以帮我们实现:网页301重定向、自定义400/403/404/500错误页面、改变文件扩展名、允许/阻止指定IP用户访问、禁止目录列表、配置默认文档等功能,可以说是功能非常强大。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
设置网站错误页面ErrorDocument 400 /error_pages/400.htmlErrorDocument 401 /error_pages/401.htmlErrorDocument 403 /error_pages/403.htmlErrorDocument 404 /error_pages/404.htmlErrorDocument 500 /error_pages/500.html 设置网页301重定向#从 old_dir 目录重定向到 new_dir 目录Redirect /old_dir/ http://www.yourdomain.com/new_dir/index.html#把通过二级目录访问的请求301重定向到二级域名RedirectMatch 301 /dir/(.*) http://dir.yourdomain.com/$1 禁止指定IP段用户的访问#禁止 IP 为 255.0.0.0 和 123.45.6.区段的 IP 访问order allow,denydeny from 255.0.0.0deny from 123.45.6.allow from all 禁止指定来源网页访问#禁止从 otherdomain.com 和 anotherdomain.com 的来源访问RewriteEngine on# Options +FollowSymlinksRewriteCond %{HTTP_REFERER} otherdomain\.com [NC,OR]RewriteCond %{HTTP_REFERER} anotherdomain\.comRewriteRule .* – [F] 图片防盗链设置#从本站以外的域名访问图片,一律显示 feed.jpgRewriteEngine onRewriteCond %{HTTP_REFERER} !^$RewriteCond %{HTTP_REFERER} !^http://(www\.)?yourdomain.com/.*$ [NC]RewriteRule \.(gif|jpg|png)$ http://www.yourdomain.com/feed.jpg [R,L] 设置文件夹首页#防止显示文件夹列表,当访问文件夹时,服务器会查找index.html,并将其做为首页文件,如不存在依次向后查找DirectoryIndex index.html index.cgi index.php 设置多媒体文件为可下载而非播放AddType application/octet-stream .mp3 .mp4 自定义HTTP报头Header set X-Pingback “http://www.yourdomain.com/xmlrpc.php”Header set article-by “yourdomain.com” 设置文件过期时间 Cache Control# 启用有效期控制ExpiresActive On# gif/png/jpg 有效期为1个月ExpiresByType image/gif “access plus 1 month”ExpiresByType image/png “access plus 1 month”ExpiresByType image/jpg “access plus 1 month”# js/css 有效期为1星期ExpiresByType text/javascript “access plus 1 week”ExpiresByType text/css “access plus 1 week” WordPress建站程序伪静态代码# BEGIN WordPress #这是一行注释,表示 WordPress 的 htaccess 从这里开始#如果Apache加载了mod_rewrite.c模块,则运行以下代码RewriteEngine On #启用 mod_rewrite 引擎RewriteBase / #设置目录重写的基准URL为 /RewriteRule ^index\.php$ – [L] #如果请求路径是 index.php,停止重写操作(避免死循环)RewriteCond %{REQUEST_FILENAME} !-f #如果请求的不是一个文件,继续处理RewriteCond %{REQUEST_FILENAME} !-d #如果请求的不是一个目录,继续处理RewriteRule . /index.php [L] #把所有的请求指向 /index.php#结束 IfModule# END WordPress #WordPress 的 htaccess 到这里结束 Discuz x3/x3.1通用伪静态代码#如果Apache加载了mod_rewrite.c模块,则运行以下代码RewriteEngine OnRewriteBase /discuzRewriteCond %{QUERY_STRING} ^(.*)$RewriteRule ^topic-(.+)\.html$ portal.php?mod=topic&topic=$1&%1RewriteCond %{QUERY_STRING} ^(.*)$RewriteRule ^article-([0-9]+)-([0-9]+)\.html$ portal.php?mod=view&aid=$1&page=$2&%1RewriteCond %{QUERY_STRING} ^(.*)$RewriteRule ^forum-(\w+)-([0-9]+)\.html$ forum.php?mod=forumdisplay&fid=$1&page=$2&%1RewriteCond %{QUERY_STRING} ^(.*)$RewriteRule ^thread-([0-9]+)-([0-9]+)-([0-9]+)\.html$ forum.php?mod=viewthread&tid=$1&extra=page\%3D$3&page=$2&%1RewriteCond %{QUERY_STRING} ^(.*)$RewriteRule ^group-([0-9]+)-([0-9]+)\.html$ forum.php?mod=group&fid=$1&page=$2&%1RewriteCond %{QUERY_STRING} ^(.*)$RewriteRule ^space-(username|uid)-(.+)\.html$ home.php?mod=space&$1=$2&%1RewriteCond %{QUERY_STRING} ^(.*)$RewriteRule ^blog-([0-9]+)-([0-9]+)\.html$ home.php?mod=space&uid=$1&do=blog&id=$2&%1RewriteCond %{QUERY_STRING} ^(.*)$RewriteRule ^archiver/(fid|tid)-([0-9]+)\.html$ archiver/index.php?action=$1&value=$2&%1RewriteCond %{QUERY_STRING} ^(.*)$RewriteRule ^([a-z]+[a-z0-9_]*)-([a-z0-9_\-]+)\.html$ plugin.php?id=$1:$2&%1#http强转为https配置RewriteEngine on RewriteBase / RewriteCond %{SERVER_PORT} !^443$ RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R] |
========AliasMatch指令========
|
1
2
3
4
5
6
7
8
9
10
11
|
用AliasMatch指令,可以用正则表达式的方式将多个URL对应至同一个目录。例如配置如下:AliasMatch ^/testph(p|ps) /usr/local/apache2/htdocs/php以上配置表示:可以用http://www.kevin.com/testphp/phpinfo.php和http://www.kevin.com/testphps/phpinfo.php来访问同一个目录/usr/local/apache2/htdocs/php中的内容 |
========重定向至其他URL========
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
修改配置文件:Redirect /xueer http://www.bo.com/yiner以上指令表示访问http:www.kevin.com/xueer时,实际访问的是http://www.bo.com/yiner Redirect指令有几个参数:temp:表示文件当前不在原来所请求的位置上,可以将来还会在这个位置上,现在只是临时的。这样,客户端会记住原始请求的URL。permanent:表示被请求的文件不在指定位置上,而是永久在新的位置上。这样,客户端会记住新的URLgone:表示文件不在此位置,而且以后也不在新的位置上。相当于404错误。但服务器会承认所请求的文件原来在此位置。所以不会被视为错误。seeother:表示文件不在所请求的位置,而且被不同位置的其它文件取代了(前三个参数都是指同一个文件,这个参数请是不同位置的不同文件取代了原来位置的原来文件) 默认情况下是使用temp参数用RedirectMatch指令可以用正则表达式的方式将多个URL重定向至同一位置。 |
========Apache接受不区分大小写的URL========
|
1
2
3
|
1) 安装mod_speling模块2) 在配置文件中添加:CheckSpelling On |
========mod_rewrite模块用途========
|
1
2
3
4
5
|
可以重写URL请求中的文件,替换成指定的;可以拒绝访问未被引用的请求;可以依据查询字符串来重写;可以将所有请求重定向是单一主机;将服务器的全部或部分请求重定向至SSL等相关工作 |
========Apache性能测试========
|
1
2
3
4
5
|
# ab -n 1000 -c 20 http://www.baidu.com/back.html 其中:-n 1000 表示请求的数目-c 20 表示一次送出20 个请求-h 可以查看帮助 |
========Apache取得网站快照========
|
1
2
3
4
5
6
7
8
9
|
修改配置文件:<Location /server-status> SetHandler server-status# Order deny,allow# Deny from all# Allow from .example.com</Location>ExtendedStatus On |
========将经常查看的文件存入高速缓存区========
|
1
2
3
4
|
修改配置文件:MMapFile /usr/local/apache2/htdocs/index.html 需要安装mod_file_cache模块 |
========将目录列表存入高速缓存区=========
|
1
2
|
修改配置文件:IndexOptions +TrackModified |
==============一个简单的apache跳转页面配置的小示例=================
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
示例如下:假设apache的域名(ServerName)为www.kevin.com 下面配置表示:访问http://www.kevin.com/shibo/admin/下匹配的path资源不存在时,页面跳转到 http://www.kevin.com/missing.html 的404错误页面。要是admin下匹配的path资源存在,则不会跳转!<IfModule proxy_module> ProxyPass /shibo/admin/* http://www.kevin.com/missing.html ProxyPassMatch /shibo/admin/* !</IfModule> 下面配置表示:访问http://www.kevin.com/shibo/admin/下匹配的所有资源时,页面跳转到 http://www.kevin.com/missing.html 的404错误页面。不管admin下匹配path资源存在还是不存在,都会跳转!<IfModule proxy_module> ProxyPass /shibo/admin/ http://www.kevin.com/missing.html ProxyPassMatch /shibo/admin/ !</IfModule>以上的配置:可以禁止在外网使用域名访问时跳转到missing.html的提示页面。但是在内网使用ip+port方式访问,不会跳转到missing.html提示页面,会正常访问。 |
十四、Apache Rewrite重写规则常用配置示例
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
1)去掉域名中的www标记RewriteCond %{HTTP_HOST} !^jkevin\.net$ [NC]RewriteRule .? http://jkevin.net%{REQUEST_URI} [R=301,L]2)去掉www标记,但是保存子域名RewriteCond %{HTTP_HOST} ^www\.(([a-z0-9_]+\.)?jkevin\.net)$ [NC]RewriteRule .? http://%1%{REQUEST_URI} [R=301,L]这里,当匹配到1%变量以后,子域名才会在%2(内部原子)中抓取到,而我们需要的正是这个%1变量。3)给子域名加www标记RewriteCond %{HTTP_HOST} ^([a-z.]+)?jkevin\.net$ [NC]RewriteCond %{HTTP_HOST} !^www\. [NC]RewriteRule .? http://www.%1jkevin.net%{REQUEST_URI} [R=301,L]这个规则抓取二级域名的%1变量,如果不是以www开始,那么就加www,以前的域名以及{REQUEST_URI}会跟在其后。4)防止图片盗链一些站长不择手段的将你的图片盗链在他们网站上,耗费你的带宽。你可以加一下代码阻止这种行为。RewriteCond %{HTTP_REFERER} !^$RewriteCond %{HTTP_REFERER} !^http://(www\.)?jkevin\.net/ [NC]RewriteRule \.(gif|jpg|png)$ – [F]如果{HTTP_REFERER}值不为空,或者不是来自你自己的域名,这个规则用[F]FLAG阻止以gif|jpg|png 结尾的URL如果对这种盗链你是坚决鄙视的,你还可以改变图片,让访问盗链网站的用户知道该网站正在盗用你的图片。RewriteCond %{HTTP_REFERER} !^$RewriteCond %{HTTP_REFERER} !^http://(www\.)?jkevin\.net/.*$ [NC]RewriteRule \.(gif|jpg|png)$ 你的图片地址 [R=301,L]除了阻止图片盗链链接,以上规则将其盗链的图片全部替换成了你设置的图片。你还可以阻止特定域名盗链你的图片:RewriteCond %{HTTP_REFERER} !^http://(www\.)?leech_site\.net/ [NC]RewriteRule \.(gif|jpg|png)$ – [F,L]这个规则将阻止域名黑名单上所有的图片链接请求。当然以上这些规则都是以{HTTP_REFERER}获取域名为基础的,如果你想改用成IP地址,用{REMOTE_ADDR}就可以了。5)如果文件不存在重定向到404页面如果你的主机没有提供404页面重定向服务,那么我们自己创建。RewriteCond %{REQUEST_FILENAME} !-fRewriteCond %{REQUEST_FILENAME} !-dRewriteRule .? /404.php [L]这里-f匹配的是存在的文件名,-d匹配的存在的路径名。这段代码在进行404重定向之前,会判断你的文件名以及路径名是否存在。你还可以在404页面上加一个?url=$1参数:RewriteRule ^/?(.*)$ /404.php?url=$1 [L]这样,你的404页面就可以做一些其他的事情,例如发一个邮件提醒,加一个搜索等等。6)重命名目录如果你想在网站上重命名目录,试试这个:RewriteRule ^/?old_directory/([a-z/.]+)$ new_directory/$1 [R=301,L]在规则里我添加了一个“.”(注意不是代表得所有字符,前面有转义符)来匹配文件的后缀名。7)将.html后缀名转换成.php前提是.html文件能继续访问的情况下,更新你的网站链接。RewriteRule ^/?([a-z/]+)\.html$ $1.php [L]这不是一个网页重定向,所以访问者是不可见的。让他作为一个永久重定向(可见的),将FLAG修改[R=301,L]。8)创建无文件后缀名链接如果你想使你的PHP网站的链接更加简洁易记-或者隐藏文件的后缀名,试试这个:RewriteRule ^/?([a-z]+)$ $1.php [L]如果网站混有PHP以及HTML文件,你可以用RewriteCond先判断该后缀的文件是否存在,然后进行替换:RewriteCond %{REQUEST_FILENAME}.php -fRewriteRule ^/?([a-zA-Z0-9]+)$ $1.php [L]RewriteCond %{REQUEST_FILENAME}.html -fRewriteRule ^/?([a-zA-Z0-9]+)$ $1.html [L]如果文件是以.php为后缀,这条规则将被执行。9)检查查询变量里的特定参数如果在URL里面有一个特殊的参数,你可用RewriteCond鉴别其是否存在:复制代码 代码如下:RewriteCond %{QUERY_STRING} !uniquekey=RewriteRule ^/?script_that_requires_uniquekey\.php$ other_script.php [QSA,L]以上规则将检查{QUERY_STRING}里面的uniquekey参数是否存在,如果{REQUEST_URI}值为script_that_requires_uniquekey,将会定向到新的URL。10)删除查询变量Apache的mod_rewrite模块会自动辨识查询变量,除非你做了以下改动:a).分配一个新的查询参数(你可以用[QSA,L]FLAG保存最初的查询变量)b).在文件名后面加一个“?”(比如index.php?)。符号“?”不会在浏览器的地址栏里显示。11)用新的格式展示当前URI如 果这就是我们当前正在运行的URLs:/index.php?id=nnnn。我们非常希望将其更改成/nnnn并且让搜索引擎以新格式展现。首先,我们 为了让搜索引擎更新成新的,得将旧的URLs重定向到新的格式,但是,我们还得保证以前的index.php照样能够运行。是不是被我搞迷糊了?实 现以上功能,诀窍就在于在查询变量中加了一个访问者看不到的标记符“marker”。我们只将查询变量中没有出现“marker”标记的链接进行重定向, 然后将原有的链接替换成新的格式,并且通过[QSA]FLAG在已有的参数加一个“marker”标记。以下为实现的方式:RewriteCond %{QUERY_STRING} !markerRewriteCond %{QUERY_STRING} id=([-a-zA-Z0-9_+]+)RewriteRule ^/?index\.php$ %1? [R=301,L]RewriteRule ^/?([-a-zA-Z0-9_+]+)$ index.php?marker &id=$1 [L]这 里,原先的URL:http://www.jkevin.net/index.php?id=nnnn,不包含marker,所以被第一个规则永久重定向到 http://www.jkevin.net/nnnn,第二个规则将http://www.jkevin.net/nnnn反定向到http: //www.jkevin.net/index.php?marker&id=nnnn,并且加了marker以及id=nnnn两个变量,最后 mod_rewrite就开始进行处理过程。第二次匹配,marker被匹配,所以忽略第一条规则,这里有一个“.”字符会出现在http://www.jkevin.net/index.php?marker&id=nnnn中,所以第二条规则也会被忽略,这样我们就完成了。注意,这个解决方案要求Apache的一些扩展功能,所以如果你的网站放于在共享主机中会遇到很多障碍。12)保证安全服务启用Apache可以用两种方法辨别你是否开启了安全服务,分别引用{HTTPS}和{SERVER_PORT}变量:RewriteCond %{REQUEST_URI} ^secure_page\.php$RewriteCond %{HTTPS} !onRewriteRule ^/?(secure_page\.php)$ https://www.jkevin.net/$1 [R=301,L]以上规则测试{REQUEST_URI}值是否等于我们的安全页代码,并且{HTTPS}不等于on。如果这两个条件同时满足,请求将被重定向到安全服务URI.另外你可用{SERVER_PORT}做同样的测试,443是常用的安全服务端口RewriteCond %{REQUEST_URI} ^secure_page\.php$RewriteCond %{SERVER_PORT} !^443$RewriteRule ^/?(secure_page\.php)$ https://www.jkevin.net/$1 [R=301,L]13)在特定的页面上强制执行安全服务遇到同一个服务器根目录下分别有一个安全服务域名和一个非安全服务域名,所以你就需要用RewriteCond 判断安全服务端口是否占用,并且只将以下列表的页面要求为安全服务:RewriteCond %{SERVER_PORT} !^443$RewriteRule ^/?(page1|page2|page3|page4|page5)$ https://www.jkevin.net/%1[R=301,L]以下是怎样将没有设置成安全服务的页面返回到80端口:RewriteCond %{ SERVER_PORT } ^443$RewriteRule !^/?(page6|page7|page8|page9)$http://www.jkevin.net%{REQUEST_URI} [R=301,L]其实Rewrite里运用最多的还应该是正则表达式,如果了解点儿正则的话,写起这个规则还是比较简单的。14) ProxyPass规则示例访问http://www.kevin.com/shibo/admin/下匹配的所有资源时,页面跳转到 http://www.kevin.com/missing.html 的404错误页面。<IfModule proxy_module> ProxyPass /shibo/admin/ http://www.kevin.com/missing.html ProxyPassMatch /shibo/admin/ !</IfModule>==================================================80端口的Proxypass跳转<IfModule proxy_module> ProxyPass /companyNews http://192.168.10.149:8080/companyNews ProxyPassReverse /companyNews http://192.168.10.149:8080/companyNews ProxyPass /companyNews/* http://192.168.10.149:8080/companyNews/* ProxyPassReverse /companyNews/* http://192.168.10.149:8080/companyNews/*</IfModule><IfModule proxy_module> ProxyPass /mlslec https://hao.kevin.com.com/cgi-bin ProxyPassReverse /mlslec https://hao.kevin.com.com/cgi-bin</IfModule>==================================================443端口的Proxypass跳转<IfModule proxy_module>SSLProxyEngine OnProxyPass /xyy https://bobo.kevin.com/pay/orderqueryProxyPassReverse /xyy https://bobo.kevin.com/pay/orderqueryProxyPass /getsignkey https://bobo.kevin.com/sandbox/pay/getsignkeyProxyPassReverse /getsignkey https://bobo.kevin.com/sandbox/pay/getsignkeyProxyPass /authorize https://shibo.kevin.com/connect/oauth2/authorizeProxyPassReverse /authorize https://shibo.kevin.com/connect/oauth2/authorize</IfModule> |
===================Apache 重写跳转规则梳理=================
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
Apache 通过Rewrite实现URL的跳转和域名跳转。Rewirte主要的功能就是实现URL的跳转,它的正则表达式是基于Perl语言。可基于服务器级的(httpd.conf)和目录级的 (.htaccess)两种方式。如果要想用到rewrite模块,必须先安装或加载rewrite模块。方法有两种:一种是编译apache的时候就直接 安装rewrite模块.另一种是编译apache时以DSO模式安装apache,然后再利用源码和apxs来安装rewrite模块。基于服务器级的(httpd.conf)有两种方法,一种是在httpd.conf的全局下直接利用RewriteEngine on来打开rewrite功能;另一种是在局部里利用RewriteEngine on来打开rewrite功能,下面将会举例说明,需要注意的是,必须在每个virtualhost里用RewriteEngine on来打开rewrite功能。否则virtualhost里没有RewriteEngine on它里面的规则也不会生效。基于目录级的(.htaccess),要注意一点那就是必须打开此目录的FollowSymLinks属性且在.htaccess里要声明 RewriteEngine on。1)举例说明-------------------------------------------------------------------------------------------------------------------------------示例一下面是在一个虚拟主机里定义的规则。功能是把client请求的主机前缀不是www.kevin.cn和192.168.10.20都跳 转到主机前缀为http://www.kevin.cn, 避免相同内容的网页有多个指向的域名,如http://kevin.cn。配置如下:NameVirtualHost 192.168.10.20:80ServerAdmin slj@bobo.cnDocumentRoot “/web”ServerName kevin.cnRewriteEngine on #打开rewirte功能RewriteCond %{HTTP_HOST} !^www.kevin.cn [NC] #声明Client请求的主机中前缀不是www.kevin.cn, 其中 [NC] 的意思是忽略大小写RewriteCond %{HTTP_HOST} !^192.168.10.20 [NC] #声明Client请求的主机中前缀不是192.168.10.20,其中 [NC] 的意思是忽略大小写RewriteCond %{HTTP_HOST} !^$ #声明Client请求的主机中前缀不为空RewriteRule ^(.*) http://www.bobo.cn/ [L] #含义是如果Client请求的主机中的前缀符合上述条件,则直接进行跳转到http://www.bobo.cn/,[L]意味着立即停止重写操作,并 不再应用其他重写规则。这里的.*是指匹配所有URL中不包含换行字符,()括号的功能是把所有的字符做一个标记,以便于后面的应用.就是引用前面里的 (.*)字符。示例二将输入 anan.com 的域名时跳转到http:www.kevin.cn配置如下:RewriteEngine onRewriteCond %{HTTP_HOST} ^anan.com [NC]RewriteRule ^(.*) http://www.kevin.cn/ [L]示例三:近期更换了域名,新域名为www.yang.com, 更加简短好记。这时需要将原来的域名ss.bobo.cn, 以及论坛所在地址ss.bobo.cn/wang/定向到新的域名,以便用户可以找到,并且使原来的论坛 URL 继续有效而不出现 404 未找到,比如原来的http://ss.bobo.cn/wang/tread-60.html, 让它在新的域名下继续有效,点击后转发到http://wang.yang.com/tread-60.html,而其他网页,如原先的http: //ss.bobo.cn/purchase不会到二级域名wang.yang.com/purchase上,而是到 www.yang.com/purchase按照这样的要求重定向规则应该这样写:RewriteEngine OnRewriteCond %{REQUEST_URI} ^/wang/RewriteRule ^wang/(.*) http://wang.yang.com/$1 [R=permanent,L]RewriteCond %{REQUEST_URI} !^/wang/RewriteRule ^(.*) http://www.yang.com/$1 [R=permanent,L]------------------------------------------------------------------------------------------------------------------------------------------2)Apache mod_rewrite规则重写的标志一览R [=code](force redirect)强制外部重定向强制在替代字符串加上http://thishost[:thisport]/前缀重定向到外部的URL.如果code不指定,将用缺省的302 HTTP状态码。F (force URL to be forbidden) 禁用URL,返回403HTTP状态码。G (force URL to be gone) 强制URL为GONE,返回410HTTP状态码。P (force proxy) 强制使用代理转发。L (last rule) 表明当前规则是最后一条规则,停止分析以后规则的重写。N (next round) 重新从第一条规则开始运行重写过程。C (chained with next rule) 与下一条规则关联,如果规则匹配则正常处理,该标志无效,如果不匹配,那么下面所有关联的规则都跳过。T=MIME-type(force MIME type) 强制MIME类型NS (used only if no internal sub-request) 只用于不是内部子请求NC(no case) 不区分大小写QSA(query string append) 追加请求字符串NE(no URI escaping of output) 不在输出转义特殊字符例如:RewriteRule /foo/(.*) /bar?arg=P1%3d$1 [R,NE] 将能正确的将/foo/zoo转换成/bar?arg=P1=zooPT(pass through to next handler) 传递给下一个处理例如:RewriteRule ^/abc(.*) /def$1 [PT] #将会交给/def规则处理Alias /def /ghiS=num(skip next rule(s))#跳过num条规则E=VAR:VAL(set environment variable) #设置环境变量例子一:同时达到下面两个要求:用http://www.kevin.cn/xxx.php 来访问http://www.kevin.cn/xxx/用http://xiaoye.kevin.cn 来访问 http://www.kevin.cn/user.php?username=xiaoye的功能配置如下:RewriteEngine OnRewriteCond %{HTTP_HOST} ^www.kevin.cnRewriteCond %{REQUEST_URI} !^user.php$RewriteCond %{REQUEST_URI} .php$RewriteRule (.*).php$ http://www.kevin.cn/$1/ [R]RewriteCond %{HTTP_HOST} !^www.kevin.cnRewriteRule ^(.+) %{HTTP_HOST} [C]RewriteRule ^([^.]+).kevin.cn http://www.kevin.cn/user.php?username=$1例子二:/type.php?typeid=* –> /type*.html/type.php?typeid=*&page=* –> /type*page*.html配置如下:RewriteRule ^/type([0-9]+).html$ /type.php?typeid=$1 [PT]RewriteRule ^/type([0-9]+)page([0-9]+).html$ /type.php?typeid=$1&page=$2 [PT]------------------------------------------------------------------------------------------------------------------------------------------3)使用Apache的URL Rewrite配置多用户虚拟服务器)要实现这个功能,首先要在DNS服务器上打开域名的泛域名解析(自己做或者找域名服务商做)。比如,把 *.bobo.com和 *.bobo.cn全部解析到了我的IP地址192.168.10.183上。然后,看一下我的Apache中关于*.bobo.com的虚拟主机的设定。配置如下:ServerAdmin webmaster@bobo.comDocumentRoot /home/www/www.bobo.comServerName dns.bobo.comServerAlias dns.bobo.com bobo.com *.bobo.comCustomLog /var/log/httpd/osa/access_log.log” commonErrorLog /var/log/httpd/osa/error_log.log”AllowOverride NoneOrder deny,allow#AddDefaultCharset GB2312RewriteEngine onRewriteCond %{HTTP_HOST} ^[^.]+.bobo.(cn|us)$RewriteRule ^(.+) %{HTTP_HOST}$1 [C]RewriteRule ^([^.]+).bobo.(cn|us)(.*)$ /home/www/www.bobo.com/sylvan$3?un=$1&%{QUERY_STRING} [L]#在这段设定中,我把*.bobo.cn和*.bobo.com 的Document Root都设定到了 /home/www/www.bobo.com#继续看下去,在这里我就配置了URL Rewrite规则。RewriteEngine on #打开URL Rewrite功能RewriteCond %{HTTP_HOST} ^[^.]+.bobo.(cn|us)$ #匹配条件,如果用户输入的URL中主机名是类似 xxxx.bobo.com 或者 xxxx.bobo.cn 就执行下面一句RewriteRule ^(.+) %{HTTP_HOST}$1 [C] #把用户输入完整的地址(GET方式的参数除外)作为参数传给下一个规则,[C]是Chain串联下一个规则的意思RewriteRule ^([^.]+).bobo.(cn|us)(.*)$ /home/www/dev.bobo.com/sylvan$3?un=$1&%{QUERY_STRING} [L]最关键的是这一句,使用证则表达式解析用户输入的URL地址,把主机名中的用户名信息作为名为un的参数传给/home/www/dev.bobo.com 目录下的脚本,并在后面跟上用户输入的GET方式的传入参数。并指明这是最后一条规则([L]规则)。注意,在这一句中指明的重写后的地址用的是服务器上 的绝对路径,这是内部跳转。如果使用http://xxxx这样的URL格式,则被称为外部跳转。使用外部跳转的话,浏览着的浏览器中的URL地址会改变 成新的地址,而使用内部跳转则浏览器中的地址不发生改变,看上去更像实际的二级域名虚拟服务器。设置后重启Apache服务器就大功告成了! |

浙公网安备 33010602011771号