Глава 23. Легаси и гибридные среды
«В подавляющем большинстве случаев миграция к ZTA должна быть путешествием, а не одномоментной заменой существующей инфраструктуры.» — NIST SP 800-207, Section 7
Предыдущая глава описала мультиоблачную архитектуру для организаций, строящих с нуля. Реальность большинства — brownfield: тысячи приложений, написанных до Zero Trust, Active Directory двадцатилетней давности, мейнфреймы, обрабатывающие финансовые транзакции. Эта глава — практическое руководство по внедрению Zero Trust в существующую инфраструктуру без остановки бизнеса.
23.1 Зачем: brownfield — это норма
Правило 80/20 от Google
Google — одна из немногих организаций, публично задокументировавших полный цикл brownfield-миграции (6 статей BeyondCorp, 2014-2018, + статья «Long Tail of Zero Trust», 2020). Ключевой урок:
Первые 80% приложений мигрируют относительно гладко. Последние 20% — «длинный хвост» (long tail) — требуют непропорциональных усилий.
В длинный хвост BeyondCorp попали:
| Категория | Проблема | Решение Google |
|---|---|---|
| Финансовые системы | Критичные для бизнеса, нельзя рисковать простоем | Выделенные исключения с усиленным мониторингом |
| Физическая безопасность | Встроенные системы без поддержки HTTP | Микросегментированный VPN (не классический) |
| Non-HTTP приложения | Проприетарные протоколы, несовместимые с Access Proxy | Client-side helpers, протокольные мосты |
| Latency-sensitive | Прокси добавляет задержку, критичную для некоторых сервисов | Географически распределённые прокси |
Google не решил проблему «длинного хвоста» одним инструментом. Для каждой категории — отдельный подход. Даже Google использовал VPN как fallback для самых сложных случаев — но это был микросегментированный VPN с интеграцией в BeyondCorp policy engine, а не классический full-tunnel.
Источники: BeyondCorp and the Long Tail of Zero Trust (USENIX ;login:online, 2020), Migrating to BeyondCorp (USENIX ;login:, Summer 2017)
NIST SP 800-207: три модели сосуществования
NIST SP 800-207 (Section 7) описывает три стадии перехода:
| Модель | NIST Section | Описание |
|---|---|---|
| Pure ZTA | 7.1 | Полностью Zero Trust; все ресурсы за PEP. Greenfield или финал миграции |
| Hybrid ZTA + Perimeter | 7.2 | ZT для новых/критичных ресурсов, периметр для legacy. Большинство организаций здесь |
| Perimeter → ZTA Migration | 7.3 | 7 шагов перехода (подробно в Главе 4) |
NIST явно говорит: hybrid-модель — допустимое долгосрочное состояние, не промежуточный костыль. Организация может годами работать в гибридном режиме, постепенно расширяя ZT-покрытие.
Источник: NIST SP 800-207, Sections 7.1-7.3
23.2 ZT proxy pattern: Zero Trust без модификации приложения
Принцип: прокси вместо переписывания
Если приложение не поддерживает OIDC/SAML/mTLS, поставьте перед ним identity-aware proxy — обратный прокси, который:
- Аутентифицирует пользователя через IdP
- Проверяет авторизацию по политикам
- Передаёт identity-контекст в HTTP-заголовках
- Приложение получает
X-Auth-Request-User,X-Auth-Request-Email— без изменений кода
oauth2-proxy: минимальный ZT-шлюз
oauth2-proxy v7.14.2 (январь 2026) — CNCF Sandbox (принят 2 октября 2025). MIT-лицензия. Поддерживает 18+ IdP-провайдеров, включая любой совместимый с OIDC.
Deployment на Kubernetes с NGINX Ingress:
# oauth2-proxy Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: oauth2-proxy
namespace: auth
spec:
replicas: 2
selector:
matchLabels:
app: oauth2-proxy
template:
metadata:
labels:
app: oauth2-proxy
spec:
containers:
- name: oauth2-proxy
image: quay.io/oauth2-proxy/oauth2-proxy:v7.14.2
args:
- --provider=oidc
- --oidc-issuer-url=https://login.microsoftonline.com/TENANT_ID/v2.0
- --client-id=$(CLIENT_ID)
- --client-secret=$(CLIENT_SECRET)
- --cookie-secret=$(COOKIE_SECRET)
- --email-domain=*
- --upstream=static://202
- --http-address=0.0.0.0:4180
- --reverse-proxy=true
- --set-xauthrequest=true
ports:
- containerPort: 4180
---
apiVersion: v1
kind: Service
metadata:
name: oauth2-proxy
namespace: auth
spec:
selector:
app: oauth2-proxy
ports:
- port: 4180
targetPort: 4180Ingress для защищённого приложения:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: legacy-app
annotations:
nginx.ingress.kubernetes.io/auth-url: "https://$host/oauth2/auth"
nginx.ingress.kubernetes.io/auth-signin: "https://$host/oauth2/start?rd=$escaped_request_uri"
nginx.ingress.kubernetes.io/auth-response-headers: >-
x-auth-request-user, x-auth-request-email, authorization
spec:
rules:
- host: legacy-app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: legacy-app
port:
number: 8080Helm chart: helm repo add oauth2-proxy https://oauth2-proxy.github.io/manifests
Источники: oauth2-proxy docs, NGINX Ingress External OAUTH, oauth2-proxy CNCF
Pomerium: полноценный ZT access proxy
Pomerium v0.32.0 — Apache 2.0 (open source core), Enterprise $7/user/month. В отличие от oauth2-proxy, Pomerium — не просто auth-прокси, а полноценная ZT access platform с поддержкой TCP и UDP.
Архитектура (4 компонента):
| Компонент | Роль |
|---|---|
| Proxy | Принимает запросы, маршрутизирует к upstream. Единственный компонент в user traffic path |
| Authenticate | OAuth 2.0/OIDC аутентификация, управление сессиями |
| Authorize | Проверка политик на каждый запрос (PPL или Rego) |
| Databroker | Хранение persistent state (сессии, claims, токены) |
Все 4 компонента могут работать как единый процесс (all-in-one, по умолчанию) или как отдельные Deployments (split mode для масштабирования).
Pomerium Policy Language (PPL):
# config.yaml — маршрут к legacy-приложению
routes:
- from: https://legacy-crm.example.com
to: http://legacy-crm.internal:8080
policy:
allow:
and:
- domain:
is: example.com
- claim/groups:
has: crm-users
deny:
or:
- email:
is: terminated-user@example.com
# TCP-маршрут для legacy SSH
- from: tcp+https://ssh-bastion.example.com:22
to: tcp://10.0.1.50:22
policy:
allow:
and:
- email:
is: admin@example.comNon-HTTP протоколы через TCP/UDP tunneling:
| Протокол | From (Pomerium) | To (upstream) | Клиент |
|---|---|---|---|
| SSH | tcp+https://ssh.example.com:22 | tcp://server:22 | pomerium-cli / Desktop |
| RDP | tcp+https://rdp.example.com:3389 | tcp://server:3389 | pomerium-cli / Desktop |
| PostgreSQL | tcp+https://db.example.com:5432 | tcp://db-server:5432 | pomerium-cli + psql |
| DNS | udp+https://dns.example.com:53 | udp://dns-server:53 | pomerium-cli (v0.29+) |
Источники: Pomerium Architecture, PPL, TCP Support
Сравнение: oauth2-proxy vs Pomerium
| Аспект | oauth2-proxy v7.14.2 | Pomerium v0.32.0 |
|---|---|---|
| Scope | Auth proxy (OIDC/OAuth2) | Full ZT access proxy |
| Протоколы | Только HTTP | HTTP, TCP, UDP (SSH, RDP, DB) |
| Политики | Email/domain/group allow-lists | PPL (YAML), Rego (Enterprise) |
| mTLS | Нет | Автоматический TLS, mTLS к upstream |
| Identity-контекст | X-Auth-Request-* headers | JWT с полными claims |
| CNCF | Sandbox (октябрь 2025) | Нет |
| Лицензия | MIT | Apache 2.0 (Enterprise $7/user/mo) |
| Когда использовать | Простой OIDC-шлюз для веб-приложений | ZT для всех протоколов |
Рекомендация: oauth2-proxy — для быстрого старта с веб-приложениями. Pomerium — когда нужен доступ к SSH, RDP, базам данных через единую точку с identity-aware политиками.
23.3 Active Directory → Entra ID: путь к Zero Trust
Почему AD — барьер для Zero Trust
Active Directory (on-prem) предполагает периметр: Kerberos-тикеты, NTLM-хеши, Group Policy через LDAP — всё работает в доверенной сети. Zero Trust требует идентичности, проверяемые везде: OIDC-токены, Conditional Access, continuous evaluation. Мост между ними — гибридная идентичность.
Критический дедлайн: 30 сентября 2026
Microsoft Entra Connect Sync — инструмент синхронизации AD → Entra ID. Версия 2.5.79.0 (февраль 2026) включает обязательные hardening-изменения. Все более ранние версии перестанут работать 30 сентября 2026.
Источник: Entra Connect Version History
Гибридная аутентификация: три метода
| Метод | Как работает | Позиция Microsoft |
|---|---|---|
| PHS (Password Hash Sync) | Хеши паролей синхронизируются в Entra ID. Аутентификация в облаке | Рекомендуемый. Простой, надёжный, работает как fallback |
| PTA (Pass-Through Authentication) | On-prem агенты валидируют пароли в реальном времени | Поддерживается. Для организаций, запрещающих хранение хешей в облаке |
| Federation (AD FS) | Перенаправление аутентификации на on-prem AD FS | Устаревающий путь. Microsoft рекомендует миграцию с ADFS |
Рекомендация Microsoft: PHS как основной метод, всегда включён даже при использовании PTA для резилиентности.
Источники: Migrate from Federation to Cloud Auth, Resilient Hybrid Auth
Entra Cloud Sync: стратегическая замена Connect Sync
Entra Cloud Sync — рекомендуемый путь миграции с Entra Connect Sync:
| Аспект | Entra Connect Sync | Entra Cloud Sync |
|---|---|---|
| Установка | Полный сервер (.NET, SQL) | Лёгкий агент |
| HA | Staging server (ручной failover) | Несколько агентов active-active |
| Multi-forest | Требует AD trusts | Нативная поддержка disconnected forests |
| Интервал синхронизации | 30 минут | 2 минуты |
| Группы | Без ограничений | До 50 000 участников |
| Конфигурация | On-prem wizard | Облачная (портал Entra) |
| Будущее | Maintenance mode | Активная разработка |
Дорожная карта миграции AD → Zero Trust:
- Включить PHS — мост к облачной аутентификации, не нарушает существующие процессы
- Включить MFA — Entra ID Protection, Conditional Access. Zero Trust начинается с MFA
- Conditional Access — device compliance, location-based, risk-based policies
- Миграция на Cloud Sync — лёгкий агент, 2-минутная синхронизация
- Decommission AD (если возможно) — для cloud-native организаций
Источники: What is Entra Cloud Sync, Migrate Connect to Cloud Sync
23.4 Legacy-протоколы: SSH, RDP, базы данных
От SSH bastion к identity-aware access
Традиционный SSH bastion host — единая точка доступа, но с проблемами: статические SSH-ключи, общие аккаунты, нет гранулярного аудита.
Teleport v18 (BSL-лицензия, бесплатно для <100 сотрудников) заменяет bastion:
| Возможность | SSH bastion | Teleport v18 |
|---|---|---|
| Аутентификация | SSH-ключи (статические) | Краткосрочные сертификаты (минуты-часы) |
| SSO | Нет | OIDC, SAML, GitHub |
| MFA | Нет | Per-session MFA (TOTP, WebAuthn) |
| Аудит | auth.log | Полная запись сессий (replay) |
| Протоколы | SSH | SSH, RDP, K8s, HTTPS, 14+ типов БД, MCP |
HashiCorp Boundary v0.21.0 (BSL 1.1) — альтернативный подход через credential injection: пользователь подключается к ресурсу, не зная пароля. Boundary запрашивает credentials из Vault и инжектит их в соединение.
| Модель | Описание | Доступность |
|---|---|---|
| Credential brokering | Пользователь видит credentials (временные) | Community Edition |
| Credential injection | Пользователь не видит credentials | Enterprise / HCP only |
Источники: Teleport Protocols, Boundary v0.21.0
RDP: от открытого порта к identity-aware gateway
| Решение | Как работает | Клиент | Стоимость |
|---|---|---|---|
| Cloudflare Access | Browser-based RDP (IronRDP + WebSocket) через Cloudflare Tunnel | Браузер (no client) | Бесплатно до 50 пользователей |
| Pomerium | TCP tunnel через identity-aware proxy | pomerium-cli / Desktop | Apache 2.0 (open source) |
| Azure Virtual Desktop | Managed RDP + Conditional Access + CAE | Windows App / браузер | Per-user licensing |
| Teleport | Certificate-based RDP + session recording | tsh client / браузер | BSL (free <100 emp) |
Базы данных: от shared passwords к per-session credentials
| Инструмент | Поддерживаемые БД | Модель безопасности |
|---|---|---|
| Teleport | PostgreSQL, MySQL, MongoDB, Oracle, Redis, Elasticsearch, CockroachDB, Snowflake, Spanner, SQL Server, DynamoDB, Cassandra, ClickHouse | Certificate-based, per-session MFA |
| Boundary | Любая TCP-доступная БД | Credential brokering/injection через Vault |
| Pomerium | Любая TCP-доступная БД | Identity-aware tunnel, пользователь предоставляет свои credentials |
| Vault Dynamic Secrets | PostgreSQL, MySQL, MongoDB, Oracle, MSSQL, Elasticsearch, Redis, Cassandra | Временные credentials, TTL, auto-revoke |
Для баз данных оптимален Vault Dynamic Secrets (Глава 6): каждое соединение получает уникальные credentials с коротким TTL. Teleport/Boundary обеспечивают identity-aware доступ и аудит.
23.5 Lab: oauth2-proxy перед legacy-приложением
В этой лабораторной работе мы защитим простое веб-приложение без встроенной аутентификации с помощью oauth2-proxy и NGINX Ingress Controller.
Предварительные требования
- Docker, kind, kubectl, Helm v3
- Аккаунт в Entra ID (или другом OIDC-провайдере)
Шаг 1: Создание кластера и установка NGINX Ingress
# Создание kind-кластера с ingress-ready нодами
cat <<EOF | kind create cluster --name zt-proxy-lab --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
kubeadmConfigPatches:
- |
kind: InitConfiguration
nodeRegistration:
kubeletExtraArgs:
node-labels: "ingress-ready=true"
extraPortMappings:
- containerPort: 80
hostPort: 80
protocol: TCP
- containerPort: 443
hostPort: 443
protocol: TCP
EOF
# Установка NGINX Ingress Controller
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml
kubectl wait --namespace ingress-nginx \
--for=condition=ready pod \
--selector=app.kubernetes.io/component=controller \
--timeout=90sШаг 2: Развёртывание legacy-приложения
# Простое приложение без аутентификации
kubectl create namespace demo
kubectl -n demo create deployment legacy-app \
--image=hashicorp/http-echo \
-- -text="Hello from legacy app! No auth built in."
kubectl -n demo expose deployment legacy-app --port=5678Шаг 3: Установка oauth2-proxy
# Создать Secret с OIDC-параметрами
# Замените значения на ваши
kubectl -n demo create secret generic oauth2-proxy-secret \
--from-literal=client-id=YOUR_CLIENT_ID \
--from-literal=client-secret=YOUR_CLIENT_SECRET \
--from-literal=cookie-secret=$(openssl rand -base64 32 | tr -- '+/' '-_')
# Установка через Helm
helm repo add oauth2-proxy https://oauth2-proxy.github.io/manifests
helm upgrade --install oauth2-proxy oauth2-proxy/oauth2-proxy \
--namespace demo \
--set config.existingSecret=oauth2-proxy-secret \
--set extraArgs.provider=oidc \
--set extraArgs.oidc-issuer-url=https://login.microsoftonline.com/TENANT_ID/v2.0 \
--set extraArgs.email-domain="*" \
--set extraArgs.set-xauthrequest=true \
--set extraArgs.reverse-proxy=trueШаг 4: Создание Ingress с auth-annotations
# ingress-legacy-app.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: legacy-app
namespace: demo
annotations:
nginx.ingress.kubernetes.io/auth-url: "http://oauth2-proxy.demo.svc.cluster.local:4180/oauth2/auth"
nginx.ingress.kubernetes.io/auth-signin: "http://localhost/oauth2/start?rd=$escaped_request_uri"
nginx.ingress.kubernetes.io/auth-response-headers: "x-auth-request-user, x-auth-request-email"
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: legacy-app
port:
number: 5678
- path: /oauth2
pathType: Prefix
backend:
service:
name: oauth2-proxy
port:
number: 4180kubectl apply -f ingress-legacy-app.yamlШаг 5: Проверка
# Без аутентификации — редирект на IdP
curl -s -o /dev/null -w "%{http_code}" http://localhost/
# Ожидаемый ответ: 302 (redirect to OIDC login)
# Откройте http://localhost/ в браузере:
# 1. Браузер перенаправляет на Entra ID (или другой IdP)
# 2. После аутентификации — доступ к legacy-app
# 3. Приложение получает заголовки:
# X-Auth-Request-User: user@example.com
# X-Auth-Request-Email: user@example.comШаг 6: Очистка
kind delete cluster --name zt-proxy-labРезультат: legacy-приложение без единой строки изменённого кода теперь защищено OIDC-аутентификацией. Для production добавьте TLS (cert-manager), группы/роли в IdP, и Conditional Access в Entra ID.
Связь с другими главами
| Тема | Глава | Связь |
|---|---|---|
| NIST 800-207 миграция | Гл. 4 | 7 шагов миграции Section 7.3 |
| BeyondCorp архитектура | Гл. 3 | EIG, Access Proxy, Trust Inferer |
| IdP и OIDC | Гл. 5 | Фундамент идентичности, SAML для legacy |
| PAM и Vault | Гл. 6 | Dynamic secrets для баз данных |
| ZTNA | Гл. 11 | Cloudflare Access, Entra Private Access |
| Мультиоблако | Гл. 22 | SPIRE federation, OPA bundles |
| Новые горизонты | Гл. 24 | IoT/OT Zero Trust, PQC для legacy TLS |
| Эталонная архитектура | Гл. 25 | Enterprise brownfield сценарий |
Итоги
- Brownfield — норма. NIST 800-207 Section 7.2 описывает hybrid ZTA + perimeter как допустимое долгосрочное состояние
- ZT proxy pattern — самый быстрый путь к Zero Trust для legacy: oauth2-proxy (HTTP, CNCF Sandbox) или Pomerium (HTTP + TCP + UDP, полноценный ZT)
- AD → Entra ID: начните с PHS + MFA, мигрируйте на Cloud Sync (2-минутная синхронизация). Дедлайн Entra Connect Sync: 30 сентября 2026
- Non-HTTP протоколы: Teleport (SSH, RDP, DB — certificate-based), Boundary (credential injection через Vault), Pomerium (TCP/UDP tunneling)
- Правило BeyondCorp: первые 80% мигрируют гладко; для последних 20% нужны индивидуальные решения. Планируйте «длинный хвост» заранее
- Начните с одного legacy-приложения + oauth2-proxy — это работающий proof of concept за один день