如何仅在HTTPS上从.htaccess设置HSTS标头


81

我的Web应用程序在我控制的不同数量的主机上运行。为了避免需要更改每个虚拟主机的Apache配置,我在仓库中使用.htaccess文件添加了大多数配置,因此每个主机的基本设置仅需几行。这也使得在部署新版本时可以更改配置。目前,.htaccess(un)设置标头,进行一些重写魔术并控制UA的缓存。

我想使用.htaccess在应用程序中启用HSTS。设置标题很容易:

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

但是规范明确指出:“ HSTS主机不得在通过非安全传输传递的HTTP响应中包含STS头字段。” 所以我不想在通过HTTP连接发送标头时发送标头。参见http://tools.ietf.org/html/draft-ietf-websec-strict-transport-sec-14

我尝试使用环境变量设置标头,但是我被卡在那里。有谁知道该怎么做?


堆栈溢出是一个有关编程和开发问题的网站。这个问题似乎与主题无关,因为它与编程或开发无关。请在帮助中心中查看我可以询问哪些主题。也许超级用户Unix&Linux Stack Exchange是一个更好的选择。另请参阅我在哪里发布有关Dev Ops的问题?
jww

6
@jww .htaccess文件是我的Web应用程序回购的一部分,由开发人员维护,以获取应用程序的所需行为(例如,缓存,重写url和设置正确的标头)。在SO上,这个问题被浏览了近2万次(并且[apache],[。htaccess]和[mod-header]标签可用)。因此,我认为这不是话题。
nielsr

1
“ .htaccess文件是我的Web应用程序回购的一部分,由开发人员维护...” -都不包括在Stack Overflow中。一个很好的嗅探测试是,您可以显示您的代码吗?在这种情况下,答案是否定的。经过检查,这只是一个Apache配置问题。“问题被查看了将近2万次...” -Stack Overflow是一个垃圾场。在这里提出一个离题的问题,然后它被搜索引擎索引。现象的其他示例包括通过SSH传输文件。开发人员有时也会使用SSH。
jww

Answers:


110

显然,存在一个可以轻松使用的HTTPS环境变量。对于有相同问题的人:

Header set Strict-Transport-Security "max-age=31536000" env=HTTPS

2
此设置在哪个文件中进行?
ted.strauss 2014年

7
@ ted.strauss,它将在.htaccess文件中。
2015年

由于某些原因,这在我的服务器上不起作用。Apache 2.4
Andy

14
也没有为我工作;但是附加"expr=%{HTTPS} == 'on'"工作。整行是Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" "expr=%{HTTPS} == 'on'"。也许是因为always关键字?
AdrianFöder17年

3
请注意,条件中的HTTPS env var与我们在mod_rewrite条件(和Apache expr)中通常看到env=HTTPS服务器var不同%{HTTPS}。由于这是一个env变量,因此它取决于环境。服务器配置。有时它从未设置。有时,它被赋予了相同的值HTTPS服务器VAR(因此它始终设置为“关闭”或“上” -与条件env=HTTPS永远如此!env=HTTPS只是测试的环境变量是否设置,并不在于它是“上” 。)建议在Apache
2.4+

28

为了建立尼尔斯的答案,我在.htaccess中使用以下内容来满足https://hstspreload.org上的安全部署建议,该建议会将域硬编码到Chrome浏览器中。请注意,这将在您的子域中强制执行HSTS,并且预加载列表中的内容无法轻易撤消,因此rtfm。

<IfModule mod_headers.c>
Header set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" env=HTTPS
</IfModule>

6
是的,这是比较安全的-如果您只打算在整个域中使用HTTPS。如果不是这样,那将是非常危险的-因此在没有警告的情况下提出建议是不负责任的。假设您的网络服务器使用此标头响应顶级域(example.com)上的请求-那么当您包含子域时,由其他网络服务器通过http而不是https(例如intranet.example.com)提供服务的任何其他子域, 不管用。包括preload标签也可以将其提交到预加载列表,因此将其硬编码到Web浏览器中,然后是不可逆的。
巴里·波拉德

几年后,所以我只想指出,您的摘录到今天仍然有效。
KGIII

6

您可以使用它并将其放在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。并使用HSTS标头将非www https重定向到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虚拟主机上进行设置,而不能在HTTP虚拟主机上进行设置。

什么时候应该使用我,不应该使用.htaccess文件?

允许.htaccess文件将使Apache在每次访问服务器时都寻找它们。由于还搜索父目录,因此这将花费一些(少量)时间,并且可能影响服务器的性能。 资源


Apache将始终寻找.htaccess文件。因此,除非您禁用了.htaccess查找,否则不会提高性能,因为Apache仍会检查文件。
Rudy Broersma '18

1

另一种选择是始终设置标头并有条件地将其删除以用于非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)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.