Выделенная безопасность в сервисной архитектуре
От: vsb Казахстан  
Дата: 15.06.22 23:36
Оценка:
Предположим, у нас есть некий набор сервисов. Часть этих сервисов принимает и отправляет запросы снаружи, часть этих сервисов работает друг с другом. Всё на уровне HTTP.

Есть понятие безопасности. Основа это безопасность для запросов в сервис. То бишь сервис обрабатывает не все запросы, а только некоторые. Дополнительно можно добавить безопасность для исходящих запросов.

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

Есть логичная мысль хотя бы часть этого процесса обеспечения безопасности вынести уровнем выше.

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

Во-вторых это что-то вроде фаервола для реверс-прокси. Поясню. Входящие запросы извне идут на реверс-прокси вроде nginx. Можно сделать выделенный сервис для аутентификации, например keycloak. Тогда для всех запросов можно универсально вытаскивать пользователя, его роли. И дальше уже по этим ролям так же универсально осуществлять проверку URL. Ну банально — /admin/* доступно только пользователю с ролью admin. И так написать кучу правил.

Это то, что сделать в целом понятно, как (ну точней пока не понятно, но вроде как инструменты должны быть). Это сделать можно в одном месте и иметь таким образом обзор безопасности всего проекта. Можно делать правила вида deny by default и для нового функционала уже нужно будет специальным образом добавлять правила.

Что мне пока не понятно — это можно ли таким же образом сделать правила безопасности более гранулярные.

Простой пример — форум. Есть функционал для удаления сообщения, ну например HTTP DELETE /messages/123. Удалять могут админы и пользователи свои сообщения. Информация о том, что сообщение пользователя — лежит в базе данных конкретного сервиса. Соответственно не понятно, как подобная безопасность может быть реализована универсально в отрыве от сервиса.

Единственное, что приходит в голову: проектировать URL более вдумчиво. Например HTTP DELETE /admin/messages/123 это функционал для админов. И HTTP DELETE /self/messages/12 это функционал удаления собственных сообщений, причём 12 это некий id сообщения, уникальный для конкретного пользователя, условно — 12-е сообщение текущего пользователя. В таком случае можно сделать универсальные правила безопасности.

Ну ещё приходит в голову ввести некие универсальные понятия ресурса, прав на ресурс. К примеру в базе данных keycloak для каждого сообщения на форуме создаётся ресурс, который привязывается к пользователю. И тогда уже можно сделать правила безопасности в отрыве от логики сервиса. Но это я пишу вообще "от балды", я не знаю, есть ли такое.

Резюмирую цель, чего хочется добиться:

1. Программист сервиса про безопасность вообще не думает. Для него все входящие запросы легитимны. Он думает про то, как реализовать то, для чего этот сервис пишется.

2. Некий программист или администратор высшего уровня уже думает про безопасность, но на более универсальном, на более высоком уровне. В каком-то декларативном виде описывает безопасность системы, лишь самым минимальным образом внося в неё конкретные знания про конкретные сервисы (например конкретные URL-ы).

3. Система не делает никаких компромисов в безопасности в итоге.
Отредактировано 15.06.2022 23:38 vsb . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.