Coder Social home page Coder Social logo

Support for Traefik about oauth2-proxy HOT 57 CLOSED

oauth2-proxy avatar oauth2-proxy commented on June 20, 2024 29
Support for Traefik

from oauth2-proxy.

Comments (57)

JoelSpeed avatar JoelSpeed commented on June 20, 2024 13

I had a quick check through the docs and it looks like you might be able to use Forward Authentication

You could check against /oauth2/auth the same way the Nginx auth_request module does, but Traefik doesn't have a redirection option if that request fails. There are two options here, see if Traefik can capture the 401 and serve a different error page (the /oauth2/sign_in page?) or we try and make the /oauth2/auth endpoint traefik compatible too

from oauth2-proxy.

czunker avatar czunker commented on June 20, 2024 13

The above PR lacks tests and docs. I will have a look at that the coming days.

But for functionality, it works nice with our setup with traefik. It reduces the number of middlewares down to one:

apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: traefik-oauth2-proxy-verify
  namespace: traefik-ingress
spec:
  forwardAuth:
    address: http://oauth2-proxy:4180/oauth2/auth_or_start
    trustForwardHeader: true

It also skips the provider button.
This is the same behavior, as thomseddon/traefik-forward-auth shows.

@maxlaverse
I adopted your suggested change to the current code base and marked it accordingly. Hope that's ok.

from oauth2-proxy.

Beanow avatar Beanow commented on June 20, 2024 9

I've also been using https://github.com/thomseddon/traefik-forward-auth/ and testing a switch to oauth2-proxy using the info here and in the blogpost. Definitely can agree traefik-forward-auth is much easier to use.

Let me try and summarize some of the issues I ran into.
The later two are quality-of-life things, but the first two are reasons I wouldn't use oauth2-proxy with traefik.

/oauth2/auth + 401 handler

Pointing the forward auth middleware to /oauth2/auth and handling any 401 results with /oauth2/sign_in means we can't automatically redirect using --skip-provider-button=true. This is because the 401 status will be kept, and the browser won't follow a location header for 401.

Workaround: --upstream=static://202 + / forward auth

Rather than using /oauth2/auth, if we use --upstream=static://202 requesting / will attempt to proxy, and behaves similar to /oauth2/auth except we can decide to redirect or show a login page with 401. As a bonus it checks for ajax too.

Original URI

Neither the 401 handler, nor the / proxy request sets X-Auth-Request-Redirect or ?rd=.
Instead Traefik will give us X-Forwarded-* headers.
https://github.com/containous/traefik/blob/29bd6faa18780623622e1688e86e00c0e4ba99f9/pkg/middlewares/auth/forward.go#L161

Options

  • Changing the headers in Traefik. Not yet supported. traefik/traefik#5036
  • Supporting Traefiks headers in oauth2-proxy.
    Having X-Forwarded-Method, -Proto, -Host and -Uri we can reconstruct whatever we need.

Blanket PathPrefix('/oauth2') rule

In this issue / blog, oauth2-proxy has a frontend rule of PathPrefix('/oauth2'). This means any request to /oauth2/* will be sent to oauth2-proxy. Regardless of whether there's any resources on that host we're trying to protect with the middleware. We need this usually for handling the callback or logout.

thomseddon/traefik-forward-auth handles this using the authorization request instead. As X-Forwarded-Uri includes the path and query, we can detect callback codes and redirect. Allowing to be as selective in intercepting requests as the scope of the middleware.

Another benefit with this approach is that we can change the prefix from /oauth2 to anything else without having to duplicate this change in the frontend rule.

Missing "auth host mode"

This mode is very convenient for protecting many (sub)domains. But haven't found a way to do this with oauth2-proxy.
Loosely related to the previous point, as auth host mode wouldn't require a blanket /oauth2 handler.

What the examples implement is "overlay mode".
If you're protecting https://service.example.com/ the callback goes to https://service.example.com/oauth2/callback.
For https://service2.example.com/ the callback goes to https://service2.example.com/oauth2/callback.

Rather it would be swell to set a URL to send callbacks to, and redirect to the original domain we're protecting.
E.g. https://service.example.com/ goes to https://auth.example.com/oauth2/callback.
https://service2.example.com/ goes to https://auth.example.com/oauth2/callback.

Reason you want to do this is because most providers will require a redirect url whitelist. Having a single auth.example.com location to handle these means you don't need to update the list for every new host.

from oauth2-proxy.

SuperSandro2000 avatar SuperSandro2000 commented on June 20, 2024 8

bump

from oauth2-proxy.

alexandrst88 avatar alexandrst88 commented on June 20, 2024 7

ok, finally, we made it work.

  1. I've checkout the code that @maxlaverse provided
  2. Ouath2 Config(I'm using helm chart.)
extraArgs:
  provider: oidc
  redirect-url: https://oauth2-proxy.example.org/oauth2/callback
  oidc-issuer-url: https://dex.example.org/
  cookie-secure: false
  email-domain: "*"
  cookie-domain: .example.org
  pass-access-token: true
  pass-authorization-header: true
  skip-provider-button: false
  whitelist-domain: .example.org
  #http-address: 0.0.0.0:4180
  set-authorization-header: true
  set-xauthrequest: true
  skip-auth-preflight: false
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    external-dns.alpha.kubernetes.io/target: some-ingress.example.org
    kubernetes.io/ingress.class: traefik
  labels:
    app: oauth2-proxy
    chart: oauth2-proxy-0.12.3
    heritage: Tiller
    release: oauth2-proxy
  name: oauth2-proxy
  namespace: kube-system
spec:
  rules:
  - host: oauth2-proxy.example.org
    http:
      paths:
      - backend:
          serviceName: oauth2-proxy
          servicePort: 80
        path: /
  1. Kubernetes dashboard
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    external-dns.alpha.kubernetes.io/target: some-ingress.example.org
    igress.kubernetes.io/auth-trust-headers: "true"
    ingress.kubernetes.io/auth-remove-header: "false"
    ingress.kubernetes.io/auth-response-headers: Authorization
    ingress.kubernetes.io/auth-trust-headers: "true"
    ingress.kubernetes.io/auth-type: forward
    ingress.kubernetes.io/auth-url: https://oauth2-proxy.example.org/oauth2/auth_or_start?rd=https://kubernetes-secure-dashboard.example.org
    kubernetes.io/ingress.class: traefik
  labels:
    app: kubernetes-dashboard-secure
  name: kubernetes-dashboard-secure
  namespace: kube-system
spec:
  rules:
  - host: kubernetes-secure-dashboard.example.org
    http:
      paths:
      - backend:
          serviceName: kubernetes-dashboard
          servicePort: 443
        path: /
status:
  loadBalancer: {}

@JoelSpeed i pretty sure, it PR of @maxlaverse could be merge, if you like his approach. @maxlaverse thank you with workaround!

P.S I can provide documentation about setup with traefik.

from oauth2-proxy.

maxlaverse avatar maxlaverse commented on June 20, 2024 6

I had not because I quickly stumbled upon issues trying to build the oauth2_proxy locally and I knew it would be really fast to write my own small application rather than learning about this code base and the configuration options.

I had a look after you wrote that comment and implemented a change that seems to work fine with Traefik:
https://github.com/pusher/oauth2_proxy/compare/master...maxlaverse:support_traefik?expand=1

As you said initially, we need an endpoint pretty similar to the existing one (or the same, modified). It should answer to those auth requests with a redirection to the authentication portal if the user is not authenticated. It could be an option.

There is one small detail which is that Traefik expects a 200 if the session is valid, and not a 202.

from oauth2-proxy.

linuxgemini avatar linuxgemini commented on June 20, 2024 6

I have made PR #957 to handle redirects better in general. This also makes Traefik supported.

from oauth2-proxy.

czunker avatar czunker commented on June 20, 2024 5

Hi there,

I managed it to get oauth2-proxy v6.1.0 working with traefik 2.2.8 and keycloak as OIDC provider. oauth2-proxy and traefik are running on kubernetes.

I'll try to explain which config worked for me.

These are the config options for oath2_proxy:

Args:
      --http-address=0.0.0.0:4180
      --cookie-domain=.example.com
      --insecure-oidc-allow-unverified-email=true
      --oidc-issuer-url=https://login.example.org/auth/realms/company
      --pass-access-token=true
      --pass-authorization-header=true
      --provider=oidc
      --redirect-url=https://oauth.k8s-playground.example.com/oauth2/callback
      --reverse-proxy=true
      --set-authorization-header=true
      --set-xauthrequest=true
      --silence-ping-logging=true
      --skip-auth-preflight
      --skip-provider-button=true
      --whitelist-domain=.k8s-playground.example.com
      --config=/etc/oauth2_proxy/oauth2_proxy.cfg

I used three traefik middlewares to implement the integration from traefik to oauth2_proxy.
One for sign in:

apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: traefik-oauth2-proxy-signin
  namespace: traefik-ingress
spec:
  errors:
    query: /oauth2/sign_in
    service:
      name: oauth2-proxy
      port: 4180
    status:
    - "401"

One for the verification:

apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: traefik-oauth2-proxy-verify
  namespace: traefik-ingress
spec:
  forwardAuth:
    address: http://oauth2-proxy:4180/oauth2/auth
    trustForwardHeader: true

Until here, the config is mostly taken from this issue and the linked blog.

To let oauth2_proxy know where to redirect after the authentication I implemented an idea from this issue:

apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
  name: alertmanager-redirect-header-middleware
  namespace: traefik-ingress
spec:
  headers:
    customRequestHeaders:
      X-Auth-Request-Redirect: https://alertmanager.k8s-playground.example.com/
    customResponseHeaders:
      X-Auth-Request-Redirect: https://alertmanager.k8s-playground.example.com/

The Ingress object for alertmanager references these middlewares:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-staging
    kubernetes.io/ingress.class: traefik-ingress
    meta.helm.sh/release-name: prometheus-operator
    meta.helm.sh/release-namespace: monitoring
    traefik.ingress.kubernetes.io/router.middlewares: traefik-ingress-alertmanager-redirect-header-middleware@kubernetescrd,traefik-ingress-traefik-oauth2-proxy-signin@kubernetescrd,traefik-ingress-traefik-oauth2-proxy-verify@kubernetescrd
  labels:
    app: prometheus-operator-alertmanager
    app.kubernetes.io/managed-by: Helm
    chart: prometheus-operator-9.3.1
    heritage: Helm
    release: prometheus-operator
  name: prometheus-operator-alertmanager
  namespace: monitoring
spec:
  rules:
  - host: alertmanager.k8s-playground.example.com
    http:
      paths:
      - backend:
          serviceName: prometheus-operator-alertmanager
          servicePort: 9093
        path: /
        pathType: ImplementationSpecific
  tls:
  - hosts:
    - alertmanager.k8s-playground.example.com
    secretName: alertmanager-cert

But this setup has still some caveats:

  • Because of the missing dynamic redirect, the header middleware would have to be implemented for each Ingress which should be secured by oauth2_proxy. This could be fixed in traefik. Besides the issues mentioned by @Beanow , there are more which might support this use case: traefik/traefik#6839, traefik/traefik#6814
    The other option is to fix this in oauth2_proxy as mentioned by @Beanow . It should be possible to use the traefik headers in case there is no X-Auth-Request-Redirect header present.
  • The other two middlewares for verification and sign in could be integrated into one with the PR by @maxlaverse
  • I didn't manage it to directly redirect to the login page of our keycloak. As already mentioned by @Beanow

From what I understand, with these fixes it should be nearly as easy as thomseddon/traefik-forward-auth, which we are currently using.

from oauth2-proxy.

etho201 avatar etho201 commented on June 20, 2024 3

My traefik domain is domain.com while my auth domain was login.domain.com so it's possible that it only works if the oauth2_proxy domain is a subdomain of the one which is requesting the authorization.
If you wanted to authorize any {subdomain:[a-z0-9-]+}.corp.example.com you might need to host oauth2_proxy on login.{subdomain:[a-z0-9-]+}.corp.example.com. Your setup seems much more complex than what I tested though.
You might also try to set cookies for corp.example.com.

I heavily followed devster31's example and was finally able to get it working with a more complex setup which includes subdomains. The key changes I needed to make involved adding - "-whitelist-domain=.${FQDN}" and adding the Hostregexp to the Traefik frontend rule.

Using oauth2 has greatly simplified my workflow, where before I had to login separately to every micro-service, now I have SSO capabilities for several apps. I'm very happy with the results!

Here is what I did to get it working with subdomains:

  oauth2:
    container_name: oauth2
    image: quay.io/pusher/oauth2_proxy:latest-armv6
    command:
      - "-cookie-domain=${FQDN}"
      - "-cookie-secure=true"
      - "-email-domain=*"
      - "-github-org=${GITHUB_ORG}"
      - "-http-address=0.0.0.0:4180"
      - "-pass-access-token"
      - "-provider=github"
      - "-redirect-url=https://${FQDN}/oauth2/callback"
      - "-set-authorization-header"
      - "-set-xauthrequest"
      - "-whitelist-domain=.${FQDN}"
    environment:
      - "OAUTH2_PROXY_CLIENT_ID=${GITHUB_OAUTH_CLIENT_ID}"
      - "OAUTH2_PROXY_CLIENT_SECRET=${GITHUB_OAUTH_CLIENT_SECRET}"
      - "OAUTH2_PROXY_COOKIE_SECRET=${OAUTH2_PROXY_COOKIE_SECRET}"
    expose:
      - "4180"
    #ports:
      #- 4180:4180
    labels:
      - "traefik.enable=true"
      - "traefik.backend=oauth2"
      - "traefik.frontend.rule=HostRegexp:{subdomain:.+}.${FQDN},${FQDN}; PathPrefix:/oauth2"
      - "traefik.port=4180"
      - "traefik.docker.network=traefik_proxy"
      - "traefik.frontend.headers.SSLRedirect=true"
      - "traefik.frontend.headers.STSSeconds=315360000"
      - "traefik.frontend.headers.browserXSSFilter=true"
      - "traefik.frontend.headers.contentTypeNosniff=true"
      - "traefik.frontend.headers.forceSTSHeader=true"
      - "traefik.frontend.headers.SSLHost=example.com"
      - "traefik.frontend.headers.STSIncludeSubdomains=true"
      - "traefik.frontend.headers.STSPreload=true"
      - "traefik.frontend.headers.frameDeny=true"
    networks:
      - traefik_proxy
    restart: unless-stopped

Then for the services I want to protect, I just add this to each one:

services:
  <myservice>:
    labels:
    [...]
      # Require oauth2 for authentication
      - "traefik.frontend.auth.forward.address=https://${FQDN}/oauth2/auth"
      - "traefik.frontend.auth.forward.trustForwardHeader=true"
      - "traefik.frontend.auth.forward.authResponseHeaders=X-Auth-Request-User,X-Auth-Request-Email,Authorization,Set-Cookie"
      - "traefik.frontend.errors.401.backend=oauth2"
      - "traefik.frontend.errors.401.status=401"
      - "traefik.frontend.errors.401.query=/oauth2/sign_in"

The only thing that is slightly awkward is upon first successful authentication I get re-routed to the ${FQDN}, rather than the point of origin (regardless if this was a subdomain or subfolder). Does anyone have any suggestions on how to fix this? Or is that how it's supposed to work?

Example:

  • Say I go to https://${FQDN}/app1. I sign in using GitHub and then I get redirected to ${FQDN}. I would prefer to get redirected to https://${FQDN}/app1.
  • The same thing would happen if I were to go to https://app2.${FQDN}. I am asked to authenticate and then I get redirected to ${FQDN}, when I would prefer to get redirected to https://app2.${FQDN}.
  • If I authenticate one time, the cookie keeps my authentication for all services -- so now I can go directly to any of the apps, which is great! At least with this I can overlook the one erroneous redirect.

from oauth2-proxy.

markthebault avatar markthebault commented on June 20, 2024 3

is there any update on this topic, I am also trying to use oauth2 proxy instead of traefik-forward-auth without any success. I use the middleware of @czunker.

from oauth2-proxy.

HWiese1980 avatar HWiese1980 commented on June 20, 2024 3

It's been a couple years. Is there a comprehensive guide now about how to properly and correctly set this up?

from oauth2-proxy.

mazzy89 avatar mazzy89 commented on June 20, 2024 2

Yeah. Indeed I gave up. It is not possible with the current implementation running oauth2-proxy and Traefik on Kubernetes

from oauth2-proxy.

fnkr avatar fnkr commented on June 20, 2024 2

@etho201 Here is my config for Traefik v2.0: https://gist.github.com/fnkr/a58b0cc741ffe4fb074b146476db4399
It is working, but there is a bug (see README.md).

from oauth2-proxy.

SuperSandro2000 avatar SuperSandro2000 commented on June 20, 2024 2

/unstale

from oauth2-proxy.

guyspr avatar guyspr commented on June 20, 2024 1

@tchellomello I'm having the same issue. I think we want to use the https://oauth/oauth2/start?rd=ORIGINAL_DOMAIN url for the forwardAuth.address. But the problem is, how do we get the redirect (?rd=...) to insert the current URL.

If oauth2_proxy could automatically use the Forward header to determine the redirect from start, it should work just fine using a single auth endpoint for all your subdomains.

from oauth2-proxy.

JoelSpeed avatar JoelSpeed commented on June 20, 2024 1

@guyspr Would it be possible for traefik to set a X-Auth-Request-Redirect header? OAuth2 Proxy can use this in place of the rd parameter already

from oauth2-proxy.

genert avatar genert commented on June 20, 2024 1

@JoelSpeed That would be an excellent way with Traefik, unfortunately there is no way to do that with it at the moment.

Opened issue to track the discussion and plans with this - traefik/traefik#6463

from oauth2-proxy.

devster31 avatar devster31 commented on June 20, 2024

This should be possible. I'm using the following to test the authorization on traefik's dashboard page (which matches DOMAIN/traefik):

services:
  oauth2:
    command:
    - "-cookie-secret=${OAUTH2_PROXY_COOKIE_SECRET}"
    - "-cookie-secure=false"
    - "-email-domain=*"
    - "-github-org=dispenserinc" # doesn't seem to work, see requests below
    - "-provider=github"
    - "-redirect-url=http://login.${DOMAIN}/oauth2/callback"
    - "-set-xauthrequest"
    - "-set-authorization-header"
    - "-http-address=0.0.0.0:4180"
    environment:
      - "OAUTH2_PROXY_CLIENT_ID=${GITHUB_OAUTH_CLIENT_ID}"
      - "OAUTH2_PROXY_CLIENT_SECRET=${GITHUB_OAUTH_CLIENT_SECRET}"
    expose:
      - "4180"
    image: quay.io/pusher/oauth2_proxy:v3.1.0
    labels:
      - "traefik.frontend.rule=Host:login.${DOMAIN},${DOMAIN},PathPrefix=/oauth2"
      # this should be both login and normal domain and with the PathPrefix for the redirect
    restart: unless-stopped

  traefik2:
    command:
      - --accesslog
      - --api # defaults to port 8080
      - --docker
    image: traefik:maroilles-alpine
    labels:
      - "traefik.api.port=8080"
      - "traefik.api.frontend.rule=PathPrefixStrip:/traefik"
      - "traefik.api.frontend.auth.forward.address=http://login.${DOMAIN}/oauth2/auth"
      - "traefik.api.frontend.auth.forward.authResponseHeaders=Authorization"
      - "traefik.api.frontend.auth.forward.headerField=X-Auth-Request-User"
      - "traefik.api.frontend.errors.401.backend=oauth2-home"
      - "traefik.api.frontend.errors.401.status=401"
      - "traefik.api.frontend.errors.401.query=/oauth2/sign_in"
    ports:
      - "80:80"     # The HTTP port
      - "443:443"   # The HTTPS port
      - "8080:8080" # The Web UI (enabled by --api)
    restart: unless-stopped
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"

the request goes to the Sign In page, it authorizes with GitHub as expected, however the final callback returns an HTML with:

403 Permission Denied
http: named cookie not present

Sign In

Logs for requests

oauth2_1     | 2019/02/15 22:38:20 oauthproxy.go:188: OAuthProxy configured for GitHub Client ID: <<censored>>
oauth2_1     | 2019/02/15 22:38:20 oauthproxy.go:194: Cookie settings: name:_oauth2_proxy secure(https):false httponly:true expiry:168h0m0s domain: refresh:disabled
oauth2_1     | 2019/02/15 22:38:20 http.go:52: HTTP: listening on 0.0.0.0:4180
oauth2_1     | 2019/02/15 22:38:31 oauthproxy.go:796: 172.18.0.5:58850 ("10.0.0.1") Cookie "_oauth2_proxy" not present
oauth2_1     | 10.0.0.1 - - [15/Feb/2019:22:38:31 +0000] DOMAIN GET - "/traefik" HTTP/1.1 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.20 Safari/537.36" 403 2478 0.002
oauth2_1     | 10.0.0.1 - - [15/Feb/2019:22:38:33 +0000] DOMAIN GET - "/oauth2/start?rd=%2Ftraefik" HTTP/1.1 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.20 Safari/537.36" 302 300 0.000
oauth2_1     | 2019/02/15 22:38:34 github.go:125: Missing Organization:"dispenserinc" in []
oauth2_1     | 2019/02/15 22:38:34 github.go:294: got 200 from "https://api.github.com/user" <<censored JSON response>>>
oauth2_1     | 2019/02/15 22:38:34 oauthproxy.go:498: ErrorPage 403 Permission Denied http: named cookie not present
oauth2_1     | 10.0.0.1 - - [15/Feb/2019:22:38:33 +0000] login.DOMAIN GET - "/oauth2/callback?code=<<code>>&state=<<state>>%3A%2Ftraefik" HTTP/1.1 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.20 Safari/537.36" 403 353 1.151
oauth2_1     | 2019/02/15 22:38:35 oauthproxy.go:796: 172.18.0.5:58850 ("10.0.0.1") Cookie "_oauth2_proxy" not present
oauth2_1     | 10.0.0.1 - - [15/Feb/2019:22:38:35 +0000] login.DOMAIN GET - "/favicon.ico" HTTP/1.1 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.20 Safari/537.36" 403 2482 0.000

from oauth2-proxy.

JoelSpeed avatar JoelSpeed commented on June 20, 2024

@devster31 This would be good to have in the documentation if you have time to create a PR

from oauth2-proxy.

devster31 avatar devster31 commented on June 20, 2024

Well it's not working yet, not sure it's relevant to include. It currently seems to catch every path for a specific Host rule and oauth2_proxy isn't setting the cookie necessary for auth.
@JoelSpeed any suggestions on how to debug the missing cookie?

from oauth2-proxy.

devster31 avatar devster31 commented on June 20, 2024

I'm still facing an http: named cookie not present unfortunately.
I also noticed there seems to be no way to debug internal requests and headers unfortunately (no --verbose or --debug options).
I can't do much more, I'm leaving the last config I have for posterity:

  oauth2:
    command:
    # - -client-id     # environment
    # - -client-secret # environment
    # - -cookie-secret # environment
    - "-cookie-secure=true"
    - "-email-domain=*"
    - "-github-org=<org>"
    - "-http-address=0.0.0.0:4180"
    - "-provider=github"
    - "-redirect-url=https://login.${DOMAIN}/oauth2/callback"
    - "-set-authorization-header"
    - "-set-xauthrequest"
    environment:
    - "OAUTH2_PROXY_CLIENT_ID=${GITHUB_OAUTH_CLIENT_ID}"
    - "OAUTH2_PROXY_CLIENT_SECRET=${GITHUB_OAUTH_CLIENT_SECRET}"
    - "OAUTH2_PROXY_COOKIE_SECRET=${OAUTH2_PROXY_COOKIE_SECRET}"
    expose:
    - "4180"
    image: quay.io/pusher/oauth2_proxy:v3.1.0
    labels:
    - "traefik.backend=oauth2"
    - "traefik.frontend.rule=Host:login.${DOMAIN},${DOMAIN};PathPrefix:/oauth2"
    networks:
    - backend
    restart: unless-stopped

  myservice:
    ...
    labels:
    - "traefik.frontend.auth.forward.address=https://login.${DOMAIN}/oauth2/auth"
    - "traefik.frontend.auth.forward.trustForwardHeader=true"
    - "traefik.frontend.auth.forward.authResponseHeaders=X-Auth-Request-User,X-Auth-Request-Email,Authorization"
    - "traefik.frontend.errors.401.backend=oauth2"
    - "traefik.frontend.errors.401.status=401"
    - "traefik.frontend.errors.401.query=/oauth2/sign_in"
    ...

from oauth2-proxy.

JoelSpeed avatar JoelSpeed commented on June 20, 2024

I can't see any mention there of forwarding of the Set-Cookie header, do you know if Traefik does this internally as Nginx does?

You may also want to try explicitly setting the cookie-domain to the domain (or a parent domain) of the website you are trying to protect here

from oauth2-proxy.

devster31 avatar devster31 commented on June 20, 2024

Regarding the Set-Cookie I don't know if Traefik does it. I tried including it in authResponseHeaders but it didn't seem to work.
I'll do another round with cookie-domain and see if it changes anything.

from oauth2-proxy.

devster31 avatar devster31 commented on June 20, 2024

-cookie-domain seems to fix it
To recap, here the options which would make it work (apparently)
labels in whichever service needs authentication

services:
  <myservice>:
    labels:
    [...]
    - "traefik.frontend.auth.forward.address=https://<auth-domain>/oauth2/auth"
    - "traefik.frontend.auth.forward.trustForwardHeader=true"
    - "traefik.frontend.auth.forward.authResponseHeaders=X-Auth-Request-User,X-Auth-Request-Email,Authorization,Set-Cookie"
    - "traefik.frontend.errors.401.backend=oauth2"
    - "traefik.frontend.errors.401.status=401"
    - "traefik.frontend.errors.401.query=/oauth2/sign_in"
  [...]

and the following is the config I used for GitHub

  oauth2:
    command:
    # - -client-id     # environment
    # - -client-secret # environment
    # - -cookie-secret # environment
    - "-cookie-domain=<traefik-domain>"
    - "-cookie-secure=true"
    - "-email-domain=*"
    - "-github-org=<myorg>"
    - "-http-address=0.0.0.0:4180"
    - "-pass-access-token"
    - "-provider=github"
    - "-redirect-url=https://<auth-domain>/oauth2/callback"
    - "-set-authorization-header"
    - "-set-xauthrequest"
    environment:
    - "OAUTH2_PROXY_CLIENT_ID=${GITHUB_OAUTH_CLIENT_ID}"
    - "OAUTH2_PROXY_CLIENT_SECRET=${GITHUB_OAUTH_CLIENT_SECRET}"
    - "OAUTH2_PROXY_COOKIE_SECRET=${OAUTH2_PROXY_COOKIE_SECRET}"
    expose:
    - "4180"
    image: quay.io/pusher/oauth2_proxy:v3.1.0
    labels:
    - "traefik.backend=oauth2" # necessary for custom error pages
    - "traefik.frontend.rule=Host:<auth-domain>;PathPrefix:/oauth2"
    networks: # optional
    - backend
    restart: unless-stopped

I separated auth-domain and traefik-domain even though one is a subdomain of the other, not sure about the implications of this.
Two things to note:

  • the ; is particularly important in the host rules, it's an AND in traefik in order to match the oauth container
  • it is almost a requirement specifying traefik.backend as this is then a parameter in the labels of the containers requiring authentication, the automatically generated one isn't always predictable

from oauth2-proxy.

camerondavison avatar camerondavison commented on June 20, 2024

@devster31 I have been trying to get this to work, but I cannot seem to get it to work. If I use

HostRegexp:{subdomain:[a-z0-9-]+}.corp.example.com;PathPrefix:/oauth2 I can get the flow to set the cookie correctly, but then I end up on my auth domain with a 404 after it sets the cookie and tries to put me back to where I came from.

in your example you say one is a subset of the other which is which?

is auth-domain something like login.corp.example.com and then traefik.domain something like app.corp.example.com ? Or does one not have a subdomain at all?

from oauth2-proxy.

devster31 avatar devster31 commented on June 20, 2024

My traefik domain is domain.com while my auth domain was login.domain.com so it's possible that it only works if the oauth2_proxy domain is a subdomain of the one which is requesting the authorization.
If you wanted to authorize any {subdomain:[a-z0-9-]+}.corp.example.com you might need to host oauth2_proxy on login.{subdomain:[a-z0-9-]+}.corp.example.com. Your setup seems much more complex than what I tested though.
You might also try to set cookies for corp.example.com.

from oauth2-proxy.

mazzy89 avatar mazzy89 commented on June 20, 2024

@devster31 I'm trying to port that configuration in the case that Traefik runs on k8s. I'll post here some updates about it

from oauth2-proxy.

mazzy89 avatar mazzy89 commented on June 20, 2024

I've tried to port the docker configuration of traefik to k8s I haven't had any luck at the moment.

Here below the configuration.

Helm chart values.yaml

    extraArgs:
      email-domain: "*"
      cookie-domain: "<domain>"
      cookie-secure: "true"
      pass-access-token:
      provider: "gitlab"
      redirect-url: "https://login.<domain>/oauth2/callback"
      set-authorization-header:
      set-xauthrequest:
      login-url: https://gitlab.com/oauth/authorize
      redeem-url: https://gitlab.com/oauth/token
      validate-url: https://gitlab.com/api/v4/user

    service:
      type: ClusterIP
      port: 80
      annotations: {}

    ingress:
      enabled: true
      path: /oauth2
      # Used to create an Ingress record.
      hosts:
        - login.<domain>
      annotations:
        ingress.kubernetes.io/ssl-proxy-headers: "X-Forwarded-Proto: https"
        ingress.kubernetes.io/ssl-redirect: "true"
        kubernetes.io/ingress.class: traefik

Annotations applied to my service

      annotations:
          ingress.kubernetes.io/ssl-proxy-headers: "X-Forwarded-Proto: https"
          ingress.kubernetes.io/ssl-redirect: "true"
          kubernetes.io/ingress.class: traefik

          ingress.kubernetes.io/auth-type: "forward"
          ingress.kubernetes.io/auth-url: "https://login.<domain>/oauth2/auth"
          ingress.kubernetes.io/auth-trust-headers: "true"
          ingress.kubernetes.io/auth-response-headers: "X-Auth-Request-User,X-Auth-Request-Email,Authorization,Set-Cookie"
          traefik.ingress.kubernetes.io/error-pages: |-
            oauth2:
              status:
              - "401"
              backend: "login.<domain>/oauth2"
              query: "/oauth2/sign_in"

when I get into my the service the oauth2 proxy login page is displayed but then when I click on the button to sign in I get 401 at the url:

https://<my-service>.<domain>/oauth2/start?rd=%2F

and I can't continue.

Some logs from oauth2-proxy:

oauth2-proxy-5457cbc5b5-s5bdz oauth2-proxy 2019/06/06 00:22:56 oauthproxy.go:796: 100.96.4.142:51370 ("100.96.3.1") Cookie "_oauth2_proxy" not present
oauth2-proxy-5457cbc5b5-s5bdz oauth2-proxy 100.96.3.1 - - [06/Jun/2019:00:22:56 +0000] login.<domain> GET - "/oauth2/auth" HTTP/1.1 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36" 401 21 0.000
oauth2-proxy-5457cbc5b5-s5bdz oauth2-proxy 2019/06/06 00:22:56 oauthproxy.go:403: Warning: request host is "0.0.0.0" but using configured cookie domain of "<domain>"
oauth2-proxy-5457cbc5b5-s5bdz oauth2-proxy 100.96.4.142 - - [06/Jun/2019:00:22:56 +0000] 0.0.0.0 GET - "/oauth2/sign_in" HTTP/1.1 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36" 200 2471 0.000
oauth2-proxy-5457cbc5b5-s5bdz oauth2-proxy 2019/06/06 00:22:56 oauthproxy.go:796: 100.96.4.142:51370 ("100.96.3.1") Cookie "_oauth2_proxy" not present
oauth2-proxy-5457cbc5b5-s5bdz oauth2-proxy 100.96.3.1 - - [06/Jun/2019:00:22:56 +0000] login.<domain> GET - "/oauth2/auth" HTTP/1.1 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36" 401 21 0.000
oauth2-proxy-5457cbc5b5-s5bdz oauth2-proxy 2019/06/06 00:22:56 oauthproxy.go:403: Warning: request host is "0.0.0.0" but using configured cookie domain of "<domain>"
oauth2-proxy-5457cbc5b5-s5bdz oauth2-proxy 100.96.4.142 - - [06/Jun/2019:00:22:56 +0000] 0.0.0.0 GET - "/oauth2/sign_in" HTTP/1.1 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36" 200 2471 0.000

from oauth2-proxy.

runningman84 avatar runningman84 commented on June 20, 2024

I would recommend to check out this project:
https://github.com/travisghansen/external-auth-server/

from oauth2-proxy.

alexandrst88 avatar alexandrst88 commented on June 20, 2024

Seems like it's not possible to do with traefik, because error-pages annotation returns html rendered page, with Found link which has rd query inside. and then comes another query on favicon.ico, which mess up cookies.

I'm trying to implement authentification on kubernetes, traefik -> kube-dash -> oauth_proxy -> kube-dash

from oauth2-proxy.

maxlaverse avatar maxlaverse commented on June 20, 2024

@mazzy89 @alexandrst88
I have oauth_proxy2 running on many different installations but since it doesn't work with Traefik I wrote my own in 200 lines of Go and based on https://github.com/golang/oauth2.
In theory it supports Gitlab since the library is generic (not sure about kube-dash). I'm not sure if I will open-source it but I can push it in a repo if you want to have a look

from oauth2-proxy.

JoelSpeed avatar JoelSpeed commented on June 20, 2024

Out of interest (I'm not a traefik user), has anyone worked out what would need to be changed about the proxy in order to support traefik? Could we return a no body error for the traefik user agent to get this to work? (Assuming they set a user agent unique to traefik) We already do this for AJAX requests

from oauth2-proxy.

alexandrst88 avatar alexandrst88 commented on June 20, 2024

Seems like it would work with traefik, if traefik has logic as nginx with nginx.ingress.kubernetes.io/auth-signin,

@JoelSpeed I have in logs this message
Cookie "_oauth2_proxy" not present, could it be related that in intial requests, cookie is not set, and ouath2 proxy is thinking, during my two requests, that request on / and requests on /favicon.ico is completely two different clients, not one?

from oauth2-proxy.

alexandrst88 avatar alexandrst88 commented on June 20, 2024

 @JoelSpeed what's your thoughts?

from oauth2-proxy.

JoelSpeed avatar JoelSpeed commented on June 20, 2024

WRT to the redirecting to the FQDN, you can an a query string to the /oauth2/sign_in URI, I don't know if traefik has it available but maybe something like /oauth2/sign_in?rd=https://${FQDN}/${URI} might work?

from oauth2-proxy.

alexandrst88 avatar alexandrst88 commented on June 20, 2024

No, it's not available, so, I'm thinking I will try to contribute to traefik, to support this endpoint as nginx does.

from oauth2-proxy.

caarlos0 avatar caarlos0 commented on June 20, 2024

I had a look after you wrote that comment and implemented a change that seems to work fine with Traefik:
https://github.com/pusher/oauth2_proxy/compare/master...maxlaverse:support_traefik?expand=1

@maxlaverse any plans on opening that PR?

from oauth2-proxy.

maxlaverse avatar maxlaverse commented on June 20, 2024

Before opening a PR I would need to add tests and documentation.

First I'd like to know if this small change I propose in a branch would be a way to go @caarlos0. Because to have Traefik and the oauth2_proxy working together we could also add a query string to the existing auth endpoint, or modify Traefik.

from oauth2-proxy.

mazzy89 avatar mazzy89 commented on June 20, 2024

I remember that i’ve added the query string but it did not work in my case. Have anyone tried this query string?

from oauth2-proxy.

caarlos0 avatar caarlos0 commented on June 20, 2024

Before opening a PR I would need to add tests and documentation.

First I'd like to know if this small change I propose in a branch would be a way to go @caarlos0. Because to have Traefik and the oauth2_proxy working together we could also add a query string to the existing auth endpoint, or modify Traefik.

allright, I'll try to deploy your branch to test :)

from oauth2-proxy.

caarlos0 avatar caarlos0 commented on June 20, 2024

ok, you branch definitely work @maxlaverse !

My config:

ingress:
  annotations:
    ingress.kubernetes.io/auth-response-headers: "X-Auth-Request-User, X-Auth-Request-Email, Authorization, Set-Cookie"
    ingress.kubernetes.io/auth-type: forward
    ingress.kubernetes.io/auth-trust-headers: "true"
    ingress.kubernetes.io/auth-url: "https://login.foo.bar/oauth2/auth_or_start?rd=https://app.foo.bar"

and the basic ones on oauth2_proxy:

extraArgs:
  client-id: aaaa
  client-secret: vvvvv
  provider: github
  github-org: myorg
  footer: foo
  cookie-secret: secret
  cookie-domain: foo.bar
  whitelist-domain: .foo.bar
  cookie-secure: true
  redirect-url: https://login.foo.bar/oauth2/callback

One thing I was not able to make work is redirection after logging in, e.g., going not logged to app.foo.bar/blah, logging in and then going back to the same url. I tried to use ?rd=$$escaped_request_uri but that cause the redirect to go to login.foo.bar/blah instead 🤔 Any tips?

from oauth2-proxy.

etho201 avatar etho201 commented on June 20, 2024

Here's a link to my docker-compose file for anyone interested in seeing how I implemented this oauth2 proxy with Traefik. It's working great!

https://github.com/etho201/docker-compose/blob/master/pi4-stack/docker-compose.yml

The only minor annoyance is what I listed earlier...

The only thing that is slightly awkward is upon first successful authentication I get re-routed to the ${FQDN}, rather than the point of origin (regardless if this was a subdomain or subfolder). Does anyone have any suggestions on how to fix this? Or is that how it's supposed to work?

...but I can certainly live with that.

from oauth2-proxy.

etho201 avatar etho201 commented on June 20, 2024

Has anyone had any luck configuring this with Traefik v2.0?

from oauth2-proxy.

etho201 avatar etho201 commented on June 20, 2024

@fnkr Thank you for providing that gist. It's the best example I've seen of a Traefik 2.0 configuration (especially with the traefik.yaml file).

from oauth2-proxy.

tchellomello avatar tchellomello commented on June 20, 2024

@etho201 Here is my config for Traefik v2.0: https://gist.github.com/fnkr/a58b0cc741ffe4fb074b146476db4399
It is working, but there is a bug (see README.md).

@fnkr Thanks for sharing your config. I got it working, however, I'm facing some issues to get the redirect to work. I can authenticate but the URL is not being redirected to the original URL requested. Any ideas?

from oauth2-proxy.

tchellomello avatar tchellomello commented on June 20, 2024

@fnkr I think it is related with #328

from oauth2-proxy.

piscue avatar piscue commented on June 20, 2024

I'm following this, not sure if it solve the issue: https://alex.thom.ae/2020/01/12/deploy-traefik-prometheus-grafana-oauth2_proxy-docker-compose/

from oauth2-proxy.

JoelSpeed avatar JoelSpeed commented on June 20, 2024

I'm following this, not sure if it solve the issue: https://alex.thom.ae/2020/01/12/deploy-traefik-prometheus-grafana-oauth2_proxy-docker-compose/

This is great, would be great if we could reach out to the author and ask if he would mind us having a copy of this in our documentation

from oauth2-proxy.

tlex avatar tlex commented on June 20, 2024

I'm the author of that article and, in the meanwhile, I've switched to thomseddon/traefik-forward-auth. Less headache after updates. Back in February, when I've last revised the article, it worked.

from oauth2-proxy.

JoelSpeed avatar JoelSpeed commented on June 20, 2024

@tlex I'm sorry to hear you've moved away from the project

Would you mind if we included excerpts from your article within our documentation? It would be good to attribute you somehow if we did, perhaps you could co-author the commit somehow

from oauth2-proxy.

tlex avatar tlex commented on June 20, 2024

No problem, you can use the entire blog post, assuming you're linking back to it.

from oauth2-proxy.

github-actions avatar github-actions commented on June 20, 2024

This issue has been inactive for 60 days. If the issue is still relevant please comment to re-activate the issue. If no action is taken within 7 days, the issue will be marked closed.

from oauth2-proxy.

github-actions avatar github-actions commented on June 20, 2024

This issue has been inactive for 60 days. If the issue is still relevant please comment to re-activate the issue. If no action is taken within 7 days, the issue will be marked closed.

from oauth2-proxy.

DanielHabenicht avatar DanielHabenicht commented on June 20, 2024

Is the approach of @czunker documented somewhere? I could only find the multiple Middleware's way here: https://oauth2-proxy.github.io/oauth2-proxy/docs/configuration/overview/#configuring-for-use-with-the-traefik-v2-forwardauth-middleware

from oauth2-proxy.

linuxgemini avatar linuxgemini commented on June 20, 2024

Is the approach of @czunker documented somewhere? I could only find the multiple Middleware's way here: https://oauth2-proxy.github.io/oauth2-proxy/docs/configuration/overview/#configuring-for-use-with-the-traefik-v2-forwardauth-middleware

the documentation is written when #957 got merged, which is somewhat based on czunker's method but better handled and is in the core.

from oauth2-proxy.

DanielHabenicht avatar DanielHabenicht commented on June 20, 2024

@linuxgemini thanks for answering, I think I was just missing some attributes while copying them over to my kubernetes deployment. It works now.

One thing I couldn't bring to work with the documentation was the redirect back to the initial page with --skip-provider-button=true. I've seen the discussion in #1023 and opened an issue (#1255) to not bother the people subscribed to this issue.

from oauth2-proxy.

Johannestegner avatar Johannestegner commented on June 20, 2024

I have made PR #957 to handle redirects better in general. This also makes Traefik supported.

To get this working, I had to set the passHostHeader argument in my error handler middleware to false (and use /oauth2/sign_in path) and it worked as expected.
Only took me 3 hours to figure out! ;)

from oauth2-proxy.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.