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

Илья Шипицин chipitsine at gmail.com
Thu Jan 23 06:40:17 UTC 2014


23 января 2014 г., 2:49 пользователь Gena Makhomed <gmm at csdoc.com> написал:
> On 22.01.2014 16:18, Илья Шипицин wrote:
>
>> очевидно, если пользователь предъявляет вам сертификат,
>> то у него есть закрытый ключ.
>
>>
>>
>> чтобы nginx смог дальше предъявить этот же сертификат, получается надо
>> дубликаты всех пользовательских закрытых ключей держать на nginx ?
>>
>> или вы какой-то другой сценарий имели в виду ?
>
>
> Другой сценарий.
>
> Есть два сервера. На каждом из этих двух серверов работает
> веб-сервис, который отвечает на запросы пользователей по протоколу
> http и https. Кроме того, этим двум сервисам надо время от времени
> обмениваться между собой информацией. Причем канал связи между ними
> надо сделать максимально защищенным, так чтобы никто посторонний
> не мог отправлять пакеты одному сервису от имени другого сервиса.
>
> Самый надежный вариант, что я смог придумать - это сделать
> свой собственный Certificate authority (с помощью easy-rsa)
> создать в нем сертификаты для каждого сервера и каждого клиента,
> и настроить проверку всех клиентских и серверных сертификатов
> на уровне nginx.
>
> Каждый из этих двух веб-сервисов выступает одновременно
> и в роли клиента и в роли сервера при связи друг с другом.
>
> Все что связано с сертификатами и TLS/SSL хотелось бы оставить
> на уровне nginx, чтобы веб-сервисам приходил plain http,
> и разработчикам этих веб-сервисов не приходилось бы потом
> заморачиваться с https-запросами и клиентскими сертификатами.

это чревато тем, что для приложения вся ваша магия выльется в "еще
одну точку отказа", как вы выразились.
как приложение отреагирует, если магия сломается ? а сломаться она
может легко, например, нет доступа к CRL-ке и сервер не принял
сертификат, который ему предъявил nginx


>
> Если веб-приложение работает как сервер - ему запрос приходит
> на http://127.0.0.1:80/ а если веб-приложение работает как клиент
> и хочет связаться с другим веб-сервисом - то оно просто отправляет
> plain http запрос на http://127.0.0.1:8080/ - здесь слушает nginx
> и проксирует этот запрос через https с mutual auth на удаленный сервер.

необязательно на C/C++, можно на nginx-lua за полдня набросать то, что
вы хотите.

>
> Если nginx работает в роли сервера - тогда без проблем можно
> настроить проверку валидности клиентского сертификата.
> Приблизительно вот так:
>
> server {
>     listen 11.22.33.44:555 ssl;
>     ...
>     ssl_client_certificate /etc/tls/api.example.com/ca.crt;
>     ssl_verify_client on;
>
>     # allow connection only for client with certificate with serial "01"
>     if ($ssl_client_serial != "01") { return 403; }
>
> Но если nginx работает в роли клиента и проксирует запросы от сервиса
> к другому серверу через proxy_pass https:// - тут не получается
> настроить его, чтобы он предъявлял свой клиентский сертификат
> и чтобы проверял валидность серверного сертификата.
>
> Скорее всего - такой функциональности сейчас в nginx таки нет.
> Только не понятно - ее "еще нет" или же "вообще нет и не будет".
>
> Подозреваю, что такая функциональность в nginx будет полезной
> не только мне, но и большому количеству других пользователей.

очень легко уйти в холивар насчет "полезно ли большому количеству пользователей"

>
> И возможно это даже будет killer feature, которая позволит
> еще больше увеличить % использование nginx в современном
> web 2.0 и будущем web 3.0. Если это кому-то интересно.
>
> Альтернативные варианты - это разве что OpenVPN.
> Но nginx надежнее и удобнее в эксплуатации.
>
> Тем более, что в общем случае может быть больше чем два
> таких веб-сервиса, которые взаимодействуют между собой.

сейчас немного другой тренд.
скажем так, OAuth
но там вся логика строится на приложении, не на транспорте.

Майкрософт эту тему двигает, у него она называется "Claim based access
control" (раньше любимая тема была RBAC = role based access control)

>
> Может быть я ошибаюсь, но с моей точки зрения идеальным
> вариантом решения этой и многих других подобных задач -
> было бы научить nginx работать в таком proxy_pass режиме.
>
> Самому писать такой патч - я полгода наверное буду вспоминать
> все нюансы работы С/С++ и разбираться с устройством OpenSSL.
> Тем более, что еще не факт, что его примут в основную ветку.
>
> Если бы существовала в природе Nginx Foundation и можно было
> бы пожертвовать некоторое количество денег, обозначив свой интерес
> в том чтобы в nginx появилась такая feature - я бы не задумываясь
> часть своей зарплаты потратил бы на то, чтобы "проголосовать" за нее.
> Возможно, если это надо не только мне, но и другим людям - тогда
> эта задача поднялась бы повыше в списке приоритетов на разработку.
>
> Могу даже попробовать пойти к начальству и предложить вариант
> чтобы компания единолично спонсировала появление такой feature
> в nginx, которая была бы полезной для реализации этой задачи.
>
> Но прежде чем куда-то идти и о чем-то просить - вот сначала
> попытался узнать в списке рассылки - может быть я какой-то
> неправильный вариант решения для этой задачи придумал
> и ее все обычно решают другим, более простым способом?

вариант как вариант.
сейчас модно креативить :-)

>
> Или же по каким-то техническим или идеологическим причинам
> такая feature никогда не может быть добавлена в nginx,
> и поэтому мне надо искать какие-то другие варианты
> решения для этой нашей задачи?
>
>
>
>
>>> Как сделать Mutual authentication
>>> между двумя сервисами с помощью nginx?
>>>
>>> На двух разных серверах nginx слушает на порту 443
>>> и проксирует клиентские запросы на порт 80 backend`а.
>>>
>>> "На вход" проверка клиентского сертификата работает отлично.
>>> А когда backend делает клиентский запрос на 127.0.0.1:8080 -
>>> nginx проксирует этот запрос на 443 порт удаленного сервера
>>> по https. Но как сделать так, чтобы при proxy_pass nginx
>>> еще и предьявлял клиентский сертификат удаленному сервису?
>>>
>>> Или какой софт можно использовать здесь вместо nginx,
>>> если nginx это делать не умеет и такая функциональность
>>> в нем никогда не будет реализована по каким-то причинам?
>>> Хотя, это наверное была бы killer feature, полезная многим.
>>>
>>> Если только принимать https-запросы на уровне nginx,
>>> а отправлять https-запросы через само приложение
>>> - тогда будет layering violation и клиентскому
>>> приложению придется давать доступ к файлу ключа.
>>>
>>> Может быть кто-то уже решал такую или похожую задачу?
>
>
> --
> Best regards,
>  Gena
>
> _______________________________________________
> nginx-ru mailing list
> nginx-ru at nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx-ru


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