Интеграция защищённого контура в Yandex Cloud
Разбираем кейс построения закрытого контура разработки в Yandex Cloud
О заказчике
Всем привет! НИКСИС на связи.
В этой статье разберём кейс построения закрытого контура разработки в Yandex Cloud.
Заказчику требовалась готовая среда разработки «под ключ»: лёгкая в администрировании, масштабируемая, с минимумом ответственности и максимумом отказоустойчивости. При этом инфраструктура должна была быть защищена от несанкционированного доступа, чтобы внутренние наработки компании не попали в чужие руки.
На тот момент у заказчика было несколько физических серверов, обслуживание которых требовало значительных человеческих ресурсов. Без регулярной поддержки и развития такая инфраструктура со временем могла стать существенным ограничением для дальнейшей работы.
Поэтому было принято решение создать production-контур в отечественном облаке.
Что требовалось
Одновременно необходимо было сохранить изоляцию инфраструктуры и предоставить разработчикам возможность создавать и запускать сервисы в Yandex Cloud.
При полностью закрытом контуре возникают несколько проблем:
- По окончании настройки весь доступ к внешнему миру (и интернету, конечно) будет отключён, что усложняет администрирование: обновления будут проходить через согласование с ИБ.
- Закрытые контуры требуют больших инвестиций в разработку и дальнейшую поддержку, так как все компоненты должны быть реализованы внутри компании.
- Могут возникнуть проблемы при интеграции новых технологий или продуктов от других поставщиков. В дальнейшем это может осложнить масштабирование и расширение бизнеса.
Исходные требования были следующими:
- настроить соединение между облаком и сетью Заказчика;
- завязать всю авторизацию на LDAP.
После нескольких брейнштормов и рабочих созвонов пришли к следующему решению:
- Создать IPsec-туннель между Yandex Cloud и UserGate по протоколу IKEv2.
- Использовать LDAP и Keycloak для авторизации, где это возможно.
- С помощью Terraform-модулей из репозитория nxs-marketplace-terraform автоматизировать развёртывание инфраструктуры.
Сама инфраструктура должна была состоять из:
- StrongSwan;
- Kubernetes;
- GitLab;
- Vault by HashiCorp;
- Keycloak;
- и ряда других компонентов.
Настраиваем StrongSwan site-to-site IKEv2 IPsec tunnel
Для начала разберёмся, что такое IPsec-туннель.
Это виртуальный канал связи, который создаётся между двумя устройствами для безопасной передачи данных. Туннель шифрует данные перед отправкой и расшифровывает их после получения. Таким образом, даже при перехвате трафика злоумышленник не сможет прочитать или изменить передаваемые данные.
Если сравнивать, например, с OpenVPN, который работает на уровне пользователя, то IPsec, работающий на уровне ядра системы, позволяет повысить скорость и производительность.
Для туннеля был выбран протокол IKEv2. IKEv1, созданный ещё в 1990-х годах, на сегодняшний день считается устаревшим вариантом протокола.
В качестве метода шифрования выбрали PSK (Pre-Shared Key).
Перед проектной командой стоял выбор между PSK и сертификатами. В итоге остановились на PSK по нескольким причинам.
Во-первых, это удобнее с точки зрения эксплуатации: в случае компрометации проще и быстрее сгенерировать и передать новый ключ, чем работать с сертификатами. Иногда время, потраченное на восстановление канала связи, может стоить очень дорого.
Во-вторых, контур закрытый, и информация о нём доступна только определённому кругу сотрудников.
Сначала необходимо было построить туннель между Yandex Cloud и закрытым контуром Заказчика.
Всё выглядело достаточно просто. Но, как это обычно бывает с инфраструктурными проектами, возникла проблема.
В последней на тот момент версии прошивки UserGate был обнаружен баг.
При создании IPsec-туннеля UserGate создавал множественные соединения, которые разрывались по тайм-ауту. Проблема была подтверждена разработчиком, а версия ПО отправлена на доработку.
Поскольку процесс уже был запущен, пришлось изменить первоначальную схему.
В итоге была реализована связка:
StrongSwan (виртуальная машина в Yandex Cloud) → StrongSwan (виртуальная машина за UserGate в инфраструктуре Заказчика).
Основные этапы настройки:
-
1. Устанавливаем StrongSwan.
-
2. Конфигурим /etc/ipsec.conf:
config setup charondebug="all" uniqueids=yes strictcrlpolicy=no conn connection authby=secret left=10.12.0.21 leftid=84.0.0.1 leftsubnet=10.12.0.0/24,10.13.0.0/24 right=202.0.0.3 rightid=%any rightsubnet=10.1.1.0/24,10.1.4.0/24 ike=aes256-sha256-modp2048,aes256-sha256-modp1024,aes256-sha1-modp2048,aes256-sha1-modp1024! esp=aes256-sha256,aes256-sha1! keyingtries=3 ikelifetime=1h lifetime=8h dpdaction=hold auto=start type=tunnel keyexchange=ikev2
Если коротко, то left — это локальный (local) сервер, а right — удалённый (remote).
Всё, что связано с шифрованием (ike, esp) на обоих хостах должно быть одинаково. Подробности можно найти в официальной документации.
3. Настраиваем /etc/ipsec.secrets:
#source destination 84.0.0.1 202.0.0.3 : PSK "тут какой-то ключ в base64"
Тут важна только строчка с адресами и ключом, source/destination указаны для того, чтобы не запутаться.
4. Настраиваем сеть как описано в этой статье.
-
5. Добавляем правила в /etc/ufw/before.rules:
# разрешаем ssh
-A ufw-before-input -p tcp -m tcp --dport 22 -j ACCEPT
-A ufw-before-output -p tcp -m tcp --sport 22 -j ACCEPT
Включаем перенаправление трафика ESP:
-A ufw-before-forward --match policy --pol ipsec --dir in --proto esp -s 10.12.0.0/24 -j ACCEPT -A ufw-before-forward --match policy --pol ipsec --dir out --proto esp -d 10.12.0.0/24 -j ACCEPT # разрешаем forwarding -A ufw-before-forward -s 10.1.1.0/24 -d 10.12.0.0/24 -i eth0 -m policy --dir in --pol ipsec --reqid 1 --proto esp -j ACCEPT -A ufw-before-forward -s 10.12.0.0/24 -d 10.1.1.0/24 -o eth0 -m policy --dir out --pol ipsec --reqid 1 --proto esp -j ACCEPT -A ufw-before-forward -s 10.1.4.0/24 -d 10.12.0.0/24 -i eth0 -m policy --dir in --pol ipsec --reqid 1 --proto esp -j ACCEPT -A ufw-before-forward -s 10.12.0.0/24 -d 10.1.4.0/24 -o eth0 -m policy --dir out --pol ipsec --reqid 1 --proto esp -j ACCEPT
Такие правила необходимо создать для каждой подсети, но важно указать корректный интерфейс и адреса.
Дополнительная информация с примерами есть на официальном сайте.
-
6. Создаём статические маршруты до сетей назначения.
После делаем аналогичные операции на втором сервере, только меняем местами адреса сетей и хостов.

Настраиваем инфраструктуру
Порядок настройки не является обязательным. Однако выбранная последовательность позволяет сократить время реализации проекта.
Большинство решений принималось с учётом дальнейшей эксплуатации: инфраструктура должна была быть понятной и удобной для администраторов, которым предстояло её поддерживать.
1. VPN
«Зачем? Ведь уже есть IPsec-туннель», — может возникнуть вопрос.
VPN необходим для удобного доступа сотрудников и внешних подрядчиков к инфраструктуре.
Для этой задачи был выбран Pritunl VPN.
Преимущества:
- простота первичной настройки;
- начало работы сразу после установки;
- простое добавление сущностей;
- удобное создание новых пользователей.
2. GitLab
GitLab был развёрнут в Docker Compose.
Основная причина — удобство сопровождения:
- меньше проблем с обновлениями;
- всё находится в одном месте, что снижает порог вхождения для следующих инженеров, которые будут работать над проектом;
- при необходимости всё можно разместить за внешним Nginx, но для закрытого контура это скорее опционально.
После развёртывания и настройки GitLab каждый следующий шаг описывается с помощью IaC.
CI/CD настраивается для всего, что возможно автоматизировать, чтобы клиент мог создавать инфраструктуру и сервисы с минимальным количеством ручных действий.
При этом каждый проект должен содержать README с подробным описанием сервиса.
3. Кластер Kubernetes
Следующий компонент — Kubernetes.
Решение — Managed Kubernetes от Yandex Cloud.
Во-первых, бюджеты проекта позволяли использовать managed-решение.
Во-вторых, это снимает значительную часть ответственности за состояние и обслуживание кластера.
В-третьих, у команды Nixys есть Terraform-модуль, с помощью которого кластер можно быстро развернуть.
Все необходимые опции описаны, а сам модуль поддерживается и развивается.
Terraform-модуль доступен в репозитории nxs-marketplace-terraform.
4. Кластер Vault
Бэкендом будет выступать Consul.
Почему именно Vault? Всем сервисам необходимы сертификаты.
Поэтому следующим шагом становится деплой и настройка cert-manager в связке с Vault.
5. Cert-manager
Сert-manager запускается в кластере Kubernetes.
Для быстрого получения сертификатов из Vault настраивается ClusterIssuer.
Для наших целей манифест выглядит следующим образом:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: vault-issuer
spec:
vault:
auth:
kubernetes:
mountPath: /v1/auth/kubernetes
role: clusterissuer
secretRef:
key: token
name: issuer-token-lmzpj
path: pki/sign/example
server: http://vault.example.com
Это немного отличается от примера из инструкции, поэтому требуются небольшие корректировки:
- имя роли указывается в соответствии с используемой конфигурацией. В данном случае —
clusterissuer;
path—pki/sign/example, расположение сертификатов в Vault.
Чтобы Ingress стали защищёнными, в их манифесты добавляется аннотация с именем ClusterIssuer:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-name
namespace: example
labels:
app: example
annotations:
cert-manager.io/cluster-issuer: vault-issuer
meta.helm.sh/release-name: example-name
meta.helm.sh/release-namespace: example
spec:
ingressClassName: nginx
rules:
- host: example.example.com
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: example
port:
number: 8080
После настройки сертификатов во все Ingress добавляется соответствующая аннотация:
annotations:
cert-manager.io/cluster-issuer: vault-issuer
6. Keycloak
Изначально планировалось построить авторизацию на базе связки Keycloak + LDAP, но в процессе выяснилось, что вместо LDAP уже настроен ADFS.
Поэтому было принято решение использовать существующую инфраструктуру.
Требовалась единая точка авторизации в AD через связку Keycloak ↔ ADFS.
В итоге SSO было настроено на базе SAML 2.0.
SSO
Single Sign-On упрощает работу пользователей: после одной авторизации они получают доступ к сервисам, подключённым к Keycloak, пока действует пользовательская сессия.
Пользователи создаются в Active Directory, после чего для авторизации в системе используются корпоративные учётные данные.
SAML
Если говорить упрощённо, SAML — стандарт обмена информацией о безопасности между различными системами.
Он позволяет передавать информацию об аутентификации и авторизации между сервисами без необходимости повторного ввода учётных данных.
После настройки Keycloak авторизация настраивается для сервисов, которые были развёрнуты ранее:
- GitLab;
- Vault;
- Grafana;
- Kibana.
Подробно останавливаться на настройке Keycloak не будем, иначе статья превратится в галерею скриншотов.
Со стороны Keycloak настраивается Identity Provider согласно официальной инструкции.
После этого настраиваются Clients для каждого сервиса, кроме Kibana.
Для Kibana используется oauth2-proxy. Информация по его настройке и конфигурации приведена в этой статье.
Остальные сервисы настраиваются через SAML согласно официальной документации.
Результат
В результате заказчик получил полностью закрытый контур для разработки в Yandex Cloud с защищённым соединением с корпоративной инфраструктурой.
В инфраструктуре используются StrongSwan, Kubernetes, GitLab, Vault, Consul, cert-manager, Keycloak, ADFS и другие компоненты.
При этом значительная часть инфраструктуры описана через IaC, а сервисы подключены к CI/CD. Для пользователей реализована единая точка авторизации через Keycloak и ADFS, а управление сертификатами автоматизировано с помощью Vault и cert-manager.
Отдельно стоит отметить проблему с UserGate: из-за бага в используемой версии прошивки первоначальную схему подключения пришлось изменить и добавить StrongSwan с обеих сторон.
В результате удалось сохранить закрытость контура и одновременно использовать возможности облачной инфраструктуры и автоматизации.
Спасибо за внимание!
Оставьте заявку, чтобы обсудить проект
Спасибо за обращение
Мы свяжемся с вами в ближайшее время.