如何使用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-cli
和python
包及其依赖项:
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.py
或http://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]