代码之家  ›  专栏  ›  技术社区  ›  user979331

子域不支持HSTS

  •  0
  • user979331  · 技术社区  · 3 年前

    我正在使用Semrush,我有一个通知,它真的很困扰我,我想摆脱它。1子域不支持子域的HSTS: www.domain.com ,这是我的.htdocs文件:

    Options -Indexes
    
    <IfModule mod_rewrite.c>
        Options +FollowSymLinks
        RewriteEngine On
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule ^(.*)$ index.php/$1 [L]
        RewriteCond %{HTTPS} !=on
        RewriteCond %{HTTP_USER_AGENT} ^(.+)$
        RewriteCond %{SERVER_NAME} ^example\.com$
        RewriteRule .* https://www.%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
        Header add Strict-Transport-Security "max-age=300"
    </IfModule>
    <IfModule mod_headers.c>
        <If "%{REQUEST_SCHEME} == 'https' || %{HTTP:X-Forwarded-Proto} == 'https'">
            Header always set Strict-Transport-Security "max-age=31536000"
        </If>
    </IfModule>
    

    我在末尾添加此部分:

    <IfModule mod_headers.c>
            <If "%{REQUEST_SCHEME} == 'https' || %{HTTP:X-Forwarded-Proto} == 'https'">
                Header always set Strict-Transport-Security "max-age=31536000"
            </If>
        </IfModule>
    

    但还是什么都没有,我做错了什么?

    0 回复  |  直到 3 年前
        1
  •  2
  •   MrWhite    3 年前
    Options -Indexes
    
    <IfModule mod_rewrite.c>
        Options +FollowSymLinks
        RewriteEngine On
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule ^(.*)$ index.php/$1 [L]
        RewriteCond %{HTTPS} !=on
        RewriteCond %{HTTP_USER_AGENT} ^(.+)$
        RewriteCond %{SERVER_NAME} ^example\.com$
        RewriteRule .* https://www.%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
        Header add Strict-Transport-Security "max-age=300"
    </IfModule>
    <IfModule mod_headers.c>
        <If "%{REQUEST_SCHEME} == 'https' || %{HTTP:X-Forwarded-Proto} == 'https'">
            Header always set Strict-Transport-Security "max-age=31536000"
        </If>
    </IfModule>
    

    这里有许多问题会阻碍HSTS正常工作,并且应该进行一些额外的优化。

    1. 您没有重定向 http://www.example.com (即www子域)转换为HTTPS。您需要将HTTP+WWW重定向到HTTPS+WWW才能兼容HSTS。

    2. 您正在重定向 http://example.com/ (即HTTP+non-www)到HTTPS+www。为了符合HSTS,您需要重定向到 同一主机 第一即。 http://example.com/ https://example.com/ https://www.example.com (是的,这是两个重定向,但这种情况也很少见,每个用户代理最多只发生一次,因为返回的是STS头)。

    3. 你的指令顺序不对。您的规范重定向(即HTTP到HTTPS和非www到www)需要 之前 您的前控制器重写(第一条规则)。通过将它们放在前控制器之后,除了主页、目录和静态资源之外,它们永远不会被处理。如。 http://example.com/<some-url> 将永远不会被写入的规则重定向。不确定您是如何测试HSTS与SEMrush的合规性的,但与当时编写的指令一致 http://example.com/<一些url> 会失败,因为它没有重定向。

    4. 你应该删除第一个 Header 指令-这与第二个直接冲突(正确) 头球 指令。这个 always 条件(在第二个实例中使用)是必需的,以便将标头设置为 HTTPS 301将非www重定向(即非2xx响应)到www。

    5. 您应该包括 includeSubDomains 关于的指令 Strict-Transport-Security 以便在请求域顶点时覆盖www子域。虽然 全部的 子域现在将被隐式地包括在内。如果没有这一点,将需要显式地请求www子域。(好的,在下一个请求中,您将重定向到www。)

    6. 您应该删除 <IfModule> 包装物;它们不是必需的。这些指令是强制性的,不是 可选择的 (这些包装的存在暗示了这一点)。如果mod_rewrite不可用,您的网站可能会失败,并且您将不符合HSTS。

      看见 my answer 到Webmasters堆栈上的以下问题,了解有关此方面的更多信息:
      Is Checking for mod_rewrite Really Necessary?

    7. 我从前面的HTTP+non-www重定向中假设,您不在管理SSL的前端代理(或负载均衡器)后面,在这种情况下,检查 %{HTTP:X-Forwarded-Proto} 在后面 <If> 应删除表达式。如果您不是“代理”的幕后主使,则可以伪造请求以防止 STS 正在发送回的标头(用户应该无法执行此操作)。

      相反,如果您在“代理”后面,则检查 %{REQUEST_SCHEME} == 'https' 是多余的,但不会造成伤害。顺便说一句,的使用 REQUEST_SCHEME 假设您使用的是Apache 2.4+(我希望您使用的),但是,如果您仍使用Apache 2.2,则此检查将失败,并且不会设置STS标头。

    因此,考虑到以上几点 .htaccess 文件应该这样写:

    Options +FollowSymLinks -Indexes
    
    RewriteEngine On
    
    # Redirect HTTP to HTTPS on the same host (requirement of HSTS)
    RewriteCond %{HTTPS} !=on
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
    
    # Redirect non-www to www (HTTPS only)
    RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
    RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
    
    # Front-controller
    RewriteRule ^index\.php/ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule (.*) index.php/$1 [L]
    
    <If "%{REQUEST_SCHEME} == 'https'>
        # The "always" condition is required to set the header on the HTTPS redirect
        Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
    </If>
    

    附加说明:

    • 我用过 HTTP_HOST 而不是 SERVER_NAME 自从你 需要 请求中存在的主机名。默认情况下 服务器名称 与相同 HTTP_HOST ,但这可能因服务器配置而异。

    • 当请求中存在非空的用户代理字符串(恶意请求可能会抑制用户代理字符串)时,没有理由像最初那样只应用规范重定向,所以我已经删除了这个条件。如果有什么不同的话,你会阻止这样的请求。

    • 正则表达式 ^ 在中 RewriteRule 图案 .* 因为它只需要成功——实际上不需要 火柴 任何东西,因为它以后不会被使用。

    • 额外的 RewriteRule ^index\.php/ - [L] “前端控制器”之前的指令只是一种优化,以防止重写的URL不必要地通过随后的文件系统检查。

    参考/另请参阅:


    更新: 请尝试以下操作。由于您在AWS上,您可能需要检查 X-Forwarded-Proto HTTP请求标头而不是 HTTPS Apache服务器变量,以确定对客户端的请求是否安全。

    所需的更改是对HTTP到HTTPS重定向(第一条规则)和 <如果> 最后的表达式。

    Options +FollowSymLinks -Indexes
    
    RewriteEngine On
    
    # Redirect HTTP to HTTPS on the same host (requirement of HSTS)
    RewriteCond %{HTTP:X-Forwarded-Proto} =http
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
    
    # Redirect non-www to www (HTTPS only)
    RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
    RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
    
    # Front-controller
    RewriteRule ^index\.php/ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule (.*) index.php/$1 [L]
    
    <If "%{HTTP:X-Forwarded-Proto} == 'https'>
        # The "always" condition is required to set the header on the HTTPS redirect
        Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
    </If>
    
        2
  •  0
  •   milenmk    3 年前

    您是否尝试通过DNS记录和.vconfig文件修复此问题?对于我的网站,我有:

    1. 主域的DNS A记录( A domain.com 123.123.123.123 )
    2. www的第二个DNS A记录( A www 123.123.123.123 )

    然后在domain.com.vhost中:

    <VirtualHost *:80>
    
        DocumentRoot /var/www/path_to_root
    
        ServerName domain.com
        ServerAlias domain.com
    
        RewriteEngine on
        RewriteCond %{HTTPS} off
        RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]
    
    </VirtualHost>
    

    重写规则强制HTTPS。

    如果您想强制特定域使用HTTPS,无论是在.vhost还是.htaccess中,您都可以使用:

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

    对于特定文件夹:

    RewriteEngine On 
    RewriteCond %{HTTPS} off 
    RewriteRule ^(folder1|folder2|folder3) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
    

    请确保将文件夹引用更改为实际的目录名。

        3
  •  0
  •   Aran    3 年前

    如果您能够通过Cloudflare路由您的DNS(即使是在他们的免费计划中),您也可以点击按钮启用HSTS(包括子域)。速度和安全性方面还有很多其他好处,这可能也有助于您的SEMRash报告