虚拟主机强制 https 并将 www 重定向到非 www,但没有其他子域

Jac*_*son 4 apache .htaccess mod-rewrite redirect

这本质上与htaccess force https 并将 www 重定向到非 www,但没有其他子域(即,我想配置 Apache 以将所有非 HTTPS和/或“www” URL重定向到 HTTPS 非 www URL 的问题相同) ,但我想通过虚拟主机而不是.htaccess文件来配置 Apache (因为我读到了避免.htaccess有一些好处)。

使用.htaccess文件时,我能够得到以下答案:https : //stackoverflow.com/a/34333450/1468130但是当我尝试将该答案的配置传输到我的虚拟主机配置时它不起作用;“ https://www.domain.com ” 从未重定向到“ https://domain.com ” ”。

我阅读了.htaccess虚拟主机.conf文件和虚拟主机文件之间的差异,并找到了这个http://tltech.com/info/rewriterule-in-htaccess-vs-httpd-conf/和这个:https : //www.digitalocean.com/ community/questions/can-you-use-virtual-host-config-conf-to-redirect-www-domain-to-non-www?answer=15129这似乎暗示我可以将配置包装在一个<Directory>块中它会工作。不幸的是,它没有(“ https://www.domain.com ”仍然从未重定向到“ https://domain.com ”),所以我想知道互联网是否知道我做错了什么:

<VirtualHost *:80>
        ServerName domain.com
        ServerAlias www.domain.com

        ServerAdmin admin@domain.com
        DocumentRoot /var/www/domain.com/

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        <Directory /var/www/domain.com/>
                RewriteEngine On

                # match any URL with www and rewrite it to https without the www
                RewriteCond %{HTTP_HOST} ^(www\.)(.*) [NC]
                RewriteRule (.*) https://%2%{REQUEST_URI} [L,R=301]

                # match urls that are non https (without the www)
                RewriteCond %{HTTPS} off
                RewriteCond %{HTTP_HOST} !^(www\.)(.*) [NC]
                RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
        </Directory>
</VirtualHost>
Run Code Online (Sandbox Code Playgroud)

我也试过<VirtualHost *:443>按照 Dusan Bajic 在评论中的建议进行配置,但这也没有效果;https://www.domain.com仍然不会重定向到https://domain.com

<VirtualHost *:443>
        ServerName domain.com
        ServerAlias www.domain.com

        ServerAdmin admin@domain.com
        DocumentRoot /var/www/domain.com/

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        SSLCertificateFile /etc/letsencrypt/live/domain.com/cert.pem
        SSLCertificateKeyFile /etc/letsencrypt/live/domain.com/privkey.pem
        Include /etc/letsencrypt/options-ssl-apache.conf
        SSLCertificateChainFile /etc/letsencrypt/live/domain.com/chain.pem

        <Directory /var/www/domain.com/>
                RewriteEngine On

                # match any URL with www and rewrite it to https without the www
                RewriteCond %{HTTP_HOST} ^(www\.)(.*) [NC]
                RewriteRule (.*) https://%2%{REQUEST_URI} [L,R=301]
        </Directory>
</VirtualHost>
Run Code Online (Sandbox Code Playgroud)

同样根据评论,我尝试将上述配置与块更改为仅将 HTTP 重定向到 HTTPS 的*:443配置配对。但是当我这样做时,“www”永远不会被删除。*:80<Directory>

<Directory /var/www/paradoxmayhem.com/>
        RewriteEngine On

        RewriteCond %{SERVER_NAME} =www.paradoxmayhem.com [OR]
        RewriteCond %{SERVER_NAME} =paradoxmayhem.com
        RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,QSA,R=permanent]
</Directory>
Run Code Online (Sandbox Code Playgroud)

Jac*_*son 6

知道了!显然,当我使用 letencrypt (certbot) 配置 SSL 时,它会自动创建另一个虚拟主机文件 (at /etc/apache2/sites-enabled/domain.com-le-ssl.conf),该文件对domain.com *:443虚拟主机有自己的定义,并且似乎优先于*:443我尝试设置的任何配置前。我将以下代码添加到-le-ssl.conf文件中,现在我的重定向终于可以在我想要的所有情况下工作,使用 100% Apache 虚拟主机配置:

<Directory /var/www/domain.com/>
        RewriteEngine On

        # match any URL with www and rewrite it to https without the www
        RewriteCond %{HTTP_HOST} ^(www\.)(.*) [NC]
        RewriteRule (.*) https://%2%{REQUEST_URI} [L,R=301]
</Directory>
Run Code Online (Sandbox Code Playgroud)

  • 哈!我在使用domain.com-le-ssl.conf(它在端口80中添加了一个条目??)进行letterscrypt处理时遇到了最奇怪的问题,该问题使一个子域路由(在许多站点和域中)托管在同一IP上地址不会重定向到 https。您的问题/答案给了我正确方向的提示/推动。谢谢你! (2认同)