istio: Envoy Filter doesn't merge properly BoolValues

Bug description

use_remote_address cannot be set to false on http_connection_manager filter via the new envoy filter API.

This seems to be the case for BoolType values (as opposed to bool) : I see the same problem for use_remote_address & generate_request_id, whereas I can set preserve_external_request_id to true.

cf : https://www.envoyproxy.io/docs/envoy/latest/api-v2/config/filter/network/http_connection_manager/v2/http_connection_manager.proto

Given the following Gateway :

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: istio-ingressgateway
  namespace: istio-system
spec:
  selector:
    istio: ingressgateway
  servers:
  - hosts:
    - '*.staging-1.blbl.cr'
    port:
      name: http
      number: 80
      protocol: HTTP

The use_remote_address filed is set by default to true.

When applying the following EnvoyFilter :

kind: EnvoyFilter
metadata:
  annotations:
  name: ingressgateway-settings
  namespace: istio-system
spec:
  configPatches:
  - applyTo: NETWORK_FILTER
    match:
      context: GATEWAY
      listener:
        filterChain:
          filter:
            name: envoy.http_connection_manager
    patch:
      operation: MERGE
      value:
        typed_config:
          '@type': type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager
          use_remote_address: false
          xff_num_trusted_hops: 2
  workloadSelector:
    labels:
      istio: ingressgateway

The MERGE behavior doesn’t take into account use_remote_address: false.

You get the following listener : istioctl pc listener istio-ingressgateway-fdd56884f-hl2gg --port 80 -o json

[
    {
        "name": "0.0.0.0_80",
        "address": {
            "socketAddress": {
                "address": "0.0.0.0",
                "portValue": 80
            }
        },
        "filterChains": [
            {
                "filters": [
                    {
                        "name": "envoy.http_connection_manager",
                        "typedConfig": {
                            "@type": "type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager",
                            "statPrefix": "0.0.0.0_80",
                            "rds": {
                                "configSource": {
                                    "ads": {},
                                    "initialFetchTimeout": "0s"
                                },
                                "routeConfigName": "http.80"
                            },
                            "httpFilters": [
                                {
                                    "name": "mixer",
                                    "typedConfig": {
                                        "@type": "type.googleapis.com/istio.mixer.v1.config.client.HttpClientConfig",
                                        "transport": {
                                            "networkFailPolicy": {
                                                "policy": "FAIL_CLOSE",
                                                "baseRetryWait": "0.080s",
                                                "maxRetryWait": "1s"
                                            },
                                            "checkCluster": "outbound|9091||istio-policy.istio-system.svc.cluster.local",
                                            "reportCluster": "outbound|9091||istio-telemetry.istio-system.svc.cluster.local",
                                            "reportBatchMaxEntries": 100,
                                            "reportBatchMaxTime": "1s"
                                        },
                                        "serviceConfigs": {
                                            "default": {
                                                "disableCheckCalls": true
                                            }
                                        },
                                        "defaultDestinationService": "default",
                                        "mixerAttributes": {
                                            "attributes": {
                                                "context.proxy_version": {
                                                    "stringValue": "1.3.2"
                                                },
                                                "context.reporter.kind": {
                                                    "stringValue": "outbound"
                                                },
                                                "context.reporter.uid": {
                                                    "stringValue": "kubernetes://istio-ingressgateway-fdd56884f-hl2gg.istio-system"
                                                },
                                                "source.namespace": {
                                                    "stringValue": "istio-system"
                                                },
                                                "source.uid": {
                                                    "stringValue": "kubernetes://istio-ingressgateway-fdd56884f-hl2gg.istio-system"
                                                }
                                            }
                                        },
                                        "forwardAttributes": {
                                            "attributes": {
                                                "source.uid": {
                                                    "stringValue": "kubernetes://istio-ingressgateway-fdd56884f-hl2gg.istio-system"
                                                }
                                            }
                                        }
                                    }
                                },
                                {
                                    "name": "envoy.cors"
                                },
                                {
                                    "name": "envoy.fault"
                                },
                                {
                                    "name": "envoy.router"
                                }
                            ],
                            "tracing": {
                                "operationName": "EGRESS",
                                "clientSampling": {
                                    "value": 100
                                },
                                "randomSampling": {
                                    "value": 1
                                },
                                "overallSampling": {
                                    "value": 100
                                }
                            },
                            "httpProtocolOptions": {},
                            "serverName": "istio-envoy",
                            "streamIdleTimeout": "0s",
                            "useRemoteAddress": true,
                            "xffNumTrustedHops": 2,
                            "generateRequestId": true,
                            "forwardClientCertDetails": "SANITIZE_SET",
                            "setCurrentClientCertDetails": {
                                "subject": true,
                                "cert": true,
                                "dns": true,
                                "uri": true
                            },
                            "upgradeConfigs": [
                                {
                                    "upgradeType": "websocket"
                                }
                            ],
                            "normalizePath": true
                        }
                    }
                ]
            }
        ],
        "listenerFiltersTimeout": "0.100s",
        "continueOnListenerFiltersTimeout": true,
        "trafficDirection": "OUTBOUND"
    }
]

Expected behavior

Being able to set use_remote_address to false on the ingress gateway.

Steps to reproduce the bug

create a Gateway. Add a filter link above.

Version (include the output of istioctl version --remote and kubectl version)

istio : 1.3.2 (all) kubernetes: v1.14.6-gke.13

How was Istio installed?

Helm chart from the istio/istio repo

Environment where bug was observed (cloud vendor, OS, etc)

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 3
  • Comments: 43 (27 by maintainers)

Commits related to this issue

Most upvoted comments

It’s technically possible to solve with field masks. You would need to parse EnvoyFilter as JSON and collect all “null” fields into a clear mask (google.protobuf.FieldMask). Then on top of proto merge, you have to unset all fields from the clear mask. That’s how Google APIs implement JSON PATCH. So I don’t think it’s impossible, but it is quite a bit of work to implement.

I have an easy fix for this. What if we change the default values for a few of these important settings to false and also add either a default envoyFilter or default setting which sets it to true for ingress? Then folks can actually set it to false when they need to. Any concerns?

Reading from the thread, my understanding is the envoy filter to set use_remote_address doesn’t work, have you gotten it working?

@JimmyCYJ @kyessenov @howardjohn @rshriram We want to use istio in our environment but because of above issue its forcing us to move away, may you please help us if we have any workaround for problem.