====== Nginx и Keycloak: Идеальное сочетание для обеспечения безопасности приложений ======
В современной быстро меняющейся цифровой среде обеспечение надежной безопасности на каждом этапе взаимодействия с пользователем имеет первостепенное значение. Хотя существует множество инструментов для защиты наших приложений, найти идеальное сочетание между ними может быть непросто. На помощь приходит динамичный дуэт: Nginx и Keycloak. В паре эти инструменты обеспечивают мощное решение по обеспечению безопасности вашего приложения. Nginx, известный своей высокой производительностью и масштабируемостью, в сочетании с надежными механизмами аутентификации и авторизации Keycloak строит крепость, защищающую ваши приложения от несанкционированного доступа. В этой статье будут рассмотрены тонкости этой привлекательной комбинации и показано, как можно использовать их общие преимущества для создания надежного и удобного шлюза для ваших приложений.
Прежде чем погрузиться в рассмотрение Nginx и Keycloak, давайте вернемся к некоторым основополагающим концепциям безопасности.
==== Понимание разницы: Аутентификация vs Авторизация ====
В сфере безопасности часто встречаются термины "аутентификация" и "авторизация". Хотя они могут звучать похоже и иногда используются как взаимозаменяемые, все же имеют разные значения и функции. Давайте разберемся в каждом из этих терминов, чтобы понять их разницу и важность.
=== 1. Аутентификация ===
Определение: Аутентификация - это процесс проверки подлинности личности пользователя, системы или приложения. Она отвечает на вопрос: «Вы тот, за кого себя выдаете?»
Как это работает: Наиболее распространенной формой аутентификации является комбинация имени пользователя и пароля. Когда пользователь вводит эти учетные данные, система сравнивает их с сохраненными данными, чтобы подтвердить его личность. Другие методы включают биометрию (например, распознавание отпечатков пальцев или лица), OTP (одноразовые пароли) и аппаратные токены.
**Примеры:**
Ввод пароля для входа в учетную запись электронной почты.
Использование отпечатка пальца для разблокировки смартфона.
Получение SMS-кода для подтверждения личности на сайте банка.
=== 2. Авторизация ===
Определение: После того как аутентификация установлена, авторизация определяет, что разрешено делать пользователю, системе или приложению. Она отвечает на вопрос: "Есть ли у вас разрешение на выполнение этого действия?".
Как это работает: Авторизация обычно управляется путем установки разрешений или ролей. Например, пользователю может быть предоставлен доступ к базе данных только для чтения, в то время как администратор имеет право как читать, так и изменять ее.
**Примеры:**
Обычный сотрудник может получить доступ к порталу компании, но не может вносить изменения в определенные важные документы. Администратор, напротив, может изменять, удалять и даже делиться этими документами.
В приложении для обмена файлами можно предоставить одним пользователям возможность просматривать файл, а другим - редактировать его.
Хотя и аутентификация, и авторизация играют важную роль в безопасности, они служат разным целям:
Аутентификация гарантирует, что вы общаетесь с нужным субъектом, подтверждая его личность.
Авторизация гарантирует, что у субъекта есть разрешения на выполнение определенных действий.
**Что такое шлюз (Gateway)?**
Также известный как API-шлюз (API Gateway) - это инструмент, который выступает в качестве посредника для запросов от клиентов, ищущих ресурсы на других серверах или сервисах. Многие организации используют шлюзы API в микросервисных архитектурах для управления и обеспечения безопасности сложных взаимодействий между микросервисами. Популярные API-шлюзы: Amazon API Gateway, Kong, Apigee и WSO2.
==== Как защитить приложение? ====
Представим, что мы разрабатываем веб-приложение, состоящее из трех компонентов:
* Одностраничное приложение (SPA), созданное с помощью таких фреймворков, как React или Angular.
* Data Service обрабатывает все CRUD-операции, связанные с нашими доменами, и управляет подключением к базе данных.
* Report Service получает данные из Data Service и инкапсулирует логику для генерации пользовательских отчетов.
{{https://habrastorage.org/r/w1560/getpro/habr/upload_files/2db/cf9/a95/2dbcf9a959e73e9601bdd0dfda1a2cf1.png?nolink&}}
Пример архитектуры приложения
Когда речь заходит о защите бэкенда, следует рассмотреть три основные стратегии:
1. Каждый микросервис выполняет собственную аутентификацию и авторизацию.
2. Шлюз занимается аутентификацией, а отдельные сервисы отвечают за авторизацию.
3. Шлюз обеспечивает как аутентификацию, так и авторизацию.
Каждый подход имеет свои сильные и слабые стороны. Для краткости в этой статье не будем вдаваться в подробности того, какая стратегия лучше. По правде говоря, определение наилучшего варианта требует всестороннего понимания системы, о которой идет речь.
В следующих разделах мы подробно рассмотрим вторую и третью стратегии, сосредоточившись на том, как NGINX и Keycloak могут эффективно использоваться для этих целей.
==== Что такое Keycloak? ====
Keycloak - это инструмент управления идентификацией и доступом (IAM) с открытым исходным кодом, разработанный компанией Red Hat. Он предоставляет расширенные функции, такие как SSO (технология единого входа в систему), Identity Brokering (посредничество в установлении личности) и Social Login (вход в систему через социальные сети), не требуя глубоких знаний в области безопасности.
Сочетание гибкости, широкого функционала и активной поддержки сообщества укрепило репутацию Keycloak в области управления идентификацией и доступом. Поскольку компании продолжают искать эффективные способы управления идентификационными данными без ущерба для безопасности, такие инструменты, как Keycloak, остаются незаменимыми.
==== Что такое Nginx? ====
Nginx был создан Игорем Сысоевым в 2002 году, а первый публичный релиз состоялся в 2004 году. Изначально разработанный для решения проблемы C10K (обработка 10 000 одновременных соединений), Nginx создавался с нуля для высокоэффективности и масштабируемости.
По своей сути Nginx - это веб-сервер. Но за прошедшие годы он превратился в нечто большее. Сегодня Nginx также может работать как обратный прокси-сервер, балансировщик нагрузки, прокси-сервер почты и даже HTTP-кэш.
**Недостатки Nginx Plus**
Nginx предлагает бесплатную версию своего программного обеспечения, но есть и платная версия премиум-класса, известная как Nginx Plus. В то время как Nginx Plus поддерживает единый вход с Keycloak, бесплатная версия, к сожалению, этого не делает. Это немного разочаровывает, учитывая популярность как Nginx, так и Keycloak. В TargPatrol мы используем оба инструмента, поэтому нам пришлось разработать метод, позволяющий им эффективно взаимодействовать друг с другом.
==== Модернизированная архитектура ====
Давайте внесем некоторые изменения в нашу архитектуру. Обновленная версия изображена на рисунке ниже.
{{https://habrastorage.org/r/w1560/getpro/habr/upload_files/396/c9f/183/396c9f183e30fd92a27450affe6d245b.png?nolink&}}
Модернизированная архитектура приложения
Как показано на рисунке, служба Nginx теперь работает как API-шлюз. Его основная роль заключается в обеспечении аутентификации и авторизации. Тем временем служба Keycloak действует как наш сервер единого входа (SSO). DataService и ReportService обрабатывают запросы, поступающие от Nginx, но они больше не управляют аутентификацией и авторизацией для этих запросов.
Я не буду углубляться в интеграцию SPA с Keycloak в этой статье, поскольку существует множество исчерпывающих ресурсов по этой теме. Например, вы можете обратиться к __[[https://medium.hexadefence.com/securing-a-react-app-using-keycloak-ac0ee5dd4bfc|этому руководству__]]__.
Как мы должны работать с аутентификацией в этом сценарии? Мы можем использовать nginx прокси аутентификации.
Пример nginx конфигурации:
http {
...
location /auth {
proxy_ssl_server_name on;
proxy_pass https://targpatrol-keycloak.local/realms/targpatrol-dev/protocol/openid-connect/userinfo;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
}
location /data {
auth_request /auth;
auth_request_set $auth_status $upstream_status;
error_page 401 = @handle_unauthorized;
proxy_pass http://data-service.local;
include /etc/nginx/common/ssl-headers.conf;
js_content authService.authorize;
}
location /report {
auth_request /auth;
auth_request_set $auth_status $upstream_status;
error_page 401 = @handle_unauthorized;
proxy_pass http://report-service.local;
include /etc/nginx/common/ssl-headers.conf;
js_content authService.authorize;
}
}
Что здесь происходит? Сначала мы определили /auth route, который проверяет наш запрос с помощью Keycloak. Мы просто отправляем запрос с Authorization header в Keycloak, запрашивая информацию о пользователе. Если в заголовке будет указан действительный токен, Keycloak ответит 200 OK, вернув текущие данные пользователя.
Маршруты для сервисов Data и Report содержат инструкцию 'auth_request'. Каждый раз, когда мы пытаемся получить к ним доступ, сначала будет отправлен запрос в Keycloak.
Хорошо, с процессом аутентификации мы разобрались, а как насчет авторизации? Для этого мы можем использовать функциональность nginx под названием ngx_http_js_module. Этот модуль позволяет выполнять JavaScript-код при запросе. Давайте разберемся, что такое 'js_content':
function extractPayload (token) {
const tokenParts = token.split('.');
const encodedPayload = tokenParts[1];
const decodedPayload = Buffer.from(encodedPayload, 'base64').toString('utf-8');
return JSON.parse(decodedPayload);
}
function authorize(request) {
const token = request.headersIn.Authorization;
if (!token || !(token.slice(0, 7) === 'Bearer ')) {
return false;
}
const payload = extractPayload(token);
const roles = payload['roles'];
# request url
const url = request.uri;
# here we can compare url and roles
# to allow or deny access
return false;
}
Этот файл называется authService.js. Он должен содержать функцию с именем authorize, поскольку в инструкции js_content мы ссылаемся на нее как на authService.authorize (в соответствии с форматом fileName.functionName). Здесь можно использовать обычный JavaScript. Сначала мы разбираем заголовок Authorization, чтобы извлечь токен Bearer, который был сгенерирован Keycloak, в объектную форму. Затем мы можем сопоставить роли с URL-адресом запроса, чтобы либо удовлетворить, либо отклонить запрос. Все довольно просто!
Одна из проблем этого подхода заключается в том, что каждый запрос направляется в Keycloak. Возможное решение - перейти от js_content в nginx к сервису Node.js (или другому подходящему языку). Этот сервис будет иметь интеграцию с Keycloak на стороне сервера. Отметим, что эту функцию поддерживает только Nginx Plus, а не бесплатная версия. Для получения более подробной информации вы можете обратиться к: Документация Keycloak. (__[[https://www.keycloak.org/docs/latest/securing_apps/#_nodejs_adapter|Keycloak’s documentation__]]__)
==== Заключение ====
Подводя итог, можно сказать, что сочетание Nginx и Keycloak представляет собой убедительное решение для обеспечения безопасности шлюза. В то время как Nginx эффективно управляет и маршрутизирует веб-трафик, Keycloak обеспечивает надежную аутентификацию и авторизацию. Их совместные возможности создают укрепленный уровень защиты, повышая удобство работы пользователей и безопасность системы. Благодаря бесшовной интеграции этих инструментов компании могут не только повысить уровень защиты, но и оптимизировать работу. Поскольку цифровой ландшафт продолжает развиваться, такие инструменты, как Nginx и Keycloak, становятся незаменимыми для тех, кто ищет сбалансированное сочетание производительности, гибкости и безопасности.