如何设置 HSTS 头从.htaccess 只对 HTTPS

我的 Web 应用程序运行在我控制的不同数量的主机上。为了防止需要更改每个 vhost 的 Apache 配置,我使用。Htaccess 文件在我的回购,所以每个主机的基本设置只是几行。这也使得在部署新版本时更改配置成为可能。目前。Htaccess (un)设置头部,进行一些重写,并控制 UA 的缓存。

我想使用.htaccess 在应用程序中启用 HSTS:

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

But the spec clearly states: "An HSTS Host MUST NOT include the STS header field in HTTP responses conveyed over non-secure transport.". So I don't want to send the header when sending it over HTTP connections. See https://datatracker.ietf.org/doc/html/draft-ietf-websec-strict-transport-sec-14 .

我试图使用环境变量来设置头部,但是我被卡住了。有人知道怎么做吗?

82564 次浏览

Apparently there is a HTTPS environment variable available that can be used easily. For people with the same question:

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

To build on nielsr's answer, I used the following in the .htaccess to meet the secure deployment recommendations at https://hstspreload.org which will hardcode the domain into the Chrome browser. Be aware this will enforce HSTS across your subdomains, and that inclusion in the preload list cannot easily be undone, so rtfm.

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

For httpd.conf (if you have access to edit this) you can use

<VirtualHost 65.81.122.43:443>
Header always set Strict-Transport-Security "max-age=31536000; includeSubdomains;"
</VirtualHost>

NOTE : You need to set it on the HTTPS vhost only and cannot be on http vhost.

When should I, and should I not use .htaccess files?

Allowing .htaccess files will make Apache look for them upon every access to your server. Since parent directories are searched as well, this will take some (small) amount of time, and can impact your server's performance. Source

Yet another alternative is to always set the header and conditionally remove it for non-ssl connections:

Header always set   Strict-Transport-Security "max-age=31536000" early
Header        unset Strict-Transport-Security env=!HTTPS

This has the advantage, that the Header directive can be used with both the env condition as well as the early flag. With a single Header directive, env and early cannot be used together, they are mutually exclusive (see official documentation: https://httpd.apache.org/docs/current/mod/mod_headers.html#header).

You can use this and put it on your htaccess file to comply with https://hstspreload.org. put this in your .htaccess file.

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

first, it will do redirection for non https to https. and redirect non www https to www https with HSTS header.

(http://example.com -> https://example.com -> https://www.example.com - with HSTS header)

Tested and comply with https://hstspreload.org