envoyproxy/envoy

Filter chain match by `sourcePrefixRanges` is not working correctly with CIDR `0.0.0.0/0`

Open

#34,299 opened on May 22, 2024

View on GitHub
 (2 comments) (1 reaction) (0 assignees)C++ (5,373 forks)batch import
area/listenerbughelp wanted

Repository metrics

Stars
 (27,997 stars)
PR merge metrics
 (Avg merge 8d) (378 merged PRs in 30d)

Description

Title: Filter chain match by sourcePrefixRanges is not working correctly with CIDR 0.0.0.0/0

Description:

In our LDS configuration, we are configuring 2 different filter chains. Both filter chains have the same configuration and log the Filter Chain Name field, which allows us to see which filter chain is being applied.

  • The first one has no FilterChainMatch and applies by default.
  • The second one has a FilterChainMatch for sourcePrefixRanges.

If we configure the second FilterChainMatch with the range sourcePrefixRanges 127.0.0.0/24, it works correctly:

  • If Source IP is 127.0.0.1, it applies the second filter chain:
{"downstreamIp":"127.0.0.1","filterChain":"filter_chain_with_match"}
{"downstreamIp":"127.0.0.1","filterChain":"filter_chain_with_match"}
  • If Source IP is not on 127.0.0.0/24 range (10.97.145.78), it applies the first filter chain:
{"downstreamIp":"10.97.145.78","filterChain":"default"}
{"downstreamIp":"10.97.145.78","filterChain":"default"}

If we configure the second FilterChainMatch with the range sourcePrefixRanges 0.0.0.0/0, it should always apply the second filter chain, regardless of the source IP, but it does not work correctly. Each time we start Envoy with the same LDS config, either the first or the second one is being applied randomly:

{"downstreamIp":"10.97.145.78","filterChain":"default"}
{"downstreamIp":"127.0.0.1","filterChain":"default"}
{"downstreamIp":"10.97.145.78","filterChain":"filter_chain_with_match"}
{"downstreamIp":"127.0.0.1","filterChain":"filter_chain_with_match"}

Config that works with 127.0.0.0/24:

resources:
  - name: listener_http
    address:
      socketAddress:
        address: 0.0.0.0
        portValue: 8081
    filterChains:
      - name: default
        filters:
          - name: envoy.filters.network.http_connection_manager
            typedConfig:
              statPrefix: ingress_http
              routeConfig:
                name: local_route
                virtualHosts:
                  - name: local_service
                    domains:
                      - '*'
                    routes:   
                      - match:
                          prefix: /
                        route:
                          cluster: service_upstream
                          timeout: 60s
              httpFilters:                
                - name: envoy.filters.http.router
                  typedConfig:
                    '@type': >-
                      type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
              accessLog:
                - name: envoy.access_loggers.stdout
                  typedConfig:
                    logFormat:
                      jsonFormat:
                        downstreamIp: '%DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT%'
                        filterChain: default
                      contentType: json_format
                    '@type': >-
                      type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
              '@type': >-
                type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
      - name: filter_chain_with_match
        filterChainMatch:
          sourcePrefixRanges:
            - addressPrefix: 127.0.0.0
              prefixLen: 24
        filters:
          - name: envoy.filters.network.http_connection_manager
            typedConfig:
              statPrefix: ingress_http
              routeConfig:
                name: local_route
                virtualHosts:
                  - name: local_service
                    domains:
                      - '*'
                    routes:   
                      - match:
                          prefix: /
                        route:
                          cluster: service_upstream
                          timeout: 60s
              httpFilters:                
                - name: envoy.filters.http.router
                  typedConfig:
                    '@type': >-
                      type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
              accessLog:
                - name: envoy.access_loggers.stdout
                  typedConfig:
                    logFormat:
                      jsonFormat:
                        downstreamIp: '%DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT%'
                        filterChain: filter_chain_with_match
                      contentType: json_format
                    '@type': >-
                      type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
              '@type': >-
                type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
    '@type': type.googleapis.com/envoy.config.listener.v3.Listener

Config that NOT works with 0.0.0.0/0:

resources:
  - name: listener_http
    address:
      socketAddress:
        address: 0.0.0.0
        portValue: 8081
    filterChains:
      - name: default
        filters:
          - name: envoy.filters.network.http_connection_manager
            typedConfig:
              statPrefix: ingress_http
              routeConfig:
                name: local_route
                virtualHosts:
                  - name: local_service
                    domains:
                      - '*'
                    routes:   
                      - match:
                          prefix: /
                        route:
                          cluster: service_upstream
                          timeout: 60s
              httpFilters:                
                - name: envoy.filters.http.router
                  typedConfig:
                    '@type': >-
                      type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
              accessLog:
                - name: envoy.access_loggers.stdout
                  typedConfig:
                    logFormat:
                      jsonFormat:
                        downstreamIp: '%DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT%'
                        filterChain: default
                      contentType: json_format
                    '@type': >-
                      type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
              '@type': >-
                type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
      - name: filter_chain_with_match
        filterChainMatch:
          sourcePrefixRanges:
            - addressPrefix: 0.0.0.0
              prefixLen: 0
        filters:
          - name: envoy.filters.network.http_connection_manager
            typedConfig:
              statPrefix: ingress_http
              routeConfig:
                name: local_route
                virtualHosts:
                  - name: local_service
                    domains:
                      - '*'
                    routes:   
                      - match:
                          prefix: /
                        route:
                          cluster: service_upstream
                          timeout: 60s
              httpFilters:                
                - name: envoy.filters.http.router
                  typedConfig:
                    '@type': >-
                      type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
              accessLog:
                - name: envoy.access_loggers.stdout
                  typedConfig:
                    logFormat:
                      jsonFormat:
                        downstreamIp: '%DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT%'
                        filterChain: filter_chain_with_match
                      contentType: json_format
                    '@type': >-
                      type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
              '@type': >-
                type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
    '@type': type.googleapis.com/envoy.config.listener.v3.Listener

Contributor guide