Docker Caddy v2 and Azure OAuth2

1. Caddy version (caddy version):

v2.3.0 h1:fnrqJLa3G5vfxcxmOH/+kJOcunPLhSBnjgIvjXV/QTA=

2. How I run Caddy:

a. System environment:

Docker

b. Command:

caddy run

c. Service/unit/compose file:

version: '2'
services:
  # Reverse Proxy
  reverseProxy:
    restart: always
    privileged: true
    build: ./reverseProxy
    ports:
      - "80:80"
      - "127.0.0.1:2019:2019"

d. My complete Caddyfile or JSON config:

:80 {

  route /auth* {
    auth_portal {
      path /auth
      backends {
        azure_oauth2_backend {
          method oauth2
          realm azure
          provider azure
          tenant_id <tenant_id in uuid format>
          client_id <client_id in uuid format>
          client_secret <client_secret tested and working with other services>
          scopes openid email profile
        }
      }
    }
  }

  # @auth {
  #   not path /401/ /static/*
  # }

  # basicauth @auth {
  # Test credentials => kiko : test
  #   kiko JDJhJDE0JDRBMFJpMzFxakpvTUouT1VWR29uOXVlRmc2L3V6ZE9hbnQuNkRiUHA5cWNnRlhRUEQxT0Nh
  # }

  # handle_errors {
  #   @401 {
  #     expression {http.error.status_code} == 401
  #   }
  #   # rewrite @401 /401/
  #   redir @401 /401/
  # }

  route /401/ {
    reverse_proxy flask:5000
  }

  route /static/* {
    file_server
    reverse_proxy flask:5000
  }

  route /nodered/* {
    jwt {
      auth_url /auth/oauth2/azure
      allow roles everyone Everyone
    }

    uri strip_prefix /nodered
    reverse_proxy 10.114.101.1:1880
  }

  route /ui/* {
    jwt {
      auth_url /auth/oauth2/azure
      allow roles everyone Everyone
    }

    reverse_proxy 10.114.101.1:1880
  }

  route /chronograf/* {
    jwt {
      auth_url /auth/oauth2/azure
      allow roles everyone Everyone
    }

    reverse_proxy chronograf:8888
  }

  route /* {
    jwt {
      auth_url /auth/oauth2/azure
      allow roles everyone Everyone
    }

    reverse_proxy flask:5000
  }

}

3. The problem I’m having:

First a little explanation, device in question is IoT device with docker based os on it. There are multiple containers running (ex. flask, nodered, chronograf) and caddy is supposed to replace nginx as a reverse proxy.
What I want to do is when someone reaches port 80 on said device, to be redirected to Azure OAuth2 and if authenticated to be able to reach web services behind caddy (flask, nodered, chronograf). If auth not successful, give 401.
First I made it work with basicauth (I left that part in Caddyfile, commented out), but when I tried to implement OAuth2 it fails with a timeout when trying to get metadata (I am able to get the metadata json using curl with that same url from the caddy log)

4. Error messages and/or full log output:

/srv # caddy run
2021/03/20 02:44:20.665 INFO    using adjacent Caddyfile
2021/03/20 02:44:20.672 INFO    admin   admin endpoint started  {"address": "tcp/localhost:2019", "enforce_origin": false, "origins": ["localhost:2019", "[::1]:2019", "127.0.0.1:2019"]}
2021/03/20 02:44:20.673 INFO    tls.cache.maintenance   started background certificate maintenance      {"cache": "0xc00016e150"}
2021/03/20 02:44:20.674 INFO    http    server is listening only on the HTTP port, so no automatic HTTPS will be applied to this server {"server_name": "srv0", "http_port": 80}
2021/03/20 02:44:20.676 INFO    http.handlers.auth_portal       JWT token name found    {"instance_name": "portal-1", "token_name": "access_token"}
2021/03/20 02:44:20.676 WARN    http.handlers.auth_portal       JWT token origin not found, using default       {"instance_name": "portal-1"}
2021/03/20 02:44:50.677 INFO    tls.cache.maintenance   stopped background certificate maintenance      {"cache": "0xc00016e150"}
run: loading initial config: loading new config: loading http app module: provision http: server srv0: setting up route handlers: route 3: loading handler modules: position 0: loading module 'subroute': provision http.handlers.subroute: setting up subroutes: route 0: loading handler modules: position 0: loading module 'subroute': provision http.handlers.subroute: setting up subroutes: route 0: loading handler modules: position 0: loading module 'auth_portal': provision http.handlers.auth_portal: authentication provider registration error, instance portal-1, error: portal-1: backend configuration error: failed to fetch metadata for OAuth 2.0 authorization server: Get "https://login.microsoftonline.com/<tenant_id>/v2.0/.well-known/openid-configuration": dial tcp: i/o timeout

5. What I already tried:

I read around forum, read in detail (multiple times) ReadMe here, apparently I am missing something so I’d appreciate if @greenpau or anyone can help me out and point me in the right direction.

6. Links to relevant resources:

In case it’s relevant, here is also the Dockerfile for reverseProxy container:

FROM caddy:2.3.0-builder-alpine AS builder

RUN xcaddy build \
    --with github.com/greenpau/caddy-auth-portal \
    --with github.com/greenpau/caddy-auth-jwt

FROM caddy:2.3.0-alpine

COPY --from=builder /usr/bin/caddy /usr/bin/caddy

RUN apk add --no-cache \
        nano

COPY Caddyfile /etc/caddy

EXPOSE 80

CMD [ "cat" ]

the CMD [ "cat" ] is there just so I can enter the container terminal and run caddy with caddy run, after I make it work (hopefully), that command will be removed.

@kiko283 , please open github issue. I’ll try helping you there.

1 Like

This topic was automatically closed after 30 days. New replies are no longer allowed.