LINUX.ORG.RU

HTTPS + APACHE 2.4 - NEED HELP :)

 , , ,


0

1

Добрый день! Извиняюсь, что не по теме Django, но точно знаю, что здесь сидит большое количество специалистов и мб кто то поможет советом. Необходимо заставить работать HTTPS на Apache в локальной сети (с самоподписным сертификатом).

Что сделано:

По статье с Хабра (https://habr.com/post/192446/) были созданы самоподписные сертификаты и ключи). На сервере подключен модуль mod_ssl.so, а так же выполнены настройки: SSLEngine On SSLCertificateFile «путь до/сертификата.crt» SSLCertificateKeyFile «путь до/ключа.key» SSLCACertificateFile «путь до/CA-сертификата.crt» (пробовал с этой опцией и без)

<Location /> SSLRequireSSL On SSLVerifyClient optional SSLVerifyDepth 1 (пробовал различные значения...) SSLOptions +StdEnvVars +StrictRequire </Location> Запускаю апач - все ок, ошибок нет. На клиенте импортирую сертификат CA (пробовал так же выписывать для юзеров отдельный сертификат по аналогии с сервером и импортировать его - не помогло) в доверенные корневые центры + перезагружаю браузер. Захожу на сайт - https работает, шифрование идет (проверял снифером), если сертификат удалить у пользователя - браузер сразу же начинает ругаться на то, что нет доверия к сертификату и пускает на страницу с перечеркнутым HTTPS (поидее так и должно быть). Тут я подумал, что было бы отлично, чтобы пользователи без сертификата вообще не могли использовать ресурс (либо через mod_rewrite в случае ошибок ssl редиректились куда-либо... пока надо реализовать хотябы недоступность ресурса, в случае когда у юзера нет сертификата), для этого надо применить директиву SSLVerifyClient require, поменял конфиг + перезапустил апач. На клиенте проверил, что сертификат есть в контейнере, захожу на сайт.... а он сразу выходит в ошибку ERR_SSL_PROTOCOL_ERROR.

Кусок лога ssl:

*[Wed Sep 12 16:12:11.074234 2018] [ssl:error] [pid 4508:tid 944] [client 10.32.140.66:49330] AH02261: Re-negotiation handshake failed [Wed Sep 12 16:12:11.074234 2018] [ssl:error] [pid 4508:tid 944] SSL Library Error: error:140890C7:SSL routines:ssl3_get_client_certificate:peer did not return a certificate — No CAs known to server for verification? AH02008: SSL library error 1 in handshake SSL Library Error: error:140800FF:SSL routines:ssl3_accept:unknown state*

Отсюда вопрос - почему https нормально работает (реально шифрует и не ругается в браузере) при использовании SSLVerifyClient optional, а не работает с флагом require, и как сделать так, чтобы работал с require? Большое спасибо за консультации!


почему https ... не работает с флагом require, и как сделать так, чтобы работал с require?

Флаг «require» подразумевает ОБЯЗАТЕЛЬНУЮ аутентификацию с помощью клиентского сертификата. Для этого соответствующий, правильно оформленный клиентский сертификат должен быть импортирован в хранилище веб-обозревателя - в раздел личных сертификатов (не в раздел доверенных корневых центров!).

Серверный сертификат и клиентский сертификат - это совершенно разные вещи, у них разное назначение. Поэтому клиентский сертификат надо оформлять не «по аналогии», а как положено - по инструкции оформления клиентских сертификатов. Клиентский сертификат должен быть заверен серверной частью. По идее, если бы вы правильно установили клиентский сертификат, то при заходе на страницу веб-сервера обозреватель попросил бы вас выбрать сертификат для аутентификации. Судя по вашему описанию, у вас до этого дело не доходило. Ну и сообщение «ssl3_get_client_certificate: peer did not return a certificate» говорит о том, что веб-обозреватель не предоставил серверу сертификат.

Так что, гуглите дальше:
аутентификация по клиенскому сертификату
аутентификация по клиентским сертификатам в Apache
авторизация в Apache по сертификату
и пр ...

vinvlad ★★
()
Ответ на: комментарий от vinvlad

А может

Добрый день! Большое спасибо за ответ.

А разве нельзя иметь дело только с двумя сертификатам - CA и server - Server прописать на апаче, а CA импортировать клиенту в корневые доверенные центры сертификации? С флагом require optional все работает ок (при данной схеме). При наличии сертификата в корневых дов.центрах ошибок не возникает и https работает как надо. Вопрос тогда в другом получается - как отследить, что данный сертификат прописан в дов.корневых центрах у пользователя? (браузер как то это опеределяет и показывает перечеркнутый https) - для моей задачи этого было бы за глаза...

может есть RewriteCond %{наличие сертификата СА в дов.корн.хранилище у пользователя} !=SUCCESS => редирект на другую страницу (как бы условие подобрать? по аналогии как браузер опеределяет...)

Или в этой схеме смысла нет и лучше не терять времени использовать аутентификацию по клиентскому сертификату? (нагуглил https://www.opennet.ru/base/sec/ssl_cert.txt.html)

Спасибо за отклик в любом случае! Сорри за мб глупые вопросы - первый раз занимаюсь настройкой подобного...

vega10
() автор топика
Ответ на: А может от vega10

Сорри за мб глупые вопросы - первый раз занимаюсь настройкой подобного...

Понимаете, для того чтобы что-то настраивать, нужно сначала получить какие-то базовые знания относительно этой области. Почитать что-то... Заниматься настройкой не осознавая, что конкретно означает каждая директива - это бессмысленное и опасное занятие.

А разве нельзя иметь дело только с двумя сертификатам - CA и server...

Нельзя. Вы конфигурите две разные задачи: HTTPS (шифрование траффика) и аутентификацию (по клиентским сертификатам). Соответственно, и используемые директивы с сертификатами тоже выполняют свои собственные функции.

Единственное, я могу еще посоветовать скачать книжку «Apache Cookbook» и прочитать там главы:
7.3 Generating Self-Signed SSL Certificates
7.4 Generating a Trusted CA
7.6 Authenticating with Client Certificates

Там, в частности, есть описание скрипта CA.pl, который упрощает интересующие вас действия. Только надо вызывать этот скрипт по его полному пути (/usr/lib/ssl/misc/CA.pl) и вместо указанного в книжке параметра "-signreq" использовать параметр "-sign".
В веб-обозреватель нужно импортировать клиентский сертификат с расширением .p12.

vinvlad ★★
()
Ответ на: А может от vega10

... клиентский сертификат должен импортироваться в веб-обозревателе в раздел личных сертификатов.

vinvlad ★★
()
Ответ на: комментарий от vinvlad

спасибо!

Спасибо еще раз за отклик и за консультации (книгу взял на заметку, прочитать однозначно надо) + факи с httpd пытаюсь изучать.

Аутентификацию настроить удалось - судя по всему, изначально использовал старую версию openssl (да, к сожалению, приходится заниматься таким мазахизмом под виндой). Скачал новую версию, сделал ca, сертификат для клиента в формате p12 - все отлично работает (запрашивается и используется), можно даже редиректить пользователя, в случае, если аутентификация по сертификату не пройдет:

SSLVerifyClient optional RewriteEngine On RewriteCond %{SSL:SSL_CLIENT_VERIFY} !^SUCCESS$ RewriteRule (.*) http://ya.ru [R] #к примеру...

Когда аутентификация заработала, я понял, что это немного не то, что мне было нужно изначально.. Мне бы просто проверять работает ли HTTPS шифрование (значек в браузере не перечеркнут) или нет => отлавливать ошибку браузера 'Ваше подключение не защищено' (тот случай, когда идет вход по https, но у пользователя отсутствует сертификат для доверия - как раз первая задача (не аутентификация)...)

vega10
() автор топика
Ответ на: спасибо! от vega10

Когда аутентификация заработала, я понял, что это немного не то, что мне было нужно изначально..

На самом деле, для того чтобы настроить HTTPS с самоподписным сертификатом в Apache/Nginx под Debian/Ubuntu, вообще не нужно возиться с генерацией сертификатов - просто ставишь пакет ssl-cert и при его установке автоматом генерится самоподписной сертификат:

/etc/ssl/certs/ssl-cert-snakeoil.pem
/etc/ssl/private/ssl-cert-snakeoil.key
его можно перегенерить командой:
make-ssl-cert generate-default-snakeoil --force-overwrite
Ну и в конфигурациях Apache/Nginx уже имеются заготовки со ссылкой на этот сертификат - их просто нужно активизировать.

Для того, чтобы веб-обозреватель работал с таким сайтом, тоже не нужно возиться с ручным импортом CA-сертификатов. Когда вы попадаете на страничку ругани с перечеркнутым https, нужно просто понажимать дальше кнопочки и подтвердить веб-обозревателю своё желание зайти на соответствующую страницу. При этом веб-обозреватель сам сохранит у себя в хранилище нужный сертификат и дальше можно спокойно работать с таким сайтом в https-режиме.

Мне бы просто проверять работает ли HTTPS шифрование (значек в браузере не перечеркнут) или нет => отлавливать ошибку браузера 'Ваше подключение не защищено' (тот случай, когда идет вход по https, но у пользователя отсутствует сертификат для доверия ...

Вам вообще не нужно отлавливать такую ситуацию, поскольку при отсутствии нужного CA-сертификата в веб-обозревателе непосредственного обращения к логике веб-сайта (отработка HTTP-запроса) не происходит - всё обрывается на этапе установления HTTPS-соединения.

Вам, на самом деле, просто нужно настроить автоматическое перенаправление на HTTPS.
Погуглите: перенаправление HTTP на HTTPS для Apache

vinvlad ★★
()
Ответ на: спасибо! от vega10

... ручной импорт самоподписного CA-сертификата в веб-обозреватель из файла может потребоваться только тогда, когда вы хотите иметь 100%-ную гарантию того, что никто не перехватил обращение к вашему сайту (DNS-spoofing) и не подсунул вам собственный самоподписной сертификат.

vinvlad ★★
()
Ответ на: комментарий от vinvlad

Доброе утро!

Еще раз хотел бы сказать, что очень Вам благодарен, в том, что делитесь Вашими знаниями и опытом..

Вам, на самом деле, просто нужно настроить автоматическое >>перенаправление на HTTPS.
Погуглите: перенаправление HTTP на HTTPS для Apache

------ По поповду перенаправления - я читал о нем на httpd.docs и даже делал эти настройки на сервере через mod_rewrite, но потом просто оставил использование https без http через настройки vhost'a (включить http и перенаправить на https могу в любой момент).

Для того, чтобы веб-обозреватель работал с таким сайтом, тоже не нужно возиться с ручным импортом CA-сертификатов. Когда вы попадаете на страничку ругани с перечеркнутым https, нужно просто понажимать дальше кнопочки и подтвердить веб-обозревателю своё желание зайти на соответствующую страницу. При этом веб-обозреватель сам сохранит у себя в хранилище нужный сертификат и дальше можно спокойно работать с таким сайтом в https-режиме.

------ Для IE это, поидее, верно, но нормально установить сертификат в автоматическом режиме не удается (сертификат для СА при установке через браузер по умолчанию лезит в хранилище личных сертификатов). В Google Chrome (к примеру 52.0.2743.116), установить сертификат аналогичным путем не удается вообще - нет кнопки 'Установить при просмотре сертификата', а при нажатии на 'Продолжить работу с этим ресурсом...' страницы грузятся, но ооооочень медленно + периодически выскакивают ошибки https (нет доверия к странице) и необходимо опять соглашаться (может в настройках можно добавить этот сайт в исключения, но это лишние настройки для пользователя) + заметил такую штуку, что если сертификат не был импортирован вручную, то сервер отдает статику ооочень-ооочень долго, а иногда страницы вообще открываются без css (обновление страницы спасает ситуацию) - для разработки сайта был использован Python Django, если сертификат импортирован, то все работает молниеносно (все настройки по деплою и работе со статикой были прописаны 1-1 как в доках).

Я вот и хотел отработать такую ситуацию - если у пользователя нет корневого CA в контейнере для доверенных корневых CA, то пользователь автоматически перенаправлялся на страницу с инструкцией о том, как установить этот сертификат + получал файл для его установки (на AutoIt накидал небольшой скрипт, с помощью которого в один клик производится импорт сертификата сразу в нужный контейнер) - так было бы удобно для пользователя. Как я понимаю - возможности реализовать такой механизм (выявления ситуации отсутствия CA сертификата) особо то и нет?

vega10
() автор топика
Ответ на: комментарий от vega10

Я вот и хотел отработать такую ситуацию - если у пользователя нет корневого CA в контейнере для доверенных корневых CA, то пользователь автоматически перенаправлялся на страницу с инструкцией о том, как установить этот сертификат ... Как я понимаю - возможности реализовать такой механизм (выявления ситуации отсутствия CA сертификата) особо то и нет?

Для того, чтобы выполнить перенаправление, вам сначала нужно установить https-соединение. Ну а поскольку нет корневого CA, то веб-обозреватель соединение не устанавливает - обрывает на начальном этапе - и вместо этого высвечивается предупреждение с перечеркнутым https.

Так что, да - такой возможности у вас нет, ваших пользователей нужно будет инструктировать каким-то другим способом. Ну и CA-сертификат нужно передавать пользователям каким-то надёжным, безопасным способом (это зависит от того, где вы всё это используете).

vinvlad ★★
()
Ответ на: комментарий от vinvlad

Для того, чтобы выполнить перенаправление, вам сначала нужно установить https-соединение. Ну а поскольку нет корневого CA, то веб-обозреватель соединение не устанавливает - обрывает на начальном этапе - и вместо этого высвечивается предупреждение с перечеркнутым https.

----- Действительно, перерыл все логи апача (error/ssl_engine) для различных ситуаций (есть сертификат или его нет) - привязаться, чтобы отловить отсутствие сертификата не к чему (явных ошибок/предупреждений по ssl нет)

Так что, да - такой возможности у вас нет, ваших пользователей нужно будет инструктировать каким-то другим способом. Ну и CA-сертификат нужно передавать пользователям каким-то надёжным, безопасным способом (это зависит от того, где вы всё это используете).

----- Только один велосипед приходит в голову: создать скрипт (отдельный exe), который импортирует сертификат СА в нужный контейнер, далее импортирует пользовательский сертификат в контейнер для личных сертификатов. В настройках апача принудительно делаем использование ssl-аутентификации по пользовательским сертификатам. Поидее, если авторизация не прошла, значит и сертификата СА скорее всего нет-> через mod_rewrite по условию SSL:SSL_CLIENT_VERIFY перекидываем пользователя на страницу с инструкцией... Другой вопрос в том - нужно ли это...

------ На время мелькнула мысль по поводу проверки наличия СА у пользователя с помощью JS, но, судя по всему, JS ограничен (тут могу ошибаться, тк весь опыт в использовании JS сводился к манипуляциям с деревом DOM сайта) в этом направлении по соображениям безопасности (нет доступа к сертификатам пользователя + нет возможности как то взаимодействовать со страницей при выводе сообщения о том, что браузер пытается открыть потенциально опасный сайт...). Смотрел через средства разработчика - никаких ошибок не появляется.

-----

по поводу медленной выдачи статики без установленного сертификата, вроде как нашел причину. Только не понимаю, почему есть такая зависимость. В логах периодически мелькали предупреждения о том, что SSLSessionCache не настроен. Произвел настройку согласно факам с httpd, предупреждения в апаче пропали и сайт стал грузиться быстрее (для браузеров без импорта сертификата), хотя может просто статика сайта в браузере закешировался, надо все почистить и перепроверить :)

И еще интересный момент - при первом входе на страницу с ошибкой в сертификате безопасности (ситуация, когда сертификат СА отсутствует у пользователя) -> при нажатии кнопки 'Далее', сертификат физически не устанавливается в нужное хранилище, а просто используется для работы в данной сессии.

vega10
() автор топика
Ответ на: комментарий от vega10

... Поидее, если авторизация не прошла, значит и сертификата СА скорее всего нет-> через mod_rewrite по условию SSL:SSL_CLIENT_VERIFY перекидываем пользователя на страницу с инструкцией...

Вы всё время забываете (или не учитываете) тот факт, что для аутентификации и отработки функционала mod_rewrite необходимо сначала успешно установить шифрованное соединение между обозревателем и веб-сервером. А раз нет CA-сертификата, то шифрованное соединение не устанавливается и до отработки всей этой логики дело просто в принципе не может дойти. Почитайте обзорные статьи по HTTP-протоколу и процедуре установления шифрованного HTTPS-соединения.

по поводу медленной выдачи статики без установленного сертификата, вроде как нашел причину. Только не понимаю, почему есть такая зависимость. В логах периодически мелькали предупреждения о том, что SSLSessionCache не настроен.

Правильная настройка SSLSessionCache позволяет сократить время установления шифрованных соединений при загрузке страницы. Поскольку веб-обозреватель при загрузке статики устанавливает несколько соединений, это естественно влияет на скорость отображения страницы. Имеют ли отношение «тормоза» к предварительной установке CA-сертификата - сомнительно (может и проявляется какая-нибудь специфика конкретного веб-обозревателя).

... сертификат физически не устанавливается в нужное хранилище, а просто используется для работы в данной сессии.

Это, вроде как, специфика Chrome - сертификат в этом случае просто кэшируется. Разные веб-обозреватели работают по-разному.

vinvlad ★★
()
Ответ на: комментарий от vinvlad

Доброе утро!

Вы всё время забываете (или не учитываете) тот факт, что для аутентификации и отработки функционала mod_rewrite необходимо сначала успешно установить шифрованное соединение между обозревателем и веб-сервером. А раз нет CA-сертификата, то шифрованное соединение не устанавливается и до отработки всей этой логики дело просто в принципе не может дойти. Почитайте обзорные статьи по HTTP-протоколу и процедуре установления шифрованного HTTPS-соединения.

----- А вот на это как раз и расчет, программа exe для клиента установит цепочку СА+сертификат для аутентификации. При входе на сайт (к примеру - пользователь ничего не устанавливал) - пользователь нажимает кнопку продолжить работу -> кешируется СА с сайта-> https устанавливается -> идет ssl аутентификация, которая обречена на редирект к инструкциям по SSL:SSL_CLIENT_VERIFY, тк сертификата для аутентификации у него нет. Если же программа ехе (по установке СА+сертификата для аутентификации) отработала - проблем при входе на ресурс никаких не будет. Вроде как, такой велосипед должен работать :) Огромнейшее Вам спасибо за содействие! В моих знаниях кучи пробелов - теперь есть что почитать на досуге :)

vega10
() автор топика
Ответ на: комментарий от vega10

А вот на это как раз и расчет ... При входе на сайт (к примеру - пользователь ничего не устанавливал) - пользователь нажимает кнопку продолжить работу ...

Одно дело, когда вы - системный администратор - нажимаете потенциально опасную кнопку «продолжить работу». Вы детально понимаете, что вы конкретно делаете в данной конкретной ситуации. И совсем другое дело, если так начинает вести себя рядовой пользователь... Не надо приучать обычных пользователей к таким безответственным поступкам! - при появлении предупреждения с перечеркнутым https они должны пугаться и бежать с вопросами к сисадмину или заглядывать на какую-то заранее известную FAQ-страничку вашей компании :)

Насколько я понимаю, речь идет о какой-то корпоративной локальной сети, где работает ваш веб-сервер. Раз вы решили шифровать в этой сети http-трафик с использованием самоподписного сертификата, то вы должны изначально предоставлять пользователям URL-ку с какой-то общей http (не https) FAQ-страничкой - типа, приклеивать на монитор :) - или соответствующим образом предварительно настраивать компы.
Это моя такая субъективная точка зрения... )

Еще, не забывайте, что у сертификатов есть определенный срок действия - через годик-другой вам придется их обновлять на каждом компе пользователя.

P.S. Полезная статейка насчет TLS:
Practical Issues with TLS Client Certificate Authentication

vinvlad ★★
()
Ответ на: комментарий от vinvlad

Насколько я понимаю, речь идет о какой-то корпоративной локальной сети, где работает ваш веб-сервер. Раз вы решили шифровать в этой сети http-трафик с использованием самоподписного сертификата, то вы должны изначально предоставлять пользователям URL-ку с какой-то общей http (не https) FAQ-страничкой - типа, приклеивать на монитор :) - или соответствующим образом предварительно настраивать компы.
Это моя такая субъективная точка зрения... )

Что-то вроде того, как вариант - через групповую установку ставить СА на контейнер с целевыми пользователями в домене. Я как раз и занимался ранее только администрированием, а сейчас осваиваю мир веб-технологий, поэтому все в новинку, иду дорогой проб и ошибок :) Единственное, над чем еще думаю - правильно ли я выбрал путь - python-django, либо проще было бы все делать через php (в интернете куча точек зрения на этот счет...)

Еще раз - огромное Вам спасибо за то, что делитесь опытом :) PS: материалы себе загрузил - буду изучать :)

vega10
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.