虚拟主机的 DocumentRoot 重写上的通配符

虚拟主机的 DocumentRoot 重写上的通配符

我在 apache2 中对通配符子域名使用这个配置,效果很好:

 <VirtualHost _default_:80>
   UseCanonicalName off
   Options FollowSymLinks
   VirtualDocumentRoot /var/www/domains/%0/httpdocs

    RewriteEngine On

    RewriteCond   %{HTTP_HOST}      ^\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b
    RewriteRule   ^(.+)             /var/www/domains/localhost/httpdocs/$1 [L]

    RewriteCond   %{HTTP_HOST}      !^[^.]+\.abc\.net [NC]
    RewriteCond   %{HTTP_HOST}      !^[^.]+\.example\.me [NC]
    RewriteCond   %{HTTP_HOST}      !^[^.]+\.mysite\.info [NC]
    RewriteCond   %{HTTP_HOST}      !^[^.]+\.xyz\.org [NC]
    RewriteCond   %{HTTP_HOST}      !\.internal$ [NC]
    RewriteCond   %{REQUEST_URI}    !^/collateral/ [NC]

    RewriteRule   ^(.+)             /var/www/domains/%{HTTP_HOST}/httpdocs/%{HTTP_HOST}/$1
    ErrorDocument 403 /error/404.php

这意味着请求“http://sub.abc.net“将获取 documentroot “/var/www/domains/sub.abc.net/httpdocs” 并请求“http://sub.xyz.org“将获取文档根目录“/var/www/domains/sub.xyz.org/httpdocs”。

但我希望将对 *.abc.net 的请求重写为 *.xyz.org documentroot。

答案1

我们需要任何.org域名都重定向到.net域名 documentroot

我认为你的意思是“重写”,而不是外部“重定向”,就像您问题中的代码一样?(您还反转了所需重写的方向,如您的问题所述,但无论如何,我会按照您在评论中所述.......org转到`.net)

这假设您只有单级 TLD,如代码中引用的(例如,,,,.net等),而不是多级“TLD”,例如。.me.info.org.co.uk

RewriteCond   %{HTTP_HOST}      !^[^.]+\.abc\.net [NC]
RewriteCond   %{HTTP_HOST}      !^[^.]+\.example\.me [NC]
RewriteCond   %{HTTP_HOST}      !^[^.]+\.mysite\.info [NC]
RewriteCond   %{HTTP_HOST}      !^[^.]+\.xyz\.org [NC]
RewriteCond   %{HTTP_HOST}      !\.internal$ [NC]
RewriteCond   %{REQUEST_URI}    !^/collateral/ [NC]
RewriteRule   ^(.+)             /var/www/domains/%{HTTP_HOST}/httpdocs/%{HTTP_HOST}/$1

请尝试以下类似操作:

# If any of these domains are requested then stop
RewriteCond %{HTTP_HOST}      ^[^.]+\.abc\.net [NC,OR]
RewriteCond %{HTTP_HOST}      ^[^.]+\.example\.me [NC,OR]
RewriteCond %{HTTP_HOST}      ^[^.]+\.mysite\.info [NC,OR]
RewriteCond %{HTTP_HOST}      ^[^.]+\.xyz\.org [NC,OR]
RewriteCond %{HTTP_HOST}      \.internal$ [NC,OR]
RewriteCond %{REQUEST_URI}    ^/collateral/ [NC]
RewriteRule ^ - [L]

# Split the requested host into HOSTNAME + TLD (env vars)
RewriteCond %{HTTP_HOST} ^([^.]+\.[^.]+)\.([^.]+)
RewriteRule ^ - [E=HOSTNAME:%1,E=TLD:%2]

# Change TLD "org" to "net"
RewriteCond %{ENV:TLD} =org [NC]
RewriteRule ^ - [E=TLD:net]

RewriteRule (.+) /var/www/domains/%{ENV:HOSTNAME}.%{ENV:TLD}/httpdocs/%{ENV:HOSTNAME}.%{ENV:TLD}/$1 [L]

第一组指令会反转您当前的条件。即,它表示如果请求针对的是“这些域”中的任何一个,则停止处理,而不是……仅在请求确实发生时才重写不是匹配任何“这些域”。这使得以下规则更简单,因为我们现在知道请求的主机是我们想要重写的主机,所以我们不需要在代码中乱加更多条件。

然后我们将请求拆分HTTP_HOST主机名(子域名 + 域名)和顶级域名仅。并将它们分别存储在两个环境变量中:HOSTNAMETLD

然后,我们测试TLD环境变量,并在必要时进行更改(即orgnet

最后,无条件重写到相应的文档根目录和子目录(使用上面分配的环境变量),如您的代码所示。请注意,您在描述中只提到了“文档根目录”,但您的代码还包括一个同名的子目录,因此我也包含了该子目录。

这假设您问题中所述的 mod_rewrite 指令是完整的。即配置中没有其他依赖指令?我添加了标志L以防万一。

相关内容