jcmoraisjr / haproxy-ingress

HAProxy Ingress

Home Page:https://haproxy-ingress.github.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Use oauth X-Auth-* with http-header-match annotation

knfoo opened this issue · comments

Description of the problem
I have an application where users login via the oauth2_proxy. I want to route the users to different backends based on the value in X-Auth-Groups.
I have asked about this in slack and was pointed to a feature that was merged but not yet released Add http-header-match annotation #944. Which seems to fit the usecase quite nicely.
I have build haproxy-ingress from source to get it deployed. When I create a ingress object now the header match is added to the haproxy configuration. But I am no longer able to login as the header match denies access to the oauth2 flow.

Frontend config

frontend _front_https
    mode http
    bind :443 ssl alpn h2,http/1.1 crt-list /etc/haproxy/maps/_front_bind_crt.list ca-ignore-err all crt-ignore-err all
    option httplog
    http-request set-var(req.path) path
    http-request set-var(req.host) hdr(host),field(1,:),lower
    http-request set-var(req.base) var(req.host),concat(\#,req.path)
    http-request set-var(req.hostbackend) var(req.base),map_dir(/etc/haproxy/maps/_front_https_host__prefix_01.map) if { hdr(X-Auth-Request-Groups) -m reg -- '(group-id)' }
    http-request set-var(req.hostbackend) var(req.base),map_dir(/etc/haproxy/maps/_front_https_host__prefix.map) if !{ var(req.hostbackend) -m found }
    http-request set-header X-Forwarded-Proto https
    http-request del-header X-SSL-Client-CN
    http-request del-header X-SSL-Client-DN
    http-request del-header X-SSL-Client-SHA1
    http-request del-header X-SSL-Client-SHA2
    http-request del-header X-SSL-Client-Cert
    use_backend %[var(req.hostbackend)] if { var(req.hostbackend) -m found }
    default_backend ingress-controllers_dh2-2-haproxy-ingress-default-backend_http

The /etc/haproxy/maps/_front_https_host__prefix_01.map

domain.com#/oauth2 observability_oauth2-proxy-helm_http
domain.com#/ observability_grafana_3000

Backend config

backend observability_grafana_3000
    mode http
    balance roundrobin
    acl https-request ssl_fc
    http-request redirect scheme https if !https-request
    option forwardfor if-none
    http-request set-header X-Real-IP %[src]
    http-request lua.auth-intercept observability_oauth2-proxy-helm_http /oauth2/auth HEAD '*' '-' '-' if !{ path_beg /oauth2/ }
    http-request redirect location /oauth2/start?rd=%[path] if !{ var(txn.auth_response_successful) -m bool } !{ path_beg /oauth2/ }
    http-request set-header X-Auth-Request-Access-Token %[var(req.auth_response_header.x_auth_request_access_token)] if { var(req.auth_response_header.x_auth_request_access_token) -m found } !{ path_beg /oauth2/ }

Expected behavior
I was expecting that the oauth2 flow was allowed so that the X-Auth-* headers would be set and the request would be sent to the right backend based on the http-header-match.

Steps to reproduce the problem

  1. build haproxy from source
  2. create ingress with oauth2
  3. test that the headers is present with whoami service
  4. add annotation http-header-match then the request to oauth2-proxy is blocked and I am redirected to the default backend

Environment information

HAProxy Ingress version: build-from-master

Ingress objects:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    haproxy-ingress.github.io/http-header-match-regex: |
      X-Auth-Request-Groups: (group-id)
    haproxy-ingress.github.io/oauth: oauth2_proxy
    haproxy-ingress.github.io/oauth-headers: X-Auth-Request-Email,X-Auth-Request-Groups,X-Auth-Request-Access-Token
    haproxy.org/cors-allow-headers: X-Auth-Request-Group,X-Auth-Request-Email,X-Auth-Request-User,X-Auth-Request-Access-Token,X-Auth-Request-Preferred-Username,X-Auth-Request-Email
    ingress.kubernetes.io/allow-http: "false"
    ingress.kubernetes.io/ssl-redirect: "true"
  labels:
    app.kubernetes.io/name: grafana
  name: spitzer
spec:
  ingressClassName: haproxy
  rules:
  - host: domain.com
    http:
      paths:
      - backend:
          service:
            name: oauth2-proxy-helm
            port:
              number: 80
        path: /oauth2
        pathType: Prefix
      - backend:
          service:
            name: grafana
            port:
              number: 80
        path: /
        pathType: Prefix
  tls:
  - hosts:
    - domain.com
    secretName: domain-com-tls

This issue got stale and will be closed in 7 days.

Fixed in v0.15.0-alpha.1, closing.