Посланник для посланника TLS для прокси-сервера TLS

Предположим, что эта архитектура

                                   ................................................
                             .                                              .
                             .                                              .
                             .                                              .
                             .                                              .
                   ┌───────────────────┐                            ┌─────────────────┐
┌──────────────────┤ Customer Firewall ├─┐     ┌────────────────────┤Provider Firewall├─┐
│                  └──────────┬────────┘ │     │Provider Network    └──┬──────────────┘ │
│   Customer Network          │          │     │             ┌─────────┴─┐              │
│                             │          │     │       ┌─────┤ Envoy - B ├───────┐      │
│                             │          │     │       │     └─────┬─────┘       │      │
│                      ┌──────┴─────┐    │     │       │           │             │      │
│       ┌─────────┐    │            │    │     │       │           │             │      │
│       │ Client  ├────┤  Envoy - A │    │     │  ┌────┴────┐  ┌───┴─────┐  ┌────┴────┐ │
│       └─────────┘    │            │    │     │  │ Service │  │ Service │  │ Service │ │
│                      └────────────┘    │     │  └─────────┘  └─────────┘  └─────────┘ │
│                                        │     │                                        │
└────────────────────────────────────────┘     └────────────────────────────────────────┘

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

Он отбросит любой несанкционированный трафик, поэтому любой неразрешенный домен/SNI будет удален.

SNI/домен Envoy B () разрешен в брандмауэре, но они не разрешают использование других доменов .

Все сервисы HTTP/HTTPS.

Вот конфигурация серверов посланников:

Посланник - А:

  • Он слушает порт80, и при каждом HTTP-трафике он перенаправляет трафик на Envoy-B, используя HTTP2 + TLSv1.3.
  • Он слушает порт443, и каждый трафик TPC перенаправляется на Envoy-B без дальнейшего шифрования.
      static_resources:
  listeners:
    # HTTP
    - name: http_forwarder
      address:
        socket_address:
          protocol: TCP
          address: 0.0.0.0
          port_value: 80
      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
                stat_prefix: ingress_http
                route_config:
                  name: http_route
                  virtual_hosts:
                    - name: http_forwarder
                      domains: [ "*" ]
                      routes:
                        - match:
                            prefix: "/"
                          route:
                            cluster: forwarder_to_envoy_b_http
                http_filters:
                  - name: envoy.filters.http.router
                    typed_config:
                      "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router

    # HTTPS/TLS
    - name: https_forwarder
      address:
        socket_address:
          protocol: TCP
          address: 0.0.0.0
          port_value: 443
      filter_chains:
        - filters:
            - name: envoy.filters.network.tcp_proxy
              typed_config:
                "@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
                cluster: forwarder_to_envoy_b_tls
                stat_prefix: https_passthrough
                access_log:
                  - name: envoy.access_loggers.stdout
                    typed_config:
                      "@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog

  clusters:
    - name: forwarder_to_envoy_b_http
      type: STRICT_DNS
      lb_policy: ROUND_ROBIN
      load_assignment:
        cluster_name: forwarder_to_envoy_b_http
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address:
                      address: envoy-b.example.com
                      port_value: 8888

      dns_resolution_config:
        resolvers:
          - socket_address:
              address: "1.1.1.1"
              port_value: 53
        dns_resolver_options:
          no_default_search_domain: true
      transport_socket:
        name: envoy.transport_sockets.tls
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
          common_tls_context:
            tls_params:
              tls_minimum_protocol_version: TLSv1_3
              tls_maximum_protocol_version: TLSv1_3

    - name: forwarder_to_envoy_b_tls
      type: STRICT_DNS
      lb_policy: ROUND_ROBIN
      load_assignment:
        cluster_name: forwarder_to_envoy_b_tls
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address:
                      address: envoy-b.example.com
                      port_value: 8889
      dns_resolution_config:
        resolvers:
          - socket_address:
              address: "1.1.1.1"
              port_value: 53
        dns_resolver_options:
          no_default_search_domain: true

Посланник - Б:

  • Он слушает порт8888, и на каждомHTTP2 + TLSv1.3трафик, он расшифровывает трафик и пересылает простой HTTP-запрос службам
  • Он слушает порт8889, и каждый трафик TPC перенаправляется на Envoy-B без дальнейшего шифрования/дешифрования.
      static_resources:
  listeners:
    - name: http_listener_0
        address:
          socket_address:
            protocol: TCP
            address: 0.0.0.0
            port_value: 8888
        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
                  stat_prefix: ingress_http
                  route_config:
                    name: local_route
                    virtual_hosts:
                      - name: local_service
                        domains: [ "*" ]
                        routes:
                          - match:
                              prefix: "/"
                            route:
                              cluster: http_cluster
                  http_filters:
                    - name: envoy.filters.http.router
                      typed_config:
                        "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
            
            transport_socket:
              name: envoy.transport_sockets.tls
              typed_config:
                "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
                common_tls_context:
                  tls_params:
                    tls_minimum_protocol_version: TLSv1_3
                    tls_maximum_protocol_version: TLSv1_3
                  tls_certificates:
                    certificate_chain:
                      filename: /certs/proxy-crt.pem
                    private_key:
                      filename: /certs/proxy-key.pem
                  alpn_protocols: HTTP2


    - name: tls_listener_0
      address:
        socket_address:
          protocol: TCP
          address: 0.0.0.0
          port_value: 8889
      filter_chains:
        - filters:
            - name: envoy.filters.network.tcp_proxy
              typed_config:
                "@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
                cluster: tls_cluster
                stat_prefix: https_passthrough
                access_log:
                  - name: envoy.access_loggers.stdout
                    typed_config:
                      "@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog

  clusters:
    - name: http_cluster
      type: STRICT_DNS
      lb_policy: ROUND_ROBIN
      load_assignment:
        cluster_name: http_cluster
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address:
                      address: private.service.example.com
                      port_value: 80

      dns_resolution_config:
        resolvers:
          - socket_address:
              address: "1.1.1.1"
              port_value: 53
        dns_resolver_options:
          no_default_search_domain: true


    - name: tls_cluster
      type: STRICT_DNS
      lb_policy: ROUND_ROBIN
      load_assignment:
        cluster_name: tls_cluster
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address:
                      address: private.service.example.com
                      port_value: 443
      dns_resolution_config:
        resolvers:
          - socket_address:
              address: "1.1.1.1"
              port_value: 53
        dns_resolver_options:
          no_default_search_domain: true

Проблема

Когда клиент отправляет HTTP-запрос, Envoy-A зашифрует его, и будет использован SNI, разрешенный в клиентском брандмауэре (вместо заголовка HOST исходного запроса).

Но когда клиент отправляет трафик HTTPS/TLS, Envoy-A просто пересылает поток TCP , поэтому SNI не меняется и остаетсяprivate.service.example.com-> Поскольку это имя хоста не разрешено в брандмауэре, оно будет удалено !

Я хочу, чтобы трафик TCP-прокси снова зашифровался, чтобы SNI изменился наenvoy-b.example.comи брандмауэр не отбрасывает запрос.

Я попытался добавитьtransport_socketдля трафика TLS на обоих хостах посланников, но это не сработало:

Envoy A > clusters > forwarder_to_envoy_b_tls:

      
      transport_socket:
        name: envoy.transport_sockets.tls
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
          common_tls_context:
            tls_params:
              tls_minimum_protocol_version: TLSv1_3
              tls_maximum_protocol_version: TLSv1_3

Envoy B > listener > tls_listener_0:

      
            transport_socket:
              name: envoy.transport_sockets.tls
              typed_config:
                "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
                common_tls_context:
                  tls_params:
                    tls_minimum_protocol_version: TLSv1_3
                    tls_maximum_protocol_version: TLSv1_3
                  tls_certificates:
                    certificate_chain:
                      filename: /certs/proxy-crt.pem
                    private_key:
                      filename: /certs/proxy-key.pem
                  alpn_protocols: HTTP2

Примечания

  1. Клиент не принимает, что посланник Б преобразует трафик HTTPS в HTTP, затем передает его (используя HTTPS), а затем снова шифрование HTTPS происходит в посланнике А.
  2. У нас нет доступа к закрытым ключам службы, поэтому, если мы сделаем то, что описано в примечании 1, сертификаты изменятся.
  3. Посланник B ТРЕБУЕТ SNI , чтобы определить, к каким сервисам следует перенаправить трафик.

0 ответов

Другие вопросы по тегам