Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: auth proxy support #531

Open
mateuszdrab opened this issue Mar 10, 2023 · 5 comments
Open

Feature Request: auth proxy support #531

mateuszdrab opened this issue Mar 10, 2023 · 5 comments
Labels
enhancement New feature or request

Comments

@mateuszdrab
Copy link

mateuszdrab commented Mar 10, 2023

Hi

I've been using the HAproxy controller as the internet facing ingress controller in my setup; however, for purpose of oauth2 authentication, I've been 'daisy-chaining' an Nginx Ingress Controller which is configured with duplicate ingresses to allow oauth2 authentication via oauth2-proxy. This is achieved with the annotations:

    nginx.ingress.kubernetes.io/auth-url: "https://$host/oauth2/auth"
    nginx.ingress.kubernetes.io/auth-signin: "https://$host/oauth2/start?rd=$escaped_request_uri"

Unfortunately, it does not appear that this ingress controller supports it - but I'd like to do away with jumping between controllers.
Is it feasible to implement support for this?
It is supported by a similar project at https://github.com/jcmoraisjr/haproxy-ingress

Thanks

@oktalz oktalz added the enhancement New feature or request label Mar 22, 2023
@ivanmatmati
Copy link
Collaborator

Hi @mateuszdrab , we might consider that in the future. Your request has been labeled as enhancement.

@Zempashi
Copy link

Zempashi commented Aug 7, 2023

I managed to get it working. That's definitely a work-around; but here the receip:
1/ Assemble the lua code in a configmap, I use a makefile for that:

lua:
        kubectl create configmap haproxy-lua --dry-run=client -o yaml \
        --from-literal=http.lua="$$(curl https://raw.githubusercontent.com/haproxytech/haproxy-lua-http/master/http.lua)" \
        --from-literal=auth-request.lua="$$(curl https://raw.githubusercontent.com/TimWolla/haproxy-auth-request/main/auth-request.lua)" \
        --from-literal=json.lua="$$(curl https://raw.githubusercontent.com/rxi/json.lua/master/json.lua)" \
        > haproxy-lua.configmap.yaml
        #kubectl apply -f heproxy-lua.configmap.yaml

2/ Modify the deployment; (I used helm) here the added values:

controller:
    extraVolumes:
    - name: haproxy-lua
      configMap:
        name: haproxy-lua
        items:
        - key: json.lua
          path: json.lua
        - key: http.lua
          path: haproxy-lua-http/http.lua
        - key: auth-request.lua
          path: auth-request.lua
    extraVolumeMounts:
    - name: haproxy-lua
      mountPath: /usr/share/haproxy
    config:
      global-config-snippet: |
        lua-prepend-path /usr/share/haproxy/?/http.lua
        lua-prepend-path /usr/share/haproxy/?.lua
        lua-load /usr/share/haproxy/auth-request.lua

3/ Now you need to modify the ingresses you want to protect with this added annotation

haproxy.org/backend-config-snippet: |
            http-request lua.auth-intercept oauth2-proxy_oauth2-proxy_http  /oauth2/auth  HEAD    *        -        -
            http-request redirect code 302 location http://%[hdr(host)]/oauth2/start?rd=%[capture.req.uri] if ! { var(txn.auth_response_successful) -m bool }

Note that I (also) use oauth2-proxy, and expose it via an ingress, so I have a backend (oauth2-proxy_oauth2-proxy_http) already created, but I guess that a backend CRD (https://www.haproxy.com/documentation/kubernetes/latest/community/configuration-reference/custom-resources/backend/) should do the trick as well

Reference:

PS: I just read a know limitation of the script I used "The backend must not be using TLS."; seeing the annotation you used, this might be a problem

@mateuszdrab
Copy link
Author

I managed to get it working. That's definitely a work-around; but here the receip: 1/ Assemble the lua code in a configmap, I use a makefile for that:

lua:
        kubectl create configmap haproxy-lua --dry-run=client -o yaml \
        --from-literal=http.lua="$$(curl https://raw.githubusercontent.com/haproxytech/haproxy-lua-http/master/http.lua)" \
        --from-literal=auth-request.lua="$$(curl https://raw.githubusercontent.com/TimWolla/haproxy-auth-request/main/auth-request.lua)" \
        --from-literal=json.lua="$$(curl https://raw.githubusercontent.com/rxi/json.lua/master/json.lua)" \
        > haproxy-lua.configmap.yaml
        #kubectl apply -f heproxy-lua.configmap.yaml

2/ Modify the deployment; (I used helm) here the added values:

controller:
    extraVolumes:
    - name: haproxy-lua
      configMap:
        name: haproxy-lua
        items:
        - key: json.lua
          path: json.lua
        - key: http.lua
          path: haproxy-lua-http/http.lua
        - key: auth-request.lua
          path: auth-request.lua
    extraVolumeMounts:
    - name: haproxy-lua
      mountPath: /usr/share/haproxy
    config:
      global-config-snippet: |
        lua-prepend-path /usr/share/haproxy/?/http.lua
        lua-prepend-path /usr/share/haproxy/?.lua
        lua-load /usr/share/haproxy/auth-request.lua

3/ Now you need to modify the ingresses you want to protect with this added annotation

haproxy.org/backend-config-snippet: |
            http-request lua.auth-intercept oauth2-proxy_oauth2-proxy_http  /oauth2/auth  HEAD    *        -        -
            http-request redirect code 302 location http://%[hdr(host)]/oauth2/start?rd=%[capture.req.uri] if ! { var(txn.auth_response_successful) -m bool }

Note that I (also) use oauth2-proxy, and expose it via an ingress, so I have a backend (oauth2-proxy_oauth2-proxy_http) already created, but I guess that a backend CRD (https://www.haproxy.com/documentation/kubernetes/latest/community/configuration-reference/custom-resources/backend/) should do the trick as well

Reference:

PS: I just read a know limitation of the script I used "The backend must not be using TLS."; seeing the annotation you used, this might be a problem

Thanks for sharing your steps - I think I overlooked this and never got to investigate it.

The backend was indeed set to https; however, I can change that easily.

Does it work fine when backend is http and frontend is https with SSL termination enabled?

@paldib
Copy link

paldib commented Apr 18, 2024

@Zempashi @mateuszdrab I am trying to reproduce your configuration but the backend configuration is invalid, at least from the haproxy's perspective. It is not included in the/etc/haproxy/haproxy.cfg but i get a /etc/haproxy/failed/haproxy.cfg.96ad8aec-f482-4716-8053-d422ad54de39 instead. In the log I can see this:

msg="config parsing [/etc/haproxy/haproxy.cfg.2bddb069-c5a1-4e0b-a3e9-ccd8e78a2e28:396]: 'http-request' 
expects 'wait-for-handshake', 'set-log-level', 'set-nice', 'use-service', 'sc-add-gpc(*)', 'sc-inc-gpc(*)', 
'sc-inc-gpc0(*)',  'sc-inc-gpc1(*)', 'sc-set-gpt(*)', 'sc-set-gpt0(*)', 'send-spoe-group', 'do-resolve(*)', 
'cache-use', 'add-acl(*)', 'add-header', 'allow', 'auth', 'capture', 'del-acl(*)', 'del-header', 'del-map(*)', 
'deny', 'disable-l7-retry', 'early-hint', 'normalize-uri', 'redirect', 'reject', 'replace-header', 
'replace-path', 'replace-pathq', 'replace-uri', 'replace-value', 'return', 'set-header', 
'set-map(*)', 'set-method', 'set-path',  'set-pathq', 'set-query', 'set-uri', 'strict-mode', 
'tarpit',  'track-sc(*)', 'set-timeout', 'wait-for-body',  'set-var-fmt(*)', 'set-var(*)', 'unset-var(*)', 
'set-dst', 'set-dst-port',  'set-mark', 'set-src', 'set-src-port',  'set-tos', 'silent-drop', 
'set-priority-class', 'set-priority-offset',  'set-bandwidth-limit',  but got 'lua.auth-intercept'."

I checked the documentation here and here. In backednd you can only use lua service with use-service but auth-intercept is an action that can only be used in frontend. The problem with this is there is only one frontend that is globally used and can not configure from annotations. So it looks like this workaround dose not work anymore.

@vaskozl
Copy link

vaskozl commented May 26, 2024

I also found it needs to be included in the frontend section I use frontend-config-snippet which enables auth for all ingresses.

To maintain ingress without reverse proxy auth, you can make a separate ingress class or something like the public_hosts acl in my config.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

6 participants