通用的大規模虛擬主機配置會導致每個虛擬主機請求出現 404 狀態代碼

通用的大規模虛擬主機配置會導致每個虛擬主機請求出現 404 狀態代碼

我正在嘗試使用 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 -tapachectl -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.comexample.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

相關內容