Безопасность internal сервисов

#AWS #security

Вы не поверите, но это новый пост. Третий раз сажусь за статью и снова её переписываю.

Итак, давайте поговорим о безопасности. Не о той, что сложная, а о базовой.

Допустим у вас есть облако и в нём есть какие-то инфраструктурные сервисы. Пусть будет графана и кибана. Как обычно происходит? Мы настраиваем какой-то лдап или не настраиваем и открываем сервис в мир. Кто ж на него зайдёт, если пароль знаем только мы?

Да в принципе кто угодно. Сервисы полны уязвимостей и надо постоянно следить за тем чтобы его не взломали и постоянно обновлять. В смысле даже в два часа ночи из пивнушки.

Как обычно решают эту проблему? Ну можно насетапить VPN.

Правда VPN тоже обычно не очень хорошо подходит. Особенно когда появляются пользователи которым надо дать доступ к одному сервису, но не надо давать к другому. Опять же единая точка отказа, все дела. Не удобно. Естественно я знаю что можно рулить разными VLANами, подсетями, но вот честно, я ни разу не видел чтобы такая система работала хорошо и без сбоев и чтобы новый сервис добавлялся без тикета админам.

В гугле вот тоже подумали что это не удобно и сделали BeyondCorp - штуку которая занимается аутентификацией и только аутентификацией. А ребята из cloudflare подсуетились и сделали аналог.

Получается так: юзер заходит на сайт, ему предлагают пройти аутентификацию, он проходит, после чего сервис начинает проксировать запросы на ваш сервис. Тут тоже два пути: можно настроить проксю внутрь периметра, а можно просто ограничить доступ к сервису с айпишников cloudflare. В принципе неплохо придумано.

Но есть ещё один хитрый вариант - AWS cognito. Это сервис от AWS, который имеет кучу интеграций с разными там фейсбуками, гуглом, AWS и всякие там openid и SAML, что делает его чертовски удобным.

Так что если теперь мы хотим дать доступ к какой-то графане, то нам надо просто сделать ALB и прописать там редирект на когнито, который уже и будет заниматься безопасностью. Вот тут написано подробнее.

Штука работает отлично и даже умеет передавать параметры юзера в хедерах. То есть в случае с графаной и разными другими сервисами можно пропустить второй шаг аутентификации и использовать auth-proxy. Впрочем, для этого вам будет необходимо расшифровать параметры которые ALB будет вам передавать в заголовке x-amzn-oidc-accesstoken, который представляет из себя JWT. Можно написать простенький сервис который будет это делать или добавить пару строк на LUA в openresty/nginx. Зато в итоге юзер пройдя аутентификацию на стороне Cognito будет авторизован в grafana. Если у вас разные роли для разных пользователей это может быть полезным.

Чем мне нравится такой подход?

  1. Он децентрализован. На каждый сервис можно создать отдельный балансер и отдельный юзер пул в cognito с своими настройками. Даже если что-то одно отвалится, второе продолжит работать.
  2. Намного проще давать доступ. Не надо сетапить какие-то клиенты, ничего настраивать, юзеры просто используют бразуер и пароль, который вы им дали (ну или вообще если уже залогинены в какой-то google, то всё происходит автоматически)
  3. Можно легко автоматизировать при помощи terraform.
  4. Безопасноть аутентификации это уже чужая головная боль, а не моя. Конечно, на каком-то уровне страшно отдавать безопасность в руки SaaS. Как мне сказал один безопасник (на серьезных щах, между прочим) "А что будет если SAML взломают? Мы должны это контролировать". Единственное что я могу тут ответить, что если взломают SAML или взломают AWS, то ваша инфраструктура, вероятнее всего, будет где-то в конце списка целей для атаки. Опять же ночью будут просыпаться спецы AWS. Да и балансеры можно просто потушить и ждать пока починят или переходить на какие-то экстра варианты.

В общем, такой подход к безопасности внутренних сервисов мне очень нравится и я его смело рекомендую.