1 个子域不支持 HSTS

1 subdomain doesn't support HSTS

我的网站托管在 AWS and I am using SEMRush 上以跟踪任何服务器和编程问题。

我的 SEMRush 在 运行 时发现了这个错误。

2 subdomains don't support HSTS.

因此我用下面的代码来解决这个问题

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

现在 1 个错误已解决,但还有一个子域有相同的错误。

如您所见rosterelf.com仍然不支持 HSTS。

此外,我正在我的 htaccess 中将非 www 重定向到 www,这就是我的 .htaccess 文件的样子。

<IfModule mod_rewrite.c>

    <IfModule mod_negotiation.c>
        Options -MultiViews
    </IfModule>

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

    RewriteEngine On

    ##
    ## You may need to uncomment the following line for some hosting environments,
    ## if you have installed to a subdirectory, enter the name here also.
    ##
    # RewriteBase /

    ##
    ## Uncomment following lines to force HTTPS.
    ##
    # RewriteCond %{HTTPS} off
    # RewriteRule (.*) https://%{SERVER_NAME}/ [L,R=301]
    
    # CONDITIONS FOR ONLY LIVE SITE STARTS 
    RewriteCond %{HTTPS} off
    RewriteCond %{HTTP_HOST} !^www\. [NC]
    RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]
    # CONDITIONS FOR ONLY LIVE SITE ENDS  
    
    ##
    ## Allow robots.txt
    ##
    RewriteRule ^robots.txt - [L]

    ## 301 redirect for old support details page url to new one 
    ## OLD URL https://www.rosterelf.com/support-detail/1903/how-can-employees-clock-inout-of-time-clock-different-slug 
    ## NEW URL https://www.rosterelf.com/support-detail/how-can-employees-clock-inout-of-time-clock-different-slug 
    
    RewriteRule ^(support-detail)/\d+/([\w-]+)/?$  // [R=301,NC,L]
    RewriteRule ^blog-detail/\d+/([\w-]+)/?$ /blog/ [R=301,NC,L]



    ##
    ## Black listed folders
    ##
    RewriteRule ^bootstrap/.* index.php [L,NC]
    RewriteRule ^config/.* index.php [L,NC]
    RewriteRule ^vendor/.* index.php [L,NC]
    RewriteRule ^storage/cms/.* index.php [L,NC]
    RewriteRule ^storage/logs/.* index.php [L,NC]
    RewriteRule ^storage/framework/.* index.php [L,NC]
    RewriteRule ^storage/temp/protected/.* index.php [L,NC]
    RewriteRule ^storage/app/uploads/protected/.* index.php [L,NC]

    ##
    ## White listed folders
    ##
    RewriteCond %{REQUEST_FILENAME} -f
    RewriteCond %{REQUEST_FILENAME} !/.well-known/*
    RewriteCond %{REQUEST_FILENAME} !/storage/app/uploads/public/.*
    RewriteCond %{REQUEST_FILENAME} !/storage/app/media/.*
    RewriteCond %{REQUEST_FILENAME} !/storage/app/resized/.*
    RewriteCond %{REQUEST_FILENAME} !/storage/temp/public/.*
    RewriteCond %{REQUEST_FILENAME} !/themes/.*/(assets|resources)/.*
    RewriteCond %{REQUEST_FILENAME} !/plugins/.*/(assets|resources)/.*
    RewriteCond %{REQUEST_FILENAME} !/modules/.*/(assets|resources)/.*
    RewriteRule !^index.php index.php [L,NC]

    ##
    ## Block all PHP files, except index
    ##
    RewriteCond %{REQUEST_FILENAME} -f
    RewriteCond %{REQUEST_FILENAME} \.php$
    RewriteRule !^index.php index.php [L,NC]

    ##
    ## Standard routes
    ##
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]

</IfModule>

我需要在下面输入代码吗

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

超出 <IfModule mod_rewrite.c> 条件?我应该怎么做才能解决这个问题?

有人可以指导我吗..

谢谢

如果你想将 header 也添加到重定向,那么你肯定需要 always,所以试试这个:

Header always set Strict-Transport-Security "max-age=31536000"

my SEMRush found this error when I run it.

澄清一下,这不是严格意义上的“错误”,除非您明确尝试实施 HSTS。 (看起来你不是?)HSTS 是推荐

but still having one more subdomain having the same error.

SEMRush的身份很好奇;那不是子域,那是“域顶点”(即没有子域)。

RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]

实施 HSTS 时,您需要首先在“相同的主机名”上从 HTTP 重定向到 HTTPS, 规范化主机名之前,即。在您从 no-www(域顶点)重定向到 www.

之前

这意味着你不能做你在这里做的事情...在一个重定向中从 HTTP 和 no-www 重定向到 HTTPS 和 www。 (当前注释掉的 HTTP 到 HTTPS 重定向是您需要使用的。)

但是,您当前的规则也不完整,因为它在请求 HTTPS 时无法规范化主机名。 IE。它不会https://example.com/ 重定向到https://www.example.com/。检查 HTTPS 是否为 off 的第一个条件确保规则仅针对 HTTP 请求进行处理。

实施 HSTS 时,您的重定向需要这样写:

# 1. Redirect HTTP to HTTPS on the same host
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

# 2. Redirect non-www to www
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]    

第二个规范化主机名的重定向假设您没有其他应该可以访问的子域,因为它重定向任何“不是 www”的内容。

是的,这确实(不幸地)意味着用户在第一次请求 http://example.com/ 时将经历两次重定向。但这是 HSTS 的本质。这只是用户第一次访问 non-canonical 主机名上的 HTTP。

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

这会在 HTTPS“成功”响应上设置 STS header。但是,HSTS 还要求您在从 no-www 到 www 的 HTTPS 规范重定向上设置此 header。目前,上述指令仅在 onsuccess (200 Ok) 响应(默认)上设置 header。要在 301 重定向上设置 header,您需要 always 条件,如 @BarryPollard has already pointed out in his answer:

# Set the STS header on redirects as well as 200 OK responses.
Header always set Strict-Transport-Security "max-age=31536000"

补充一下,always 条件不仅会在 3xx 响应上设置 header,还会在其他 4xx 响应上设置

<If> 表达式本身也有点可疑。您应该只检查 X-Forwarded-Proto header 如果 您的应用程序服务器位于管理安全连接的 front-end 代理之后。但是,如果您在代理后面,则无需检查 REQUEST_SCHEME 服务器变量。 (看起来这个表达式是一个通用的“catch-all”。)上面表达式的问题是,如果你不在代理后面,那么恶意请求可能会注入 X-Forwarded-Proto HTTP 请求header 并欺骗您的服务器发送 header.

从您的 HTTP 到 HTTPS 重定向(检查 HTTPS 服务器变量)看起来您 而不是 front-end 代理。虽然,也许你是,我们需要将上面的 HTTP 修改为 HTTPS 重定向?

因此,如果您不在 front-end 代理后面,则以下 <If> 表达式更可取:

<If "%{REQUEST_SCHEME} == 'https'>

或者,

<If "%{HTTPS} == 'on'>

如果使用 Apache 2.2(或 Apache 2.4),您可以执行以下操作而不是使用 <If> 表达式:

# Set HSTS env var only if HTTPS
RewriteCond %{HTTPS} on
RewriteRule ^ - [E=HSTS:1]

# Set STS header only when the HSTS env var is set (including redirects)
Header always set Strict-Transport-Security "max-age=31536000" env=HSTS
Out side of `<IfModule mod_rewrite.c>` condition ?

将指令放在 <IfModule> 容器的内部或外部在这种情况下没有区别(因为可能安装了 mod_rewrite 和 mod_headers)。事实上,严格来说,<IfModule> 包装器可能应该完全删除。

有关此问题的更多信息,请参阅 my answer 网站管理员堆栈中的以下问题: