实验的环境
LAMP环境:
操作系统: centos7.4
apache版本:httpd-2.4.10
PHP版本: php5.6.32
源码包存放位置:/usr/src
源码包编译安装位置:
apache: /usr/local/apache/
php:/server/php-5.4
mysql:/server/mysql-5.5/
rewrite-禁止网站下某个目录执行PHP文件
Rewrite规则简介
Rewirte主要的功能就是实现URL的跳转,它的正则表达式是基于Perl语言。可基于服务器级的(httpd.conf)和目录级的 (.htaccess)两种方式。如果要想用到rewrite模块,必须先安装或加载rewrite模块。
安装Rewirte模块两种方式:
方法一:是编译apache的时候就直接 安装rewrite模块。
方法二:编译apache时以DSO模式安装apache,然后再利用源码和apxs来安装rewrite模块。
基于服务器级的(httpd.conf)有两种方法:
方法1:在httpd.conf的全局下 直接利用RewriteEngine on来打开rewrite功能;
方法2:在局部里利用RewriteEngine on来打开rewrite功能,下面将会举例说明,需要注意的是,必须在每个virtualhost里用RewriteEngine on来打开rewrite功能。否则virtualhost里没有RewriteEngine on它里面的规则也不会生效。
基于目录级的(.htaccess),要注意一点那就是必须打开此目录的FollowSymLinks属性且在.htaccess里要声明RewriteEngine on。
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=zed -
PT(pass through to next handler) 传递给下一个处理
例如:
RewriteRule ^/abc(.*) /def$1 [PT] # 将会交给/def规则处理
Alias /def /ghi -
S=num(skip next rule(s)) 跳过num条规则
-
E=VAR:VAL(set environment variable) 设置环境变量
mod_rewrite模块检查及安装
[root@yunzu63 ~]# /usr/local/apache/bin/httpd -M |grep rewrite //没有加载rewrite模块
[root@yunzu63 ~]# ls /usr/local/apache/modules/* |grep rewrite
/usr/local/apache/modules/mod_rewrite.so
[root@yunzu63 ~]# vim /etc/httpd/httpd.conf
修改:
161 #LoadModule rewrite_module modules/mod_rewrite.so
改为:
LoadModule rewrite_module modules/mod_rewrite.so
[root@yunzu63 ~]# systemctl restart httpd
[root@yunzu63 ~]# /usr/local/apache/bin/httpd -M |grep rewrite
rewrite_module (shared)
实战举例
实现client请求的主机前缀不是www.yunzu.com和192.168.1.63都跳转到主机前缀为http://www.yunzu.com.cn 。例如当用户在地址栏写入http://yunzu.com.cn和bbs.yunzu.com直接跳转到http://www.yunzu.com.cn登录网站。
[root@yunzu63 ~]# vim /etc/httpd/httpd.conf
在:
172 User daemon
173 Group daemon
之后插入:
RewriteEngine on
RewriteCond %{HTTP_HOST} !^www.yunzu.com [NC]
RewriteCond %{HTTP_HOST} !^192.168.1.63 [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule ^/(.*) http://www.yunzu.com.cn/ [L]
注释:
RewriteEngine on #打开rewirte功能
RewriteCond %{HTTP_HOST} !^www.yunzu.com [NC] #声明Client请求的主机中前缀不是www.yunzu.com,[NC]的意思是忽略大小写
RewriteCond %{HTTP_HOST} !^192.168.1.63 [NC] #声明Client请求的主机中前缀不是192.168.1.63,[NC]的意思是忽略大小写
RewriteCond %{HTTP_HOST} !^$ #声明Client请求的主机中前缀不为空,[NC]的意思是忽略大小写
RewriteRule ^/(.*) http://www.yunzu.com.cn/ [L]
#含义是如果Client请求的主机中的前缀符合上述条件,则直接进行跳转到http://www.yunzu.com.cn/,[L]意味着立即停止重写操作,并不再应用其他重写规则。这里的.是指匹配所有URL中不包含换行字符,()括号的功能是把所有的字符做一个标记,以便于后面的应用. 就是引用前面里的(.)字符。
添加hosts记录文件:
[root@yunzu63 ~]# vim /etc/hosts
192.168.1.63 www.yunzu.com
192.168.1.63 www.yunzu.com.cn
192.168.1.63 yunzu.com.cn
192.168.1.63 yunzu.com
192.168.1.63 bbs.yunzu.com
重启服务:
[root@yunzu63 ~]# systemctl restart httpd
测试:
http://www.yunzu.com/ #可以正常访问
http://192.168.1.63/ #可以正常访问
http://yunzu.com.cn/ #直接跳转到http://www.yunzu.com.cn/
http://bbs.yunzu.com/ #直接跳转到http://www.yunzu.com.cn/
可以实现跳转说明成功。
实例二.将输入 bbs.test.com 的域名时跳转到www.test.com
[root@yunzu63 ~]# vim /etc/httpd/httpd.conf
改:
RewriteEngine on
RewriteCond %{HTTP_HOST} !^www.yunzu.com [NC]
RewriteCond %{HTTP_HOST} !^192.168.1.63 [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule ^/(.) http://www.yunzu.com.cn/ [L]
为:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^bbs.test.com [NC]
RewriteRule ^/(.) http://www.test.com/ [L]
[root@yunzu63 ~]# vim /etc/hosts #hosts文件中追加
192.168.1.63 bbs.test.com
192.168.1.63 www.test.com
[root@yunzu63 ~]# systemctl restart httpd
禁止目录浏览
由于开启目录浏览会让我们整个目录下的内容全部都暴露到外面,因此我们必须要禁止目录浏览功能。当然一些目录开放给客户做下载的,可以忽略此项优化。
我们通过修改apache主配置文件httpd.conf中的标签内的Options选项参数来实现禁用目录浏览。
先复制一些目录:
[root@yunzu63 ~]# cp -r /boot/grub/ /usr/local/apache/htdocs/
测试:http://192.168.1.63/grub/
现在禁止访问:
[root@yunzu63 ~]# vim /etc/httpd/httpd.conf #找到根目录中的
<Directory “/usr/local/apache/htdocs”>
。。。
改: Options Indexes FollowSymLinks
为: Options FollowSymLinks
注:直接删除Indexes 此选项即可
[root@yunzu63 ~]# systemctl restart httpd
禁止PHP解析网站中某个目录中的php文件
企业的站点有时会提供用户进行上传操作,而用户上传文件的存放目录,我们是不能给php的解析权限的,否则会对apache服务和系统造成危害。
实例:
[root@yunzu63 ~]# mkdir /usr/local/apache/htdocs/data #data目录是我们需要保护目录
[root@yunzu63 ~]# vim /usr/local/apache/htdocs/data/a.php
测试:
http://192.168.1.63/data/a.php #可以正常解析访问
现在配置:
[root@yunzu63 ~]# vim /etc/httpd/conf/httpd.conf
在:
210
211 AllowOverride none
212 Require all denied
213 </Directory
之后,添加以下内容:
<Directory “/usr/local/apache/htdocs/data” >
<Files ~ “.php”>
AllowOverride none
Require all denied
</ Files>
</ Directory>
[root@yunzu63 ~]# systemctl restart httpd
测试:
http://192.168.1.63/data/a.php #发现执行不成了