如何仅在 HTTPS 上从 .htaccess 设置 HSTS 标头 [关闭]
Posted
技术标签:
【中文标题】如何仅在 HTTPS 上从 .htaccess 设置 HSTS 标头 [关闭]【英文标题】:How to set HSTS header from .htaccess only on HTTPS [closed] 【发布时间】:2014-07-31 10:13:43 【问题描述】:我的 Web 应用程序在我控制的不同数量的主机上运行。为了防止需要更改每个虚拟主机的 Apache 配置,我在我的存储库中使用 .htaccess 文件添加了大部分配置,因此每个主机的基本设置只有几行。这也使得在部署新版本时更改配置成为可能。目前 .htaccess (un) 设置标头,执行一些重写魔术并控制 UA 的缓存。
我想使用 .htaccess 在应用程序中启用 HSTS。只需设置标题很容易:
Header always set Strict-Transport-Security "max-age=31536000"
但规范明确指出:“HSTS 主机不得在通过非安全传输传输的 HTTP 响应中包含 STS 标头字段。”。因此,我不想在通过 HTTP 连接发送标头时发送标头。见https://datatracker.ietf.org/doc/html/draft-ietf-websec-strict-transport-sec-14。
我尝试使用环境变量设置标题,但我被困在那里。有谁知道怎么做?
【问题讨论】:
Stack Overflow 是一个编程和开发问题的网站。这个问题似乎离题了,因为它与编程或开发无关。请参阅帮助中心的What topics can I ask about here。也许Super User 或Unix & Linux Stack Exchange 会是一个更好的提问地方。另见Where do I post questions about Dev Ops? @jww .htaccess 文件是我的网络应用程序库的一部分,由开发人员维护以获得应用程序的所需行为(例如缓存、重写 url 和设置正确的标题)。这个问题在 SO 上被查看了近 20K 次(并且 [apache]、[.htaccess] 和 [mod-headers] 标签可用)。所以我不认为这是题外话。 “.htaccess 文件是我的网络应用程序库的一部分,由开发人员维护......” - 也不是包含在 Stack Overflow 上的标准。一个好的嗅探测试是,你能展示你的代码吗?在这种情况下,答案是否定的。经过检查,它只是一个 Apache 配置问题。 “这个问题被浏览了近 20K 次......” - Stack Overflow 是一个垃圾场。这里提出了一个离题的问题,然后它被搜索引擎索引。该现象的其他示例包括Transferring files over SSH。开发人员有时也会使用 SSH。 【参考方案1】:显然有一个可以轻松使用的 HTTPS 环境变量。对于有相同问题的人:
Header set Strict-Transport-Security "max-age=31536000" env=HTTPS
【讨论】:
这个设置是在什么文件里做的? @ted.strauss 它会在.htaccess
文件中。
由于某种原因,这在我的服务器上不起作用。阿帕奇 2.4
对我也不起作用;但是附加"expr=%HTTPS == 'on'"
worked。然后整行是Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" "expr=%HTTPS == 'on'"
。也许是因为always
keyword?
请注意,env=HTTPS
条件中的HTTPS
env var 与我们通常在 mod_rewrite 条件中看到的 server var 不同(和 Apache expr) 为%HTTPS
。由于这是一个 env 变量,它依赖于环境,即。服务器配置。有时它永远不会被设置。有时它被分配与HTTPS
服务器变量相同的值(因此它始终设置为“关闭”或“开启” - 并且条件env=HTTPS
总是为真!env=HTTPS
只是测试是否设置了 env var,而不是“打开”。)建议在 Apache 2.4+ 上使用 @AdrianFöder 建议的 Apache expr【参考方案2】:
为了以 nielsr 的回答为基础,我在 .htaccess 中使用了以下内容来满足 https://hstspreload.org 的安全部署建议,这会将域硬编码到 Chrome 浏览器中。请注意,这将在您的子域中强制执行 HSTS,并且包含在预加载列表中的内容无法轻易撤消,因此 rtfm。
<IfModule mod_headers.c>
Header set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" env=HTTPS
</IfModule>
【讨论】:
如果您只打算在整个域中使用 HTTPS,它会更安全一些。如果不是,那将是非常危险的——因此在没有警告的情况下提出它是不负责任的。假设您的网络服务器使用此标头响应***域(example.com)的请求 - 然后当您包含子域时,其他网络服务器仅通过 http 而不是 https(例如 intranet.example.com)服务的任何其他子域, 不管用。包含预加载标签还允许将其提交到预加载列表,因此它被硬编码到网络浏览器中,然后是不可逆的。 几年过去了,所以我只是说你的sn-p到今天仍然有效。【参考方案3】:您可以使用它并将其放在您的 htaccess 文件中以符合https://hstspreload.org。把它放在你的 .htaccess 文件中。
RewriteCond %HTTPS !=on
RewriteRule ^(.*)$ https://%HTTP_HOST/$1 [R=301,L]
RewriteCond %HTTP_HOST !^www\.
RewriteRule ^(.*)$ https://www.%HTTP_HOST/$1 [R=301,L,E=HTTPS:1]
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" env=HTTPS
首先,它会将非 https 重定向到 https。并将非 www https 重定向到带有 HSTS 标头的 www https。
(http://example.com -> https://example.com -> https://www.example.com - 带有 HSTS 标头)
经过测试并符合https://hstspreload.org
【讨论】:
【参考方案4】:对于httpd.conf
(如果您有权编辑此内容),您可以使用
<VirtualHost 65.81.122.43:443>
Header always set Strict-Transport-Security "max-age=31536000; includeSubdomains;"
</VirtualHost>
注意:您只需要在 HTTPS vhost 上设置它,不能在 http vhost 上。
我应该什么时候使用,不应该使用 .htaccess 文件?
允许 .htaccess 文件将使 Apache 在每次访问您的服务器时查找它们。由于还会搜索父目录,因此这将花费一些(少量)时间,并且可能会影响服务器的性能。 Source
【讨论】:
Apache 将始终查找 .htaccess 文件。因此,除非您禁用 .htaccess 查找,否则这不会提高性能,因为 Apache 无论如何都会检查该文件。【参考方案5】:另一种选择是始终设置标头并有条件地将其删除以用于非 ssl 连接:
Header always set Strict-Transport-Security "max-age=31536000" early
Header unset Strict-Transport-Security env=!HTTPS
这样做的好处是Header
指令可以与env
条件以及early
标志一起使用。对于单个Header
指令,env
和early
不能一起使用,它们是互斥的(参见官方文档:https://httpd.apache.org/docs/current/mod/mod_headers.html#header)。
【讨论】:
以上是关于如何仅在 HTTPS 上从 .htaccess 设置 HSTS 标头 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
在 ubuntu 13.10 上从 XAMPP 移动到 LAMP 后 htaccess 不起作用(在 apache linux 服务器中启用 htaccess)
如何使用 .htaccess 正确地将 HTTP 301 重定向到 HTTPS?