The Jerusalem PostSuspect arrested in fatal shooting of 30-year-old man in Jaffa as police probe motive of incidentESPN DeportesBoston Celtics: resumen de temporada baja y previa 2026-27וואלהצה"ל: חוסל ראש חולייה מארגון הטרור גא"פ שפשט לכיסופים ב-7 באוקטוברRTP DesportoBenfica aponta ao tricampeonato de futsalInquirerDy thanks Marcos for directing VAT removal on system loss chargeDaily MaverickCULTURAL PHENOMENON: Star Trek at 60 and the optimistic future it still dares us to imagineESPNDay: Ohio State 'to make some hard decisions' after Texas collapseDeadlineAmazon Prime Video Debuts $30-A-Month Bundle With AMC+, BritBox, MGM+, PBS Masterpiece & StarzABC NewsMeasles-related deaths in Pennsylvania rise to 4, health officials sayVarietyQuentin Tarantino to Publish ‘Cliff Booth’ Novel Before Brad Pitt and David Fincher’s Movie Streams on NetflixCBS Sports2026 Week 2 NFL odds, start times, betting lines, spreads: Get Week 2 NFL picks, predictions for every gameXatakaVivió hasta los 103 años, actuó en más de 90 películas y fue nominado a tres Óscar. Hoy su hijo es toda una leyenda de Hollywood
The Daily Newsstand · Free, Always
Tuesday, September 15, 2026

Почему трафик филиалов тормозит через ЦОД и как исправить это с помощью Identity‑First

Translate

Привет, Хабр! Меня зовут Андрей Бирюков. Я — независимый эксперт в области ИТ и ИБ, преподаю в учебных центрах и пишу статьи и книги.

При построении сетей архитекторы привыкли придерживаться принципа построения иерархии Access → Distribution → Core → Firewall → Internet. Однако в современных сетях эта иерархия превращается в сетку, где точка принятия решения о маршрутизации это уже не IP‑адрес получателя, а идентификатор (SID) пользователя.

В этой статье мы пройдем путь от того «как было» к тому «как стало» на конкретных конфигах и логике принятия решений.

Проблемы обратных маршрутов

Давайте рассмотрим один достаточно типовой сценарий. У компании имеется основной офис в Москве, в котором располагается корневой файрволл, обеспечивающий выход в интернет. Также есть офис в Екатеринбурге.

Что происходит, когда пользователь этого офиса обращается к внешним ресурсам в облаке.

Путь трафика (классический подход):

Задержка: 35 мс (Ekb‑Msk) * 2 (туда и обратно) + время обработки firewall = ~80 мс. Это терпимо. Но когда вы включаете SSL Decryption на фаерволе, задержка превращается в 150 мс, и приложение в облаке начинает «дергаться».

Теперь рассмотрим те проблемы, которые вызывает подобный подход.

Здесь первой ошибкой сетевого администратора является попытка разрешить доступ через PBR (Policy‑Based Routing), чтобы направить облачный трафик напрямую в интернет, минуя фаервол. Для этого архитектор готовит следующий access‑list:

ip access-list extended BYPASS_MSFT
 permit tcp any 13.107.0.0/16
 permit tcp any 52.112.0.0/14
!
route-map PBR_TO_INTERNET permit 10
 match ip address BYPASS_MSFT
 set ip next-hop 172.16.255.1 (локальный интернет-шлюз)

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

При этом, таблица состояний на фаерволе сбивается, потому что он видит только половину сессии.

В результате сетевики вынуждены настраивать «симметричный возврат» (Unicast Reverse Path Forwarding в loosen mode), что приводит к появлению дополнительных дыр в безопасности.

Так что предложенный вариант нельзя назвать самым лучшим, поэтому давайте посмотрим на другие решения.

Модель «Identity‑First»

Для начала, давайте зададимся одним простым вопросом, а всегда ли нужно туннелировать пользователя в ЦОД?

На самом деле нам достаточно туннелировать только политики в Edge.

Например, мы можем вместо L3VPN использовать SD‑WAN Fabric с интеграцией с ZTNA (Zero Trust Network Access). Но ключевая магия у нас может происходить не в маршрутизаторе, а в DNS Forwarder и агентe на рабочей станции.

Теперь логика маршрутизации существенно изменится, так как агент на ноутбуке будет поднимать туннель (WireGuard/IPsec) не до Москвы, а до ближайшей точки присутствия (PoP) провайдера (например, в Казани).

В этой PoP стоит виртуальный маршрутизатор, который смотрит не на dst‑ip, а на Certificate SAN пользователя и полученный из AD тэг приложения.

Соответственно, если приложение помечено как SaaS‑FastPath, трафик отпускается в интернет прямо из Казани.

Если же приложение помечено как Corporate‑Critical (например, это SAP или запрос к внутренней базе), трафик уходит по IPsec Tunnel в ЦОД, но не в фаервол, а напрямую на Service Mesh приложения.

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

Давайте в качестве примера рассмотрим реализацию на базе Linux‑хоста в качестве PoP (маршрутизатор на Free Range Routing с использованием nftables. Здесь вместо настройки статических маршрутов мы используем Policy Routing на основе cgroups, который ставится агентом на клиенте.

Но на стороне PoP мы встречаем трафик и обрабатываем его на уровне политик.

Вот минимальный фрагмент логики на стороне шлюза PoP (связка Python + pyroute2), который эмулирует принятие решения:

from pyroute2 import IPRoute
import subprocess

# Получаем маркер пользователя из пакета (в реальности - из TLS SNI или Cookie)
# Допустим, мы инкапсулировали Identity в поле DSCP (неправильно, но для примера)
# Или используем VXLAN GPE с метаданными.

def classify_traffic(iface="eth0"):
    ip = IPRoute()
    # Создаем отдельную таблицу маршрутизации для "SaaS" трафика
    # Таблица 100 - быстрый путь без инспекции
    ip.route("add", dst="0.0.0.0/0", gateway="100.64.0.1", table=100)  # Прямой выход в интернет
    # Таблица 200 - путь через фаервол-прокси в ЦОД
    ip.route("add", dst="10.0.0.0/8", gateway="192.168.255.2", table=200) # IPsec к Core

    # Правило выбора таблицы: если пакет имеет fwmark 0x01 (установленный агентом)
    ip.rule("add", fwmark=0x01, table=100)
    ip.rule("add", fwmark=0x02, table=200)

    # Включаем маршрутизацию источника (чтобы обратный трафик шел через тот же PoP)
    # echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter
    # Устанавливаем значение 2 (Loose Mode), но только для трафика с марком, чтобы не нарушить безопасность.
    subprocess.run(["sysctl", "-w", "net.ipv4.conf.all.rp_filter=2"])

if name == "__main__":
    classify_traffic()

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

DNS как маршрутизатор

А теперь рассмотрим наиболее интересный и важный шаг в настройке нашего сетевого взаимодействия.

В предлагаемой архитектуре вы перестаете полагаться на маршруты в BGP, а начинаете управляеть трафиком через DNS‑ответы.

То есть, вместо того чтобы раздавать по DHCP один DNS‑сервер (например, московский DC), вы даете филиалам локальный кеширующий резолвер (CoreDNS или dnsmasq), который подключен к Central Policy Controller.

Вот пример Corefile для CoreDNS (PoP в Казани). Мы используем плагин view для разделения клиентов по подсетям, но главное — мы используем плагин rewrite, чтобы перенаправлять запросы к внутренним сервисам на локальный IP балансировщика.

.:53 {
    # Сначала проверяем, не является ли запрос внутренним
    view internal {
        expr type() == 'A' && name() matches '\.internal\.company\.$'
        # Перенаправляем запрос к сервису "hr" на локальный прокси в этом PoP
        rewrite name hr.internal.company. hr-proxy.pop-kazan.svc.cluster.local
        forward . 10.200.0.1  # Внутренний кластерный DNS
    }

    view external {
        # Все остальные запросы (SaaS)
        # Мы не даем реальный IP Microsoft. Мы даем IP ближайшего кеширующего прокси (Squid + SSL Bump)
        # Или, если политика разрешает, отдаем реальные публичные IP через резолвер Cloudflare (1.1.1.1)
        forward . 1.1.1.1 1.0.0.1 {
            prefer_udp
            max_concurrent 1000
        }
        # Логируем все DNS-запросы для Security Analytics (угрозы через DNS-туннели)
        log
    }
}

Здесь логика работы DNS заключается в том, что, если пользователь идет на google.com, DNS отдает ему CNAME на локальный кеш в Казани. Трафик даже не поднимается в IP‑стек маршрутизации до Москвы.

Сохранение состояния при отказе PoP

Однако, тут есть важная проблема, связанная с тем, что произойдет, когда PoP в Казани отвалится? Клиент потеряет связь с маршрутизатором, и все его TCP сессии оборвутся.

Это неприемлемо например, для RDP‑соединений.

В качестве решения здесь можно воспользоваться Multipath TCP (MTCP) на уровне агента и Anycast IP для PoP. MTCP представляет собой расширение протокола TCP, которое позволяет одновременно использовать несколько сетевых путей для передачи данных

Мы поднимаем один и тот же VIP (например, 10.255.255.254) на всех PoP‑точках в России и анонсируем его в BGP с разным весом (Local Pref).

Но чтобы не было флопа (хаотичного изменения маршрута) при сбое, мы используем BGP PIC (Prefix Independent Convergence) с таймером удержания.

Конфиг BGP на маршрутизаторе PoP (модуль GoBGP) может иметь следующий вид:

bgp:
  router-id: "10.0.1.1"
  as: 65001
  neighbors:
    - neighbor-address: "10.0.0.2"  # Соседний PoP для резерва
      peer-as: 65001
      route-reflector-client: true
      afi-safi:
        - "ipv4-unicast"
  policies:
    # Анонсируем наш локальный префикс для балансировки
    - name: "announce-anycast"
      type: "accept"
      statement:
        - condition:
            prefix: "10.255.255.254/32"
          action:
            route-action: "accept"
            set-local-pref: 150  # В основном PoP выше

При этом, на клиенте под Linux мы настраиваем WireGuard с двумя эндпоинтами и скриптом переключения:

# /etc/wireguard/wg0.conf

[Interface]

PrivateKey = xxxx

Address = 10.1.0.2/32

# Таймеры для быстрого переключения

Table = auto
FwMark = 0x01

[Peer]
PublicKey = PoP_Kazan
Endpoint = 10.255.255.254:51820  # Anycast IP!
PersistentKeepalive = 15
AllowedIPs = 0.0.0.0/0

[Peer]
PublicKey = PoP_Moscow
Endpoint = 10.255.255.254:51820  # Тот же IP, другой физический хост
PersistentKeepalive = 25
AllowedIPs = 0.0.0.0/0

В итоге, когда пакет идет на 10.255.255.254, маршрутизатор ядра выбирает ближайший по метрике BGP PoP, и если он падает, BGP убирает маршрут, и WireGuard автоматически начинает стучаться в следующий (поскольку IP один, но MAC‑адрес соседнего маршрутизатора уже другой).

Здесь единственная проблема это обновление ARP на клиенте, поэтому мы используем NDP (для IPv6) или ставим arp_ignore=2 и arp_announce=2, чтобы клиент постоянно перезапрашивал MAC‑адрес для Anycast IP.

Инспекция SSL без деградации

Самой большой проблемой в старой модели является проведение инспекции трафика, поэтому в новой модели мы выносим ее в Edge, но делаем выборочной.

Для этого, в PoP мы запускаем Envoy Proxy как Forward Proxy, который фильтрует трафик по SNI.

В результате для .banking.ru мы включаем полную инспекцию, а для.rutube.ru пропускаем «как есть», только проверяем сертификат на валидность (не отозван ли через OCSP).

Конфигурация Envoy в формате yaml для маршрутизации на уровне L7 внутри PoP будет следующей:

static_resources:
  listeners:
  - name: proxy_listener
    address:
      socket_address:
        address: 0.0.0.0
        port_value: 10000
    filter_chains:
    - filters:
      - name: envoy.filters.network.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
          codec_type: AUTO
          stat_prefix: ingress_http
          route_config:
            name: local_route
            virtual_hosts:
            - name: backend
              domains: ["*"]
              routes:
              # Маршрут для критичных приложений
              - match:
                  safe_regex:
                    google_re2: {}
                    regex: '.*\.(sap|oracle)\.internal$'
                route:
                  cluster: backhaul_to_dc
                  # Включаем таймаут для длинных операций
                  timeout: 300s
              # Маршрут по умолчанию (SaaS)
              - match:
                  prefix: "/"
                route:
                  cluster: direct_egress
                  # Используем HTTP/2 для улучшения работы с Microsoft
                  http2_protocol_options: {}
          http_filters:
          - name: envoy.filters.http.router
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router

  clusters:
  - name: backhaul_to_dc
    connect_timeout: 30s
    type: STRICT_DNS
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: backhaul_to_dc
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: 10.10.10.1  # IP шлюза в ЦОД
                port_value: 443

    transport_socket:
      name: envoy.transport_sockets.tls
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
        # Используем mTLS для безопасности
        common_tls_context:
          tls_certificates:
          - certificate_chain: { filename: "/certs/client.crt" }
            private_key: { filename: "/certs/client.key" }

  - name: direct_egress
    connect_timeout: 10s
    type: LOGICAL_DNS
    dns_lookup_family: V4_ONLY
    lb_policy: MAGLEV  # Используем консистентный хеш для кеширования
    load_assignment:
      cluster_name: direct_egress
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: 8.8.8.8  # Условный шлюз (реально - локальный NAT)
                port_value: 443

Подведем итог

Старая архитектура что называется тянула пользователя к данным, работая по принципу User → DC → Firewall → Internet.

Новая тянет данные к пользователю и политику к данным.

Агент на ноутбуке получает от контроллера список доменов для прямого доступа и список для туннелирования.

В свою очередь, для прямого доступа ноутбук шлет запрос на локальный PoP, где стоит Envoy с прозрачным кешем (если это статика вроде JS‑библиотек) или просто проксирует в 1.1.1.1.

Для туннелирования трафик заворачивается в сегмент VXLAN с тэгом пользователя (User‑ID) и отправляется в ЦОД.

Фаервол в ЦОД не проверяет IP пакета, вместо этого он проверяет VXLAN‑тэг и применяет политику микросегментации (например, пользователь из отдела кадров не может пинговать БД, даже если они в одной подсети).

Соответственно, управление трафиком в филиалах сводится к одному правилу IPtables: ip route add default via wg0 table 100.

Маршруты физических интерфейсов используются только для управления (SSH) и DHCP.

Но здесь важно понимать, что при таком подходе вы полностью убиваете классический мониторинг через ICMP (ping).

То есть, вы не сможете пропинговать конечный сервер из ЦОД, потому что маршрут зависит от идентификатора сессии.

Мониторинг переводится на Active Probing через синтетические транзакции (например, искусственный пользователь логинится в SAP раз в минуту).

Это ломает голову сетевым инженерам, привыкшим к MTR, но это необходимая плата за архитектуру Zero‑Trust.

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

Это помогает перейти от точечной настройки маршрутов к управляемой и наблюдаемой сетевой архитектуре, где поведение системы можно объяснить, проверить и изменить осознанно.

Продолжить тему можно на бесплатных открытых уроках OTUS:

  • 22 сентября в 20:00. «Автоматизация управления трафиком с mitmproxy». Записаться

  • 23 сентября в 20:00. «eBPF: рентгеновское зрение для production». Записаться

А полный список бесплатных уроков сентября можно посмотреть в дайджесте.

View the original on Хабр

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.