Skip to content

Subdomain wildcard does not work together with route-acl service annotation #734

@SF97

Description

@SF97

APP VERSION: 3.1.11
CHART: kubernetes-ingress-1.44.6

It's possible to use route-acl service annotation to specify paths against regular expressions. For instance, if I want the service to only match paths with path-in-bug-repro, I can add the Service annotation haproxy.org/route-acl: path_reg path-in-bug-repro$, using the following helm value file

# helm upgrade --install -f ./values.yaml haproxy-bug oci://registry-1.docker.io/bitnamicharts/nginx
ingress:
  enabled: true
  hostname: "example.local"
  ingressClassName: "haproxy"
  tls: false

service:
  annotations:
    haproxy.org/route-acl: path_reg path-in-bug-repro$
  type: ClusterIP

# Define a custom server block.
# The content is a multi-line string containing the Nginx configuration.
serverBlock: |
  server {
    listen 0.0.0.0:8080;
    server_name _;

    location / {
      default_type text/html;

      <!DOCTYPE html>
      <html lang="en">
      <body>
          <h1>BUG REPRO</h1>
      </body>
      </html>
      ';
    }
  }

And requests to said path will match:

Image

Other paths will not:

Image

However, when trying to use this feature in combination with wildcard subdomains, it does not work. Using the YAML (notice the wildcard in the hostname)

# helm upgrade --install -f ./values.yaml haproxy-bug oci://registry-1.docker.io/bitnamicharts/nginx
ingress:
  enabled: true
  hostname: "*.example.local"
  ingressClassName: "haproxy"
  tls: false

service:
  annotations:
    haproxy.org/route-acl: path_reg path-in-bug-repro$
  type: ClusterIP

# Define a custom server block.
serverBlock: |
  server {
    listen 0.0.0.0:8080;
    server_name _;

    location / {
      # Set the Content-Type header so browsers render the HTML correctly.
      default_type text/html;

      <!DOCTYPE html>
      <html lang="en">
      <body>
          <h1>BUG REPRO</h1>
      </body>
      </html>
      ';
    }
  }

If I access the an subdomain of the wildcard, for instance subdomain.example.local it will not match

Image

However, if I add the hostname as subdomain.example.com exactly, without wildcard, it starts working again.

Image

This led me to debug the ACL rules, and I found out that in https://github.com/haproxytech/kubernetes-ingress/blob/master/pkg/route/route.go#L107 the Ingress controller always adds a path -m beg <hostname>, which leads to a if { var(txn.host) -m str *.example.local } rule. Notice the -m str *.example.com it's matching an exact match of string that has a literal "*" and then .example.com

Image

Instead, when using wildcard subdomains, the Ingress controller should use suffix match, which would work for subdomains:

if { var(txn.host) -m end .example.local }

AFAIK that should fix the issue and make subdomain wildcards and route-acl work correctly together :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions