Bases de données

Canaille peut lire et écrire dans différentes bases de données. Cette page présente les differents « backends » des bases de données et leurs spécificités :

En-mémoire

Canaille est fourni avec un«  backend » léger en mémoire par défaut. Il est utilisé lorsqu’aucun autre backend n’a été configuré.

Ce backend est destiné uniquement à des fins de test et ne devrait pas être utilisé dans des environnements de production.

SQL

Canaille peut utiliser n’importe quelle base de données acceptées par SQLAlchemy, comme sqlite, postgresql ou mariadb.

Configuration

Il est utilisé quand le paramètre de configuration CANAILLE_SQL est défini. Par exemple :

config.toml
[CANAILLE_SQL]
SQL_DATABASE_URI = "postgresql://user:password@localhost/database"

Vous pouvez trouver plus de détails sur la configuration SQL dans la dedicated section.

Migrations

Par défaut, les migrations sont appliquées lorsque l’application web est lancée. Vous pouvez désactiver ce comportement avec le paramètre de configuration AUTO_MIGRATE. Cependant les migrations ne sont pas appliquées lorsque l’interface en ligne de commande est utilisée.

Les migrations sont effectuées avec flask-alembic, qui fournit un outil console dédié pour les paramétrer. Vous pouvez consulter la documentation de flask-alembic et la commande canaille db si vous rencontrez des soucis.

LDAP

Canaille peut utiliser OpenLDAP comme base de données principale. Elle est utilisée quand le paramètre de configuration CANAILLE_LDAP est défini. Par exemple :

config.toml
[CANAILLE_LDAP]
URI = "ldap://ldap"
ROOT_DN = "dc=example,dc=org"
BIND_DN = "cn=admin,dc=example,dc=org"
BIND_PW = "very-secret-password"

USER_BASE = "ou=users,dc=example,dc=org"
USER_CLASS = "inetOrgPerson"

GROUP_BASE = "ou=groups,dc=example,dc=org"

Si vous voulez utiliser l’authentification TOTP/HOTP, vous devrez ajouter la classe oathHOTPToken à l’utilisateur :

USER_CLASS = ["inetOrgPerson", "oathHOTPToken"]

Vous pouvez trouver plus de détails sur la configuration LDAP dans la dedicated section.

Note

Actuellement, seuls les schémas inetOrgPerson, oathHOTPToken et groupOfNames ont été testés. Si vous voulez utiliser différents schémas ou serveurs LDAP, des adaptations peuvent être nécessaires. Toute amélioration est bienvenue.

Intégration de surcouches (« overlays ») OpenLDAP

Canaille peut s’intégrer avec plusieurs « overlays » OpenLDAP :

memberof / refint

les greffons memberof et refint sont nécessaires pour que l’appartenance d’un utilisateur à un groupe fonctionne correctement dans Canaille.

Voici un exemple de configuration compatible avec canaille :

memberof-config.ldif
dn: cn=module,cn=config
cn: module
objectClass: olcModuleList
olcModuleLoad: memberof

dn: olcOverlay=memberof,olcDatabase={1}mdb,cn=config
objectClass: olcConfig
objectClass: olcMemberOf
objectClass: olcOverlayConfig
objectClass: top
olcOverlay: memberof
olcMemberOfDangling: ignore
olcMemberOfRefInt: TRUE
olcMemberOfGroupOC: groupOfNames
olcMemberOfMemberAD: member
olcMemberOfMemberOfAD: memberOf
refint-config.ldif
dn: cn=module,cn=config
cn: module
objectClass: olcModuleList
olcModuleLoad: refint

dn: olcOverlay=refint,olcDatabase={1}mdb,cn=config
objectClass: olcConfig
objectClass: olcOverlayConfig
objectClass: olcRefintConfig
objectClass: top
olcOverlay: refint
olcRefintAttribute: memberof
olcRefintAttribute: member
olcRefintAttribute: manager
olcRefintAttribute: owner

Vous pouvez adapter et charger ces fichiers de configuration avec :

# Adapt those commands according to your setup
sudo ldapadd -Q -H ldapi:/// -Y EXTERNAL -f memberof-config.ldif
sudo ldapadd -Q -H ldapi:/// -Y EXTERNAL -f refint-config.ldif

ppolicy

Si l’overlay ppolicy est configuré et que l’attribut pwdEndTime est disponible (depuis OpenLDAP 2.6), alors la gestion du bloquage de compte sera activée dans Canaille. Pour permettre aux utilisateurs de gérer l’expiration de leur compte, ils ont besoin du droit d”écriture sur l’attribut lock_date.

Voici un exemple de configuration compatible avec canaille :

ppolicy-config.ldif
dn: cn=module,cn=config
cn: module
objectClass: olcModuleList
olcModuleLoad: ppolicy

dn: olcOverlay=ppolicy,olcDatabase={1}mdb,cn=config
objectClass: olcOverlayConfig
objectClass: olcPPolicyConfig
olcOverlay: ppolicy
olcPPolicyDefault: cn=passwordDefault,dc=example,dc=org
olcPPolicyUseLockout: TRUE
ppolicy.ldif
dn: cn=passwordDefault,dc=example,dc=org
objectClass: person
objectClass: top
objectClass: pwdPolicy
sn: passwordDefault
cn: passwordDefault
pwdAttribute: userPassword
pwdMustChange: TRUE
pwdLockout: TRUE
pwdAllowUserChange: TRUE
pwdGraceAuthNLimit: 1
pwdMaxFailure: 999

Vous pouvez adapter et charger ces fichiers de configuration avec :

# Adapt those commands according to your setup
sudo ldapadd -Q -H ldapi:/// -Y EXTERNAL -f ppolicy-config.ldif
sudo ldapadd -Q -H ldapi:/// -Y EXTERNAL -f ppolicy.ldif

otp

Si l’overlay otp est configuré, vous pourrez ajouter l’authentification par mot de passe unique (OTP) dans Canaille.

Voici un exemple de configuration compatible avec canaille :

otp-config.ldif
dn: cn=module,cn=config
cn: module
objectClass: olcModuleList
olcModuleLoad: otp

dn: olcOverlay=otp,olcDatabase={1}mdb,cn=config
objectClass: olcOverlayConfig
olcOverlay: otp

Vous pouvez adapter et charger ce fichier de configuration avec :

# Adapt this command according to your setup
sudo ldapadd -Q -H ldapi:/// -Y EXTERNAL -f otp-config.ldif

Vous aurez aussi besoin d’ajouter la classe oathHOTPToken à l’utilisateur :

config.toml
[CANAILLE_LDAP]
...
USER_CLASS = ["inetOrgPerson", "oathHOTPToken"]

Manual schema installation

Schema installation can be automatically done using the install command. If for some reason you prefer to install schemas manually, here is how to do. First of all, you need to locate the oauth2-openldap.ldif on your system, or copy it from the Canaille repository.

Using ldapadd

sudo ldapadd -Q -H ldapi:/// -Y EXTERNAL -f /path/to/oauth2-openldap.ldif

Using slapadd

Soyez attentif à arrêter votre serveur LDAP avant d’exécuter slapadd

sudo service slapd stop
sudo -u openldap slapadd -n0 -l /path/to/oauth2-openldap.ldif
sudo service slapd start

Schema update

OpenLDAP provides no way of migrating schemas. Canaille provides its own LDAP OIDC schemas, luckily they are quite stable, but fixes may happen. Updating LDAP schemas may be a tricky operation, the safest way to achieve this is to follow those steps:

Backup and purge

First, let us backup the OIDC objects and then remove them from the database. Please perform your own backups too, in case something unexpected happens.

Backup and purge OIDC related objects
canaille dump client authorizationcode consent token > dump.json
canaille delete client --noconfirm
canaille delete authorizationcode --noconfirm
canaille delete consent --noconfirm
canaille delete token --noconfirm

Delete the old schema

You can use the ldapdelete command to remove the old schema.

In the following command, you might adapt the schema DN, for instance use cn={4}oauth,cn=schema,cn=config instead of cn=oauth,cn=schema,cn=config.

Removing the old schema with ldapdelete
sudo ldapdelete -Q -H ldapi:/// -Y EXTERNAL "cn=oauth,cn=schema,cn=config"

For good measure, you may then restart your ldap server.

Alternatively you could use the slapmodify command. It is supposed to be executed while your LDAP server is turned off.

Removing the old schema with slapmodify
sudo slapmodify -n0 <<EOL
dn: cn=oauth,cn=schema,cn=config
changetype: delete
EOL

Add the new schema

To add the new schema, run the install command or follow instructions on the Manual schema installation section.

Restore the data

Now that the schemas are updated, you can restore the saved data:

Restore OIDC related objects
canaille restore < dump.json

Dump and restore

Backups

The canaille dump and canaille restore commands can be used to dump all the Canaille objects, or load them in the current database. Those commands can be used for backuping Canaille data.

Migration

The dump format is the same whatever database backend is used, and thus it can be used to migrate from a database backend to another. To achieve a migration, you need to have two configuration files prepared for the source database and the destination database. For instance, if you want to migrate from a LDAP database to a SQL database, you can execute something like this:

Migrating data from a LDAP directory to a SQL database
env CONFIG=sql-config.toml canaille install
env CONFIG=ldap -config.toml canaille dump | env CONFIG=sql-config.toml canaille restore