apache下的rewrite实例一则

蚊子前几天上线了个页面,程序员做的时候是把动态页面和静态页面分离开的放在了两个目录,同时呢,所用域名下又没有使用二级目录,目录结构是这样的

php文件:/data/webroot/php/cgi
html等静态文件:/data/webroot/html

访问情况是这样的(我用我自己的域名做举例):

d.wenzizone.cn/index.php或者d.wenzizone.cn—>/data/webroot/php/cgi/index.php
d.wenzizone.cn/index.html及所有静态文件 —>/ata/webroot/html
所有php的页面都 —>/data/webroot/php/cgi/

开发人员告诉我了这个结构之后,蚊子认为只能通过apache的url rewrite来实现了,apache的配置如下

<VirtualHost *:80>
    ServerAdmin [email protected]
    DocumentRoot /data0/webroot           #这里一定要设置到这级目录
    ServerName d.wenzizone.cn
    DirectoryIndex index.php
    ErrorLog logs/d.wenzizone.cn-error_log
    CustomLog logs/d.wenzizone.cn-access_log common
    <directory /data0/webroot>
        DirectoryIndex index.php
        rewriteengine on
        RewriteBase /      #将/data0/webroot设置为基准目录

        #将d.wenzizone.cn和d.wenzizone.cn/的访问转化成d.wenzizone.cn/index.php 

        rewritecond %{REQUEST_URI} ="" [OR]
        rewritecond %{REQUEST_URI} =/
        rewriterule ^(.*)$ index.php

        #将所有php的页面重定向到基准目录下的php/cgi目录下

        rewritecond %{REQUEST_FILENAME} !-f
        rewritecond %{REQUEST_FILENAME} \.php$
        rewriterule ^(.*)$ /php/cgi/$1 [L]

        #将所有非php的静态文件重定向到基准目录下的html目录下

        rewritecond %{REQUEST_FILENAME} !-f
        rewritecond %{REQUEST_URI} !\.php$
        rewriterule ^(.*)$ /html/$1 [L]
    </directory>

    #下面这两项是打开rewrite日志,当时蚊子为了调试打开了,成功之后关闭就好了,不然会增加apache负担
    #rewritelog /var/log/httpd/rewrite.log
    #RewriteLogLevel 3
</VirtualHost>

保存后重启apache就可以了。

另外补充一点的,对于上面这个需求来讲,在nginx下实现起来是非常容易的,下面蚊子也把nginx下的实现方式写出来

server {
    listen       80;
    server_name  d.wenzizone.cn;

    location = / {
        root /data1/webroot/php/cgi;
        index index.php;
    }

    location / {
        root /data1/webroot/html;
        index index.html index.htm;
        expires 30d;
    }

    location ~* \.php$ {
            root /data1/webroot/php/cgi;
            index index.php;
            fastcgi_pass   127.0.0.1:9000;
            include        fastcgi_params;
            fastcgi_param  SCRIPT_FILENAME          $document_root$uri;
            fastcgi_param  SCRIPT_NAME              $uri;
    }
}

对于蚊子的需求,基于apache如果哪位达人还有更好更简便的方法,还望告知,不胜感激

squid反向代理apache认证网站[技术]

今天蚊子在配置apache的authbasic认证,如果直接访问apache就始终可以验证通过,但只要通过squid访问就始终重复的让我输入用户名密码,后来google了一下,还真找到了解决办法,不过网上那个人用的是squid2.6,我用的squid3.0,不过经过蚊子测试,完全可以正常使用

解决方法就是:

在cache_peer的最后加上login=PASS参数,然后重启就行了。

linux下使用apache+svn+ssl配置安全版本控制平台[技术]

公司决定把原来windows下的svn迁移到linux下,于是有了这篇文章,蚊子决定把linux下配置apache+svn+ssl的过程记录下来,方便以后查看。

环境:

        centos 5.4_x64
        apache 2.2.14
        subversion-1.4.2(担心包关联性问题,就没有考虑最新版本)

安装过程:

1,apache安装

# ./configure –prefix=/usr/local/apache –enable-so –enable-dav=shared –enable-dav-fs=shared –enable-dav-lock=shared –enable-ssl=shared

make

make install

如果这台apache不做其他使用,这个配置就已经足够

2,subversion安装

subversion-1.4.2]# ./autogen.sh  #建议先执行此领命,subversion会进行初始化,之前蚊子在make的时候报错,后来执行此操作后,make就顺利过去了

subversion-1.4.2]# ./configure –with-apxs=/usr/local/apache/bin/apxs –with-apr=/usr/local/apache/bin/apr-1-config –with-apr-util=/usr/local/apache/bin/apu-1-config –with-ssl

subversion-1.4.2]# make
subversion-1.4.2]# make install

到此,如果没有出错,安装工作就已经完成了,下面进入配置阶段

1,apache的配置

正常安装下

LoadModule dav_module modules/mod_dav.so
LoadModule dav_fs_module modules/mod_dav_fs.so
LoadModule dav_lock_module modules/mod_dav_lock.so
LoadModule dav_svn_module     modules/mod_dav_svn.so
LoadModule authz_svn_module   modules/mod_authz_svn.so
LoadModule ssl_module   modules/mod_ssl.so

这几个module保证不是被注释的,另外找到
Include conf/extra/httpd-dav.conf
Include conf/extra/httpd-ssl.conf

这两行,去掉前面的注释。

编辑conf/extra/httpd-dav.conf,加入如下内容,其余内容可以全部删除

<Location /svn>   #是在url或者svn客户端上指定的访问路径
   DAV svn           #声明svn
   SVNParentPath /data3/svn  #用来表示共同的父目录,所有不同的版本库都是存放在此目录下
   AuthzSVNAccessFile /data3/svn/authz  #指定保存路径中的版本库访问策略文件
   AuthType Basic   #往下是apache的简单认证方式,及密码文件存放位置
   AuthName "Subversion repository"
   AuthUserFile /data3/svn/htpasswd
   Require valid-user
</Location>

编辑完成后保存退出,由于http访问的方式密码传输是明文的,所以还需要配置ssl进行加密传输

接下来配置ssl,需要以下几个步骤:

第一步,创建key和request:
openssl req -new > new.cert.csr

第二步,从key中删除passphrase(可选):
openssl rsa -in privkey.pem -out new.cert.key

第三步,把request转换成signed sert:
openssl x509 -in new.cert.csr -out new.cert.cert -req -signkey new.cert.key -days 1825

第四步,把cert和key文件拷贝到适当的位置:
cp new.cert.cert /usr/local/apache/conf/server.crt
cp new.cert.key /usr/local/apache/conf/server.key

注:如果你没有在第二步从key中把passphrase删除,那么每次你启动apache的时候你都要输入密码。这也就意味着如果你的服务器因为某些原因重新启动了,除非你在服务器旁手动敲入了密码,否则你的web服务器就不会启动。

到此,apache的配置就完成了,接下来对subversion来进行配置

2,subversion的配置

在/data3/svn下创建authz文件,内容如下

[group]
test=abc

[test:/]
@test=rw

保存退出。

设置abc的密码

/usr/local/apache/bin/htpasswd –bc /data3/svn/htpasswd abc 12345678

这样就会在/data3/svn下创建htpasswd文件,内容如下:

abc:gtnqpowogqB/Y

密码采用加密的方式。

创建test库:

svnadmin create /data3/svn/test

到此启动apahce就可以测试了:https://ip/svn/test,同样也可以使用svn客户端来访问svn list https://ip/svn/test,输入用户名密码后就可以访问新建的test库了。

apache rewrite在per-server和per-dir两种模式下的效率对比[转]

虽说rewrite不 难,但有些细节可能不是每个人都清楚,比如说rewrite在per-server和per-dir两种配置下的效率,下面我们通过开启日志来判断到底哪 个效率好,在实验前请下做好相关配置,并编辑适当的测试文件a.html,b.html,每次测试后通过tail -f /usr/local/apache2/logs/rewrite.log来实时监控发生了什么。

先看per-server配置:

01 <VirtualHost *:80>
02     ServerName _default_
03
04     RewriteEngine on
05
06     RewriteLog /usr/local/apache2/logs/rewrite.log
07     RewriteLogLevel 9
08
09     # RewriteRule ^/a.html$ /usr/local/apache2/htdocs/b.html [L]
10     # RewriteRule ^/a.html$ /b.html
[L]
11 </VirtualHost>

规则:RewriteRule ^/a.html$ /usr/local/apache2/htdocs/b.html

日志:

init rewrite engine with requested uri /a.html
applying pattern ‘^/a.html

to uri ‘/a.html’
rewrite ‘/a.html’ -> ‘/usr/local/apache2/htdocs/b.html’
local path result: /usr/local/apache2/htdocs/b.html
go-ahead with /usr/local/apache2/htdocs/b.html [OK]

规则:RewriteRule ^/a.html$ /b.html

日志:

init rewrite engine with requested uri /a.html
applying pattern ‘^/a.html

to uri ‘/a.html’
rewrite ‘/a.html’ -> ‘/b.html’
local path result: /b.html
prefixed with document_root to /usr/local/apache2/htdocs/b.html
go-ahead with /usr/local/apache2/htdocs/b.html [OK]

再看per-dir配置:

01 <Directory “/usr/local/apache2/htdocs”>
02     RewriteEngine on
03
04     RewriteLog
/usr/local/apache2/logs/rewrite.log
05     RewriteLogLevel 9
06
07     # RewriteRule ^a.html$ /usr/local/apache2/htdocs/b.html
[L]
08     # RewriteRule ^a.html$ /b.html [L]
09     # RewriteRule ^a.html$ b.html [L]
10 </Directory>

规则:RewriteRule ^a.html$ /usr/local/apache2/htdocs/b.html

日志:

strip per-dir prefix: /usr/local/apache2/htdocs/a.html -> a.html
applying pattern ‘^a.html

to uri ‘a.html’
rewrite ‘a.html’ -> ‘/usr/local/apache2/htdocs/b.html’
strip document_root prefix: /usr/local/apache2/htdocs/b.html -> /b.html
internal redirect with /b.html [INTERNAL REDIRECT]
strip per-dir prefix: /usr/local/apache2/htdocs/b.html -> b.html
applying pattern ‘^a.html

to uri ‘b.html’
pass through /usr/local/apache2/htdocs/b.html

规则:RewriteRule ^a.html$ /b.html

日志:

strip per-dir prefix: /usr/local/apache2/htdocs/a.html -> a.html
applying pattern ‘^a.html

to uri ‘a.html’
rewrite ‘a.html’ -> ‘/b.html’
internal redirect with /b.html [INTERNAL REDIRECT]
strip per-dir prefix: /usr/local/apache2/htdocs/b.html -> b.html
applying pattern ‘^a.html

to uri ‘b.html’
pass through /usr/local/apache2/htdocs/b.html

规则:RewriteRule ^a.html$ b.html

日志:

strip per-dir prefix: /usr/local/apache2/htdocs/a.html -> a.html
applying pattern ‘^a.html

to uri ‘a.html’
rewrite ‘a.html’ -> ‘b.html’
add per-dir prefix: b.html -> /usr/local/apache2/htdocs/b.html
strip document_root prefix: /usr/local/apache2/htdocs/b.html -> /b.html
internal redirect with /b.html [INTERNAL REDIRECT]
strip per-dir prefix: /usr/local/apache2/htdocs/b.html -> b.html
applying pattern ‘^a.html

to uri ‘b.html’
pass through /usr/local/apache2/htdocs/b.html

即便简单通过日志的行数,我们也能看到per-server的效率高于per-dir,仔细查看日志,会发现当在per-dir配置下使用rewrite 时,系统会发生一次“INTERNAL REDIRECT”,所以以后写rewrite时,除非必要,否则不要使用pre-dir配置,而应尽可能使用per-server配置,至于是使用 file路径,还是url路径,差别不大,不过url路径的看上去更短些,也更好维护一些。

原文出自:http://hi.baidu.com/thinkinginlamp/blog/item/ff49972b9d267bf1e6cd4019.html

编译php出现Error: Command failed with rc=65536错误及解决

今天搭建lamp环境的时候,php编译总是报下面这个错误,搞得我好不郁闷,我的lamp环境是:

linux:  centos5.3
apache: 2.2.11
php:    5.2.9
mysql:  5.1.34

在编译apache和mysql的时候都很正常,而且在以前版本的情况下我原先的配置环境下,我的所有编译参数都是正常可用的

最后发现是在编译apache的时候出现的问题,我原来编译apache的参数是


后来我更改了apache的编译参数,结果php编译就正常了,改后的apache参数是


不知道我的这个办法是不是同样适合遇到问题的你们。

apache userdir的使用[原创]

昨天有人在qq群里问了个问题,当他用apache开启了userdir_mod后,总是出现Permission denied的错误日志,为此我也亲自用vmvare测试了一下,我就把我的解决办法写出来
我的apache版本是2.2.9
首先编辑httpd.conf,找到

# Language settings
#Include conf/extra/httpd-languages.conf

# User home directories
Include conf/extra/httpd-userdir.conf        #找到这行,并去掉前面的“#”符号

# Real-time info on requests and configuration
#Include conf/extra/httpd-info.conf

conf/extra/httpd-userdir.conf这个文件可以默认不用修改,然后添加用户

useradd test
su - test
mkdir public_html
echo "test">public_html/index.html

然后启动apache,如果没有报错,就可以使用http://yourip/~test/
就应该可以看到“test”这个内容了
不过遗憾的告诉大家,经过我这样做,结果errorlog中还是有

[Tue Aug 26 18:07:09 2008] [error] [client 192.168.213.1] (13)Permission denied: access to /~test/ denied
[Tue Aug 26 18:07:10 2008] [error] [client 192.168.213.1] (13)Permission denied: access to /~test/ denied
[Tue Aug 26 18:08:11 2008] [error] [client 192.168.213.1] (13)Permission denied: access to /~test/ denied

后来群里那哥们说他把selinux关了之后就搞定,既然兄弟这样说,那我就做吧,先检查了一下目前我的selinux的状态,发现我的selinux本身就是关的,那看来问题不在此处,继续在网上翻阅,最后在一个论坛中发现,如果想访问各个用户,用户目录必须对apache来说有X的权限,所以赶紧试了一下

chmod -R +x /home/test/

这次再访问http://yourip/~test/,久违的test内容果然出现了至此问题解决

总结:1,关闭selinux 
   2,用户目录对apache需要有x的权限

参考文章:http://www.linuxquestions.org/questions/linux-server-73/user-directories-permission-problem-571332/