Как установить заголовок HSTS из .htaccess только на HTTPS

Мое веб-приложение работает на другом количестве хостов, которые я контролирую. Чтобы предотвратить необходимость изменения конфигурации Apache для каждого виртуального хоста, я добавляю большую часть конфигурации с использованием файлов .htaccess в свое репо, поэтому базовая настройка каждого хоста занимает всего пару строк. Это также дает возможность изменить конфигурацию при развертывании новой версии. В настоящее время .htaccess (un) устанавливает заголовки, выполняет некоторую магию перезаписи и контролирует кеширование UA.

Я хочу включить HSTS в приложении, используя .htaccess. Просто настроить заголовок очень просто:

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

Но в спецификации четко указано: «Хост HSTS НЕ ДОЛЖЕН включать поле заголовка STS в HTTP-ответы, передаваемые по незащищенному транспорту». Поэтому я не хочу отправлять заголовок при отправке по HTTP-соединениям. См. http://tools.ietf.org/html/draft-ietf-websec-strict-transport-sec-14.

Я пытался установить заголовок с помощью переменных окружения, но застрял там. Кто-нибудь знает, как это сделать?


person nielsr    schedule 10.06.2014    source источник
comment
Stack Overflow - это сайт для вопросов по программированию и разработке. Этот вопрос кажется не по теме, потому что он не о программировании или разработке. См. Какие темы можно задать здесь в Справочном центре. Возможно, суперпользователь или Unix и Linux Stack Exchange лучше спросить. Также см. Где я могу задать вопросы о Dev Ops?   -  person jww    schedule 05.11.2016
comment
@jww Файлы .htaccess являются частью моего репозитория веб-приложения и поддерживаются разработчиками для достижения желаемого поведения приложения (например, кэширование, перезапись URL-адресов и установка правильных заголовков). Здесь, на SO, вопрос просматривается почти 20 тысяч раз (доступны теги [apache], [.htaccess] и [mod-headers]). Так что я не думаю, что здесь это не по теме.   -  person nielsr    schedule 17.03.2017
comment
Файлы .htaccess являются частью моего репозитория веб-приложений и поддерживаются разработчиками ... - Также нет критериев для включения в Stack Overflow. Хороший снифф-тест: можете ли вы показать свой код? В этом случае ответ - НЕТ. После проверки это просто вопрос конфигурации Apache. Вопрос просмотрен почти 20 тысяч раз ... - Stack Overflow - это свалка. Здесь задается вопрос не по теме, а затем он индексируется поисковой системой. Другие примеры этого явления включают передачу файлов по SSH. Разработчики тоже иногда используют SSH.   -  person jww    schedule 17.03.2017


Ответы (5)


По-видимому, доступна переменная среды HTTPS, которую можно легко использовать. Для людей с таким же вопросом:

Header set Strict-Transport-Security "max-age=31536000" env=HTTPS
person nielsr    schedule 10.06.2014
comment
в каком файле сделана эта настройка? - person ted.strauss; 30.11.2014
comment
@ ted.strauss он будет в .htaccess файле. - person zen; 07.05.2015
comment
По какой-то причине это не работает на моем сервере. Apache 2.4 - person Andy; 19.10.2017
comment
У меня тоже не сработало; однако добавление "expr=%{HTTPS} == 'on'" работало. Тогда вся строка будет Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" "expr=%{HTTPS} == 'on'". Может это из-за alwaysключевого слова? - person Adrian Föder; 17.11.2017
comment
Обратите внимание, что HTTPS env var в условии env=HTTPS отличается от server var, который мы обычно видим в условиях mod_rewrite (и выражение Apache) как %{HTTPS}. Поскольку это переменная env, она зависит от среды, т.е. конфигурация сервера. Иногда никогда не устанавливается. Иногда ему присваивается то же значение, что и переменной сервера HTTPS (поэтому он всегда либо выключен, либо включен, а условие env=HTTPS всегда истинно! env=HTTPS просто проверяет, установлена ​​ли переменная env, а не что он включен.) Использование выражения Apache, как предлагает @ AdrianFöder, рекомендуется на Apache 2.4+ - person MrWhite; 26.01.2018
comment
Заголовки как-то перезаписывались, когда я запускал PHP в режиме CGI вместо Module. Вот почему у меня это не сработало. stackoverflow.com / questions / 32147413 / - person Andy; 17.04.2018
comment
Ответ Адриана Фодера сработал очень хорошо, спасибо, для этого потребовались одинарные кавычки на 'on' - person pedrotester; 23.12.2019

Чтобы опираться на ответ 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>
person LJT    schedule 13.09.2016
comment
Это немного более безопасно, да - если вы когда-либо собираетесь использовать HTTPS только во всем своем домене. В противном случае это невероятно опасно - и поэтому безответственно предлагать это без предупреждения. Предположим, ваш веб-сервер отвечает этим заголовком на запрос в домене верхнего уровня (example.com) - тогда, поскольку вы включаете субдомены, любой другой субдомен, обслуживаемый другим веб-сервером, только через http, а не https (например, intranet.example.com) , не будет работать. Включение тега предварительной загрузки также позволяет отправить это в список предварительной загрузки, чтобы он был жестко запрограммирован в веб-браузерах, а затем стал необратимым. - person Barry Pollard; 18.09.2016
comment
Прошло несколько лет, поэтому я просто отмечаю, что ваш фрагмент все еще эффективен на сегодняшний день. - person KGIII; 08.10.2020

Вы можете использовать это и поместить в свой файл 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 на www https с заголовком HSTS.

(http://example.com -> https://example.com -> https://www.example.com - с заголовком HSTS)

Протестировано и соответствует https://hstspreload.org

person Yuda Prawira    schedule 09.05.2019

Для httpd.conf (если у вас есть доступ для редактирования) вы можете использовать

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

ПРИМЕЧАНИЕ. Вам необходимо установить его только на виртуальном хосте HTTPS и не может быть на виртуальном хосте http.

Когда мне следует и не следует ли использовать файлы .htaccess?

Разрешение файлов .htaccess заставит Apache искать их при каждом доступе к вашему серверу. Поскольку поиск выполняется и в родительских каталогах, это займет некоторое (небольшое) время и может повлиять на производительность вашего сервера. Источник

person Aniket Thakur    schedule 17.03.2017
comment
Apache всегда будет искать файлы .htaccess. Поэтому, если вы не отключили поиск .htaccess, это не улучшит производительность, поскольку Apache все равно будет проверять наличие файла. - person Rudy Broersma; 31.01.2018

Еще одна альтернатива - всегда устанавливать заголовок и условно удалять его для соединений, отличных от 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).

person studersi    schedule 15.01.2019