Protecting Docker services with OpenLDAP

I self host a lot of services that I want to be able to access while I’m on the go. Originally I started off by having all of my applications behind a VPN. I liked how none of my services were exposed to the outside internet, but on iOS I had to keep reconnecting the VPN all the time.

Next I put all my services behind Traefik, and enabled Basic Authentication. I liked how easy it was to share, but I now had to enter my credentials for each subdomain and 1Password was unable to autofill the login pop up.

Finally I have landed on using Authelia, an open source authentication server that can use OpenLDAP. While I have been extremely happy with the software, the documentation is still in the early stages, and it required me to piece together a multiple different sources to figure this out.

The steps below do not contain the full configuration that you need. They are intended to explain the key steps required. If you would like to skip to a full working example, I pushed an example docker-compose here:

authelia-docker-example

Service Requirements

Authelia requires:

  • redis
  • mongo
  • openldap

Authelia configuration

Configure authentication_backend.ldap to point to your ldap instance.

authentication_backend:
  ldap:
    url: ldap://openldap
    base_dn: dc=example,dc=org
    user: cn=admin,dc=example,dc=org
    password: admin

Next, configure the rules. The important part is that you need to setup a rule to bypass Authelia. If you forget this step, you will end up with a redirect loop.

rules:
  - domain: auth.example.org
    policy: bypass

You can configure your root domain to require single factor authentication, while all your subdomains require multifactor.

rules:
  - domain: *.example.org
    policy: two_factor
  - domain: example.org
    policy: one_factor

All that’s left are the fairly straightforward options: session.secret, session.domain, redis, and mongo.

docker compose

version: “3services:
  auth:
    image: clems4ever/authelia:v3.15.0
    container_name: authelia
    labels:
      traefik.frontend.rule: “Host:auth.example.org”
      traefik.port: 9091
      traefik.enable: true
    volumes:
      - ./authelia_config.yml:/etc/authelia/config.yml:ro
...

Configure traffic

Setup forward auth for the https entrypoint.

defaultEntryPoints = [“https”]
[entryPoints]
  [entryPoints.https]
    address = “:443”
    [entryPoints.https.tls]
    [entryPoints.https.auth.forward]
      address = “http://authelia:9091/api/verify?rd=https://auth.example.org/%23/“
...

Enjoy

Traefik now requires a login for every service. Authelia has built in rate limiting that should discourage any sort of brute force attack on your users. For a next step, you can restrict access to resources based on the group the user is in. For example, you can restrict Portainer’s access to only admin members.