What I looked at, how I deployed it, what I have integrated with it.
In completing my Masters Degree my final Capstone topic was to be on an Emerging Technology. Back in 2019, I selected new new yet to be ratified protocol Webauthn.
Webauthn is a standard for using PKI instead of passwords to authenticate users. It removes the need for a password, instead using Public-Private Key pairs to verify users. The Webauthn standard was developed with support from Microsoft, Google, Apple and many others, so it was going to be the next big thing. I just don’t think I realised how long it would take to eventuate.
Fast forward to 2022, and now Webauthn support is built in to iOS 16, MacOS Ventura, Safari, Chrome and Edge. You can use your iPhone as the keystore, and using the CTAP protocol, can authenticate across platforms using a QR code.
I wanted to use Webauthn to authenticate to all services that I was hosting, especially the publicly exposed services. So how to do it? I was looking at a range of different authentication options, that I could run in docker that would make it easy to deploy and update. I also wanted to use open source. the list that I came up with was
- Authentik
- Authelia
- Keycloak
Authentik had a great feature comparison table staking it against Azure AD, ADFS, Okta and Duo. When you look at that table it Authentik literally ticks a lot of boxes. So I pulled to docker-compose.yml (its a fairly hefty one) and started playing.
---
version: '3.4'
services:
postgresql:
image: docker.io/library/postgres:12-alpine
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
start_period: 20s
interval: 30s
retries: 5
timeout: 5s
volumes:
- database:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=${PG_PASS:?database password required}
- POSTGRES_USER=${PG_USER:-authentik}
- POSTGRES_DB=${PG_DB:-authentik}
redis:
image: docker.io/library/redis:alpine
command: --save 60 1 --loglevel warning
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
start_period: 20s
interval: 30s
retries: 5
timeout: 3s
volumes:
- redis:/data
server:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2022.8.2}
restart: unless-stopped
command: server
environment:
AUTHENTIK_REDIS__HOST: redis
AUTHENTIK_POSTGRESQL__HOST: postgresql
AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
# AUTHENTIK_ERROR_REPORTING__ENABLED: "true"
# WORKERS: 2
volumes:
- ./media:/media
- ./custom-templates:/templates
- geoip:/geoip
ports:
- "9001:9001"
- "9443:9443"
worker:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2022.8.2}
restart: unless-stopped
command: worker
environment:
AUTHENTIK_REDIS__HOST: redis
AUTHENTIK_POSTGRESQL__HOST: postgresql
AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
# AUTHENTIK_ERROR_REPORTING__ENABLED: "true"
# This is optional, and can be removed. If you remove this, the following will happen
# - The permissions for the /media folders aren't fixed, so make sure they are 1000:1000
# - The docker socket can't be accessed anymore
user: root
volumes:
- ./media:/media
- ./certs:/certs
- /var/run/docker.sock:/var/run/docker.sock
- ./custom-templates:/templates
- geoip:/geoip
geoipupdate:
image: "maxmindinc/geoipupdate:latest"
volumes:
- "geoip:/usr/share/GeoIP"
environment:
GEOIPUPDATE_EDITION_IDS: "GeoLite2-City"
GEOIPUPDATE_FREQUENCY: "8"
volumes:
database:
driver: local
redis:
driver: local
geoip:
driver: local
Opening a browser and hitting port 9443 and I got the initial setup wizard.
The aim will be to setup and many applications as I can with SSO. be that either via SAML or OATH 2.0 or openID connect (which is far simpler).
In doing further research I have determined I Will be able to use Node Proxy Manager (NPM) to authenticate those services that don’t support SSO using proxy level authentication. NPM also provides SSL certs, but I have another post on that.
Here is a list of the appliction that I am using and what Method of Authentication they use
Application | Authentik Authentication Type | Application Specific |
WordPress | Oauth 2.0 | Plugin Name |
Portainer | Oauth 2.0 | OOB |
Wiki.js | Oauth 2.0 | OOB |
Guacamole | OpenID Connect | auth-openid Docker .env config |
PiHole | Authentik Proxy / NPM proxy | Removed admin login |
LibreNMS | OpenID Connect | Using the Socialite Plugin, This one was the hardest and tool me the longest. |
Homarr | Authentik Proxy / NPM proxy | By Default no Auth |
Some of the Apps were very easy to get going, and others were a lot more difficult. LibreNMS was the most challenging do to firstly having to get the Socialite plugin working, but once that was working (which required an upgrade of PHP on that OS, as I am not running LibreNMS in a container), it has been stable and working great!
I’ll do a post in detail on each particular app, which I have documented on my internal wiki for my reference, but will punish here for everyone else to learn from.