如何设置大规模虚拟主机使用Apache2 + mod_rewrite + mod_userdir + mod_suexec在CentOS 5.3

如何使用Apache2 + mod_rewrite + mod_userdir + mod_suexec设置大容量虚拟主机在CentOS 5.3

版本:1.2
最后编辑:2009年7月7日

这个howto显示了使用mod_rewrite进行大量虚拟主机的一种方法来动态地将文件系统上的目录列表映射到虚拟主机。 另外,通过将传入的URL重写到用户的主目录,我们可以使用suEXEC来使Apache执行CGI脚本作为脚本的所有者。

注意:此配置尚未在生产环境中测试。

在我们开始之前

使用Centos 5.3作为操作系统平台。

为了说明的目的,我假设www.example.com存在,并指向我们的Web服务器IP 192.168.1.1。 example.com的webroot位于/home/vhosts/example.com/public_html

Apache2

安装Apache:

yum install httpd

(Centos httpd包包含mod_rewrite + mod_userdir + mod_suexec)

配置大容量虚拟主机

vim /etc/httpd/conf/httpd.conf

在顶部添加以下内容:

LoadModule rewrite_module modules/mod_rewrite.so

在文件的底部添加以下内容:

## get the server name from the Host: header
UseCanonicalName Off


## splittable logs
LogFormat "%{Host}i %h %l %u %t \"%r\" %s %b" vcommon
CustomLog logs/access_log vcommon


RewriteEngine On


## Create a handle to convert upper or mixed-case to lower-case
RewriteMap lowercase int:tolower


##-----------------------------------
## where hostname has www prefix
##-----------------------------------
## Firstly create custom variable that contains the host without the www prefix
RewriteCond %{HTTP_HOST} ^www\.(.*)$ 
RewriteRule .? - [E=noWWWHost:%1]


## Map the virtualhost to the documentroot
RewriteCond %{REQUEST_URI} !^/~
RewriteCond %{HTTP_HOST} ^www\. 
RewriteRule ^/(.*)$ /home/vhosts/${lowercase:%{ENV:noWWWHost}}/public_html/$1


##-----------------------------------
## where hostname *does not* have www prefix
##-----------------------------------
## Map the virtualhost to the documentroot
RewriteCond %{REQUEST_URI} !^/~
RewriteCond %{HTTP_HOST} !^www\. 
RewriteRule ^/(.*)$ /home/vhosts/${lowercase:%{HTTP_HOST}}/public_html/$1

有关上述配置的一些注意事项:

  • 我们的网站位于/ home / vhosts - 每个子文件夹是网站的域名(不含www前缀),例如/home/vhosts/example.com
  • 如果一个请求访问www.example.com的服务器,它将被动态地重写到example.com
  • documentroot目录是“public_html” - 这个名称是suEXEC所必需的,我们稍后会看到。 如果你不打算使用suEXEC,那么你做这个任何你喜欢的,并相应地更新重写器。

在虚拟主机的public_html中创建index.html:

echo "index.html Hello World" > /home/vhosts/example.com/public_html/index.html

启动Apache:

/etc/init.d/httpd start

现在浏览http://www.example.com/应该会显示“index.html Hello World”。 如果没有发生这种情况,请检查Apache错误日志:

tail /var/log/httpd/error_log

使用suEXEC + mod_userdir执行我们的CGI脚本

由于这是一个共享的网络托管平台,与许多不同的用户和网站,我们希望执行CGI脚本作为网站的所有者,而不是网络服务器进程。 suEXEC允许我们这样做a)静态使用virtualhost config或b)动态使用mod_userdir。

首先,每个网站必须由与该网站的域名相同的用户拥有。 例如网站example.com

useradd -d /home/vhosts/example.com example.com

这将创建一个用户example.com ,其主目录是/home/vhosts/example.com 。 www.example.com的所有网络文件将进入/home/vhosts/example.com/public_html

您可以将每个用户手动添加到/ etc / passwd中,也可以设置主机以查找LDAP目录以获取帐户信息。

启用mod_userdir:

vim /etc/httpd/conf/httpd.conf

确保您的配置中出现以下行:

LoadModule userdir_module modules/mod_userdir.so


<IfModule mod_userdir.c>
    UserDir public_html
</IfModule>

现在,当我们使用http://192.168.1.1/~example.com从 Web服务器请求一个页面时,Apache将在home目录中查找public_html目录的用户名example.com。 这本身不是很有用,因为我们不希望人们在他们的URL中使用〜/位。 相反,我们将默认地将www.example.com上的URL重写为http://192.168.1.1/~example.com

对于每个页面,不需要进行此特殊的重写 - 仅适用于要在suEXEC下运行的CGI脚本。 其他页面将被较早的重写规则处理。

编辑/etc/httpd/conf/httpd.conf 。 在现有的重写规则下,插入以下内容:

## Rewrite script to userdir so we can use suEXEC
RewriteCond %{REQUEST_URI} !^/~
RewriteCond %{SCRIPT_FILENAME} /home/vhosts/(.*)/public_html/(.*\.(pl|cgi))
RewriteRule .* /~%1/%2 [PT,L]


<Directory /home/vhosts/*/public_html>
	AddHandler cgi-script .pl .cgi
	Options +ExecCGI
</Directory>

重新加载Apache配置:

/etc/init.d/httpd reload

在虚拟主机的public_html中创建Perl脚本test.pl ,内容如下:

#!/usr/bin/perl
print "Content-type: text/html\n\n";
print "<H1>test.pl Hello World</H1>\n";

给脚本执行权限并将所有权更改为正确的用户:

chmod +x test.pl
chown example.com:example.com test.pl

现在,浏览到http://www.example.com/test.pl应该会显示“test.pl Hello World”。 如果没有发生这种情况,请检查以下日志文​​件:

tail /var/log/httpd/error_log
tail /var/log/httpd/suexec.log

PHP + Python

扩展suEXEC处理包括PHP和Python(或任何其他)很简单。 首先,确保安装php-clipython包及其依赖项:

yum install php-cli
yum install python

public_html文件夹中创建几个“hello world”脚本,如下所示:

test.py

#!/usr/bin/python

print "Content-type: text/html\n\n"
print "test.py Hello world!"

test.php

#!/usr/bin/php-cgi

<?
echo "test.php Hello world!";
?>

选择要由正确用户拥有的文件,并使用chmod + x设置可执行位。

注意:每个脚本需要在第一行指定解释器,例如#!/ usr / bin / python 。 为避免每个文件必须这样做,您可以执行以下操作:

echo ":PHP:E::php::/usr/bin/php-cgi:" > /proc/sys/fs/binfmt_misc/register
echo ":Python:E::py::/usr/bin/python:" > /proc/sys/fs/binfmt_misc/register

现在修改Apache配置,以.php.py扩展名重写文件请求。 我们还需要将这些扩展添加到cgi-script的处理程序

/etc/httpd/conf/httpd.conf

## Rewrite script to userdir so we can use suEXEC
RewriteCond %{REQUEST_URI} !^/~
RewriteCond %{SCRIPT_FILENAME} /home/vhosts/(.*)/public_html/(.*\.(pl|cgi|php|py))
RewriteRule .* /~%1/%2 [PT,L]


<Directory /home/vhosts/*/public_html>
	AddHandler cgi-script .pl .cgi .php .py
	Options +ExecCGI
</Directory>

PHP注意:/etc/php.ini中设置cgi.force_redirect = 0以避免CGI REDIRECT_STATUS错误

重新加载Apache配置:

/etc/init.d/httpd reload

现在,浏览http://www.example.com/test.pyhttp://www.example.com/test.php应该会显示“Hello World”。 如果没有发生这种情况,请检查以下日志文​​件:

tail /var/log/httpd/error_log
tail /var/log/httpd/suexec.log

Catchall

如果您想要将不存在的虚拟主机的请求定向到一个全部站点,请将其作为/etc/httpd/conf/httpd.conf中最后一个重写规则:

## Redirect non-existent virtualhosts
RewriteCond %{REQUEST_URI} !^/~
RewriteCond %{SCRIPT_FILENAME} (/home/vhosts/.*)/public_html/.*
RewriteCond %1 !-d
RewriteRule .? http://www.google.com [R,NS,L]
赞(52) 打赏
未经允许不得转载:优客志 » 系统运维
分享到:

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏