首页 > apache

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

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 webmaster@d.wenzizone.cn
    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如果哪位达人还有更好更简便的方法,还望告知,不胜感激

阅读全文

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

解决方法就是:

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

阅读全文

公司决定把原来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库了。

阅读全文

虽说rewrite不 难,但有些细节可能不是每个人都清楚,比如说rewriteper-serverper-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

阅读全文

蚊子今天写了一个nagios监控apache的进程数的脚本,同时学习到了一个新的命令:getopts,现把脚本分享如下。

 

有需要的朋友拿去用吧,此脚本参考了nagios-exchange站点上的check_apacheconcreq这个脚本,这个脚本是监控当前请求的数量,有兴趣的可以去下载:http://exchange.nagios.org/components/com_mtree/attachment.php?link_id=1374&cf_id=29

阅读全文

为了学习nginx,又苦于公司生产环境没有打算要换到nginx上,于是就想到拿自己搭建的监控环境开刀了,一路配置下来确实还是遇到不少麻烦,不过还好最终还都是圆满解决掉了,下面就把我这次从apache迁移到nginx的过程整理下来

原来的监控环境是apache+cacti+nagios,按照网上相关的文档,配置起来那真是傻瓜之所及也,我也不太想赘述了,网上google一下后大把大把的。

新的监控环境nginx+cacti+nagios,其实就是把apache换成了nginx而已,cacti和nagios的安装方法我也不多说了,自己去搜好了,就把转换过程和需要注意的地方写下来。

nginx安装我不赘述,首先是cacti相关的配置,详细如下

location /cacti/ {
         alias /data/wwwroot/web/cacti/;
         index index.php index.html index.htm;
         }

location ~ \.php$ {
         root           /data/wwwroot/web/;
         fastcgi_pass   127.0.0.1:9000;
         fastcgi_index  index.php;
         fastcgi_param  SCRIPT_FILENAME  $document_root/$fastcgi_script_name;
         include        fastcgi_params;
        }

下面解释一下上面的配置,因为我的地址是http://ip/cacti/这样的形式,所以我定义了location /cacti/这个,然后把这个目录重定向到了cacti所在的目录,再看后面php的配置,首先定义了root地址是/data/wwwroot/web/这个就是后面$document_root内容,我的访问php的页面是http://ip/cacti/plugins/monitor/monitor.php,在这个url里cacti/plugins/monitor/monitor.php这部分是$fastcgi_script_name的值,因为涉及到了php页面,所以就会到$document_root即/data/wwwroot/web/下去找,这也就是为什么root定义的时候我不是直接的定义到了/data/wwwroot/web/cacti下,之前我就是在这里出的错误,结果就是始终找不到所需要的文件。

因为nginx本身是不支持cgi的,所以需要使用一个perl脚本来进行转换,脚本如下

#!/usr/bin/perl
use FCGI;
use Socket;
use FCGI::ProcManager;
sub shutdown { FCGI::CloseSocket($socket); exit; }
sub restart  { FCGI::CloseSocket($socket); &main; }
use sigtrap ‘handler’, \&shutdown, ‘normal-signals’;
use sigtrap ‘handler’, \&restart,  ‘HUP’;
require ‘syscall.ph’;
use POSIX qw(setsid);

END()   { }
BEGIN() { }
{
 no warnings;
*CORE::GLOBAL::exit = sub { die "fakeexit\nrc=" . shift() . "\n"; };
};
eval q{exit};
if ($@) {
 exit unless $@ =~ /^fakeexit/;
}
&main;

sub daemonize() {
 chdir ‘/’ or die "Can’t chdir to /: $!";
 defined( my $pid = fork ) or die "Can’t fork: $!";
 exit if $pid;
 setsid() or die "Can’t start a new session: $!";
 umask 0;
}

sub main {

 $proc_manager = FCGI::ProcManager->new( {n_processes => 5} );
 $socket = FCGI::OpenSocket( "/usr/local/nginx/logs/cgi.sock", 10 )
 ; #use UNIX sockets – user running this script must have w access to the ‘nginx’ folder!!
 $request =
 FCGI::Request( \*STDIN, \*STDOUT, \*STDERR, \%req_params, $socket,
 &FCGI::FAIL_ACCEPT_ON_INTR );
 $proc_manager->pm_manage();
 if ($request) { request_loop() }
 FCGI::CloseSocket($socket);
}

sub request_loop {
 while ( $request->Accept() >= 0 ) {
 $proc_manager->pm_pre_dispatch();

 #processing any STDIN input from WebServer (for CGI-POST actions)
 $stdin_passthrough = ”;
 { no warnings; $req_len = 0 + $req_params{‘CONTENT_LENGTH’}; };
 if ( ( $req_params{‘REQUEST_METHOD’} eq ‘POST’ ) && ( $req_len != 0 ) )
 {
 my $bytes_read = 0;
 while ( $bytes_read < $req_len ) {
 my $data = ”;
 my $bytes = read( STDIN, $data, ( $req_len – $bytes_read ) );
 last if ( $bytes == 0 || !defined($bytes) );
 $stdin_passthrough .= $data;
 $bytes_read += $bytes;
 }
 }

 #running the cgi app
 if (
 ( -x $req_params{SCRIPT_FILENAME} ) &&    #can I execute this?
 ( -s $req_params{SCRIPT_FILENAME} ) &&    #Is this file empty?
 ( -r $req_params{SCRIPT_FILENAME} )       #can I read this file?
 )
 {
 pipe( CHILD_RD,   PARENT_WR );
 pipe( PARENT_ERR, CHILD_ERR );
 my $pid = open( CHILD_O, "-|" );
 unless ( defined($pid) ) {
 print("Content-type: text/plain\r\n\r\n");
 print
"Error: CGI app returned no output – Executing $req_params{SCRIPT_FILENAME} failed !\n";
 next;
 }
 $oldfh = select(PARENT_ERR);
 $|     = 1;
 select(CHILD_O);
 $| = 1;
 select($oldfh);
 if ( $pid > 0 ) {
 close(CHILD_RD);
 close(CHILD_ERR);
 print PARENT_WR $stdin_passthrough;
 close(PARENT_WR);
 $rin = $rout = $ein = $eout = ”;
 vec( $rin, fileno(CHILD_O),    1 ) = 1;
 vec( $rin, fileno(PARENT_ERR), 1 ) = 1;
 $ein    = $rin;
 $nfound = 0;

 while ( $nfound =
 select( $rout = $rin, undef, $ein = $eout, 10 ) )
 {
 die "$!" unless $nfound != -1;
 $r1 = vec( $rout, fileno(PARENT_ERR), 1 ) == 1;
 $r2 = vec( $rout, fileno(CHILD_O),    1 ) == 1;
 $e1 = vec( $eout, fileno(PARENT_ERR), 1 ) == 1;
 $e2 = vec( $eout, fileno(CHILD_O),    1 ) == 1;

 if ($r1) {
 while ( $bytes = read( PARENT_ERR, $errbytes, 4096 ) ) {
 print STDERR $errbytes;
 }
 if ($!) {
 $err = $!;
 die $!;
 vec( $rin, fileno(PARENT_ERR), 1 ) = 0
 unless ( $err == EINTR or $err == EAGAIN );
 }
 }
 if ($r2) {
 while ( $bytes = read( CHILD_O, $s, 4096 ) ) {
 print $s;
 }
 if ( !defined($bytes) ) {
 $err = $!;
 die $!;
 vec( $rin, fileno(CHILD_O), 1 ) = 0
 unless ( $err == EINTR or $err == EAGAIN );
 }
 }
 last if ( $e1 || $e2 );
 }
 close CHILD_RD;
 close PARENT_ERR;
 waitpid( $pid, 0 );
 } else {
 foreach $key ( keys %req_params ) {
 $ENV{$key} = $req_params{$key};
 }

 # cd to the script’s local directory
 if ( $req_params{SCRIPT_FILENAME} =~ /^(.*)\/[^\/] +$/ ) {
 chdir $1;
 }
 close(PARENT_WR);

 #close(PARENT_ERR);
 close(STDIN);
 close(STDERR);

 #fcntl(CHILD_RD, F_DUPFD, 0);
 syscall( &SYS_dup2, fileno(CHILD_RD),  0 );
 syscall( &SYS_dup2, fileno(CHILD_ERR), 2 );

 #open(STDIN, "<&CHILD_RD");
 exec( $req_params{SCRIPT_FILENAME} );
 die("exec failed");
 }
 } else {
 print("Content-type: text/plain\r\n\r\n");
 print
"Error: No such CGI app – $req_params{SCRIPT_FILENAME} may not exist or is not executable by this process.\n";
 }
 }
}

把上面这个脚本存放在/usr/local/bin下或者你习惯放置的位置,起名cgiwrap-fcgi.pl,当然你也可以使用其他的名字。当执行这个pl脚本的时候会在/usr/local/nginx/logs/生成一个cgi.sock文件,这个生成的文件要对nginx运行用户有访问的权限,因为我nginx用daemon这个用户跑的,所以我设置这个文件对daemon用户有访问的权限。

这个脚本设置好了之后再来看下nginx里的配置

location ~\.cgi$ {
         rewrite ^/nagios/cgi-bin/(.*)\.cgi /$1.cgi break;
         fastcgi_pass unix:/usr/local/nginx/logs/cgi.sock;
         fastcgi_param  SCRIPT_FILENAME  /usr/local/nagios/sbin/$fastcgi_script_name;
         include        fastcgi_params; 
         fastcgi_index  index.cgi;
         auth_basic      "nagios";
        auth_basic_user_file    /usr/local/nagios/etc/htpasswd.users; 
         }

location /nagios/ { 
         alias /usr/local/nagios/share/; 
         index index.html; 
         auth_basic      "nagios"; 
        auth_basic_user_file    /usr/local/nagios/etc/htpasswd.users; 
         }

location /pub/images/ {
                        alias /usr/local/nagios/share/docs/images/; 
         auth_basic      "nagios";
            auth_basic_user_file    /usr/local/nagios/etc/htpasswd.users; 
         }

接下来就是需要生成nagios执行cgi的用户和设置密码

/usr/local/apache2/bin/htpasswd -c /usr/local/nginx/conf/htpasswd.users nagiosadmin

接下来修改/usr/local/nagios/etc/cgi.cfg文件,在其中找到#default_user_name=guest这行,将其改为default_user_name=nagiosadmin,到此迁移工作就已经完成了,下面来启动相应的程序来测试吧,再次我写了一个nginx的启动脚本,内容如下

#!/bin/sh

spswfile=/usr/local/php529/bin/spawn-fcgi
phpcgi=/usr/local/php529/bin/php-cgi
nginxfile=/usr/local/nginx/sbin/nginx
cgifile=/usr/local/bin/cgiwrap-fcgi.pl

isrun() {
    if
        (ps auxf|grep nginx|grep -v grep >/dev/null 2>&1) && (ps auxf|grep php-cgi|grep -v grep >/dev/null 2>&1)
    then
        return 0
    else
        return 1
    fi
}

nginx_start() {
    if isrun
    then
        echo "nginx already start"
        exit 0
    else
        killall -9 php-cgi >/dev/null 2>&1
        killall -9 nginx >/dev/null 2>&1
                killall -9 perl >/dev/null 2>&1
        $spswfile -a 127.0.0.1 -p 9000 -f $phpcgi >/dev/null 2>&1
                /usr/bin/perl $cgifile >/dev/null 2>&1 &
        $nginxfile >/dev/null 2>&1
                sleep 10
                /bin/chown daemon /usr/local/nginx/logs/cgi.sock
    fi
}

nginx_stop() {
        killall -9 php-cgi >/dev/null 2>&1
        killall -9 nginx >/dev/null 2>&1
                killall -9 perl >/dev/null 2>&1
        rm -rf /usr/local/nginx/logs/nginx.pid
}

case $1 in
    start)      nginx_start;;
    stop)       nginx_stop;;
    restart)    nginx_stop
                nginx_start
                ;;
    *)          echo "useage: {start|stop}";;
esac

这样只需要执行这个脚本就可以启动fastcgi和cgi及nginx了,接下来就可以进行真正的测试了

以上文章参考了:

http://wiki.nginx.org/NginxSimpleCGI
http://www.lazysa.com/2009/05/392.html

另外有一点需要注意的就是cgi.cfg的修改,网上很多文章都没有提到,就是我上面写的那个是有默认用户的,如果那个不做修改的话,访问nagios的主机和服务的时候都显示如下,更改之后就没有问题了

无权查看任何主机的信息…
请检查HTTP服务器关于该CGI的访问权限设置。

 

 

阅读全文

今天搭建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参数是


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

阅读全文

昨天有人在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/

阅读全文