Re: Mutual authentication средствами nginx

Илья Шипицин chipitsine at gmail.com
Thu Jan 23 15:32:18 UTC 2014


четверг, 23 января 2014 г. пользователь Gena Makhomed написал:

> On 23.01.2014 13:53, Илья Шипицин wrote:
>
>  Еще одной точки отказа тут нет, nginx в любом случае используется.
>>> nginx стартует с рутовыми правами и доступ к сертификатам у него есть.
>>> Если сервер не принял сертификат - значит у этого клиента доступа нет.
>>>
>>
>> еще одна точка отказа тут есть.
>> nginx предъявляет свой сертификат серверу, сервер может отказать либо
>> потому что у пользователя нет доступа, либо в силу того, что сервер не
>> смог скачать CRL
>>
>
> Какая разница, кто делает исходящий https-запрос - nginx или backend ?
> Тем более, что CRL скачивать не надо - это локальный файл. Экзотические
> варианты "сломалась файловая система" и т.п. предлагаю не рассматривать.



CRL это свойство удостоверяющего центра, выпустившего сертификат клиента. в
этом свойстве публикуется URL, по которому можно скачать актуальный список
отозванных сертификатов. или не скачать, если по каким-то причинам адрес
недоступен. посмотрите какой-нибудь корневой сертификат, там есть параметр
CDP (CRL distribution point), о нем речь


CRL в файлике - да, так делают, но это не общий случай. как файлик узнает,
что удостоверяющий центр отозвал очередной сертификат?


>
>  надо либо в одном случае возвращать "temp fail", в другом "perm fail",
>> либо что-то еще, но логику отработки ошибок надо как-то реализовывать на
>> стороне приложения
>>
>
> Почему надо возвращать "temp fail", если у пользователя нет доступа?
> Доступа нет, а потом он появляется? Так бывает только в анекдотах:


именно так. доступа нет по причинам не зависящим напрямую от клиента и
сервера
кроме магии с CRL очень легко налететь на. ситуацию "протухший сертификат"
(истек срок действия)


>
> Китайцы взломали сервер Пентагона, вот как это было:
> 1. Каждый китаец попробовал один пароль.
> 2. Каждый второй пароль был "Мао Цзедун"
> 3. На 74357181-й попытке- сервер согласился, что у него пароль "Мао Цзедун"
>
>  Если вся логика работы с TLS/SSL будет только на уровне nginx - это
>>> нормально, а если часть там, часть там - то это layering violation.
>>>
>>
>> если вся логика с ssl на стороне nginx, это точка отказа
>>
>
> Если используется только nginx - новых точек отказа не добавляется.
> Если использовать еще дополнительно stunnel или OpenVPN - тогда
> в системе появляются новые точки отказа, которых до того не было.
>
>  необязательно на C/C++, можно на nginx-lua за полдня набросать
>>> то, что вы хотите.
>>>
>>
>>     Каким образом, разве nginx-lua сможет добавить к proxy_pass
>>     ту функциональность, которой там сейчас нет, в частности, передачу
>>     на удаленный сервер клиентского сертификата и проверку серверного?
>>
>> content_by_lua и любой креатив в ваших силах
>> ценой, возможно, большого оверхеда
>>
>
> http://wiki.nginx.org/HttpLuaModule#content_by_lua
>
> Acts as a "content handler" and executes Lua code string specified in
> <lua-script-str> for every request. The Lua code may make API calls and is
> executed as a new spawned coroutine in an independent global environment
> (i.e. a sandbox).
>
> Чем поможет "make API calls", если в nginx этой функциональности нет?



в content_by_lua можно запилить любой код на Lua и вернуть ответ в терминах
nginx


>
>  Логично же делать максимальный уровень защиты
>>> через Mutual authentication между сервисами.
>>>
>>
>> у нас одна из любимых ошибок - "неидемпотентность сервиса", то есть, к
>> примеру есть несколько экземпляров одного сервиса. мы обращаемся к
>> сервису, делаем запрос "поменяй то-то и то-то", запрос уходит в таймаут,
>> что делать ?
>>
>> идеальной была бы ситуация, когда многократно выполенный запрос не
>> приводил бы к многократному изменению данных (это ведь, по сути, один и
>> тот же запрос). такие типы сервисов называются "идемпотентными".
>>
>> если сервис таким свойством не обладает, в каких-то случаях лучше
>> зафейлиться, чем уходить на следующую реплику
>>
>> а теперь представьте, что вы "прячете" топологию сервисов за nginx, все
>> становится еще сложнее, у nginx в коде события "tcp connect timeout"
>> (когда запрос не ушел и безопасно его еще раз повторить) и "http
>> response timeout" (когда надо быть максимально аккуратным) выглядят
>> одинаково
>>
>> кстати, надо будет патч на эту тему сделать ))
>>
>
> Прятать топологию сервисов за nginx - это имхо общепринятая практика.
> Если один backend не смог ответить на запрос - он направляется
> на обработку другому.
>
> Да, сервисы желательно делать идемпотентными. Это понятно.
> Но к вопросу создания Mutual authentication между сервисами
> средствами nginx вопросы идемпотентности какое имеют отношение?


nginx к этому имеет ровно то отношение, что у него срабатывает
proxy_next_upstream, то есть кроме шифрования он делает перебор реплик



>
> Грубо говоря, Mutual authentication с помощью "магии"
> превращает незащищенное http соединение в высокозащищенное
> HTTPS соединение. А софт на backend`е об этом не должен знать,
> точно так же как он не должен знать про особенности работы TCP
> протокола или про нюансы маршрутизации IP пакетов в сетях Ethernet.


ох уж эти затейники "приложение не должно знать про маршрутизацию IP", вот
смотрите, приложение пишет в tcp сокет 1 байт и не хочет ничего знать про
пакеты. что должна делать операционка ? добавить 40 байт хедера и отправить
пакет, в котором будет 1 байт данных на 40 байт хедера ? подождать, может
будут еще данные ? а если их долго не будет ?

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




>
> Вот потому и говорю, что по моим ощущениям, переносить логику работы
> с Mutual authentication на backend - это есть 100% layering violation.


а вы никому не говорите про violation )) никто и не заметит


>
>      Вот например, реальная задача. Есть небольшой хостинг -
>>     несколько десятков сайтов, которые созданы под заказ.
>>
>>     Вместо того, чтобы для каждого сайта создавать свою админку,
>>     цеплять к ней SSL-сертификат, - проще и удобнее сделать всего
>>     одну админку, куда будут заходить пользователи по https,
>>     и там они смогут управлять своими сайтами. А сами сайты:
>>
>>     www.example.com <http://www.example.com> - сюда ходят пользователи
>> сайта
>>     api.example.com <http://api.example.com> - сюда ходит админка с
>>     Mutual authentication
>>
>>     Сейчас - сайтов десятки, потом может быть сотни и тысячи.
>>     И что делать, настраивать и поддерживать в живом состоянии
>>     сотни и тысячи stunnel`ей? Каждому выделяя свой отдельный
>>     порт на стороне контейнера с админкой? Это будет nightmare.
>>     Практически это нереальный вариант. Наверное придется таки
>>     идти на layering violation и обучать админку делать https-
>>     запросы с предъявлением клиентского сертификата через curl.
>>
>> реальна задача- это замечательно, но я не понял, в каком месте возникает
>> профит от mutual authentication, вероятно, надо больше деталей
>>
>
> Клиентские сайты могут быть размещены как на серверах компании,
> которая занималась созданием этих сайтов, так и на собственных
> серверах клиента. Управлять желательно и теми и теми одинаковым
> образом из одной админки, чтобы не было "вагонов двух типов" -


админка это свойство сайта, нехай бы и жила там же где сайт. если вы
захотите внедрить доработку на конкретный сайт, за что остальные должны
страдать?




> про которые говорил Дейкстра в своей знаменитой притче:
> http://www.vspu.ac.ru/~chul/dijkstra/pritcha/pritcha.htm
>
>  если вы хотите проверять серты на nginx и сообщать приложению, это
>> делается через переменные nginx, у нас такой сценарий используется, могу
>> конфиги помочь составить
>>
>
> Серверную часть " ... =(HTTPS)=> nginx2 =(http)=> tomcat2"
> я уже настроил и здесь все работает просто отлично.
>
> Кстати, сообщать приложению о том, что кто-то пытается
> подключиться к api.example.com с невалидным сертификатом
> не надо, смысла в этом никакого нет.


есть ситуации, когда это работает.
пример, есть домен с приложением, ssl используется для транспорта,
пользователи ходят без сертификатов, на этом же домене по оптеделенному
адресу, скажем /api/ работает сервис, который авторизует по сертификатам.

поэтому сертификат мы не требуем, но если есть - передаем в приложение и
пусть оно само разбирается, кто это пришел


>
> Проблемы осталась пока что только с настройкой
> вот этой части: "tomcat1 =(http)=> nginx1 =(HTTPS)=> ..."
> Не получается сделать так, чтобы nginx1 предъявлял удаленному
> сервису свой клиентский сертификат и проверял сертификат
> удаленного сервиса.
>
>      ==============================__============================
>>
>>     Вторая задача - это большой веб-сервис, который построен
>>     с использованием Micro Service Architecture, физически
>>     размещен на нескольких серверах с горизонтальным масштабированием
>>
>> nginx ломает идею горизонтального масштабирования, или вы планируете
>> горизонтально плодить много экземпляров nginx?
>>
>
> Если есть 25 экземпляров tomcat`а - и каждый из них делает исходящие
> запросы через свой nginx на 127.0.0.1:8080 - то понятно, что экземпляров
> nginx тоже будет много, как минимум по количеству серверов/контейнеров.
> И да, для простоты администрирования системы, 1 приложение == 1 tomcat.


а tomcat будет ходить только на свой nginx ?

>
>  tomcat1 =(http)=> nginx1 =(HTTPS)=> nginx2 =(http)=> tomcat2
>>
>
> --
> Best regards,
>  Gena
>
> _______________________________________________
> nginx-ru mailing list
> nginx-ru at nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx-ru
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/nginx-ru/attachments/20140123/c200f8b7/attachment-0001.html>


Подробная информация о списке рассылки nginx-ru