emissary-ingress / emissary

open source Kubernetes-native API gateway for microservices built on the Envoy Proxy
https://www.getambassador.io
Apache License 2.0
4.34k stars 680 forks source link

hostBinding not respected for TCP listeners #5732

Open rgs1 opened 1 month ago

rgs1 commented 1 month ago

For HTTP chains, hosts are properly filtered out if their namespace and selector don't match:

https://github.com/emissary-ingress/emissary/blob/master/python/ambassador/envoy/v3/v3listener.py#L790

However, for TCP chains all hosts are considered regardless:

https://github.com/emissary-ingress/emissary/blob/master/python/ambassador/envoy/v3/v3listener.py#L184

Filtering would have to happen here:

https://github.com/emissary-ingress/emissary/blob/master/python/ambassador/envoy/v3/v3listener.py#L184

Ideally hostBinding would apply to all mappings, otherwise you might end with the wrong certificate for some TCPMappings.

kflynn commented 1 month ago

Hmmmmmmm. @rgs1, do you have a minimal config to hand to reproduce this? There are some subtleties with TCPMappings; I want to make sure I'm looking at the scenario you're wrestling with.

rgs1 commented 1 month ago

I think something like this should repro this (not tested):

---
apiVersion: getambassador.io/v3alpha1
kind: Host
metadata:
  name: a-host
spec:
  hostname: '*.domain.com'
  requestPolicy:
    insecure:
      action: Redirect
  tlsContext:
    name: tlscontext
  tlsSecret:
    name: secret
---
apiVersion: getambassador.io/v3alpha1
kind: Host
metadata:
  labels:
    redis: "yes"
  name: b-host
spec:
  hostname: '*.b.domain.com'
  metadata_labels:
    redis: "yes"
  requestPolicy:
    insecure:
      action: Redirect
  tlsContext:
    name: tlscontext-b
  tlsSecret:
    name: secret-b
---
apiVersion: getambassador.io/v3alpha1
kind: Listener
metadata:
  name: redis-listener
spec:
  hostBinding:
    selector:
      matchLabels:
        redis: "yes"
  port: 6379
  protocolStack:
  - TCP
  securityModel: XFP

If you apply this, you'll see that the listener gets assigned the TLS cert for the first hosts (hosts are sorted when they need to be looked up to be attached to a listener), instead of the one that should match the hostBinding.