Databases¶
Canaille can read and save data in different databases. This page presents the different database backends and their specificities:
Memory¶
Canaille comes with a lightweight inmemory backend by default. It is used when no other backend has been configured.
This backend is only for test purpose and should not be used in production environments.
SQL¶
Canaille can use any database supported by SQLAlchemy, such as sqlite, postgresql or mariadb.
Configuration¶
It is used when the CANAILLE_SQL
configuration parameter is defined. For instance:
[CANAILLE_SQL]
SQL_DATABASE_URI = "postgresql://user:password@localhost/database"
You can find more details on the SQL configuration in the dedicated section
.
Migrations¶
By default, migrations are applied when you run the web application.
You can disable this behavior with the AUTO_MIGRATE
setting.
Migrations are not automatically applied with the use of the CLI though.
Migrations are done with flask-alembic, that provides a dedicated CLI to manually tune migrations.
You can check the flask-alembic documentation and the canaille db
command line if you are in trouble.
LDAP¶
Canaille can use OpenLDAP as its main database.
It is used when the CANAILLE_LDAP
configuration parameter is defined. For instance:
[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"
If you want to use TOTP/HOTP authentication, you will need to add the oathHOTPToken
class to the user:
USER_CLASS = ["inetOrgPerson", "oathHOTPToken"]
You can find more details on the LDAP configuration in the dedicated section
.
Note
Currently, only the inetOrgPerson
, oathHOTPToken
and groupOfNames
schemas have been tested.
If you want to use different schemas or LDAP servers, adaptations may be needed.
Patches are welcome.
OpenLDAP overlays integration¶
Canaille can integrate with several OpenLDAP overlays:
memberof / refint¶
memberof and refint overlays are needed for the Canaille group membership to work correctly.
Here is a configuration example compatible with canaille:
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
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
You can adapt and load those configuration files with:
# 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¶
If the ppolicy overlay is configured and the pwdEndTime
attribute is available (since OpenLDAP 2.6), then account locking support will be enabled in canaille. To allow users to manage account expiration, they need to have a write permission on the lock_date
attribute.
Here is a configuration example compatible with canaille:
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
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
You can adapt and load those configuration files with:
# 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¶
If the otp overlay is configured, you will be able to add one-time passcode authentication in canaille.
Here is a configuration example compatible with canaille:
dn: cn=module,cn=config
cn: module
objectClass: olcModuleList
olcModuleLoad: otp
dn: olcOverlay=otp,olcDatabase={1}mdb,cn=config
objectClass: olcOverlayConfig
olcOverlay: otp
You can adapt and load this configuration file with:
# Adapt this command according to your setup
sudo ldapadd -Q -H ldapi:/// -Y EXTERNAL -f otp-config.ldif
You will also need to add the oathHOTPToken
class to the user:
[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
¶
Be careful to stop your ldap server before running 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.
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 slapmodify
command to delete the old schema.
It is supposed to be executed while your LDAP server is turned off.
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:
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:
env CONFIG=sql-config.toml canaille install
env CONFIG=ldap -config.toml canaille dump | env CONFIG=sql-config.toml canaille restore