一般的な大規模な vhost 構成により、すべての vhost リクエストで 404 ステータス コードが返される

一般的な大規模な vhost 構成により、すべての vhost リクエストで 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>

しかし、汎用 vhost セットアップの行を追加すると、Web サーバーはすべての vhost (サブドメイン) 要求に対して 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 のドキュメントで、フォルダー名のマジック文字列リテラルの説明を見つけました。Apache 2.4 の Apache のバージョン 2.4 より前のバージョンでは、Apache 2.4 は vhost エイリアスをサポートしていませんでした。 しかし、問題は解決するどころか、ますます混乱してしまいます...

Web サーバーは openSUSE 42.2 最小限で実行されます。すでに示唆されているように、実際のドメイン名はここで に変更されますexample.com。この問題に関するご助力は大歓迎です。

編集: 最初の回答に対するコメントでも述べたように、RewriteRulevhost 構成に必ずしも何も必要としないソリューションが必要です。使用している 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

編集:

でリダイレクトを実行したくない場合は、vhost 構成にリダイレクトを配置できます.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 を使用しています。これは、/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

関連情報