Authentik with Traefik and Uptime-kuma?

Describe your question/

I would like Uptime-Kuma to be authenticated using authentik.
When try to navigate to https://uptime-kuma.domain.org/ I am not getting redirected to authentik login page.

Relevant info

With the bad config I have done concerning this app, I still have external access to uptime-kuma without any authentication. I should be able to logiin with authentik.

Screenshots

Traefik dynamic file config:

authentik:
      forwardAuth:
        address: "http://authentik-server:9000/outpost.goauthentik.io/auth/traefik"
        trustForwardHeader: true
        authResponseHeaders:
          - X-authentik-username
          - X-authentik-groups
          - X-authentik-email
          - X-authentik-name
          - X-authentik-uid
          - X-authentik-jwt
          - X-authentik-meta-jwks
          - X-authentik-meta-outpost
          - X-authentik-meta-provider
          - X-authentik-meta-app
          - X-authentik-meta-version
routers:
    uptime-kuma:
      rule: "host(`uptime-kuma.domain.org`)"
      middlewares:
        - https-redirectscheme
        - authentik
      priority: 10
      service: uptime-kuma
    authentik:
      rule: "Host(`authentik.domain.org`) && PathPrefix(`/outpost.goauthentik.io/`)"
      priority: 10
      service: authentik
# service web
    uptime-kuma:
      loadBalancer:
        servers:
          - url: "http://192.168.XXX.XXX"
    authentik:
      loadBalancer:
        servers:
          - url: "http://authentik-server:9000/outpost.goauthentik.io"

Authentik config (Provider auth transfer apps))

- application:  
                  - name: Traefik Forward Auth Kuma
                  - slug: traefik-forward-auth-kuma
                  - provider: Traefik Forward Auth Provider Kuma
                  - Any

- Provider for uptime-kuma
                   - authorisation flux: default-provider-authorization-implicit ....
                   - forward auth single app
                   - external host: uptime-kuma.domain.org
                   - flux advanced parameters: default-authentication-flow

Authentification parameters:
                    - intercept the authentication header
                    - OIDC: Traefik forward ...
  
advanced flux parameters:

                     - auth flux: default-authentication-flow

Traefik labels for the Kuma docker compose files:

labels:
      - "traefik.enable=true"
      - "traefik.http.routers.kuma.entrypoints=http-external"
      - "traefik.http.routers.kuma.rule=Host(`uptime-kuma.domains.org`)"
      - "traefik.http.middlewares.kuma-https-redirect.redirectscheme.scheme=https"
      - "traefik.http.routers.kuma.middlewares=kuma-https-redirect"
      - "traefik.http.routers.kuma-secure.entrypoints=https-external"
      - "traefik.http.routers.kuma-secure.rule=Host(`uptime-kuma.domains.org`)"
      - "traefik.http.routers.kuma-secure.tls=true"
      - "traefik.http.routers.kuma-secure.service=kuma"
      - "traefik.http.routers.kuma.middlewares=authentik@file"
      - "traefik.http.services.kuma.loadbalancer.server.port=3001"

I have made some change but still have the same pb ... I have access to Kuma without any auth. I have done the test from my phone outside of my home network.
Please help.
Thx

  • authentik version:2025.2.0
  • Traefik version 3.3
  • Deployment: docker-compose,

Thx

You want to use Traefik dynamic config file or Docker labels? Why "uptime-kuma.domain.org" twice?

Provide the full YAML hierarchy, so we know where the provided snippets belong.

I would like to use the dynamic config.

http:
  middlewares:
    default-whitelist:
      ipWhiteList:
        sourceRange:
          - 173.245.48.0/20
          - 103.21.244.0/22
          - 103.22.200.0/22
          - 103.31.4.0/22
          - 141.101.64.0/18
          - 108.162.192.0/18
          - 190.93.240.0/20
          - 188.114.96.0/20
          - 197.234.240.0/22
          - 198.41.128.0/17
          - 162.158.0.0/15
          - 104.16.0.0/13
          - 104.24.0.0/14
          - 172.64.0.0/13
          - 131.0.72.0/22
          - 2400:cb00::/32
          - 2606:4700::/32
          - 2803:f800::/32
          - 2405:b500::/32
          - 2405:8100::/32
          - 2a06:98c0::/29
          - 2c0f:f248::/32
    https-redirectscheme:
      redirectScheme:
        scheme: https
        permanent: true
    secured:
      chain:
        middlewares:
          - default-whitelist
    crowdsec-bouncer:
      forwardauth:
        address: http://bouncer-traefik:8080/api/v1/forwardAuth
        trustForwardHeader: true  
    # https://github.com/goauthentik/authentik/issues/2366
    authentik:
      forwardAuth:
        address: "http://authentik-server:9000/outpost.goauthentik.io/auth/traefik"
        trustForwardHeader: true
        authResponseHeaders:
          - X-authentik-username
          - X-authentik-groups
          - X-authentik-email
          - X-authentik-name
          - X-authentik-uid
          - X-authentik-jwt
          - X-authentik-meta-jwks
          - X-authentik-meta-outpost
          - X-authentik-meta-provider
          - X-authentik-meta-app
          - X-authentik-meta-version
    my-traefik-get-real-ip:
            plugin:
                traefik-get-real-ip:
                    Proxy:
                        - proxyHeadername: X-From-Cdn
                          proxyHeadervalue: cdn1
                          realIP: X-Forwarded-For
                        - proxyHeadername: X-From-Cdn
                          proxyHeadervalue: cdn2
                          realIP: Client-Ip
                        - overwriteXFF: "true"
                          proxyHeadername: X-From-Cdn
                          proxyHeadervalue: cdn3
                          realIP: Cf-Connecting-Ip
                        - proxyHeadername: '*'
                          realIP: RemoteAddr 
                                                               
 #region routers 
  routers:
    authentik:
      rule: "Host(`authentik.domain.org`) && PathPrefix(`/outpost.goauthentik.io/`)"
      priority: 10
      service: authentik
    uptime-kuma:
      rule: "Host(`uptime-kuma.domain.org`)"
      middlewares:
        - https-redirectscheme
        - authentik
      priority: 10
      service: uptime-kuma
       
#region services
  services:
# service Proxmox
# service web
    uptime-kuma:
      loadBalancer:
        servers:
          - url: "http://192.168.XXX.XXX"
    authentik:
      loadBalancer:
        servers:
          - url: "http://authentik-server:9000/outpost.goauthentik.io"
    
    
    
    
    
        
          

as requested thx again for your support.

I still don’t understand why you have a router for it in dynamic config file and in the Docker labels. What’s the intention?

I am a bit confused and I have to go back to the docs. It seems that I haven't understood the difference between the dockers labels and the dynamics files .... I have removed the uptime-kuma input from the dynamic file. Back to the docs :frowning:

Still not redirect to the authentik login page ....

New dynamic config file:

http:
  middlewares:
    default-whitelist:
      ipWhiteList:
        sourceRange:
          - 173.245.48.0/20
          - 103.21.244.0/22
          - 103.22.200.0/22
          - 103.31.4.0/22
          - 141.101.64.0/18
          - 108.162.192.0/18
          - 190.93.240.0/20
          - 188.114.96.0/20
          - 197.234.240.0/22
          - 198.41.128.0/17
          - 162.158.0.0/15
          - 104.16.0.0/13
          - 104.24.0.0/14
          - 172.64.0.0/13
          - 131.0.72.0/22
          - 2400:cb00::/32
          - 2606:4700::/32
          - 2803:f800::/32
          - 2405:b500::/32
          - 2405:8100::/32
          - 2a06:98c0::/29
          - 2c0f:f248::/32
    https-redirectscheme:
      redirectScheme:
        scheme: https
        permanent: true
    secured:
      chain:
        middlewares:
          - default-whitelist
    crowdsec-bouncer:
      forwardauth:
        address: http://bouncer-traefik:8080/api/v1/forwardAuth
        trustForwardHeader: true  
    # https://github.com/goauthentik/authentik/issues/2366
    authentik:
      forwardAuth:
        address: "http://authentik-server:9000/outpost.goauthentik.io/auth/traefik"
        trustForwardHeader: true
        authResponseHeaders:
          - X-authentik-username
          - X-authentik-groups
          - X-authentik-email
          - X-authentik-name
          - X-authentik-uid
          - X-authentik-jwt
          - X-authentik-meta-jwks
          - X-authentik-meta-outpost
          - X-authentik-meta-provider
          - X-authentik-meta-app
          - X-authentik-meta-version
    my-traefik-get-real-ip:
            plugin:
                traefik-get-real-ip:
                    Proxy:
                        - proxyHeadername: X-From-Cdn
                          proxyHeadervalue: cdn1
                          realIP: X-Forwarded-For
                        - proxyHeadername: X-From-Cdn
                          proxyHeadervalue: cdn2
                          realIP: Client-Ip
                        - overwriteXFF: "true"
                          proxyHeadername: X-From-Cdn
                          proxyHeadervalue: cdn3
                          realIP: Cf-Connecting-Ip
                        - proxyHeadername: '*'
                          realIP: RemoteAddr 
                                                               
 #region routers 
  routers:
    authentik:
      entryPoints:
        - "https-external"
      rule: "Host(`authentik.domain.org`) && PathPrefix(`/outpost.goauthentik.io/`)"
      priority: 10
      service: authentik
       
#region services
  services:
# service Proxmox
# service web
    authentik:
      loadBalancer:
        servers:
          - url: "http://authentik-server:9000/outpost.goauthentik.io"    
                

authentik-server is the name of the container

The dynamic config is loaded via providers. It contains Traefik routers, middlewares, services, etc.

When using providers.docker and labels, the Traefik target service is automatically set to the Docker service/container itself.

Thx a lot for these information, I really have to go deeper in the docs ...
Have you find any way of helping me to resolv my initial pb ?

Sorry, have not used Traefik ForwardAuth yet.

Ok no problem .... Any tips for the traefik dashboard ? I do have access to it through his ip numer+port, but not with his FQDN ....

services:
  traefik:
    image: traefik:v3.3.4
    container_name: traefik
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true

    read_only: true
    mem_limit: 2G
    cpus: 0.75
    depends_on:
      - dockerproxy
    networks:
      - mynet
      - socket-t
    #command:
      #- '--host=tcp://t-docker-socket-proxy:2375'

    ports:
      - target: 80
        published: 1180
        protocol: tcp
        mode: host
      - target: 443
        published: 11443
        protocol: tcp
        mode: host
      - target: 8080
        published: 8087
        protocol: tcp
        mode: host
      - target: 1181
        published: 1181
        protocol: tcp
        mode: host
      - target: 11444
        published: 11444
        protocol: tcp
        mode: host
    environment:
      - CF_API_EMAIL=${CF_API_EMAIL}
      - TZ=${TZ}
      - TRAEFIK_DASHBOARD_CREDENTIALS=${TRAEFIK_DASHBOARD_CREDENTIALS}
      - CLOUDFLARE_DNS_API_TOKEN=${CLOUDFLARE_DNS_API_TOKEN}

    volumes:
      - /etc/localtime:/etc/localtime:ro
      - $BASE/traefik/data/traefik.yml:/traefik.yml:ro
      - $BASE/letsencrypt:/letsencrypt
      - $BASE/traefik/data/dynamic_conf.yml:/dynamic_conf.yml:ro
      - /var/log/crowdsec/:/var/log/crowdsec

    labels:

      - "traefik.enable=true"
      - "traefik.http.routers.dashboard.rule=Host(`traefik.mynet.org`) && PathPrefix(`/api`) || PathPrefix(`/dashboard`)"
      - "traefik.http.routers.dashboard.service=api@internal"
      - "traefik.http.routers.dashboard.middlewares=auth"
      - "traefik.http.middlewares.auth.basicauth.users=${user}:${passwd}"
      - "traefik.http.routers.traefik-secure.entrypoints=https-external"
      - "traefik.http.routers.traefik.middlewares=traefik-https-redirect"
      - "traefik.http.routers.traefik-secure.entrypoints=https"
      - "traefik.http.routers.traefik-secure.tls=true"
      - "traefik.http.routers.traefik-secure.tls.certresolver=dns-cloudflare"
      - "traefik.http.routers.traefik-secure.tls.domains[0].main=mynet.org"
      - "traefik.http.routers.traefik-secure.tls.domains[0].sans=*.mynet.org"
      - "traefik.http.services.traefik.loadbalancer.server.port=8087"


      # middlewares

      - "traefik.http.middlewares.traefik-https-redirect.redirectscheme.scheme=https"
      # middlewares security headers
      - "traefik.http.middlewares.hsts.headers.customResponseHeaders.Strict-Transport-Security=max-age=31536000; includeSubDomains; preload"
      - "traefik.http.middlewares.security-headers.headers.accesscontrolallowmethods=GET, OPTIONS, PUT"
      - "traefik.http.middlewares.security-headers.headers.accesscontrolmaxage=100"
      - "traefik.http.middlewares.security-headers.headers.addvaryheader=true"
      - "traefik.http.routers.traefik.middlewares=hsts"
      - "traefik.http.middlewares.security-headers.headers.hostsproxyheaders=X-Forwarded-Host"
      - "traefik.http.middlewares.security-headers.headers.sslredirect=true"
      - "traefik.http.middlewares.security-headers.headers.sslproxyheaders.X-Forwarded-Proto=https"
      - "traefik.http.middlewares.security-headers.headers.stsseconds=63072000"
      - "traefik.http.middlewares.security-headers.headers.stsincludesubdomains=true"
      - "traefik.http.middlewares.security-headers.headers.stspreload=true"
      - "traefik.http.middlewares.security-headers.headers.forcestsheader=true"
      - "traefik.http.middlewares.security-headers.headers.framedeny=true"
      - "traefik.http.middlewares.x-frame-options.headers.customResponseHeaders.X-Frame-Options=SAMEORIGIN"
      - "traefik.http.routers.traefik.middlewares=csp-headers"
      - "traefik.http.middlewares.csp-headers.headers.customResponseHeaders.Content-Security-Policy=frame-ancestors 'self' https://www.mynet.org"
      - "traefik.http.middlewares.security-headers.headers.contenttypenosniff=true"
      - "traefik.http.middlewares.security-headers.headers.browserxssfilter=true"
      - "traefik.http.middlewares.security-headers.headers.referrerpolicy=same-origin"
      - "traefik.http.middlewares.security-headers.headers.featurepolicy=camera 'none'; geolocation 'none'; microphone 'none'; payment 'none'; usb 'none'; vr 'none';"
      - "traefik.http.middlewares.security-headers.headers.customresponseheaders.X-Robots-Tag=none,noarchive,nosnippet,notranslate,noimageindex"
  dockerproxy:
    image: wollomatic/socket-proxy:1.5.3
    container_name: t-docker-socket-proxy
    command:
      - '-loglevel=info'
      - '-allowfrom=0.0.0.0/0'
      - '-listenip=0.0.0.0'
      - '-allowGET=/v1\..{1,2}/(version|containers/.*|events.*)'

      - '-watchdoginterval=3600'
      - '-stoponwatchdog'
      - '-shutdowngracetime=10'
    restart: unless-stopped
    read_only: true
    mem_limit: 64M
    cap_drop:
      - ALL
    security_opt:
      - no-new-privileges
    user: 65534:110 # change gid from 998 to the gid of the docker group on your host
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    networks:
      - socket-t


networks:
  mynet:
    name: mynet
    external: true
  socket-t:
    driver: bridge
    internal: true
    attachable: false
      

I have trying many combinaition helped by the traefik docs without success, I do have an error 404 page note found.

Share your Traefik static config.

Compare to simple Traefik example.

global:
  checkNewVersion: true
  sendAnonymousUsage: false
api: 
  #basePath: /traefik
  dashboard: true
  insecure: true
  #debug: false
entryPoints:
  http:
    address: ":80"
    forwardedHeaders:
      trustedIPs: 
        # Start of Clouflare public IP list for HTTP requests, remove this if you don't use it
        - 173.245.48.0/20
        - 103.21.244.0/22
        - 103.22.200.0/22
        - 103.31.4.0/22
        - 141.101.64.0/18
        - 108.162.192.0/18
        - 190.93.240.0/20
        - 188.114.96.0/20
        - 197.234.240.0/22
        - 198.41.128.0/17
        - 162.158.0.0/15
        - 104.16.0.0/13
        - 104.24.0.0/14
        - 172.64.0.0/13
        - 131.0.72.0/22
        - 2400:cb00::/32
        - 2606:4700::/32
        - 2803:f800::/32
        - 2405:b500::/32
        - 2405:8100::/32
        - 2a06:98c0::/29
        - 2c0f:f248::/32
        # End of Cloudlare public IP list
    http:
      middlewares:
        - crowdsec-bouncer@file
      redirections:
        entryPoint:
          to: https
          scheme: https
  https:
    address: ":443"
    forwardedHeaders:
      trustedIPs: 
        # Start of Clouflare public IP list for HTTP requests, remove this if you don't use it
        - 173.245.48.0/20
        - 103.21.244.0/22
        - 103.22.200.0/22
        - 103.31.4.0/22
        - 141.101.64.0/18
        - 108.162.192.0/18
        - 190.93.240.0/20
        - 188.114.96.0/20
        - 197.234.240.0/22
        - 198.41.128.0/17
        - 162.158.0.0/15
        - 104.16.0.0/13
        - 104.24.0.0/14
        - 172.64.0.0/13
        - 131.0.72.0/22
        - 2400:cb00::/32
        - 2606:4700::/32
        - 2803:f800::/32
        - 2405:b500::/32
        - 2405:8100::/32
        - 2a06:98c0::/29
        - 2c0f:f248::/32
        # End of Cloudlare public IP list
    http:
      middlewares: 
        - crowdsec-bouncer@file
  http-external:  # changement
    address: ":1181"
    http:
      middlewares:
        - crowdsec-bouncer@file
      redirections:
        entrypoint:
          to: https-external
          scheme: https
  https-external:
    address: ":11444"
    http:
      middlewares:
        - crowdsec-bouncer@file
serversTransport:
  insecureSkipVerify: true
providers:
  docker:
    network: mynet
    endpoint: "tcp://t-docker-socket-proxy:2375"
    exposedByDefault: false
  file:
    filename: /dynamic_conf.yml
    watch: true
certificatesResolvers:
  dns-cloudflare:
    acme:
      email: my-email
      storage: ./letsencrypt/acme.json
      dnsChallenge:
        provider: cloudflare
      caServer: https://acme-v02.api.letsencrypt.org/directory
        #disablePropagationCheck: true # uncomment this if you have issues pulling certificates through cloudflare, By setting this flag to true disables the need to wait for the propagation of the TXT record to all authoritative name servers.
experimental:
  plugins:
    traefik-get-real-ip:
      moduleName: "github.com/Paxxs/traefik-get-real-ip"
      version: "v1.0.3"
    crowdsec-bouncer-traefik-plugin:
      moduleName: "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin"
      version: "v1.2.1"
log:
  level: "INFO"
  filePath: "/var/log/crowdsec/traefik.log"
accessLog:
  filePath: "/var/log/crowdsec/access.log"
bufferingSize: 50


I have checked your docs this midday too ... Thx for sharing.

It seems you try to use a lot of security, like Cloudflare, Docker socket proxy and crowdsec.

On the other side you use api.insecure.true, which creates an entrypoint on port 8080 without auth.

Why not start with a working best practice example and add piece by piece. My linked example includes /dashboard/ on regular entrypoint with auth.

Yes and this is right, please keep in mind that I have started to use Traefik more than a year ago, and this config file is completed with new input bit by bit, it is becoming big and complex.
I had the opposite approach, first make the dashboard working from outside insecurely and when done, go for the secure config .. Thx for your help, I will follow your advice.

The secure api is done, but I still do have a pb with the login/passwd using digestauth.

I have add those labels:

      - "traefik.http.routers.dashboard.rule=Host(`traefik.domain.org`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
      - "traefik.http.routers.dashboard.service=api@internal"
      - "traefik.http.routers.dashboard.tls=true"
      - "traefik.http.routers.dashboard.entrypoints=https-external"
      - "traefik.http.routers.dashboard.middlewares=auth"
      - "traefik.http.middlewares.auth.digestauth.users=user:realm:xxxxxxxxx"
      - "traefik.http.routers.dashboard.tls.certresolver=dns-cloudflare"

The 404 error disappear, I am able to use the FQDN instead of the IP number, I have the popup of the login/passwd but it refuse to log in ... I have encoded the login/passwd in hard ... Same result.

Working if using basicauth.

You are using an encoded password (doc)?

if you are asking if I have used htdigest to generate the passwd, the answer is yes.

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.