Haproxy from Nginx Config Conversion (HASSIO Authentik Auth)

Hi all, new to haproxy and in the process of translating my config to it from nginx (specifically swag if that matters), have the majority working but unsure how to translate the following into haproxy for hassio auth with Authentik:

proxy_set_header X-ak-hass-user $X_ak_hass_user;
auth_request_set $X_ak_hass_user $upstream_http_x_ak_hass_user;

Docs for what i’m trying to do is here: Home Assistant | authentik

Below is my config:

global
        log /dev/log    local0
        log /dev/log    local1 notice
        chroot /var/lib/haproxy
        stats socket /run/haproxy/admin.sock mode 660 level admin
        stats timeout 30s
        user haproxy
        group haproxy
        daemon
        maxconn 40000
        ulimit-n 81000

        # Default SSL material locations
        ca-base /etc/ssl/certs
        crt-base /etc/ssl/private

        # See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate
       ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
        ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
        ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets

       # Crowdsec bouncer
       lua-prepend-path /usr/lib/crowdsec/lua/haproxy/?.lua
       lua-load /usr/lib/crowdsec/lua/haproxy/crowdsec.lua
       setenv CROWDSEC_CONFIG /etc/crowdsec/bouncers/crowdsec-haproxy-bouncer.conf

       # Authentik Auth Lua files
       lua-prepend-path /usr/local/share/lua/5.3/?.lua
       lua-load /usr/local/share/lua/5.3/auth-request.lua

defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        option forwardfor
        timeout connect 30s
        timeout client  30s
        timeout server  5s
        errorfile 400 /etc/haproxy/errors/400.http
        errorfile 403 /etc/haproxy/errors/403.http
        errorfile 408 /etc/haproxy/errors/408.http
        errorfile 500 /etc/haproxy/errors/500.http
        errorfile 502 /etc/haproxy/errors/502.http
        errorfile 503 /etc/haproxy/errors/503.http
        errorfile 504 /etc/haproxy/errors/504.http

listen stats
    bind *:8404
    stats enable
    stats hide-version
    stats realm Haproxy\ Statistics
    stats uri /haproxy_stats
    stats auth HAProxy:Password

# Frontend to redirect HTTP to HTTPS with code 301
frontend http-redirect
    bind *:80
    http-request redirect scheme https code 301
    acl letsencrypt-acl path_beg /.well-known/acme-challenge/
    use_backend letsencrypt-backend if letsencrypt-acl

# LE Backend
backend letsencrypt-backend
    server letsencrypt 127.0.0.1:8888

# Frontend for redirecting traffic to the required frontend
frontend https-redirect
    bind *:443 ssl crt /etc/ssl/home.MYDOMAIN.com.pem
    mode tcp
    option tcplog
    tcp-request inspect-delay 5s
    tcp-request content accept if { req_ssl_hello_type 1 }
    acl internal src 0.0.0.0/24 #IP RANGE OF MY NETWORK

    use_backend internal if internal

# Frontend for users
frontend internal
    bind abns@internal accept-proxy
    # Crowdsec bouncer
    stick-table type ip size 10k expire 30m # declare a stick table to cache captcha verifications
    http-request lua.crowdsec_allow # action to identify crowdsec remediation
    http-request track-sc0 src if { var(req.remediation) -m str "captcha-allow" } # cache captcha allow decision
    http-request redirect location %[var(req.redirect_uri)] if { var(req.remediation) -m str "captcha-allow" } # redirect to initial url
    http-request use-service lua.reply_captcha if { var(req.remediation) -m str "captcha" } # serve captcha template if remediation is captcha
    http-request use-service lua.reply_ban if { var(req.remediation) -m str "ban" } # serve ban template if remediation is ban

    #Authentik config
    acl protected-frontends hdr(host) -m reg -i ^(?i)(arrs|downloads)\.(home|media)\.home\.MYDOMAIN\.com
    acl is_authentikoutpost path -m reg ^/outpost.goauthentik.io/

    http-request set-var(req.scheme) str(http) if !{ ssl_fc }
    http-request set-var(req.questionmark) str(?) if { query -m found }

    http-request set-header X-Real-IP %[src]

    http-request set-header X-Forwarded-Method %[method]
    #http-request set-header X-Forwarded-Proto  %[var(req.scheme)] #had to remove this as hassio breaks if its enabled, everything works fine without it
    http-request set-header X-Forwarded-Host   %[req.hdr(Host)]
    http-request set-header X-Original-URL     %[url]
    # websockets break if all headers are passed to be_auth_requests as the Upgrade header screws the process up - so we pass manual list
    http-request lua.auth-intercept be_auth_request /outpost.goauthentik.io/auth/nginx HEAD x-original-url,x-real-ip,x-forwarded-host,x-forwarded-proto,user-agent,cookie,accept,x-forwarded-method x-authentik-username,x-authentik-uid,x-authentik-email,x-authentik-name,x-authentik-groups - if protected-frontends !is_authentikoutpost

    http-request redirect code 302 location /outpost.goauthentik.io/start?rd=%[hdr(X-Original-URL)] if protected-frontends !{ var(txn.auth_response_successful) -m bool } { var(txn.auth_response_code) -m int 401 } !is_authentikoutpost
    http-request deny if protected-frontends !{ var(txn.auth_response_successful) -m bool } { var(txn.auth_response_code) -m int 403 } !is_authentikoutpost
    http-request redirect location %[var(txn.auth_response_location)] if protected-frontends !{ var(txn.auth_response_successful) -m bool } !is_authentikoutpost

    # Select backend based on services.map file or use backend no-match if not found.
    use_backend be_auth_request if protected-frontends is_authentikoutpost
    use_backend %[base,lower,map_beg(/etc/haproxy/services.map,no-match)]
    use_backend %[req.hdr(host),lower,map(/etc/haproxy/services.map,no-match)]

backend internal
    mode tcp
    server loopback-for-tls abns@internal send-proxy-v2

backend be_auth_request
    server proxy home:9000 check

listen be_auth_request_proxy
    bind :9000
    server be_auth_request home:9000 check

listen ldap_proxy
    bind :389
    server proxy home:389 check

backend ldap
    server be_auth_request home:389 check

# Normal Backends
backend no-match
    http-request deny deny_status 403

backend homedash
    server homedash home:81 check

backend hassio
    server hassio home:8123 check

backend downloads
    server downloads home:8200 check
backend prowlarr
    server prowlarr home:9696 check
backend radarr
    server radarr home:7878 check
backend sonarr
    server sonarr home:8989 check
backend arrs
    server arrs home:5055 check

# Backend for google to allow DNS resolution if using reCAPTCHA
backend captcha_verifier
    server captcha_verifier www.google.com:443 check

# Backend for crowdsec to allow DNS resolution
backend crowdsec
    server crowdsec *:8080 check

And services.map:

home.MYDOMAIN.com homedash
#
auth.home.MYDOMAIN.com be_auth_request
home.home.MYDOMAIN.com hassio
#
arrs.media.home.MYDOMAIN.com arrs
#
downloads.media.home.MYDOMAIN.com downloads
arrs.media.home.MYDOMAIN.com/prowlarr prowlarr
arrs.media.home.MYDOMAIN.com/radarr radarr
arrs.media.home.MYDOMAIN.com/sonarr sonarr

Besides that i’m also trying to get haproxy to pass HTTP Basic credentials stored in Authentik to sonar/radarr as explained here: Sonarr | authentik Although I imagine that getting the hassio auth working will create a lightbulb moment that will help me figure it out, but may as well mention it here anyway.

Feel free to correct anything that’s just blatantly wrong, as I said, new to the world of haproxy.

Thanks people!