Apache 是一款使用量排名第一的 web 服务器,LAMP 中的 A 指的就是它。因为其开源、稳定、安全等特性而被普遍使用。下边记录了使用 Apache 以来常常用到的功能,作此梳理,做为平常运维笔记所用。javascript
1、Apache的工做模式
Apache 目前一共有三种MPM 模式(多进程处理模块),它们分别是prefork、worker、enent,主要用到前两种工做模式,且默认的工做模式是prefork。能够经过 httpd -V 来查看。php
[root@uatweb01 ~]# /usr/local/apache/bin/httpd -V | grep -i "server mpm" Server MPM: prefork
编译的时候,能够经过 configure 的参数来指定:css
--with-mpm=prefork|worker|event
1)prefork 工做模式
Apache在启动之初,就预先fork一些子进程,而后等待请求进来。之因此这样作,是为了减小频繁建立和销毁进程的开销。每一个子进程只有一个线程,在一个时间点内,只能处理一个请求。
优势:成熟稳定,兼容全部新老模块。同时,不须要担忧线程安全的问题。
缺点:一个进程相对占用更多的系统资源,消耗更多的内存。并且,它并不擅长处理高并发请求。html
2)worker 工做模式
使用了多进程和多线程的混合模式。它也预先fork了几个子进程(数量比较少),而后每一个子进程建立一些线程,同时包括一个监听线程。每一个请求过来,会被分配到1个线程来服务。线程比起进程会更轻量,由于线程一般会共享父进程的内存空间,所以,内存的占用会减小一些。在高并发的场景下,由于比起prefork有更多的可用线程,表现会更优秀一些。
优势:占据更少的内存,高并发下表现更优秀。
缺点:必须考虑线程安全的问题。java
3)event 工做模式
它和worker模式很像,最大的区别在于,它解决了keep-alive场景下,长期被占用的线程的资源浪费问题。event MPM中,会有一个专门的线程来管理这些keep-alive类型的线程,当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又容许它释放。这样加强了高并发场景下的请求处理能力。程序员
HTTP采用keepalive方式减小TCP链接数量,可是因为须要与服务器线程或进程进行绑定,致使一个繁忙的服务器会消耗完全部的线程。Event MPM是解决这个问题的一种新模型,它把服务进程从链接中分离出来。在服务器处理速度很快,同时具备很是高的点击率时,可用的线程数量就是关键的资源限 制,此时Event MPM方式是最有效的,但不能在HTTPS访问下工做。web
2、Apache的用户认证
有时候,须要给apache一些特殊的访问设置一个用户认证机制,增长安全。好比公司网站,通常都是有一个管理后台的,虽然管理后台自己就有密码,但为了更加安全,能够再设置一层用户认证。正则表达式
1)编辑配置文件) # vim /usr/local/apache2/conf/extra/httpd-vhosts.conf 在对应的虚拟主机配置中加入以下配置: <VirtualHost *:80> DocumentRoot "/usr/local/apache2/htdocs" ServerName www.kevin.com ServerAlias 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 Any Order Deny,Allow Allow from all </Directory> 或者: 在/usr/local/apache2/htdocs/php目录下创建.htaccess文件,把 Satisfy Any Order Deny,Allow Allow from all ================================================= 若是已经限制了一个目录的访问,须要用户名和密码,但想要放开这个目录中的其中一个文件(例如:back.html) 的权限,使其能够任意访问,在配置文件中添加: <Files back.html> Satisfy Any Order Deny,Allow Allow from all </Files> ================================================= 查看经过验证的用户名称: 能够查看REMOTE_USER环境变动。在access_log中也能够看到。 ================================================= 禁止经过代理服务器访问特定的URL <Directory proxy:http://192.168.10.10/music/> Order Allow,Deny Deny from all Satisfy All </Directory> 上述方法都没法知足要求时,能够使用正则表达式的方式,使用Rewrite指令。 ================================================ 想拒绝全部对目录中文件的访问,除了特殊指定扩展名的文件(好比.html文件) <Directory "/usr/local/apache2/htdocs/test"> Satisfy all Order Allow,Deny Deny from all <Files *.html> Order Deny,Allow Allow from all Satisfy any </Files> </Directory> 以上指令,使得test目录及其子目录下的全部非.html文件没法访问,只有.html的文件能够访问。
3、设置默认虚拟主机
默认虚拟主机就是配置文件里的第一个虚拟主机。关于默认虚拟主机有个特色,凡是解析到这台服务器的域名,无论是什么域名,只要在配置文件中没有配置,那么都会访问到这个主机上来。若是直接用IP访问,会访问到这个站点上来。为了不别人乱解析,因此应该把默认也就是第一个虚拟主机给禁止掉。使用allow,deny语句就能够禁止掉了。chrome
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或其它解析的域名访问,发现提示: Forbidden You 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页面。 错误号能够是其它的号码,如40三、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.1 NameVirtualHost 172.16.50.10 NameVirtualHost 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的主机名部分。
4、域名301跳转
一个站点不免会有多个域名,而多个域名总得有一个主次,好比个人网站能够用两个域名访问:www.kevin.cn 和 www.bobo.cn 但你们发现无论我用哪一个域名访问,最终都会跳转到www.bobo.con 上来。这个行为就叫作域名跳转,这里的301只是一个状态码,跳转除了301还有302,301是永久跳转,302是临时跳转,网站上必定要设置为301,这样对搜索引擎是比较友好的。apache
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 graceful 4)测试: # curl -x 192.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 -x 192.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日志
指定日志记录格式,组合日志格式(combined)或通用日志格式(common),修改配置文件: CustomLog logs/access_log combined 组合日志格式 CustomLog logs/access_log common 通用日志格式 通用日志格式与组合日志格式的"%h"控制符表示远程请求用户的身份,依据HostNameLookups指令的设定值, 多是主机名也多是IP地址。 若是想永远记录IP地址,则使用“%a”控制符。 记录从客户端收到的cookie CustomLog 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 off CustomLog "|/usr/local/apache2/bin/logresolve -c >> /usr/local/apache2/logs/access_log.resolved" combined
Apache日志切割
每访问一次网站,那么就会记录若干条日志。固然前提是已经设置了日志,日志不去管理,时间长了日志文件会愈来愈大,如何避免产生这么大的日志文件?其实apache有相关的配置,使日志按照咱们的需求进行归档,好比天天一个新日志,或者每小时一个新的日志。
1)首先简单设置日志的路径名称 # 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 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等静态对象。而这些文件的访问每每是巨量的,并且即便记录这些日志也没有什么用,那么如何过滤掉(不记录)这些日志呢?
配置日志不记录图片的访问 # 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,表示取反。
6、Apache配置静态缓存
所说的静态文件指的是图片、js、css等文件,用户访问一个站点,其实大多数元素都是图片、js、css等,这些静态文件实际上是会被客户端的浏览器缓存到本地电脑上的,目的就是为了下次再请求时再也不去服务器上下载,这样就加快了速度,提升了用户体验。但这些静态文件总不能一直缓存,它总有一些时效性,那么就得设置这个过时时间。
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 -M 2)重启服务器并验证 # apachectl -t # apachectl graceful 3)验证: # curl -x127.0.0.1:80 'http://www.kevin.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
7、Apache配置防盗链
盗链,全称是盗取连接,假如咱们的网站有不少好看的图片,别人能够查看咱们网站图片的连接,而后应用在他的网站上,这样的话,去访问他的网站,实际上消耗的是咱们的流量(由于实际连接在咱们这里),这样咱们就不得不去配置防盗链,使得别人不能复制咱们图片的连接。
防盗链的实现原理就不得不从HTTP协议提及,在HTTP协议中,有一个表头字段叫referer,采用URL的格式来表示从哪儿连接到当前的网页或文件。换句话说,经过referer,网站能够检测目标网页访问的来源网页,若是是资源文件,则能够跟踪到显示它的网页地址。有了referer跟踪来源就好办了,
这时就能够经过技术手段来进行处理,一旦检测到来源不是本站即进行阻止或者返回指定的页面。
若是想对本身的网站进行防盗链保护,则须要针对不一样的状况进行区别对待。若是网站服务器用的是apache,那么使用apache自带的Url Rewrite功能能够很轻松地防止各类盗链,其原理是检查refer,若是refer的信息来自其余网站则重定向到指定图片或网页上。
若是网站有不少漂亮的图片,好比网站域名 www.kevin.com,图片地址为 www.kevin.com/image/111.jpg,那么其它人就能够直接把这个地址放到他 本身的网站上,他的用户能够直接从他网站查看这张图片,而实际图片是从你的网站访问的,所产生的带宽消耗对你没有任何意义,应该对这些图片限制一下, 凡是在第三方站点上,严禁访问你站点的图片,如何配置呢? # vim /usr/local/apache2/conf/extra/httpd-vhosts.conf SetEnvIfNoCase Referer "^http://.*\.kevin\.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,其它都拒绝。 Directory表示指定哪一个目录,咱们设置防盗链确定是针对本站点,因此直接写站点。 SetEnv开头的是referer的白名单 local_ref 表示空的Refer filesmatch开头的指的后面这些格式的文件不设置白名单,(就是说针对这些文件作防盗链) 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,就是防盗链起了做用!
8、Apache访问控制
其实能够对apache的访问进行控制,能够设置白名单或黑名单(经过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在最后。 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 -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 -x 127.0.0.1:80 www.kevin.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 7)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 Forbidden Date: Wed, 02 Oct 2018 02:47:23 GMT Server: Apache/2.2.31 (Unix) PHP/5.4.45 Content-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 Permanently Date: Wed, 02 Oct 2018 02:47:42 GMT Server: Apache/2.2.31 (Unix) PHP/5.4.45 X-Powered-By: PHP/5.4.45 location: forum.php Cache-Control: max-age=0 Expires: Wed, 02 Oct 2018 02:47:42 GMT Content-Type: text/html # curl -x 192.168.101.230:80 -I www.kevin.com/forum.php #正常访问 HTTP/1.1 200 OK 8)若是但愿白名单限制管理员登陆网页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.php HTTP/1.1 200 OK 200,可是192.168.101.230能够正常访问
9、禁止解析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文件也是不合适的,因此有必要再禁止一下。
10、禁止指定user_agent
user_agent叫作浏览器标识,目前主流的浏览器有IE、chrome、Firefox、360、iphone的Safari、Android手机上的、百度搜索引擎、google搜索引擎等不少,每一种浏览器都有对应的user_agent。为了不一些无用的搜索引擎或机器爬虫之类引发的带宽的无辜消耗。
<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]
11、限制某个目录
能够allow和deny去如今网站根目录下的某个子目录,固然这个rewrite也能够实现。
<IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{REQUEST_URI} ^.*/shibo/* [NC] RewriteRule .* - [F] </IfModule> 这段配置,会把只要是包含 /shibo/ 字样的请求都限制了。
12、让Apache服务器的用户都有本身的URL,有本身的网页空间
配置文件里添加下面一行内容: 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/下), 后面的*号是用户名命名的目录。访问方法和上面第一种方法同样。
十3、Apache的.htaccess文件配置说明
.htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。经过对.htaccess文件进行设置,能够帮咱们实现:网页301重定向、自定义400/403/404/500错误页面、改变文件扩展名、容许/阻止指定IP用户访问、禁止目录列表、配置默认文档等功能,能够说是功能很是强大。
设置网站错误页面 ErrorDocument 400 /error_pages/400.html ErrorDocument 401 /error_pages/401.html ErrorDocument 403 /error_pages/403.html ErrorDocument 404 /error_pages/404.html ErrorDocument 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,deny deny from 255.0.0.0 deny from 123.45.6. allow from all 禁止指定来源网页访问 #禁止从 otherdomain.com 和 anotherdomain.com 的来源访问 RewriteEngine on # Options +FollowSymlinks RewriteCond %{HTTP_REFERER} otherdomain\.com [NC,OR] RewriteCond %{HTTP_REFERER} anotherdomain\.com RewriteRule .* – [F] 图片防盗链设置 #从本站之外的域名访问图片,一概显示 feed.jpg RewriteEngine on RewriteCond %{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 On RewriteBase /discuz RewriteCond %{QUERY_STRING} ^(.*)$ RewriteRule ^topic-(.+)\.html$ portal.php?mod=topic&topic=$1&%1 RewriteCond %{QUERY_STRING} ^(.*)$ RewriteRule ^article-([0-9]+)-([0-9]+)\.html$ portal.php?mod=view&aid=$1&page=$2&%1 RewriteCond %{QUERY_STRING} ^(.*)$ RewriteRule ^forum-(\w+)-([0-9]+)\.html$ forum.php?mod=forumdisplay&fid=$1&page=$2&%1 RewriteCond %{QUERY_STRING} ^(.*)$ RewriteRule ^thread-([0-9]+)-([0-9]+)-([0-9]+)\.html$ forum.php?mod=viewthread&tid=$1&extra=page\%3D$3&page=$2&%1 RewriteCond %{QUERY_STRING} ^(.*)$ RewriteRule ^group-([0-9]+)-([0-9]+)\.html$ forum.php?mod=group&fid=$1&page=$2&%1 RewriteCond %{QUERY_STRING} ^(.*)$ RewriteRule ^space-(username|uid)-(.+)\.html$ home.php?mod=space&$1=$2&%1 RewriteCond %{QUERY_STRING} ^(.*)$ RewriteRule ^blog-([0-9]+)-([0-9]+)\.html$ home.php?mod=space&uid=$1&do=blog&id=$2&%1 RewriteCond %{QUERY_STRING} ^(.*)$ RewriteRule ^archiver/(fid|tid)-([0-9]+)\.html$ archiver/index.php?action=$1&value=$2&%1 RewriteCond %{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指令:能够用正则表达式的方式将多个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: 修改配置文件: Redirect /xueer http://www.bo.com/yiner 以上指令表示访问http:www.kevin.com/xueer时,实际访问的是http://www.bo.com/yiner Redirect指令有几个参数: temp:表示文件当前不在原来所请求的位置上,能够未来还会在这个位置上,如今只是临时的。这样,客户端会记住原始请求的URL。 permanent:表示被请求的文件不在指定位置上,而是永久在新的位置上。这样,客户端会记住新的URL gone:表示文件不在此位置,并且之后也不在新的位置上。至关于404错误。但服务器会认可所请求的文件原来在此位置。因此不会被视为错误。 seeother:表示文件不在所请求的位置,并且被不一样位置的其它文件取代了(前三个参数都是指同一个文件,这个参数请是不一样位置的不一样文件取代了原来位置的原来文件) 默认状况下是使用temp参数 用RedirectMatch指令能够用正则表达式的方式将多个URL重定向至同一位置。 ================================ Apache接受不区分大小写的URL: 1) 安装mod_speling模块 2) 在配置文件中添加: CheckSpelling On ================================ mod_rewrite模块用途: 能够重写URL请求中的文件,替换成指定的; 能够拒绝访问未被引用的请求; 能够依据查询字符串来重写; 能够将全部请求重定向是单一主机; 将服务器的所有或部分请求重定向至SSL等相关工做 ================================ Apache性能测试: # ab -n 1000 -c 20 http://www.baidu.com/back.html 其中: -n 1000 表示请求的数目 -c 20 表示一次送出20 个请求 -h 能够查看帮助 ================================ Apache取得网站快照: 修改配置文件: <Location /server-status> SetHandler server-status # Order deny,allow # Deny from all # Allow from .example.com </Location> ExtendedStatus On ================================ 将常常查看的文件存入高速缓存区: 修改配置文件: MMapFile /usr/local/apache2/htdocs/index.html 须要安装mod_file_cache模块 ================================ 将目录列表存入高速缓存区 修改配置文件: IndexOptions +TrackModified
==============一个简单的apache跳转页面配置的小示例=================
示例以下: 假设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提示页面,会正常访问。
十4、Apache Rewrite重写规则总结
1)介绍
Apached的重写功能,便是mod_rewrite模块功能,它是apache的一个模块。它的功能很是强大,能够操做URL中的全部部分。所以咱们就能够改写url,给用户提供一个简介大方的url,当用户访问时能够经过mod_rewrite模块功能转换为真正的资源路径。经过mod_rewrite能实现的功能还有不少,例如隐藏真实地址、实现URL跳转、域名跳转、防盗链、限制访问资源类型等等。
2)工做流程
mod_rewrite模块在运行时会使用两个Hook程序。
a)第一个是从URL到文件名转换的Hook。当有访问到达Apache服务器的时,服务器会确认相应主机(或虚拟主机),这时mod_rewrite模块就开始工做,它将会先处理服务器全局中mod_rewrite模块所提供的指令,而后根据用户提供的指令进行改写。
b)第二个是修正URL的Hook。在此阶段mod_rewrite模块会处理非全局的设置。例如,目录中的.htaccess文件中的设置。可是此时已经完成URL的翻译(由URL转换为文件名),所以是没法在次对目录级别的URL进行改写操做,可是moe_rewrite模块会将已翻译的URL再次转换为URL的状态,继续进行目录级别的URL改写。(mod_rewrite模块将会使用读后请求阶段的回叫函数从新开始一个请求的循环处理)
Rewirte模块规则集的处理
当mod_rewrite在这两个API阶段中开始执行时,它会读取配置结构中配置好的 (或者是在服务启动时创建的服务器级的,或者是在遍历目录采集到的目录级的)规则集,而后,启动URL重写引擎来处理(带有一个或多个条件的)规则集。不管是服务器级的仍是目录级的规则集,都是由同一个URL重写引擎处理,只是最终结果处理不一样而已。
规则集中规则的顺序是很重要的,由于重写引擎是按一种特殊的顺序处理的:逐个遍历每一个规则(RewriteRule指令),若是出现一个匹配条件的规则,则可能回头遍历已有的规则条件(RewriteCond指令)。因为历史的缘由,条件规则是前置的,因此控制流程略显冗长,细节见下图-1。
可见,URL首先与每一个规则的Pattern匹配,若是匹配失败,mod_rewrite将当即终止此规则的处理,继而处理下一个规则。若是匹配成功,mod_rewrite将寻找相应的规则条件,若是一个条件都没有,则简单地用Substitution构造的新值来替换URL,而后继续处理其余规则;可是若是条件存在,则开始一个内部循环按其列出的顺序逐个处理。对规则条件的处理有所不一样:URL并不与模式进行匹配,而是首先经过扩展变量、反向引用、查找映射表等步骤创建一个TestString字符串,而后用它来与CondPattern匹配。若是匹配失败,则整个条件集和对应的规则失败;若是匹配成功,则执行下一个规则直到全部条件执行完毕。若是全部条件得以匹配,则以Substitution替换URL,而且继续处理。(本部分引用译者:金步国)
网络图片:
3)URL重写指令
只须要两步就能够完成了。第一使用RewriteEngine开启mod_rewrite模块功能;第二经过RewriteRule定义URL重写规则。
3.1)URL重写指令套路
RewriteEngine on #开启mod_rewrite模块功能 RewriteBase 路径 #基准URL(使用alias设置别名则需使用这个) RewriteCond TestString CondPattern [flags] #重写条件(能够多个) RewriteRule Pattern Substitution [flags] #重写规则 #最后两行能够能够多个 #按顺序一个一个执行RewriteRule([flags不终止状况下]) ##以上是经常使用的指令,还有一些不多见的指令,须要的本身去查资料了解
3.2)RewriteRule Pattern Substitution [flags]
a)pattern是做用于当前URL的perl兼容的正则表达式。当前URL是指该规则生效时刻的URL的值。它可能与被请求时的URL大相径庭,由于以前可能被其余RewriteRule或者alias指令修改过。
b)Substitution是当URL与Pattern匹配成功后。用来代替的字符串。
- 能够对pattern反向引用$N(N=0~9),表示正则表达式中第N个括号中的内容
- 对最后匹配的RewriteCond反向引用%N(N=0~9),表示最后匹配的RewriteCond第N对括号中的内容
- 服务器变量%{VARNAME}
- 映射函数调用${mapname:key|default} (经过RewriteMap指令定义映射辅助完成)
c)[flags],标志符,多个则用逗号隔开。
redirect|R [=code] (强制重定向 redirect)
以 http://thishost[:thisport]/(使新的URL成为一个URI) 为前缀的Substitution能够强制性执行一个外部重定向。 若是code没有指定,则产生一个HTTP响应代码302(临时性移动)。若是须要使用在300-400范围内的其余响应代码,只需在此指定这个数值便可, 另外,还能够使用下列符号名称之一: temp (默认的), permanent, seeother. 用它能够把规范化的URL反馈给客户端,如, 重写“/~”为 “/u/”,或对/u/user加上斜杠,等等。
注意: 在使用这个标记时,必须确保该替换字段是一个有效的URL! 不然,它会指向一个无效的位置! 而且要记住,此标记自己只是对URL加上 http://thishost[:thisport]/的前缀,重写操做仍然会继续。一般,你会但愿中止重写操做而当即重定向,则还须要使用’L’标记.
forbidden|F (强制URL为被禁止的 forbidden)
强制当前URL为被禁止的,即,当即反馈一个HTTP响应代码403(被禁止的)。使用这个标记,能够连接若干RewriteConds以有条件地阻塞某些URL。
gone|G(强制URL为已废弃的 gone)
强制当前URL为已废弃的,即,当即反馈一个HTTP响应代码410(已废弃的)。使用这个标记,能够标明页面已经被废弃而不存在了.
proxy|P (强制为代理 proxy)
此标记使替换成分被内部地强制为代理请求,并当即(即, 重写规则处理当即中断)把处理移交给代理模块。你必须确保此替换串是一个有效的(好比常见的以 http://hostname开头的)可以为Apache代理模块所处理的URI。使用这个标记,能够把某些远程成分映射到本地服务器名称空间, 从而加强了ProxyPass指令的功能。
注意: 要使用这个功能,代理模块必须编译在Apache服务器中。 若是你不能肯定,能够检查“httpd -l”的输出中是否有mod_proxy.c。 若是有,则mod_rewrite能够使用这个功能;若是没有,则必须启用mod_proxy并从新编译“httpd”程序。
last|L (最后一个规则 last)
当即中止重写操做,并再也不应用其余重写规则。 它对应于Perl中的last命令或C语言中的break命令。这个标记能够阻止当前已被重写的URL为其后继的规则所重写。 举例,使用它能够重写根路径的URL(’/’)为实际存在的URL, 好比, ‘/e/www/’.
next|N (从新执行 next round)
从新执行重写操做(从第一个规则从新开始). 这时再次进行处理的URL已经不是原始的URL了,而是经最后一个重写规则处理的URL。它对应于Perl中的next命令或C语言中的continue命令。 此标记能够从新开始重写操做,即, 当即回到循环的头部。
可是要当心,不要制造死循环!
chain|C (与下一个规则相连接 chained)
此标记使当前规则与下一个(其自己又能够与其后继规则相连接的, 并能够如此反复的)规则相连接。 它产生这样一个效果: 若是一个规则被匹配,一般会继续处理其后继规则, 即,这个标记不起做用;若是规则不能被匹配,则其后继的连接的规则会被忽略。好比,在执行一个外部重定向时, 对一个目录级规则集,你可能须要删除“.www” (此处不该该出现“.www”的)。
type|T=MIME-type(强制MIME类型 type)
强制目标文件的MIME类型为MIME-type。 好比,它能够用于模拟mod_alias中的ScriptAlias指令,之内部地强制被映射目录中的全部文件的MIME类型为“application/x-httpd-cgi”。
nosubreq|NS (仅用于不对内部子请求进行处理 no internal sub-request)
在当前请求是一个内部子请求时,此标记强制重写引擎跳过该重写规则。好比,在mod_include试图搜索可能的目录默认文件(index.xxx)时, Apache会内部地产生子请求。对子请求,它不必定有用的,并且若是整个规则集都起做用,它甚至可能会引起错误。因此,能够用这个标记来排除某些规则。
根据你的须要遵循如下原则: 若是你使用了有CGI脚本的URL前缀,以强制它们由CGI脚本处理,而对子请求处理的出错率(或者开销)很高,在这种状况下,能够使用这个标记。
nocase|NC (忽略大小写 no case)
它使Pattern忽略大小写,即, 在Pattern与当前URL匹配时,’A-Z’ 和’a-z’没有区别。
qsappend|QSA (追加请求串 query string append)
此标记强制重写引擎在已有的替换串中追加一个请求串,而不是简单的替换。若是须要经过重写规则在请求串中增长信息,就能够使用这个标记。
noescape|NE (在输出中不对URI做转义 no URI escaping)
此标记阻止mod_rewrite对重写结果应用常规的URI转义规则。 通常状况下,特殊字符(如’%’, ‘$’, ‘;’等)会被转义为等值的十六进制编码。 此标记能够阻止这样的转义,以容许百分号等符号出如今输出中,如:
RewriteRule /foo/(.*) /bar?arg=P1=$1 [R,NE] 能够使’/foo/zed’转向到一个安全的请求’/bar?arg=P1=zed’.
passthrough|PT (移交给下一个处理器 pass through)
此标记强制重写引擎将内部结构request_rec中的uri字段设置为 filename字段的值,它只是一个小修改,使之能对来自其余URI到文件名翻译器的 Alias,ScriptAlias, Redirect 等指令的输出进行后续处理。举一个能说明其含义的例子:若是要经过mod_rewrite的重写引擎重写/abc为/def,而后经过mod_alias使/def转变为/ghi,能够这样:
RewriteRule ^/abc(.*) /def$1 [PT]
Alias /def /ghi
若是省略了PT标记,虽然mod_rewrite运做正常, 即, 做为一个使用API的URI到文件名翻译器,它能够重写uri=/abc/…为filename=/def/…,可是,后续的mod_alias在试图做URI到文件名的翻译时,则会失效。
注意: 若是须要混合使用不一样的包含URI到文件名翻译器的模块时, 就必须使用这个标记。。混合使用mod_alias和mod_rewrite就是个典型的例子。
For Apache hackers
若是当前Apache API除了URI到文件名hook以外,还有一个文件名到文件名的hook, 就不须要这个标记了! 可是,若是没有这样一个hook,则此标记是惟一的解决方案。 Apache Group讨论过这个问题,并在Apache 2.0 版本中会增长这样一个hook。
skip|S=num (跳事后继的规则 skip)
此标记强制重写引擎跳过当前匹配规则后继的num个规则。 它能够实现一个伪if-then-else的构造: 最后一个规则是then从句,而被跳过的skip=N个规则是else从句. (它和’chain|C’标记是不一样的!)
env|E=VAR:VAL (设置环境变量 environment variable)
此标记使环境变量VAR的值为VAL, VAL能够包含可扩展的反向引用的正则表达式$N和%N。 此标记能够屡次使用以设置多个变量。这些变量能够在其后许多状况下被间接引用,但一般是在XSSI (via ) or CGI (如 $ENV{’VAR’})中, 也能够在后继的RewriteCond指令的pattern中经过%{ENV:VAR}做引用。使用它能够从URL中剥离并记住一些信息。
cookie|CO=NAME:VAL:domain[:lifetime[:path]] (设置cookie)
它在客户端浏览器上设置一个cookie。 cookie的名称是NAME,其值是VAL。 domain字段是该cookie的域,好比’.apache.org’, 可选的lifetime是cookie生命期的分钟数,可选的path是cookie的路径。
3.3)RewriteCond TestString CondPattern [flags]
Rewritecond指令定义一条规则条件。在一条rewriterule指令前面可能会有一条或者多条rewritecond指令,只有当自身模板匹配成功且这些条件也知足时(即RewriteRule中的pattern匹配成功),规则条件才被应用于当前URL处理。
3.3.1)TestString是一个纯文本的字符串
能够对pattern反向引用$N(N=0~9),紧跟在RewriteCond后面的RewriteRule正则表达式中第N个括号中的内容
反向引用%N(N=0~9),表示RewriteCond中CondPattern中第N对括号中的内容
服务器变量%{VARNAME}
3.3.2)CondPattern是条件pattern,一个应用于当前实例TestString的正则表达式。即TestString与条件pattern条件进行匹配。若是匹配则RewriteCond的值为Rrue,反之为False
能够使用如下特殊变量(可以使用'!'实现反转)
'>CondPattern’ (大于) 将condPattern看成一个普通字符串,将它和TestString进行比较,当TestString 的字符大于CondPattern为真。
‘=CondPattern’ (等于) 将condPattern看成一个普通字符串,将它和TestString进行比较,当TestString 与CondPattern彻底相同时为真.若是CondPattern只是 “” (两个引号紧挨在一块儿) 此时需TestString 为空字符串方为真。
‘-d’ (是否为目录) 将testString看成一个目录名,检查它是否存在以及是不是一个目录。
‘-f’ (是不是regular file) 将testString看成一个文件名,检查它是否存在以及是不是一个regular文件。
‘-s’ (是否为长度不为0的regular文件) 将testString看成一个文件名,检查它是否存在以及是不是一个长度大于0的regular文件。
‘-l’ (是否为symbolic link) 将testString看成一个文件名,检查它是否存在以及是不是一个 symbolic link。
‘-F’ (经过subrequest来检查某文件是否可访问) 检查TestString是不是一个合法的文件,并且经过服务器范围内的当前设置的访问控制进行访问。这个检查是经过一个内部subrequest完成的, 所以须要当心使用这个功能以下降服务器的性能。
‘-U’ (经过subrequest来检查某个URL是否存在) 检查TestString是不是一个合法的URL,并且经过服务器范围内的当前设置的访问控制进行访问。这个检查是经过一个内部subrequest完成的, 所以须要当心使用这个功能以下降服务器的性能。
3.3.3)[flags]是第三个参数,多个标志之间用逗号隔开)
’nocase|NC’ (不区分大小写) 在扩展后的TestString和CondPattern中,比较时不区分文本的大小写。注意,这个标志对文件系统和subrequest检查没有影响.
’ornext|OR’ (创建与下一个条件的或的关系) 默认的状况下,二个条件之间是AND的关系,用这个标志将关系改成OR。
4)Rewrite时服务器变量(仅列出少数)
HTTP headers:HTTP_USER_AGENT, HTTP_REFERER, HTTP_COOKIE, HTTP_HOST, HTTP_ACCEPT
connection & request:REMOTE_ADDR, QUERY_STRING
server internals::DOCUMENT_ROOT, SERVER_PORT, SERVER_PROTOCOL
system stuff: TIME_YEAR, TIME_MON, TIME_DAY
5)简单正则表达式规则
. 匹配任何单字符
[chars] 匹配字符串:chars
[^chars] 不匹配字符串:chars
text1|text2 可选择的字符串:text1或text2
? 匹配0到1个字符
* 匹配0到多个字符
+ 匹配1到多个字符
^ 字符串开始标志
$ 字符串结束标志
\n 转义符标志
注意:一代Apache要求URL有斜杠而二代Apache却不容许,所以使用 ^/?
6)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。
rewrite跳转举列说明
示例一: 下面是在一个虚拟主机里定义的规则。功能是把client请求的主机前缀不是www.kevin.cn和192.168.10.20都跳转到主机前缀为http://www.bobo.cn, 避免相同 内容的网页有多个指向的域名,如http://kevin.cn。 配置以下: NameVirtualHost 192.168.10.20:80 ServerAdmin slj@bobo.cn DocumentRoot “/web” ServerName kevin.cn RewriteEngine 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中不包含换行字符,()括号的功能是把全部的字符作一个标记,以便于后面的应用.就是引用前面里的 (.*)字符。 ============================================= 示例二:将输入 hui.com 的域名时跳转到http://www.kevin.cn 配置以下: RewriteEngine on RewriteCond %{HTTP_HOST} ^hui.com [NC] RewriteRule ^(.*) http://www.kevin.cn/ [L] ============================================= 示例三: 近期更换了域名,新域名为www.grace.com, 更加简短好记。这时须要将原来的域名ss.bobo.cn, 以及论坛所在地址ss.bobo.cn/bbs/定向到新的域名, 以便用户能够找到,而且使原来的论坛URL继续有效而不出现404未找到,好比原来的http://ss.bobo.cn/bbs/tread-60.html, 让它在新的域名下继续 有效,点击后转发到http://bbs.grace.com/tread-60.html,而其余网页,如原先的http: //ss.bobo.cn/purchase不会到二级域名bbs.grace.com/purchase上, 而是到 www.grace.com/purchase按照这样的要求重定向规则应该这样写: RewriteEngine On RewriteCond %{REQUEST_URI} ^/bbs/ RewriteRule ^bbs/(.*) http://bbs.grace.com/$1 [R=permanent,L] RewriteCond %{REQUEST_URI} !^/bbs/ RewriteRule ^(.*) http://www.grace.com/$1 [R=permanent,L] ============================================= 示例四:同时达到下面两个要求: 用http://www.kevin.cn/xxx.php 来访问http://www.kevin.cn/xxx/ 用http://xiaoye.kevin.cn 来访问 http://www.kevin.cn/user.php?username=xiaoye的功能 配置以下: RewriteEngine On RewriteCond %{HTTP_HOST} ^www.kevin.cn RewriteCond %{REQUEST_URI} !^user.php$ RewriteCond %{REQUEST_URI} .php$ RewriteRule (.*).php$ http://www.kevin.cn/$1/ [R] RewriteCond %{HTTP_HOST} !^www.kevin.cn RewriteRule ^(.+) %{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] ============================================= 示例六:使用Apache的URL Rewrite配置多用户虚拟服务器 要实现这个功能,首先要在DNS服务器上打开域名的泛域名解析(本身作或者找域名服务商作)。 好比,把 *.bobo.us和 *.bobo.cn所有解析到IP地址为70.40.213.183上。Apache中关于*.bobo.us的虚拟主机的设定以下: ServerAdmin webmaster@bobo.us DocumentRoot /home/www/www.bobo.us ServerName dns.bobo.us ServerAlias dns.bobo.us bobo.us *.bobo.us CustomLog /var/log/httpd/osa/access_log.log” common ErrorLog /var/log/httpd/osa/error_log.log” AllowOverride None Order deny,allow #AddDefaultCharset GB2312 RewriteEngine on RewriteCond %{HTTP_HOST} ^[^.]+.bobo.(cn|us)$ RewriteRule ^(.+) %{HTTP_HOST}$1 [C] RewriteRule ^([^.]+).bobo.(cn|us)(.*)$ /home/www/www.bobo.us/sylvan$3?un=$1&%{QUERY_STRING} [L] 配置说明: 在上面这段设定中,把*.bobo.cn和*.bobo.us 的Document Root都设定到了 /home/www/www.bobo.us 继续看下去,这里配置了URL Rewrite规则。 倒数第四行表示:打开URL Rewrite功能 倒数第三行表示:匹配条件,若是用户输入的URL中主机名是相似 xxxx.bobo.us 或者 xxxx.bobo.cn 就执行下面一句 倒数第二行表示:把用户输入完整的地址(GET方式的参数除外)做为参数传给下一个规则,[C]是Chain串联下一个规则的意思 倒数第一行:最关键的是这一句,使用证则表达式解析用户输入的URL地址,把主机名中的用户名信息做为名为un的参数传给/home/www/dev.bobo.us 目录下的脚本, 并在后面跟上用户输入的GET方式的传入参数。并指明这是最后一条规则([L]规则)。注意,在这一句中指明的重写后的地址用的是服务器上 的绝对路径,这是内部跳转。 若是使用http://xxxx这样的URL格式,则被称为外部跳转。使用外部跳转的话,浏览着的浏览器中的URL地址会改变成新的地址,而使用内部跳转则浏览器中的地址不发生 改变,看上去更像实际的二级域名虚拟服务器。 ============================================= 示例七:Rewrite 防盗链正则 不容许www.im286.com和www.chinaz.com 这两个网站盗链 , 其它的网站均可以盗链。 配置以下: RewriteEngine On RewriteCond %{HTTP_REFERER} chinaz.com [NC] RewriteCond %{HTTP_REFERER} im286.com [NC] RewriteRule .*\.(jpg|jpeg|gif|png|rar|zip|txt|ace|torrent|gz|swf)$ http://www.xxx.com/fuck.png [R,NC,L] ============================================= 示例七:关于判断 USER AGENT 。配置以下: RewriteEngine on RewriteCond %{HTTP_USER_AGENT} ^MSIE [NC,OR] RewriteCond %{HTTP_USER_AGENT} ^Opera [NC] RewriteRule ^.* – [F,L] #这里”-”表示没有替换,浏览器为IE和Opera的访客将被禁止访问。 ============================================= 示例八:自动添加.php扩展名及自动换.html到.php扩展名。 配置以下: RewriteEngine On RewriteBase /test RewriteCond %{REQUEST_FILENAME}.php -f RewriteRule ([^/]+)$ /test/$1.php #for hui: /test/admin => /test/admin.php RewriteRule ([^/]+)\.html$ /test/$1.php [L] #for hui: /test/admin.html => /test/admin.php ============================================= 示例九:限制目录只能显示图片 配置以下: < IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{REQUEST_FILENAME} !^.*\.(gif|jpg|jpeg|png|swf)$ RewriteRule .*$ – [F,L] < /IfModule>
7)apache重写规则的示例解析
在.htaccess里进行规制重写: RewriteEngine ON RewriteRule ^user/(w+)/?$user.php?id=$1 配置说明: ^:输入的开头 以user/开头请求的地址 (w+):提取全部的字母,传给$1 /?:可选斜杠 $:结束符 替换为:user.php?id=* 注意: 有些apache不兼容简写模式 w+ => [a-zA-Z_-] =============================== 禁止IE和Opera浏览器访问 RewriteEngine on RewriteCond %{HTTP_USER_AGENT} ^MSIE [NC,OR] RewriteCond %{HTTP_USER_AGENT} ^Opera [NC] RewriteRule ^.* - [F,L] #'-'表示不替换URL =============================== 不合法路径返回首页 RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php/$1 [L] ============================== 防盗链 RewriteEngine On RewriteCond %{HTTP_REFERER} !^http://(.+.)?mysite.com/ [NC] #判断请求的是不是本身的域名 RewriteCond %{HTTP_REFERER} !^$ #{HTTP_REFERER}不为空 RewriteRule .*.(jpe?g|gif|bmp|png)$ /images/nohotlink.jpg [L] #返回警告图片 ============================== 改变访问URL目录名),即隐藏真实的目录名字 RewriteEngine On RewriteRule ^/?old_dir/([a-z\.]+)$ new_dir/$1 [R=301,L] #new_dir为真正目录 ============================== 建立无文件后缀连接 RewriteEngine On RewriteCond %{REQUEST_FILENAME}.php -f #判断该后缀文件是否存在 RewriteRule ^/?([a-zA-Z0-9]+)$ $1.php [L] RewriteCond %{REQUEST_FILENAME}.html -f #判断该后缀文件是否存在 RewriteRule ^/?([a-zA-Z0-9]+)$ $1.html [L] ============================== 限制只能显示图片 RewriteEngine on RewriteCond %{REQUEST_FILENAME} !^.*\.(gif|jpg|jpeg|png|swf)$ RewriteRule .*$ - [F,L] ============================== 文件不存在重定向404 RewriteEngine on RewriteCond %{REQUEST_FILENAME} !f RewriteCond %{REQUEST_FILENAME} !d RewriteRule .? /404.php [L] ====================================其余配置示例==================================== 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} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule .? /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 -f RewriteRule ^/?([a-zA-Z0-9]+)$ $1.php [L] RewriteCond %{REQUEST_FILENAME}.html -f RewriteRule ^/?([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} !marker RewriteCond %{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} !on RewriteRule ^/?(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> ===================其余补充========================= Apache的URL地址重写的方法: --------------第一种方法-------------- Apache环境中若是要将URL地址重写,正则表达式是最基本的要求,但对于通常的URL地址来讲,基本的匹配就能实现咱们大部分要求,所以除非是很是特殊的URL地址, 但这不是我要讨论的范围,简单几招学会Apache中URL地址重写,经过实例展现,轻松学会URL地址重写: URL实例 重写URL:http://www.baidu.com/?p=152 原始URL:http://www.baidu.com/p152.html 重写规则: ^p([0-9]+)\.html /?p=$1 [L] 正则基础知识: ^ 匹配行的开始,匹配URL地址的开头部分,对于RewriteRule而言,域名(http://www.biuuu.com)不是URL地址的一部分,如上:?p=152 () 分隔一个被捕获的表达式,如上:([0-9]+) [] 定义字符类,如上:[0-9] 表示从0-9的数字 + 说明前面的字符能够被重复匹配1次或数次,如上:[0-9]+,表示任何数字组合 \ 字符转义,如上:转义. 其它: [L] 表示last,中止匹配其它 方法以下: 1)打开httpd.conf文件,找到 #LoadModule rewrite_module modules/mod_rewrite.so 注释前面# 2)打开httpd-vhosts.conf文件,在VirtualHost添加剧写规则, RewriteEngine On RewriteRule ^p([0-9]+)\.html /?p=$1 [L] 基本上就上面这两个步骤,其实总的来讲,Apache中URL地址重写仍是比较简单的,比看文档学习要快的多,不过要想深刻了解仍是有必要看看相关文档的,其它规则能够 自定义。记住一点:任何匹配其实就是一个正则表达式的替换过程。 建立友好的搜索引擎URL地址对于PHP程序员来讲很是重要,所以简单学会Apache中URL地址重写将是一项最基本的要求。 --------------第二种方法-------------- 1)首先检查是否已安装rewrite模块: cat httpd.conf | grep rewrite LoadModule rewrite_module modules/mod_rewrite.so 2)生成伪静态html链接: 生成伪静态html 在<VirtualHost>段最后加入 RewriteEngine on RewriteRule /goods([0-9]+).html /goods.php?id=$1 [PT] 更标准的写法为: RewriteRule ^(.*)/goods([0-9]+).html$ $1/goods.php?id=$2 [PT] 更简洁的写法: /goods(\d+)\.html /goods\.php\?id=$1 第一个(0-9]+)对应参数$1,以此类推第二个对应$2 举例: RewriteRule /forum-([0-9]+)-([0-9]+)\.html /forumdisplay.php?fid=$1&page=$2 [PT] 测试http://www.xxx.com/goods1.html 是否与/goods.php?id=1的内容相同。 最后将全部连接换成设置后的伪静态html地址方式。 [PT]:url全局转换,即转换过的goods31.html对应goods.php?id=31 (默认就是这个不加参数) [R]: url重定向 即便用goods31.html访问时跳转到goods.php?id=31 3)防盗链: RewriteCrond %{HTTP_HOST} !upkiller.com [R=301,L] RewriteRule ^(.*)$ http://www.upkiller.com/warning.html [R=301,L] 把不是来自upkiller.com的请求重定向到http://www.upkiller.com 更好的作法: RewriteCond %{HTTP_REFERER} !^http://(www\.)?upkiller\.com/.*$ [NC] RewriteRule \.(mp3|rar|jpe|gif)$ http://www.upkiller.com/warning.jpg [R=301,L] 4)防百度爬虫: RewriteCond %{HTTP_USER_AGENT} ^Baiduspider [OR] RewriteRule ^(.*)$ http://www.google.com [R=301,L] 把来自百度的爬虫转到goole
=====================Apache的ProxyPass使用小结=====================
该指令能够将远程服务器映射到本地服务器的URL空间;本地的服务器并非扮演传统意义上的代理服务器的角色,而是表现为远程服务器的一个镜像。此本地服务器常被成为反向代理(reversed proxy)或者是网关(gateway)。路径是指本地虚拟路径的名字;url指远程服务器的一个部分URL,不能包含查询字符串。
描述:将远程服务器映射到本地服务器的URL空间
语法:ProxyPass [路径] !|url [键=值 键=值 ...]] [nocanon]
上下文: server config, virtual host, directory
状态:扩展
模块:mod_proxy
apache中的mod_proxy模块主要做用就是进行url的转发,即具备代理的功能。应用此功能,能够很方便的实现同tomcat等应用服务器的整合,甚者能够很方便的实现web集群的功能。httpd.conf配置:
#保证如下模块加载 LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_http_module modules/mod_proxy_http.so #配置ProxyPass ProxyPass /new/ http://kevincom/ ProxyPass /new2/ http://192.168.0.169:8080/
须要注意:
顺序很重要:排除的指令必须在通常的ProxyPass指令以前。上面的配置已经能够实现大部分功能了,要控制细节!
例子:
使用apache做为域名www.kevin.com代理服务器,让其暴露在公网上,即DNS解析到本机器上,真正提供web服务器的是另外一台位于同一内网的机器上,假设起IP是172.16.50.40,那么只须要以下配置就能够了。
ProxyPass / http://172.16.50.40/ ProxyPassReverse / http://172.16.50.40/
- ProxyPass 很好理解,就是把全部来自客户端对http://www.kevin.com的请求转发给http://172.16.50.40上进行处理;
- ProxyPassReverse的配置老是和ProxyPass 一致,但用途很让人费解。彷佛去掉它很能很好的工做,事实真的是这样么,其实否则,若是响应中有302重定向,ProxyPassReverse就派上用场。举例说明,假设用户访问http://www.kevin.com/exam.php,经过转发交给http://172.16.50.40 /exam.php处理,假定exam.php处理的结果是实现redirect到login.php(使用相对路径,即省略了域名信息),若是没有配置反向代理,客户端收到的请求响应是重定向操做,而且重定向目的url为http://172.16.50.40/login.php ,而这个地址只是代理服务器能访问到的,可想而知,客户端确定是打不开的,反之若是配置了反向代理,则会在转交HTTP重定向应答到客户端以前调整它为 http://www.kevin.com/login.php,便是在原请求以后追加上了redirect的路径。当客户端再次请求http: //www.kevin.com/login.php,代理服务器再次工做把其转发到http://172.16.50.40/login.php。
- 客户端到服务器称之为正向代理,那服务器到客户端就叫反向代理。
ProxyPass与ProxyPassReverse及ProxyPassMatch这几个都是Apache的代理指令
1)ProxyPass
语法:ProxyPass [path] !|url
它主要是用做URL前缀匹配,不能有正则表达式,它里面配置的Path其实是一个虚拟的路径,在反向代理到后端的url后,path是不会带过去的。
示例一 ProxyPass / images/ ! 这个示例表示,/images/的请求不被转发。 ======================================= 示例二: ProxyPass /mirror/foo/ http://backend.kevin.com/ 假设当前的服务地址是http://kevin.com/,若是作上面的配置,那么访问http://kevin.com/mirror/foo/bar将被转成http://backend.kevin.com/bar 注:配置的时候,不须要被转发的请求,要配置在须要被转发的请求前面。
2)ProxyPassMatch
语法:ProxyPassMatch [regex] !|url
这个其实是url正则匹配,而不是简单的前缀匹配,匹配上的regex部分是会带到后端的url的,这个是与ProxyPass不一样的。
示例一 ProxyPassMatch ^/images ! 这个示例表示对/images的请求,都不会被转发。 ======================================= 示例二: ProxyPassMatch ^(/.*.gif) http://backend.kevin.com 这个示例表示对全部gif图片的请求,都被会转到后端,如此时请求,访问http://kevin.com/foo/bar.gif 那内部将会转换为 http://backend.kevin.com/foo/bar.gif。
3)ProxyPassReverse
语法:ProxyPassReverse [路径] url)
它通常和ProxyPass指令配合使用,此指令使Apache调整HTTP重定向应答中Location, Content-Location, URI头里的URL,这样能够避免在Apache做为反向代理使用时。
后端服务器的HTTP重定向形成的绕过反向代理的问题。好比:
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> <IfModule proxy_module> ProxyPass /kevin http://www.kevin.com/ ProxyPassReverse /kevin http://www.kevin.com/ </IfModule> <IfModule proxy_module> ProxyPass /bobo http://192.168.1.10:8080/bobo/ ProxyPassReverse /bobo http://192.168.1.10:8080/bobo/ </IfModule> ================================================== 443端口的Proxypass跳转 <IfModule proxy_module> SSLProxyEngine On ProxyPass /xyy https://bobo.kevin.com/pay/orderquery ProxyPassReverse /xyy https://bobo.kevin.com/pay/orderquery ProxyPass /getsignkey https://bobo.kevin.com/sandbox/pay/getsignkey ProxyPassReverse /getsignkey https://bobo.kevin.com/sandbox/pay/getsignkey ProxyPass /authorize https://shibo.kevin.com/connect/oauth2/authorize ProxyPassReverse /authorize https://shibo.kevin.com/connect/oauth2/authorize </IfModule>