Skip to content

Gateway listener using TURN-DTLS functional even if certificate secret is missing #215

@pylaligand

Description

@pylaligand

Description

Misconfiguration of TLS certificates is ignored at "gateway programming" time but yields errors at a later time.

Steps to Reproduce

I configured a STUNner Gateway with the following listener:

  listeners:
    - hostname: my-hostname.com
      name: udp-listener
      protocol: TURN-DTLS
      port: 3478
      tls:
        mode: Terminate
        certificateRefs:
          - name: udp-gateway-tls

The secret that the certificateRefs points to does not exist. Yet the listener is accepted:

Name:         udp-gateway
Namespace:    stunner-system
API Version:  gateway.networking.k8s.io/v1
Kind:         Gateway
Metadata:
  Creation Timestamp:  2025-11-28T18:30:12Z
  Generation:          8
  Resource Version:    3690115
  UID:                 49cc945b-80dd-48d4-9468-abd2bdfe24a4
Spec:
  Gateway Class Name:  stunner
  Listeners:
    Allowed Routes:
      Namespaces:
        From:  Selector
        Selector:
          Match Labels:
            Webrtc - Gateway - Access:  true
    Hostname:                           my-hostname.com
    Name:                               udp-listener
    Port:                               3478
    Protocol:                           TURN-DTLS
    Tls:
      Certificate Refs:
        Group:  
        Kind:   Secret
        Name:   udp-gateway-tls
      Mode:     Terminate
Status:
  Addresses:
    Type:   IPAddress
    Value:  1.2.3.4
  Conditions:
    Last Transition Time:  2025-11-28T18:30:12Z
    Message:               gateway accepted by controller stunner.l7mp.io/gateway-operator
    Observed Generation:   8
    Reason:                Accepted
    Status:                True
    Type:                  Accepted
    Last Transition Time:  2025-12-04T11:22:46Z
    Message:               dataplane configuration successfully rendered
    Observed Generation:   8
    Reason:                Programmed
    Status:                True
    Type:                  Programmed
  Listeners:
    Attached Routes:  1
    Conditions:
      Last Transition Time:  2025-12-04T11:22:46Z
      Message:               listener accepted
      Observed Generation:   8
      Reason:                Accepted
      Status:                True
      Type:                  Accepted
      Last Transition Time:  2025-12-04T11:22:46Z
      Message:               listener protocol-port available
      Observed Generation:   8
      Reason:                NoConflicts
      Status:                False
      Type:                  Conflicted
      Last Transition Time:  2025-12-04T11:22:46Z
      Message:               listener object references sucessfully resolved
      Observed Generation:   8
      Reason:                ResolvedRefs
      Status:                True
      Type:                  ResolvedRefs
    Name:                    udp-listener
    Supported Kinds:
      Group:  gateway.networking.k8s.io
      Kind:   UDPRoute
      Group:  stunner.l7mp.io
      Kind:   UDPRoute
Events:       <none>

The operator knows that the secret does not exist as I can see the following in its logs:

2025-12-04T11:22:46.8479237Z    INFO    listener-renderer       Secret not found        {"gateway": "stunner-system/udp-gateway", "listener": "udp-listener", "secret": "stunner-system/udp-gateway-tls"}

Later when attempting to connect to the gateway I observed the following in its pod's logs:

13:24:19.654207 cds_api.go:360: cds-client WARNING: invalid config: empty TLS cert for TURN-DTLS listener

Expected behavior:

I'd expected the Listener to not get accepted and the Gateway to not get programmed.

Actual behavior:

The Listener and Gateway are reconciled just fine but client queries fail down the road.

Versions

Version 1.1.0 of the Helm chart.

Info

Gateway API status

Details
apiVersion: v1
items:
- apiVersion: gateway.networking.k8s.io/v1
  kind: Gateway
  metadata:
    creationTimestamp: "2025-11-28T18:30:12Z"
    generation: 8
    labels:
      kustomize.toolkit.fluxcd.io/name: cluster-infrastructure-stunner-gateway
      kustomize.toolkit.fluxcd.io/namespace: flux-system
    name: udp-gateway
    namespace: stunner-system
    resourceVersion: "3737345"
    uid: 49cc945b-80dd-48d4-9468-abd2bdfe24a4
  spec:
    gatewayClassName: stunner
    listeners:
    - allowedRoutes:
        namespaces:
          from: Selector
          selector:
            matchLabels:
              webrtc-gateway-access: "true"
      hostname: my-hostname.com
      name: udp-listener
      port: 3478
      protocol: TURN-DTLS
      tls:
        certificateRefs:
        - group: ""
          kind: Secret
          name: udp-gateway-tls
        mode: Terminate
  status:
    addresses:
    - type: IPAddress
      value: 1.2.3.4
    conditions:
    - lastTransitionTime: "2025-11-28T18:30:12Z"
      message: gateway accepted by controller stunner.l7mp.io/gateway-operator
      observedGeneration: 8
      reason: Accepted
      status: "True"
      type: Accepted
    - lastTransitionTime: "2025-12-04T13:24:19Z"
      message: dataplane configuration successfully rendered
      observedGeneration: 8
      reason: Programmed
      status: "True"
      type: Programmed
    listeners:
    - attachedRoutes: 1
      conditions:
      - lastTransitionTime: "2025-12-04T13:24:19Z"
        message: listener accepted
        observedGeneration: 8
        reason: Accepted
        status: "True"
        type: Accepted
      - lastTransitionTime: "2025-12-04T13:24:19Z"
        message: listener protocol-port available
        observedGeneration: 8
        reason: NoConflicts
        status: "False"
        type: Conflicted
      - lastTransitionTime: "2025-12-04T13:24:19Z"
        message: listener object references sucessfully resolved
        observedGeneration: 8
        reason: ResolvedRefs
        status: "True"
        type: ResolvedRefs
      name: udp-listener
      supportedKinds:
      - group: gateway.networking.k8s.io
        kind: UDPRoute
      - group: stunner.l7mp.io
        kind: UDPRoute
- apiVersion: stunner.l7mp.io/v1
  kind: GatewayConfig
  metadata:
    creationTimestamp: "2025-11-28T18:30:12Z"
    generation: 2
    labels:
      kustomize.toolkit.fluxcd.io/name: cluster-infrastructure-stunner-gateway
      kustomize.toolkit.fluxcd.io/namespace: flux-system
    name: stunner-config
    namespace: stunner-system
    resourceVersion: "3396486"
    uid: 538be11a-2473-43bb-8d16-6c99907afa9c
  spec:
    authType: static
    dataplane: default
    loadBalancerServiceAnnotations:
      external-dns.alpha.kubernetes.io/hostname: my-hostname.com
      external-dns.alpha.kubernetes.io/ttl: "120"
    logLevel: all:DEBUG,turn:INFO
    password: password
    realm: stunner.l7mp.io
    userName: username
- apiVersion: gateway.networking.k8s.io/v1
  kind: GatewayClass
  metadata:
    creationTimestamp: "2025-11-28T18:30:12Z"
    generation: 1
    labels:
      kustomize.toolkit.fluxcd.io/name: cluster-infrastructure-stunner-gateway
      kustomize.toolkit.fluxcd.io/namespace: flux-system
    name: stunner
    resourceVersion: "753687"
    uid: d529080b-96f0-4505-9316-b647eca72f7e
  spec:
    controllerName: stunner.l7mp.io/gateway-operator
    description: STUNner is a WebRTC ingress gateway for Kubernetes
    parametersRef:
      group: stunner.l7mp.io
      kind: GatewayConfig
      name: stunner-config
      namespace: stunner-system
  status:
    conditions:
    - lastTransitionTime: "2025-11-28T18:30:12Z"
      message: GatewayClass is now managed by controller "stunner.l7mp.io/gateway-operator"
      observedGeneration: 1
      reason: Accepted
      status: "True"
      type: Accepted
- apiVersion: stunner.l7mp.io/v1
  kind: UDPRoute
  metadata:
    creationTimestamp: "2025-11-28T18:30:11Z"
    generation: 1
    labels:
      kustomize.toolkit.fluxcd.io/name: cluster-apps-demo
      kustomize.toolkit.fluxcd.io/namespace: flux-system
    name: worker-route
    namespace: demo
    resourceVersion: "3737346"
    uid: 4ae8570b-1b3e-4437-89dd-27b855cb752a
  spec:
    parentRefs:
    - group: gateway.networking.k8s.io
      kind: Gateway
      name: udp-gateway
      namespace: stunner-system
    rules:
    - backendRefs:
      - group: ""
        kind: Service
        name: worker
        namespace: demo
  status:
    parents:
    - conditions:
      - lastTransitionTime: "2025-12-04T13:24:19Z"
        message: parent stunner-system/udp-gateway accepted the route
        observedGeneration: 1
        reason: Accepted
        status: "True"
        type: Accepted
      - lastTransitionTime: "2025-12-04T13:24:19Z"
        message: all backend references successfully resolved
        observedGeneration: 1
        reason: ResolvedRefs
        status: "True"
        type: ResolvedRefs
      controllerName: stunner.l7mp.io/gateway-operator
      parentRef:
        group: gateway.networking.k8s.io
        kind: Gateway
        name: udp-gateway
        namespace: stunner-system
kind: List
metadata:
  resourceVersion: ""

Operator logs

See next message

Metadata

Metadata

Assignees

Labels

type: bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions