I have a lot of different services which I self host for me and my family like:
- PeerTube
- Lemmy
- Mastodon
- Synology NAS
- TTRSS
- NextCloud
- Matrix
- HomeAssistant
- etc.
Right now every family member needs to create a user on each of those services and have a different password on them, which is OK when you use a Password Manager, but most of my extended family members don’t. And they often forget their password and stop using the service because they can’t figure out how to reset the password with each and every service.
I would like to try to consolidate all of it with a Single Sign-On (SSO) solution but It’s not obvious to me if there is one which is not overly over engineered for hundreds of thousands of users but small and lightweight, perhaps even easy to set up.
I tried OpenLDAP but Jesus that was very involved.
I tried OpenLDAP but Jesus that was very involved.
OpenLDAP is easy :) Once you understand LDAP concepts.
Check this and read through the tasks/
directory (particularly openldap.yml
and populate.yml
. It sets up everything needed for an LDAP authentication service (if you don’t use ansible you can still read what the tasks do and you should get a pretty good understanding of what’s needed, if not let me know).
In short you need:
slapd
(the OpenLDAP server)- set up a base LDAP directory structure (OUs/Organizational Units, I only use 3 OUs:
system
,users
andgroups
) - an admin user in the LDAP directory (mine is
admin
directly at the base of the LDAP directory) - (optional but recommended) a so-called
bind
user in the LDAP directory (unvprivileged account that can only list/read users/groups) (mine isbind
under thesystem
OU) - (optional) groups to map users to their roles (e.g. only users in
access_jellyfin
are allowed to login to jellyfin) - actual user accounts, member of one or more groups if needed
When you login to an application/service configured to use the LDAP authentication backend, it connects to the LDAP directory using the bind
user credentials, and checks that the user exists (depending on how you configured the application either by name, uid, email…) , that the password you provided matches the hash stored in the LDAP directory, optionally that the user is part of the required groups. Then it allows or denies access.
There’s not much else to it:
- you can also do without the
bind
account but I wouldn’t recommend it (either configure your applications to use theadmin
user in which case they have admin access to the LDAP directory… not good. Or allow anonymous read-only access to the LDAP directory - also not ideal). slapd
stores its configuration (admin user/password, log level…) inside the LDAP directory itself as attributes of a special entity (cn=config
), so to access or modify it you have to use LDIF files and theldapadd/ldapmodify
commands, or use a convenient wrapper like the ansible modules tools used above.- once this is set up, you can forget LDIF files and use a web interface to manage contents of the LDAP directory.
- OUs and groups are different and do not serve the same purpose, OUs are just hierarchical levels (like folders) inside your LDAP tree. groups can contain multiple users/users can have multiple groups so they’re like “labels” without a notion of hierarchy. You can do without OUs and stash everything at the top level of the directory, but it’s messy.
- users (or other entities) have several attributes (common name, firstname, lastname, email, uid, password, description… it can contain anything really, it’s just a directory service)
- LDAP is hierarchical by nature, so user with Common Name (CN)
jane.doe
in OUusers
in the directory for domainexample
has the Distinguished Name (DC)cn=jane.doe,ou=users,dc=example,dc=org
. Think of it like/path/to/file
. - to look for a particular object you use filters which are just a search syntax to match specific entities (object classes) (users are
inetOrgPerson
s, groups areposixGroup
s…) and attributes (uid
,cn
,email
,phonenumber
…). Usually applications that support LDAP come with predefined filters to look for users in specific groups, etc.
Keycloak is decent. It has its own built in user database, or it can connect to an “upstream” idp like AD, GitHub, google, fb, basically anything that speaks openid or SAML. Then, it can act as an idp to each service you run. It is a bit of a chore to configure, but compared to other SSO servers it’s pretty good (looking at you shibboleth)
After about a year of using Keycloak for some #dayjob side projects, I literally just stood it up in my homelab.
It does have a learning curve, but it supports OIDC and SAML - those two should get most internal services covered.
Back end can federate with AD or LDAP - for the real stinkers who refuse to support SSO. (Looking at you Netbox)
I use keycloak. Pretty steep learning curve, but once properly set up, it can do pretty much anything.
But if you’re in a pinch, NextCloud can act as an OIDC auth provider out of the box.
NextCloud can act as an OIDC auth provider out of the box.
Oh, I did not know that, I’ll have a look, thanks!
Here is the documentation, pretty bare though: https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/oauth2.html
I started integrating Authentik lately based on seeing people recommend it. It has pretty steep learning curve. I had to follow tutorials and even then each integration have its own quirks. I got stuck on integrating my internal e-mail server with ldap provider (via authentik). It’s definitely capable but it’s a project to integrate all services.
Other SSO options are just a tough if not more complex than authentik. If you use docker and are self hosting, this is a great option. Provides basically every SSO option to connect all your services, especially if you combine it with a good reverse proxy like traefik to provide SSO to simple webapps.
If you are setting up a self hosted infrastructure and have some experience, I highly recommend checking out techno Tim’s “ssl everywhere” video for wild card ssl with traefik and then combine that with authentik for SSO with both local only and internet accessible apps.
+1 for Authentik! It definitely has a steep learning curve, but once you get comfortable with it, it’s really versatile. The integration docs have tons of walkthroughs for setting up Authentik with different apps which is epecially helpful when getting started.
I’ve found Zitadel to be the best open source Oauth2 provider. It also supports terraform for a fully IaC approach to declaring your users and their permissions.
I can only support that. This is what I am running for my small business as well and it’s been super smooth for roughly a year now! Especially self service and auto-registering based on domain names turned out to be really nice features (for a business). In my homelab I just enjoy having a nice ui.
https://github.com/zitadel/zitadel
I came from Authentik which was nice too but nowhere as feature rich as zitadel.