<br><br>четверг, 23 января 2014 г. пользователь Gena Makhomed  написал:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On 23.01.2014 13:53, Илья Шипицин wrote:<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Еще одной точки отказа тут нет, nginx в любом случае используется.<br>
nginx стартует с рутовыми правами и доступ к сертификатам у него есть.<br>
Если сервер не принял сертификат - значит у этого клиента доступа нет.<br>
</blockquote>
<br>
еще одна точка отказа тут есть.<br>
nginx предъявляет свой сертификат серверу, сервер может отказать либо<br>
потому что у пользователя нет доступа, либо в силу того, что сервер не<br>
смог скачать CRL<br>
</blockquote>
<br>
Какая разница, кто делает исходящий https-запрос - nginx или backend ?<br>
Тем более, что CRL скачивать не надо - это локальный файл. Экзотические<br>
варианты "сломалась файловая система" и т.п. предлагаю не рассматривать.</blockquote><div><br></div><div><br></div><div>CRL это свойство удостоверяющего центра, выпустившего сертификат клиента. в этом свойстве публикуется URL, по которому можно скачать актуальный список отозванных сертификатов. или не скачать, если по каким-то причинам адрес недоступен. посмотрите какой-нибудь корневой сертификат, там есть параметр CDP (CRL distribution point), о нем речь</div>
<div><br></div><div><br></div><div>CRL в файлике - да, так делают, но это не общий случай. как файлик узнает, что удостоверяющий центр отозвал очередной сертификат?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
надо либо в одном случае возвращать "temp fail", в другом "perm fail",<br>
либо что-то еще, но логику отработки ошибок надо как-то реализовывать на<br>
стороне приложения<br>
</blockquote>
<br>
Почему надо возвращать "temp fail", если у пользователя нет доступа?<br>
Доступа нет, а потом он появляется? Так бывает только в анекдотах:</blockquote><div><br></div><div>именно так. доступа нет по причинам не зависящим напрямую от клиента и сервера</div><div>кроме магии с CRL очень легко налететь на. ситуацию "протухший сертификат" (истек срок действия)</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Китайцы взломали сервер Пентагона, вот как это было:<br>
1. Каждый китаец попробовал один пароль.<br>
2. Каждый второй пароль был "Мао Цзедун"<br>
3. На 74357181-й попытке- сервер согласился, что у него пароль "Мао Цзедун"<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Если вся логика работы с TLS/SSL будет только на уровне nginx - это<br>
нормально, а если часть там, часть там - то это layering violation.<br>
</blockquote>
<br>
если вся логика с ssl на стороне nginx, это точка отказа<br>
</blockquote>
<br>
Если используется только nginx - новых точек отказа не добавляется.<br>
Если использовать еще дополнительно stunnel или OpenVPN - тогда<br>
в системе появляются новые точки отказа, которых до того не было.<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
необязательно на C/C++, можно на nginx-lua за полдня набросать<br>
то, что вы хотите.<br>
</blockquote>
<br>
    Каким образом, разве nginx-lua сможет добавить к proxy_pass<br>
    ту функциональность, которой там сейчас нет, в частности, передачу<br>
    на удаленный сервер клиентского сертификата и проверку серверного?<br>
<br>
content_by_lua и любой креатив в ваших силах<br>
ценой, возможно, большого оверхеда<br>
</blockquote>
<br>
<a href="http://wiki.nginx.org/HttpLuaModule#content_by_lua" target="_blank">http://wiki.nginx.org/<u></u>HttpLuaModule#content_by_lua</a><br>
<br>
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).<br>

<br>
Чем поможет "make API calls", если в nginx этой функциональности нет?</blockquote><div><br></div><div><br></div><div>в content_by_lua можно запилить любой код на Lua и вернуть ответ в терминах nginx</div><div> </div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Логично же делать максимальный уровень защиты<br>
через Mutual authentication между сервисами.<br>
</blockquote>
<br>
у нас одна из любимых ошибок - "неидемпотентность сервиса", то есть, к<br>
примеру есть несколько экземпляров одного сервиса. мы обращаемся к<br>
сервису, делаем запрос "поменяй то-то и то-то", запрос уходит в таймаут,<br>
что делать ?<br>
<br>
идеальной была бы ситуация, когда многократно выполенный запрос не<br>
приводил бы к многократному изменению данных (это ведь, по сути, один и<br>
тот же запрос). такие типы сервисов называются "идемпотентными".<br>
<br>
если сервис таким свойством не обладает, в каких-то случаях лучше<br>
зафейлиться, чем уходить на следующую реплику<br>
<br>
а теперь представьте, что вы "прячете" топологию сервисов за nginx, все<br>
становится еще сложнее, у nginx в коде события "tcp connect timeout"<br>
(когда запрос не ушел и безопасно его еще раз повторить) и "http<br>
response timeout" (когда надо быть максимально аккуратным) выглядят<br>
одинаково<br>
<br>
кстати, надо будет патч на эту тему сделать ))<br>
</blockquote>
<br>
Прятать топологию сервисов за nginx - это имхо общепринятая практика.<br>
Если один backend не смог ответить на запрос - он направляется<br>
на обработку другому.<br>
<br>
Да, сервисы желательно делать идемпотентными. Это понятно.<br>
Но к вопросу создания Mutual authentication между сервисами<br>
средствами nginx вопросы идемпотентности какое имеют отношение?</blockquote><div><br></div><div>nginx к этому имеет ровно то отношение, что у него срабатывает proxy_next_upstream, то есть кроме шифрования он делает перебор реплик</div>
<div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Грубо говоря, Mutual authentication с помощью "магии"<br>
превращает незащищенное http соединение в высокозащищенное<br>
HTTPS соединение. А софт на backend`е об этом не должен знать,<br>
точно так же как он не должен знать про особенности работы TCP<br>
протокола или про нюансы маршрутизации IP пакетов в сетях Ethernet.</blockquote><div><br></div><div>ох уж эти затейники "приложение не должно знать про маршрутизацию IP", вот смотрите, приложение пишет в tcp сокет 1 байт и не хочет ничего знать про пакеты. что должна делать операционка ? добавить 40 байт хедера и отправить пакет, в котором будет 1 байт данных на 40 байт хедера ? подождать, может будут еще данные ? а если их долго не будет ? </div>
<div><br></div><div>обычно прятание технических подробностей за несколькими уровнями абстракции приводит к запутанным ситуациям. не надо так делать</div><div><br></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<br>
Вот потому и говорю, что по моим ощущениям, переносить логику работы<br>
с Mutual authentication на backend - это есть 100% layering violation.</blockquote><div><br></div><div>а вы никому не говорите про violation )) никто и не заметит</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
    Вот например, реальная задача. Есть небольшой хостинг -<br>
    несколько десятков сайтов, которые созданы под заказ.<br>
<br>
    Вместо того, чтобы для каждого сайта создавать свою админку,<br>
    цеплять к ней SSL-сертификат, - проще и удобнее сделать всего<br>
    одну админку, куда будут заходить пользователи по https,<br>
    и там они смогут управлять своими сайтами. А сами сайты:<br>
<br>
    <a href="http://www.example.com" target="_blank">www.example.com</a> <<a href="http://www.example.com" target="_blank">http://www.example.com</a>> - сюда ходят пользователи сайта<br>
    <a href="http://api.example.com" target="_blank">api.example.com</a> <<a href="http://api.example.com" target="_blank">http://api.example.com</a>> - сюда ходит админка с<br>
    Mutual authentication<br>
<br>
    Сейчас - сайтов десятки, потом может быть сотни и тысячи.<br>
    И что делать, настраивать и поддерживать в живом состоянии<br>
    сотни и тысячи stunnel`ей? Каждому выделяя свой отдельный<br>
    порт на стороне контейнера с админкой? Это будет nightmare.<br>
    Практически это нереальный вариант. Наверное придется таки<br>
    идти на layering violation и обучать админку делать https-<br>
    запросы с предъявлением клиентского сертификата через curl.<br>
<br>
реальна задача- это замечательно, но я не понял, в каком месте возникает<br>
профит от mutual authentication, вероятно, надо больше деталей<br>
</blockquote>
<br>
Клиентские сайты могут быть размещены как на серверах компании,<br>
которая занималась созданием этих сайтов, так и на собственных<br>
серверах клиента. Управлять желательно и теми и теми одинаковым<br>
образом из одной админки, чтобы не было "вагонов двух типов" -</blockquote><div><br></div><div>админка это свойство сайта, нехай бы и жила там же где сайт. если вы захотите внедрить доработку на конкретный сайт, за что остальные должны страдать?</div>
<div><br></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
про которые говорил Дейкстра в своей знаменитой притче:<br>
<a href="http://www.vspu.ac.ru/~chul/dijkstra/pritcha/pritcha.htm" target="_blank">http://www.vspu.ac.ru/~chul/<u></u>dijkstra/pritcha/pritcha.htm</a><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
если вы хотите проверять серты на nginx и сообщать приложению, это<br>
делается через переменные nginx, у нас такой сценарий используется, могу<br>
конфиги помочь составить<br>
</blockquote>
<br>
Серверную часть " ... =(HTTPS)=> nginx2 =(http)=> tomcat2"<br>
я уже настроил и здесь все работает просто отлично.<br>
<br>
Кстати, сообщать приложению о том, что кто-то пытается<br>
подключиться к <a href="http://api.example.com" target="_blank">api.example.com</a> с невалидным сертификатом<br>
не надо, смысла в этом никакого нет.</blockquote><div><br></div><div>есть ситуации, когда это работает.</div><div>пример, есть домен с приложением, ssl используется для транспорта, пользователи ходят без сертификатов, на этом же домене по оптеделенному адресу, скажем /api/ работает сервис, который авторизует по сертификатам.</div>
<div><br></div><div>поэтому сертификат мы не требуем, но если есть - передаем в приложение и пусть оно само разбирается, кто это пришел</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<br>
Проблемы осталась пока что только с настройкой<br>
вот этой части: "tomcat1 =(http)=> nginx1 =(HTTPS)=> ..."<br>
Не получается сделать так, чтобы nginx1 предъявлял удаленному<br>
сервису свой клиентский сертификат и проверял сертификат<br>
удаленного сервиса.<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
    ==============================<u></u>__============================<br>
<br>
    Вторая задача - это большой веб-сервис, который построен<br>
    с использованием Micro Service Architecture, физически<br>
    размещен на нескольких серверах с горизонтальным масштабированием<br>
<br>
nginx ломает идею горизонтального масштабирования, или вы планируете<br>
горизонтально плодить много экземпляров nginx?<br>
</blockquote>
<br>
Если есть 25 экземпляров tomcat`а - и каждый из них делает исходящие<br>
запросы через свой nginx на <a href="http://127.0.0.1:8080" target="_blank">127.0.0.1:8080</a> - то понятно, что экземпляров<br>
nginx тоже будет много, как минимум по количеству серверов/контейнеров.<br>
И да, для простоты администрирования системы, 1 приложение == 1 tomcat.</blockquote><div><br></div><div>а tomcat будет ходить только на свой nginx ? </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
tomcat1 =(http)=> nginx1 =(HTTPS)=> nginx2 =(http)=> tomcat2<br>
</blockquote>
<br>
-- <br>
Best regards,<br>
 Gena<br>
<br>
______________________________<u></u>_________________<br>
nginx-ru mailing list<br>
<a>nginx-ru@nginx.org</a><br>
<a href="http://mailman.nginx.org/mailman/listinfo/nginx-ru" target="_blank">http://mailman.nginx.org/<u></u>mailman/listinfo/nginx-ru</a></blockquote>