Как внедрить двухфакторную аутентификацию в веб-приложение, не предусматривающее ее изначально

Привет, я — Саша Зеленов, архитектор в Cloud.ru. Делюсь опытом, как мы настроили у себя двухфакторную аутентификацию для веб-приложений, которые сопротивляются прогрессу.

У нас в продуктовом каталоге Cloud.ru есть несколько вендорских сервисов, в которые разработчики не заложили возможность подключения двухфакторной аутентификации или предлагаемая функциональность нас по ряду причин не устраивала. Речь про VMware (Cloud Director Availability и Horizon), Veeam (Cloud Connect, Service Provider Console) и ряд других.

Например, в рамках услуги VDI (Виртуальные рабочие места) нам требовалось сделать Horizon Admin Console доступной за пределами локальной сети, чтобы администраторы наших клиентов могли управлять своей инфраструктурой виртуальных рабочих мест независимо от того, где они находятся.

Вендор предусмотрел только один способ 2FA для доступа к консоли администратора: смарт-карта, которая потребует от нас физически передать клиенту специальные карты и считыватели для них. Еще возможна настройка доступа по сертификату, но тогда клиенту придется настраивать свой ПК для работы с консолью.

Как внедрить двухфакторную аутентификацию в веб-приложение, не предусматривающее ее изначально

Из-за сложности организации подобных работ — закупка, передача, обслуживание оборудования — нам такой способ не подходит. А в случае с сертификатом еще и потенциальный взлом или утеря ПК приводит к тому, что у злоумышленника будет доступ к «второму фактору».

Еще один пример: приложение Veeam Cloud Connect, которое используется в другой нашей услуге: резервное копирование в облако. Веб-консоль предоставляет администраторам услуги возможность управлять заданиями резервного копирования и следить за их статусом. И всё это в тесной связке с VMware Cloud Director (vCD).

Но и тут мы столкнулись с тем, что вендор еще не реализовал подходящий нам сценарий: тот, в котором есть возможность подключить Veeam Cloud Connect к SAML или OpenID-провайдеру в связке с VMware Cloud Director. Вот что ответила техническая поддержка Veeam:

Я проверил нашу внутреннюю документацию и провёл несколько тестов: к сожалению, BEM Self-Service портал для vCD не поддерживает SAML-аутентификацию. Как обходное решение, я могу предложить настроить SAML-аутентификацию в самом vCD, но работать это будет только при использовании Self-Service портала из консоли vCD. Также в нашей системе открыт Feature Request для добавления данного функционала. К сожалению, на данный момент, сроки внедрения данного функционала неизвестны.

С уважением,

Техническая поддержка Veeam

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

Обычно подобные задачи решаются с помощью VPN: многие VPN-клиенты поддерживают интеграцию с системами, реализующими проверку второго фактора перед подключением. Но это требует установки и настройки клиентского ПО, что в удаленном формате работы не очень дружелюбно для пользователей. К тому же такой вариант не предусматривает возможности разграничить уровни доступа для сотрудников компании, что требуется и у многих заказчиков, и у нас самих. Поэтому мы в Cloud.ru придумали свой альтернативный способ.

Что придумали мы

Основные компоненты

Для реализации альтернативы мы взяли Reverse Proxy с функционалом OpenID Client — использовали свободно распространяемый OAuth2 Proxy, который разместили в DMZ. И IAM (Identity Access Management) в качестве провайдера OpenID для предварительной верификации первого и второго факторов. Мы использовали IAM собственной разработки. В качестве альтернативы можно выбрать ADFS, Keycloak и другие популярные провайдеры, которые поддерживает OAuth2Proxy (полный список есть в документации на githab).

Схема работы

В нашем представлении процесс аутентификации пользователей может быть построен следующим образом:

Схема доступа к веб-приложению с Oauth2Proxy
Схема доступа к веб-приложению с Oauth2Proxy

Пользователь открывает в браузере страницу с веб-приложением (1). Запрос от пользователя к приложению всегда обрабатывает OAuth2Proxy — он проверяет наличие и актуальность сессионной куки. Если они есть, то проксирует трафик к приложению (6). Если куки просрочены или пока не дошли — перенаправляет пользователя на веб-страницу IAM (2).

IAM в свою очередь запрашивает у пользователя данные для аутентификации. В нашем случае пользователь будет вводить логин и пароль от личного кабинета Cloud.ru (3) (в вашем случае это может быть логин и пароль Active Directory), а также одноразовый код (OTP) (4), сгенерированный на устройстве пользователя. При успехе IAM возвращает пользователя на OAuth2Proxy (5). OAuth2Proxy генерирует куку и проксирует трафик к приложению (6).

Подготовка

В статье я не буду подробно описывать этап установки и настройки IAM, а также подготовку инфраструктуры. Расскажу только про то, что необходимо перед установкой Oauth2Proxy в режиме ReverseProxy.

1. Настроить IAM на работу по протоколам OpenID (в статье рассматриваем его) или SAML. Для настройки OpenID вам потребуется:SAML. Для настройки OpenID вам потребуется:

  • oidc_issuer_url — адрес конфигурации OpenID. Например, для Keycloack http://keycloakhost:keycloakport/auth/realms/{realm}/.well-known/openid-configuration
  • client_id — согласованный и зарегистрированный в IAM идентификатор OpenID Client
  • client_secret — сложная парольная фраза

2. Зарегистрировать в IAM пользователя, включить для него 2FA и настроить приложение OTP (например, Google Authenticator, Яндекс Ключ и т. п.) на смартфоне пользователя.

3. Подготовить виртуальную машину (или физический сервер), на котором будет установлен Oauth2Proxy:

  • установить ОС (на сайте проекта доступны собранные пакеты под Linux, FreeBSD, а также Docker Image и Kubernetes manifest (Helm));
  • сконфигурировать сетевые интерфейсы;
  • настроить сетевую связность и разрешения до IAM и защищаемого приложения;
  • настроить доступ в интернет для скачивания дистрибутивов.

4. Зарегистрировать в DNS А-запись, по которой пользователи будут подключаться к приложению (публичный интерфейс Oauth2Proxy). Также эта DNS-запись потребуется для настройки IAM — этот адрес необходимо использовать в качестве Valid Redirected URL.

5. Выпустить сертификат и ключ, которые покрывают выбранное на предыдущем шаге доменное имя.

Установка и запуск решения

В нашем примере:

Приступим к установке решения на развернутую на шаге 3 виртуальную машину.

1. Создаем каталог для размещения дистрибутива

sudo mkdir /opt/oauth2proxy cd /opt/oauth2proxy

2. Скачиваем архив с дистрибутивом (актуальные ссылки для вашей ОС есть на github)

sudo wget https://github.com/oauth2-proxy/oauth2-proxy/releases/download/v7.5.0/oauth2-proxy-v7.5.0.linux-amd64.tar.gz

3. Извлекаем дистрибутив из архива, делаем файл исполняемым

sudo tar -xvzf oauth2-proxy-v7.5.0.linux-amd64.tar.gz --strip-components=1 sudo chmod +x oauth2-proxy

4. Теперь генерируем Cookie Secret и сохраняем полученное значение (его будем использовать дальше в конфигурационном файле)

dd if=/dev/urandom bs=32 count=1 2>/dev/null | base64 | tr -d -- '\n' | tr -- '+/' '-'; echo

5. Создаем конфигурационный файл

sudo vim oauth.cfg

Пример файла можно взять наш — в нем не все доступные настройки. Или на сайте проекта — там полный список.

Важно: команды в этой таблице представлены для CLI. Чтобы необходимый параметр можно было использовать в конфигурационном файле, необходимо заменить «–» на «_» (например, вместо --logging-filename использовать logging_filename).

## OAuth2 Proxy Config File ## https://github.com/oauth2-proxy/oauth2-proxy ## <addr>:<port> to listen on for HTTP/HTTPS clients https_address = ":443" ##указываем какой порт будет использовать приложение ## пути для сертификата и закрытого ключа к нему - требуется для приложений использующих https соединение. В нашем примере – здесь сертификат, который покрывает внешний адрес webapp.company.ru tls_cert_file = "/etc/crt/certificate.pem" tls_key_file = "/etc/crt/certKey.key" upstreams = [ "https://webapp.localcompany.ru" ] #указываем адрес защищаемого приложения в локальной сети skip_provider_button = "true" #позволяет не показывать страницу Oauth2Proxy, а сразу перенправляет в IAM oidc_issuer_url = "https://iam.company.ru/auth/system" #Пример для Keyсloack https://keycloakhost:keycloakport/auth/realms/{realm}/.well-known/openid-configuration #Настройка позволяет указать список пользователей, кому разрешён доступ к приложению. * - любой пользователь IAM, который успешно прошёл аутентификацию по первому и второму фактору. email_domains = [ "*" ] provider = "oidc" #В нашем примере мы используем OpenId Client scope = "openid" redirect_url = "https://webapp.company.ru:443/oauth2/callback" #В качестве FQDN указываем внешний адрес публикуемого приложения; /oauth2/callback стандартный для Oauth2Proxy путь, на котором работает OpenId Connect. Для Keycloack - provider=keycloak полный список провайдеров тут client_id = "client_id_from_IAM_provider" #ID клиента, который предварительно зарегистрирован в IAM client_secret = "veryStr0nG!!SecRet_From_I@M_provider" cookie_secret = "genereted_cookie_secret" #Секрет, который мы ранее генерировали командой dd if=/dev/urandom bs=32 count=1 2>/dev/null | base64 | tr -d -- '\n' | tr -- '+/' '-_'; echo cookie_expire = "6h" #Срок жизни куки. Определяет, как часто вашим пользователям придётся проходить повторную аутентификацию

6. Теперь проверяем, запустилось ли приложение Oauth2Proxy и правильно ли оно перенаправляет на страницу IAM

sudo ./oauth2-proxy --config=./oauth2-proxy.cfg

При переходе по внешнему адресу приложения https://webapp.company.ru пользователь должен автоматически попасть на страницу IAM. Затем система запросит второй фактор. При успешном вводе первого и второго факторов пользователь должен оказаться на защищенном ресурсе.

Пример формы авторизации на сайте Cloud.ru
Пример формы авторизации на сайте Cloud.ru
Пример формы авторизации на сайте Cloud.ru, второй фактор
Пример формы авторизации на сайте Cloud.ru, второй фактор
Пример внутреннего сервиса, который доступен только через 2FA
Пример внутреннего сервиса, который доступен только через 2FA

7. Если всё работает, настраиваем автоматический запуск при загрузке системы, чтобы пользователю не пришлось совершать лишних действий. Добавляем Unit в systemd:

vim /etc/systemd/system/oauth-proxy.service [Unit] Description=oauth2-proxy daemon service After=syslog.target network.target [Service] ExecStart=/opt/oauth2proxy/oauth2proxy --config=/opt/oauth2proxy/oauth.cfg $OPTIONS ExecReload=/bin/kill -HUP $MAINPID KillMode=process Restart=always [Install] WantedBy=multi-user.target

8. Запускаем сервис командой

systemctl start oauth2-proxy

9. Активируем сервис, чтобы он стартовал при рестарте ОС

systemctl enable oauth2-proxy

Что в итоге?

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

Доступность. Всё что нужно — виртуальная машина на Linux, бесплатная Oauth2Proxy и любое OTP приложение на устройстве пользователя, при условии, что в компании уже используется какой-то провайдер 2FA;

Универсальность. Если уже есть legacy в виде сторонних продуктов, двухфакторку можно сделать с помощью такого лайфхака;

Удобство. Нам как провайдеру не надо организовывать закупку и доставку всяких физических карт и считывателей на сторону клиента, админам клиента не нужно бить тревогу в случае утери карты или устройства с сертификатом, а самому клиенту не нужно устанавливать никакого специфического ПО — все манипуляции проходят в окне браузера.

Среди недостатков, если уж придираться, можно выделить два: стойкую аллергию безопасников некоторых структур на любое не до конца отечественное ПО, даже если оно open source; не во всех случаях получится настроить SSO в защищаемое приложение, поэтому пользователям может потребоваться ввести логин и пароль дважды. Сначала на странице IAM, а потом уже в самом приложении (но это уже целых 5 факторов, что, конечно, должно понравиться безопасникам?).

11
Начать дискуссию
Карась дуреет с этих виртуальных карт: как устроен мир зарубежных виртуальных банковских карт для россиян в 2025 году? Как виртуальные карты для арбитража трафика могут помочь обычным россиянам и где их оформить?
Карась дуреет с этих виртуальных карт: как устроен мир зарубежных виртуальных банковских карт для россиян в 2025 году? Как виртуальные карты для арбитража трафика могут помочь обычным россиянам и где их оформить?

Меня зовут Жаклин Медейко, я 3 года занимаюсь арбитражом трафика и сегодня проведу для вас увлекательное сафари в мире диких платежек для арбитража и не только! Без воды и ненужной информации.

1010
22
Почему многие безопасники избегают Open Source?

Open Source (модель разработки ПО, при которой исходный код продукта доступен для изучения, изменения и распространения) всё чаще используется в корпоративном технологическом стеке.

Почему многие безопасники избегают Open Source?
11
Цифровые каналы в банковской сфере в 2024 году

Павел Мянник, CEO digital-интегратора D'Terra и управляющий партнер агентства цифрового аудита SDI360.

11
Информационная безопасность: инструкция для бизнесменов, которые хотят спать спокойно (и с деньгами)

Представьте, что ваша компания — это крепость. Только вместо стен — компьютеры, вместо стражников — сотрудники, а вместо катапульт у злоумышленников — вирусы, фишинг и криптошифровальщики. Как сохранить свой замок от захвата? Просто и с иронией рассказываем, как создать систему информационной безопасности (ИБ), которая будет работать, даже если её…

Информационная безопасность: инструкция для бизнесменов, которые хотят спать спокойно (и с деньгами)
1818
55
33
11
T-ID: как работает единый вход и подтверждение личности

Думаю, давно все привыкли к разным способам авторизации в сервисы, входить через VK ID, Google ID и тд. Но сейчас, судя по всему, в тренде более продвинутый способ входа — через банки, сразу с заполнением всех нужных данных. Расскажу подробнее про то как открыл это для себя.

T-ID: как работает единый вход и подтверждение личности
99
Риски передачи ЭЦП: как не стать жертвой волка в овечьей шкуре

Когда в беседе с владельцами бизнеса заходит речь о потере контроля или предприятия в целом, очень часто воображение рисует им красочные ужасные картины.

Риски передачи ЭЦП: как не стать жертвой волка в овечьей шкуре
1919
55
Как наш новый модуль DIGIpass поможет организовать безопасное хранение паролей в вашем корпоративном портале Битрикс24

Всем привет, это DIGIMATIX. В этой статье мы расскажем о нашем новом модуле для безопасного хранения паролей DIGIpass. Модуль разработан для корпоративного портала Битрикс24 и с его помощью вы не только решите проблему хаотичного хранения паролей, но и сможете обеспечить полный контроль их использования, минимизируя риски утечек.

Как наш новый модуль DIGIpass поможет организовать безопасное хранение паролей в вашем корпоративном портале Битрикс24
33
Как я протестировал пять российских аналогов Zoom, чтобы вам не пришлось
Как я протестировал пять российских аналогов Zoom, чтобы вам не пришлось
11
[]