<html><head><style id="outgoing-font-settings">#response_container_BBPPID{font-family: initial; font-size:initial; color: initial;}</style></head><body style="background-color: rgb(255, 255, 255); background-image: initial; line-height: initial;"><div id="response_container_BBPPID" style="outline:none;" dir="auto" contenteditable="false"> <div name="BB10" id="BB10_response_div_BBPPID" dir="auto" style="width:100%;"> попробуй сделать map от $ssl_client_verify, в котором для success будет значение off. для остальных значений - путь до файла htpasswd.</div><div name="BB10" id="BB10_response_div_BBPPID" dir="auto" style="width:100%;"><br></div><div name="BB10" id="BB10_response_div_BBPPID" dir="auto" style="width:100%;">потом в нужном месте напиши auth_basic $var_from_map</div> <div name="BB10" id="response_div_spacer_BBPPID" dir="auto" style="width:100%;"> <br style="display:initial"></div> <div id="blackberry_signature_BBPPID" name="BB10" dir="auto"> <div id="_signaturePlaceholder_BBPPID" name="BB10" dir="auto"></div> </div></div><div id="_original_msg_header_BBPPID" dir="auto"> <table width="100%" style="border-spacing: 0px; display: table; outline: none;" contenteditable="false"><tbody><tr><td colspan="2" style="padding: initial; font-size: initial; text-align: initial;"> <div style="border-right: none; border-bottom: none; border-left: none; border-image: initial; border-top: 1pt solid rgb(181, 196, 223); padding: 3pt 0in 0in; font-family: Tahoma, "BB Alpha Sans", "Slate Pro"; font-size: 10pt;"> <div id="from"><b>От:</b> vlad.shabanov@gmail.com</div><div id="sent"><b>Отправл.:</b> 1 января 2021 г. 20:47</div><div id="to"><b>Кому:</b> nginx-ru@nginx.org</div><div id="reply_to"><b>Кому:</b> nginx-ru@nginx.org</div><div id="subject"><b>Тема:</b> Клиентские SSL-сертификаты + ngx_http_auth_basic_module</div></div></td></tr></tbody></table> <br> </div><!--start of _originalContent --><div name="BB10" dir="auto" style="background-image: initial; line-height: initial; outline: none;" contenteditable="false"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""></div>Добрый день!<div class=""><br class=""></div><div class="">Хочу посоветоваться.</div><div class="">Есть сервер, где зона «для сотрудников» закрыта двумя слоями авторизации:</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>auth_basic</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>+ проверка на уровне приложения, с куками, сессиями и прочим.</div><div class=""><br class=""></div><div class="">Отказываться от auth_basic не хочется: </div><div class=""><ul class=""><li class="">В коде приложения запросто могут быть ошибки. Забыли, например, завернуть какую-нибудь функцию приложения в декоратор и получили дырку в защите.</li><li class="">Сессионную куку могут угнать. XSS, «мутные» плагины для браузеров и т. д.</li><li class="">Есть «интимная» статика, которую проверять через auth_request не хочется, т.к. замедляет.</li></ul></div><div class="">Проблема в том, что большинство браузеров неудобно работают с basic_auth: Сафари под iPhone спрашивает пароль каждые несколько часов и даже не заморачивается, чтобы его запомнить. FireFox после рестарта показывает модальный диалог со вводом пароля в одном из окон и блокирует все остальные окна с тем же сайтом. Неудобно, короче.</div><div class=""><br class=""></div><div class="">Настроил клиентские сертификаты. Есть сотни мануалов, ничего интересного. Но вот раздача сертификатов сотрудникам и установка их в браузеры – дело муторное. У каждого браузера свои тараканы, сложно объяснить сотруднику по телефону, как поставить сертификат в его браузер и т. д. А если сертификат устареет или придётся его отозвать, совсем беда.</div><div class=""><br class=""></div><div class="">Поэтому решил сделать вот какую логику:</div><div class=""><ul class=""><li class="">Если браузер предъявил сертификат, то <i class="">auth_basic</i> не требуем.</li><li class="">Если не предъявил, то пусть вводит логин+пароль через <i class="">auth_basic</i>.</li><li class="">Проверка доступа на уровне приложения никуда не девается, работаем по старому.</li></ul></div><div class="">Я не нашёл способа, как настроить конфиг nginx, чтобы эту логику реализовать. Конструкции с</div><blockquote style="margin:0 0 0 40px;border:none;padding:0px" class=""><div class="">if $ssl_client_verify == "SUCCESS" {}</div></blockquote><div class="">несовместимы с auth_basic.</div><div class=""><br class=""></div><div class="">Пока придумал только одно: отпатчил <i class="">ngx_http_auth_basic_module.c</i>, сделал в нём директиву</div><blockquote style="margin:0 0 0 40px;border:none;padding:0px" class=""><div class=""><i class="">auth_basic_skip_if_client_cert</i> <i class="">on/off</i></div></blockquote>по которой проверка пароля выключается, если предъявлен валидный клиентский сертификат.<div class=""><br class=""></div><div class="">Вопросы:</div><div class=""><ol class=""><li class="">Может быть, кто-то решал аналогичную задачу? Чтоб и два слоя защиты для страховки и удобство в повседневной работе?</li><li class="">Существует ли решение без патча ngx_http_auth_basic_module.c?</li><li class="">Интересен ли кому-нибудь этот патч? Может, на моём велосипеде ещё кто-нибудь хочет покататься? :) </li></ol></div><div class=""><br class=""></div><div class="">С уважением,</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>Владислав</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><!--end of _originalContent --></div></body></html>