我正在尝试使用 ServerAlias 设置具有大量子域的 apache 2.4 服务器。主域的基本配置工作得很好(主域 => 200,所有子域 => 404):
UseCanonicalName Off
<VirtualHost example.com>
ServerName example.com
ServerAlias www.example.com
VirtualDocumentRoot "/var/www/vhosts/example.com/httpdocs"
DirectoryIndex index.php index.html
<Directory />
Options +Indexes +FollowSymLinks +Includes
<IfModule !mod_access_compat.c>
Require all granted
</IfModule>
<IfModule mod_access_compat.c>
Order allow,deny
Allow from all
</IfModule>
AllowOverride All
</Directory>
</VirtualHost>
但是,当我为通用虚拟主机设置添加行时,Web 服务器会在每个虚拟主机(子域)请求上返回 404 状态代码:
UseCanonicalName Off
<VirtualHost example.com>
ServerName example.com
ServerAlias www.example.com
VirtualDocumentRoot "/var/www/vhosts/example.com/httpdocs"
DirectoryIndex index.php index.html
ServerAlias *.example.com
VirtualDocumentRoot "/var/www/vhosts/example.com/%1.0"
DirectoryIndex index.php index.html
<Directory />
Options +Indexes +FollowSymLinks +Includes
<IfModule !mod_access_compat.c>
Require all granted
</IfModule>
<IfModule mod_access_compat.c>
Order allow,deny
Allow from all
</IfModule>
AllowOverride All
</Directory>
</VirtualHost>
我认为它必须对正确的文件夹路径做一些事情。文件夹路径始终如下所示:
/var/www/vhosts/maindomain.com/subdomain.maindomain.com
我需要的只是一个与主域和与之关联的通用子域相匹配的配置。所以,
www.example.com
example.com
匹配文件夹路径:
/var/www/vhosts/example.com/httpdocs
和
ci.example.com
tracker.example.com
other.example.com
应与其文件夹路径匹配,如下所示:
/var/www/vhosts/example.com/ci.example.com
/var/www/vhosts/example.com/tracker.example.com
/var/www/vhosts/example.com/other.example.com
另外,由于某种奇怪的原因,如果我将其更改为%0.0
子域路径,则子域可以工作,但主域却不能。因此,使用它时,情况正好相反。主域 => 404,所有子域 => 200。
我在 apache 2.4 文档中找到了文件夹名称的魔术字符串文字的解释:http://httpd.apache.org/docs/2.4/mod/mod_vhost_alias.html 但它并没有解决我的问题,反而让我越来越困惑......
Web 服务器在 openSUSE 42.2 最低版本下运行。正如您可能已经建议的那样,此处的真实域名已更改为example.com
.对这个问题的任何帮助都会很棒。
编辑:正如我在下面对第一个答案的评论中所说,我需要一个解决方案,不一定需要RewriteRule
虚拟主机配置中的任何解决方案。因为我使用的是 php 系统,它们确实有自己的(有时非常复杂)RewriteRule
,所以我不想因为这些.htaccess
东西而陷入麻烦。但除此之外的任何其他选择cgi
都是可能的。是的,符号链接支持已启用(或可以启用)。
编辑:
符号链接示例帮助我了解了基本概念。经过一番反思,我想到了下面这个解决方案。第一个发现的规则始终适用,所以它对我有用:
UseCanonicalName Off
<VirtualHost *:80>
DocumentRoot "/var/www/vhosts/example.com/httpdocs"
ServerName www.example.com
ServerAlias example.com
<Directory />
Options Indexes FollowSymLinks Includes ExecCGI
AllowOverride All
Require all granted
Allow from all
</Directory>
</VirtualHost>
<VirtualHost *:80>
DocumentRoot "/var/www/vhosts/example.com/httpdocs"
ServerName example.com
ServerAlias *.example.com
VirtualDocumentRoot "/var/www/vhosts/example.com/%1"
<Directory />
Options Indexes FollowSymLinks Includes ExecCGI
AllowOverride All
Require all granted
Allow from all
</Directory>
</VirtualHost>
apachectl -t
并apachectl -S
说这没关系。测试并有效! :-)
答案1
尝试
<VirtualHost *:80>
ServerName example.com
DocumentRoot /var/www/vhosts/example.com/httpdocs
ServerAlias *.example.com
VirtualDocumentRoot /var/www/vhosts/example.com/%0
</VirtualHost>
这显然不包括整个配置,但它应该使您的通配符子域正常工作。
接下来,我会将所有请求重定向www.example.com
到example.com
。最简单的方法可能是使用 htaccess 文件/var/www/vhosts/example.com/www.example.com
或者,如果您打开了符号链接,则可以符号链接/var/www/vhosts/example.com/www.example.com
到/var/www/vhosts/example.com/httpdocs
编辑:
如果您不想在.htaccess
.尝试这个:
<VirtualHost *:80>
ServerName example.com
DocumentRoot /var/www/vhosts/example.com/httpdocs
ServerAlias *.example.com
VirtualDocumentRoot /var/www/vhosts/example.com/%0
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www.example.com
RewriteRule ^/(.*)$ http://example.com/$1 [L,R=301]
</VirtualHost>
我不知道有什么方法可以在没有某种重定向的情况下做到这一点。另外,将非 www 重定向到 www 或将 www 重定向到非 www 是一种很好的做法。如果您打算进行任何 SEO 工作,那么拥有与您的网站本质上重复的内容将会是一种损害。
答案2
我为自己写了一个脚本 - 这对我有用:)
但在阅读我的脚本之前 - 我给你的提示是不要使用
<VirtualHost example.com>
....
</VirtualHost>
而是使用:<VirtualHost *:80>
或<VirtualHost *>
来开始您的 VirtualHost 条目。
注意:我主要在 AIX 上工作 - 所以我使用 ksh 作为 shell。这应该适用于 /bin/sh 或 /bin/bash。
Syntax:
vhost.ksh <ServrName> [ServerAlias1] [... ServerAliasN]
#!/usr/bin/ksh
# Copyright AIXTOOLS.NET, 2014
# This script creates a vhost template
# under the assumption that the site might be served by multiple hosts
# the logs are put into a sub-directory
# ${SITEroot}/logs/LOGNAME.$host
site=$1
shift
alias=$*
HOST=`hostname -s`
SITE=/var/httpd/${site}
LOGDIR=${SITE}/logs
cat -<<EOF1
# AIXTOOLS.NET vhost.ksh output
# VirtualHost template for ${site}
# SITEBASE=${SITE}
# LOGDIR=${LOGDIR}
<VirtualHost *:80>
ServerName ${site}
EOF1
for name in ${alias}
do
print " ServerAlias ${name}"
done
cat - <<EOF2
DocumentRoot "${SITE}/htdocs"
<Directory "/var/httpd/${site}/htdocs">
Options Indexes FollowSymLinks Includes
AllowOverride All
Order allow,deny
Allow from all
</Directory>
#Logs for ${site}
# combined is chosen as default to support awstats reporting
CustomLog "${LOGDIR}/access_log.${HOST}" combined
# ErrorLog "${LOGDIR}/error_log.${HOST}"
# You can consider using different "localN" syslogs to split different vhosts
# should you need that
ErrorLog syslog:user
# LogLevel alert rewrite:trace3
# LogLevel alert
# RewriteLog "/var/httpd/${site}/logs/rewrite.log"
# RewriteLogLevel 0
</VirtualHost>
EOF2