【问题标题】:AWS- subdomain doesn't support HSTSAWS- 子域不支持 HSTS
【发布时间】:2021-09-18 03:46:15
【问题描述】:

我正在使用 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>

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

【问题讨论】:

  • 这能回答你的问题吗? 1 subdomain doesn't support HSTS
  • 我确实看到了,不,它没有解决我的问题
  • 尝试从重写规则中删除此Header add Strict-Transport-Security "max-age=300" 并检查
  • @Haridarshan 我试过了,没用
  • 请仔细阅读 Daniel Morell 的this wonderful article,它提供了有关如何处理和正确配置 HSTS 的不同选项和建议。另外,文章中也提到,尝试使用chrome://net-internals/#hsts在Known HSTS Host列表中查询和管理你的域。我希望它有所帮助。

标签: php amazon-web-services .htaccess


【解决方案1】:
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 + 非 www)重定向到 HTTPS + WWW。为了符合 HSTS,您需要先重定向到 同一主机上的 HTTPS。 IE。 http://example.com/https://example.com/https://www.example.com(是的,这是两个重定向,但也很少见,每个用户代理最多只会出现一次,因为返回的 STS 标头)。

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

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

  5. 您应该在 Strict-Transport-Security 标头中包含 includeSubDomains 指令,以便在请求域顶点时覆盖 www 子域。虽然,现在将隐含包含 all 子域。如果没有这个,则需要明确请求 www 子域。 (好的,你在下一个请求中无论如何都会重定向到 www。)

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

    有关更多信息,请参阅 my answer 到网站管理员堆栈上的以下问题:
    Is Checking for mod_rewrite Really Necessary?

  7. 我从前面的 HTTP + 非 www 重定向中假设您不在管理 SSL 的前端代理(或负载平衡器)后面,在这种情况下,在后面的 &lt;If&gt; 表达式中检查 %{HTTP:X-Forwarded-Proto}应该被删除。如果您不在“代理”后面,则可以伪造请求以防止发回 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,因为您需要请求中的主机名。默认情况下SERVER_NAMEHTTP_HOST 相同,但这可能因服务器配置而异。

  • 没有理由只在请求中存在非空 User-Agent 字符串时应用规范重定向(恶意请求可能会抑制 User-Agent 字符串),所以我已经删除了这个健康)状况。如果有的话,您会阻止此类请求。

  • RewriteRule 中的正则表达式 ^ 模式.* 更优化,因为它只需要成功 - 实际上不需要 匹配 任何东西,因为它以后不会被使用。

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

参考/另见:


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

所需的更改是 HTTP 到 HTTPS 重定向(第一条规则)和末尾的 &lt;If&gt; 表达式。

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>

【讨论】:

  • 这不起作用,它只是不断重定向并完全破坏了我的网站
  • @user979331 好吧,您可能正在使用 AWS “负载均衡器”(或相关)服务?在这种情况下,您可能需要检查 X-Forwarded-Proto 标头而不是 HTTPS 服务器变量,以确定客户端请求是否安全。最后,我用修改后的代码示例更新了我的答案。 (但是,这意味着您最初检查 %{HTTPS} !=on 的代码是错误的 - 尽管在这种情况下可以避免重定向循环,因为您在同一规则中将非 www 重定向到 www。)
  • 我会尽快查看
  • 我试了你的新代码,结果一样,一直重定向太多次
  • @user979331 确保您已清除浏览器缓存和任何中间缓存。 301(永久)重定向被永久缓存,包括任何错误的重定向。 (使用 302(临时)重定向进行测试以避免潜在的缓存问题。)它从/到(以及您看到的状态代码)重定向到什么? (检查浏览器中的网络流量以确定这一点。)
【解决方案2】:

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

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

然后在 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]

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

【讨论】:

  • 我不确定我应该在这里做什么,我有一个 .conf 文件,我可以和你分享吗?
  • @user979331 你能在这里发帖吗?您可以删除 dir 路径以保留您的数据。
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-14
    • 2016-06-22
    • 1970-01-01
    • 2020-07-14
    • 1970-01-01
    • 2020-05-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多