【问题标题】:Redirect HTTP to HTTPS on default virtual host without ServerName在没有 ServerName 的默认虚拟主机上将 HTTP 重定向到 HTTPS
【发布时间】:2012-07-22 04:36:18
【问题描述】:

在我的 apache 服务器上,我希望能够将所有传入的 http 请求重定向到等效的 https 请求。问题是我希望能够在不指定ServerName 的情况下为我的默认虚拟主机执行此操作,并让重定向与请求 url 中出现的任何服务器名称一起工作。我希望是这样的:

NameVirtualHost *:80
<VirtualHost *:80>
    RedirectPermanent / https://%{SERVER_NAME}/
    ...
</VirtualHost>

这可以使用Redirect 还是我必须求助于Rewrite

【问题讨论】:

    标签: apache http redirect https


    【解决方案1】:

    尝试将其添加到您的虚拟主机配置中:

    RewriteEngine On
    RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]
    

    【讨论】:

    • * 您可能需要添加 mod_rewrite。对于基于 ubuntu 或 debian 的主机,以下内容将起作用:sudo a2enmod rewrite 这将停止任何 configtest / apache2 配置错误。 (如果您使用上面提供的虚拟主机添加,库存设置将收到)
    • 这仅适用于主域(例如http://mywebiste.com -> https://mywebiste.com)如果我也有子域(http://blog.mywebiste.com->https://blog.mywebiste.com)怎么办?
    • 您可能需要在 RewriteEngine On 之后添加 RewriteCond %{HTTPS} off 否则您可能会得到 ERR_TOO_MANY_REDIRECTS
    • 小错字。缺少斜线,rewriteRule 应该是https://%{HTTP_HOST}/$1 [R=301,L]
    • @Dunatotatos 在 vhost 中,URI 包含前导 /,但在 htaccess 文件中,/ 前缀被删除。如果规则在 htaccess 文件中,我们确实需要在 / 之前添加 $1
    【解决方案2】:

    两者都可以正常工作。但是根据Apache docs,您应该避免使用mod_rewrite 进行简单的重定向,而是使用Redirect。所以根据他们的说法,你最好这样做:

    <VirtualHost *:80>
        ServerName www.example.com
        Redirect / https://www.example.com/
    </VirtualHost>
    
    <VirtualHost *:443>
        ServerName www.example.com
        # ... SSL configuration goes here
    </VirtualHost>
    

    Redirect之后的第一个/是url,第二部分是应该重定向的地方。

    您还可以使用它将 URL 重定向到子域: Redirect /one/ http://one.example.com/

    【讨论】:

    • 这不回答不指定服务器名称部分问题
    • 这适用于我的设置。也不要忘记尾部斜杠,否则它不会正确重定向到子文件夹
    • 谢谢,非常有帮助,而且不那么复杂。
    • 如果你想将example.com重定向到example.com,别忘了把SSL配置放入VirtualHost: ServerName example.com SSLEngine on SSLCertificateFile ... SSLCertificateKeyFile ...重定向永久/example.com 否则它将通过默认的 443 虚拟主机重定向,但 SSL 证书不正确。也不要忘记尾部的斜杠,否则它不会正确地重定向到子文件夹(如 vdidxho 所言。)
    【解决方案3】:

    这也是省略不需要的重定向的完整方法;)

    这些规则旨在用于 .htaccess 文件,因为 *:80 VirtualHost 条目中的 RewriteRule 不需要条件。

    RewriteEngine on
    RewriteCond %{HTTPS} off [OR] 
    RewriteCond %{HTTP:X-Forwarded-Proto} !https
    RewriteRule ^/(.*) https://%{HTTP_HOST}/$1 [NC,R=301,L]
    

    说明

    RewriteEngine on
    

    ==> 完全启用引擎

    RewriteCond %{HTTPS} off [OR]
    

    ==> 匹配 非 https 连接,或者(不设置 [OR] 会导致隐式 AND !)

    RewriteCond %{HTTP:X-Forwarded-Proto} !https
    

    ==> 匹配转发连接(代理、负载均衡器等)没有 https

    RewriteRule ^/(.*) https://%{HTTP_HOST}/$1 [NC,R=301,L]
    

    ==> 如果两个条件之一匹配,则重写整个 URL,发送 301 以让客户端“了解”此内容(有些可以,有些不可以),最后一条规则的 L。

    【讨论】:

    • 另一个问题,你的RewriteRule 可能永远不会匹配;很确定你想删除斜线:​​RewriteRule ^(.*) …
    • 我肯定不会。您错过了目标的 / 语法,包括“L”标志。另一种方法是像 Jon Lin 那样做。
    • 在这种情况下,RewriteCond 完全是多余的;由于 VirtualHost 已经定义为 &lt;VirtualHost *:80&gt;%{SERVER_PORT} 永远不会是 443,所以条件总是匹配的。
    • * 您可能需要添加 mod_rewrite。对于基于 ubuntu 或 debian 的主机,以下内容将起作用:sudo a2enmod rewrite 这将停止任何 configtest / apache2 配置错误。 (如果您使用上面提供的虚拟主机添加,库存设置将收到)
    【解决方案4】:

    我已经使用 mkcert 创建无限的 *.dev.net 子域和具有有效 HTTPS/SSL 证书的本地主机(Windows 10 XAMPP 和 Linux Debian 10 Apache2)

    我在 Windows 上使用 mkcert v1.4.0 创建证书(以管理员身份执行 CMD):

    mkcert -install
    mkcert localhost "*.dev.net"
    

    这将在 Windows 10 中创建此文件(我将首先在 Windows 10 XAMPP 中安装它)

    localhost+1.pem
    localhost+1-key.pem
    

    覆盖 XAMPP 默认证书:

    copy "localhost+1.pem" C:\xampp\apache\conf\ssl.crt\server.crt
    copy "localhost+1-key.pem"  C:\xampp\apache\conf\ssl.key\server.key
    

    现在,在 Apache2 for Debian 10 中,激活 SSL 和 vhost_alias

    a2enmod vhosts_alias
    a2enmod ssl
    a2ensite default-ssl
    systemctl restart apache2
    

    对于 vhost_alias 添加这个 Apache2 配置:

    nano /etc/apache2/sites-available/999-vhosts_alias.conf
    

    有了这个内容:

    <VirtualHost *:80>
       UseCanonicalName Off
       ServerAlias *.dev.net
       VirtualDocumentRoot "/var/www/html/%0/"
    </VirtualHost>
    

    添加网站:

    a2ensite 999-vhosts_alias
    

    通过 SSH 将证书复制到 /root/mkcert 并覆盖 Debian 的:

    systemctl stop apache2
    
    mv /etc/ssl/certs/ssl-cert-snakeoil.pem /etc/ssl/certs/ssl-cert-snakeoil.pem.bak
    mv /etc/ssl/private/ssl-cert-snakeoil.key /etc/ssl/private/ssl-cert-snakeoil.key.bak
    
    cp "localhost+1.pem" /etc/ssl/certs/ssl-cert-snakeoil.pem
    cp "localhost+1-key.pem" /etc/ssl/private/ssl-cert-snakeoil.key
    
    chown root:ssl-cert /etc/ssl/private/ssl-cert-snakeoil.key
    chmod 640 /etc/ssl/private/ssl-cert-snakeoil.key
    
    systemctl start apache2
    

    编辑 SSL 配置

    nano /etc/apache2/sites-enabled/default-ssl.conf
    

    在开始时使用以下内容编辑文件:

    <IfModule mod_ssl.c>
        <VirtualHost *:443>
    
                UseCanonicalName Off
                ServerAlias *.dev.net
                ServerAdmin webmaster@localhost
    
                # DocumentRoot /var/www/html/
                VirtualDocumentRoot /var/www/html/%0/
    

    ...

    上次重启:

    systemctl restart apache2
    

    注意:不要忘记在 /var/www/html/ 中为您的子域创建文件夹

    /var/www/html/subdomain1.dev.net
    /var/www/html/subdomain2.dev.net
    /var/www/html/subdomain3.dev.net
    

    【讨论】:

      猜你喜欢
      • 2016-07-16
      • 2018-03-23
      • 2017-04-08
      • 2019-08-13
      • 2017-06-04
      • 2010-10-06
      • 2012-08-18
      • 1970-01-01
      • 2018-10-12
      相关资源
      最近更新 更多