如何将所有服务器别名和 www 重定向到 .htaccess 中的 SSL 非 www

How to redirect all server aliases and www to SSL non www in .htaccess

正在寻找一种方法,使用 Apache VirtualHosts 和 .htaccess 将多个服务器别名(包括 www 和非 www)重定向到一个强制 SSL 的非 www 域。我已经搜索了一段时间并找到了几个解决方案,但它们都部分起作用。

情况如下,在我的.conf文件中我有一个虚拟主机指定如下:

<VirtualHost *:443>

        ServerName example.domain
        ServerAlias *.example.domain *.exampledomain.com exampledomain.com

        ...

</VirtualHost>
<VirtualHost *:80>

        ServerName example.domain
        ServerAlias *. example.domain *.exampledomain.com exampledomain.com

        RewriteEngine on

        RewriteCond %{SERVER_NAME} =www.example.domain [OR]
        RewriteCond %{SERVER_NAME} =example.domain
        RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]

</VirtualHost>

接下来,我的 .htaccess 中有以下内容:

        RewriteEngine On
        Options +FollowSymlinks

        RewriteBase /

        RewriteCond %{HTTPS} off
        RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

        RewriteCond %{HTTP_HOST} ^www.exampledomain.com$ [OR]
        RewriteCond %{HTTP_HOST} ^exampledomain.com$ [OR]
        RewriteCond %{HTTP_HOST} ^www\.example\.domain$
        RewriteRule ^(.*)$ https://example.domain/ [L,R=301]

结果如下:

http://example.domain/          -> https://example.domain/ - (correct)
http://www.example.domain/      -> https://example.domain/ - (correct)

http://exampledomain.com/       -> http://exampledomain.com/ - Forbidden, you dont have access...
http://www.exampledomain.com/   -> http://www.exampledomain.com/ - Forbidden, you dont have access...

https://exampledomain.com/      -> https://example.domain/ - (correct)
https://www.exampledomain.com/  -> https://www.exampledomain.com/ - Connection not secure

我真的搞不懂哪里出了问题,为什么有些重定向有效而有些无效。任何提示将不胜感激。

如果您有权访问 <VirtualHost>,那么您根本不需要(不应该)为此使用 .htaccess

如果目标是仅使用定义的两个虚拟主机在单个重定向中重定向到规范域 (+HTTPS),那么您只需要:

<VirtualHost *:443>
    ServerName example.domain
    ServerAlias *.example.domain *.exampledomain.com exampledomain.com

    RewriteEngine On

    # Redirect everything other than the canonical host to the canonical host
    RewriteCond %{HTTP_HOST} !=example\.domain
    RewriteRule ^ https://example.domain%{REQUEST_URI} [R=301,L]
</VirtualHost>

<VirtualHost *:80>
    ServerName example.domain
    ServerAlias *.example.domain *.exampledomain.com exampledomain.com

    # Unconditionally redirect everything to HTTPS + canonical host
    Redirect 301 / https://example.domain/
</VirtualHost>

mod_alias Redirect 指令是前缀匹配,匹配后的所有内容都附加到目标 URL 的末尾。因此,上面的 Redirect 指令将每个 URL 重定向到目标中的相同 URL。

您应该首先使用 302(临时)重定向进行测试,只有在确认其按预期工作后才更改为 301(永久)。您可能需要清除浏览器缓存,因为浏览器会永久缓存 301。


看看你的“成绩”:

http://exampledomain.com/       -> http://exampledomain.com/ - Forbidden, you dont have access...
http://www.exampledomain.com/   -> http://www.exampledomain.com/ - Forbidden, you dont have access...

vHost:80 容器中的当前 HTTP 到 HTTPS 重定向仅重定向 www.example.domainexample.domain,您可能不接受 vHost:80 容器中的请求,因此任何 HTTP 请求(未重定向到 HTTPS)都可能被阻止。

https://www.exampledomain.com/  -> https://www.exampledomain.com/ - Connection not secure

您的 SSL 证书需要涵盖所有域和所有别名,否则,您将(最多)收到浏览器 SSL 证书警告并且浏览器将拒绝连接到您的服务器(因此看不到重定向)。