mirror of
https://github.com/kakwa/ldapcherry
synced 2024-11-28 04:04:30 +01:00
d831b09293
* improve documentation for key: True flag in attributes.yml * improve documentation for the ldap filters and their templating * improve comment in the .ini file
527 lines
21 KiB
ReStructuredText
527 lines
21 KiB
ReStructuredText
Deploy
|
|
======
|
|
|
|
LdapCherry aims to be as simple as possible to deploy.
|
|
The Application is constituted of:
|
|
|
|
* ldapcherryd: the daemon to lauch LdapCherry.
|
|
* one ini file (ldapcherry.ini by default): the entry point for the configuration, containing all the "technical" attributes.
|
|
* two yaml files (roles.yml and attributes by default): the files containing the roles and attributes definition.
|
|
|
|
The default configuration directory is **/etc/ldapcherry/**.
|
|
|
|
Launch
|
|
------
|
|
|
|
LdapCherry is launched using the internal cherrypy server:
|
|
|
|
|
|
.. sourcecode:: bash
|
|
|
|
# ldapcherryd help
|
|
$ ldapcherryd -h
|
|
|
|
# launching ldapcherryd in the foreground
|
|
$ ldapcherryd -c /etc/ldapcherry/ldapcherry.ini
|
|
|
|
# launching ldapcherryd in the foreground in debug mode
|
|
$ ldapcherryd -c /etc/ldapcherry/ldapcherry.ini -D
|
|
|
|
# launching ldapcherryd as a daemon
|
|
$ ldapcherryd -c /etc/ldapcherry/ldapcherry.ini -p /var/run/ldapcherry/ldapcherry.pid -d
|
|
|
|
Roles and Attributes Configuration
|
|
----------------------------------
|
|
|
|
Entry point in main configuration
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
The main configuration file (**ldapcherry.ini** by default) contains two parameters locating the roles and attributes configuration files:
|
|
|
|
+-----------------+------------+-------------------------------+-------------------+
|
|
| Parameter | Section | Description | Values |
|
|
+=================+============+===============================+===================+
|
|
| attributes.file | attributes | Attributes configuration file | Path to conf file |
|
|
+-----------------+------------+-------------------------------+-------------------+
|
|
| roles.file | roles | Roles configuration file | Path to conf file |
|
|
+-----------------+------------+-------------------------------+-------------------+
|
|
|
|
Attributes Configuration
|
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
The attributes configuration is done in a yaml file (**attributes.yml** by default).
|
|
|
|
Mandatory parameters
|
|
^^^^^^^^^^^^^^^^^^^^
|
|
|
|
The mandatory parameters for an attribute, and their format are the following:
|
|
|
|
.. sourcecode:: yaml
|
|
|
|
<attr id>:
|
|
description: <Human readable description of the attribute> # (free text)
|
|
display_name: <Display name in LdapCherry forms> # (free text)
|
|
weight: <weight controlling the display order of the attributes, lower is first> # (integer)
|
|
type: <type of the attributes> # (in ['int', 'string', 'email', 'stringlist', 'fix', 'textfield'])
|
|
backends: # (list of backend attributes name)
|
|
- <backend id 1>: <backend 1 attribute name>
|
|
- <backend id 2>: <backend 2 attribute name>
|
|
|
|
.. warning::
|
|
|
|
<attr id> (the attribute id) must be unique, LdapCherry won't start if it's not.
|
|
|
|
.. warning::
|
|
|
|
<backend id> (the backend id) must be defined in main ini configuration file.
|
|
LdapCherry won't start if it's not.
|
|
|
|
Type listing
|
|
^^^^^^^^^^^^
|
|
|
|
The following **type** are supported:
|
|
|
|
* **int**: an integer (ex: uid)
|
|
* **string**: a string (ex: first name)
|
|
* **stringlist**: a string to choose from a given list of strings (ex: one of /bin/sh, /bin/bash /bin/zsh for a shell)
|
|
* **textfield**: free multiline text (ex: an SSH key)
|
|
* **email**: an email address
|
|
* **fix**: a fix value, only present shown information purposes
|
|
|
|
Type stringlist values
|
|
^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
If **type** is set to **stringlist** the parameter **values** must be filled with the list of possible values:
|
|
|
|
.. sourcecode:: yaml
|
|
|
|
<attr id>:
|
|
description: <Human readable description of the attribute>
|
|
display_name: <Display name in LdapCherry forms>
|
|
weight: <weight controlling the display order of the attributes)
|
|
|
|
type: stringlist
|
|
values:
|
|
- value1
|
|
- value2
|
|
- value3
|
|
|
|
backends:
|
|
- <backend id>: <backend attribute name>
|
|
|
|
Key attribute:
|
|
^^^^^^^^^^^^^^
|
|
|
|
One attribute must be used as a unique key across all backends.
|
|
|
|
It acts as a reconciliation key.
|
|
|
|
It also marks which attribute must be used within ldapcherry (ex: querysting parameter in links)
|
|
to point to one given user.
|
|
|
|
To set the key attribute, you must set **key** to **True** on this attribute.
|
|
|
|
Example:
|
|
|
|
.. sourcecode:: yaml
|
|
|
|
uid:
|
|
description: "UID of the user"
|
|
display_name: "UID"
|
|
search_displayed: True
|
|
key: True # defining the attribute as "key"
|
|
type: string
|
|
weight: 50
|
|
backends:
|
|
ldap: uid
|
|
ad: sAMAccountName
|
|
|
|
Authorize self modification
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
A user can modify some of his attributes (self modification).
|
|
In such case, the parameter **self** must set to **True**:
|
|
|
|
.. sourcecode:: yaml
|
|
|
|
<attr id>:
|
|
description: <Human readable description of the attribute>
|
|
display_name: <Display name in LdapCherry forms>
|
|
weight: <weight controlling the display order of the attributes)
|
|
type: <type of the attributes>
|
|
|
|
self: True
|
|
|
|
backends:
|
|
- <backend id 1>: <backend 1 attribute name>
|
|
- <backend id 2>: <backend 2 attribute name>
|
|
|
|
Autofill
|
|
^^^^^^^^
|
|
|
|
LdapCherry has the possibility to auto-fill fields from other fields,
|
|
to use this functionnality **autofill** must be set.
|
|
|
|
Example:
|
|
|
|
.. sourcecode:: yaml
|
|
|
|
gidNumber:
|
|
description: "Group ID Number of the user"
|
|
display_name: "GID Number"
|
|
weight: 70
|
|
type: int
|
|
|
|
autofill:
|
|
function: lcUidNumber # name of the function to call
|
|
args: # list of arguments
|
|
- $first-name #
|
|
- $name
|
|
- '10000'
|
|
- '40000'
|
|
|
|
backends:
|
|
ldap: gidNumber
|
|
|
|
Arguments of the **autofill** function work as follow:
|
|
|
|
* if argument starts with **$**, for example **$my_field**, the value of form input **my_field** will be passed to the function.
|
|
* otherwise, it will be treated as a fixed argument.
|
|
|
|
Available **autofill** functions:
|
|
|
|
* lcUid: generate 8 characters ascii uid from 2 other fields (first letter of the first field, 7 first letters of the second):
|
|
|
|
.. sourcecode:: yaml
|
|
|
|
autofill:
|
|
function: lcUid
|
|
args:
|
|
- $first-name
|
|
- $name
|
|
|
|
|
|
* lcDisplayName: concatenate two fields (with a space as separator):
|
|
|
|
.. sourcecode:: yaml
|
|
|
|
autofill:
|
|
function: lcDisplayName
|
|
args:
|
|
- $first-name
|
|
- $name
|
|
|
|
* lcMail: generate an email address from 2 other fields and a domain (<uid>+domain):
|
|
|
|
.. sourcecode:: yaml
|
|
|
|
autofill:
|
|
function: lcMail
|
|
args:
|
|
- $first-name
|
|
- $name
|
|
- '@example.com'
|
|
|
|
|
|
* lcUidNumber: generate an uid number from 2 other fields and between a minimum and maximum value:
|
|
|
|
.. sourcecode:: yaml
|
|
|
|
autofill:
|
|
function: lcUidNumber
|
|
args:
|
|
- $first-name
|
|
- $name
|
|
- '10000'
|
|
- '40000'
|
|
|
|
* lcHomeDir: generate an home directory from 2 other fields and a root (<root>+<uid>):
|
|
|
|
.. sourcecode:: yaml
|
|
|
|
autofill:
|
|
function: lcHomeDir
|
|
args:
|
|
- $first-name
|
|
- $name
|
|
- /home/
|
|
|
|
Roles Configuration
|
|
~~~~~~~~~~~~~~~~~~~
|
|
|
|
The roles configuration is done in a yaml file (**roles.yml** by default).
|
|
|
|
Mandatory parameters
|
|
^^^^^^^^^^^^^^^^^^^^
|
|
|
|
Roles are seen as an aggregate of groups:
|
|
|
|
.. sourcecode:: yaml
|
|
|
|
<role id>:
|
|
display_name: <role display name in LdapCherry>
|
|
description: <human readable role description>
|
|
backends_groups: # list of backends
|
|
<backend id 1>: # list of groups in backend
|
|
- <b1 group 1>
|
|
- <b1 group 2>
|
|
<backend id 2>:
|
|
- <b2 group 1>
|
|
- <b2 group 2>
|
|
|
|
.. warning:: <role id> must be unique, LdapCherry won't start if it's not
|
|
|
|
Defining LdapCherry Administrator role
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
At least one of the declared roles must be tagged to be LdapCherry administrators.
|
|
|
|
Doing so is done by setting **LC_admins** to **True** for the selected role:
|
|
|
|
.. sourcecode:: yaml
|
|
|
|
<role id>:
|
|
display_name: <Role display name in LdapCherry>
|
|
description: <human readable role description>
|
|
|
|
LC_admins: True
|
|
|
|
backends_groups: # list of backends
|
|
<backend id 1>: # list of groups in backend
|
|
- <b1 group 1>
|
|
- <b1 group 2>
|
|
<backend id 2>:
|
|
- <b2 group 1>
|
|
- <b2 group 2>
|
|
|
|
Nesting roles
|
|
^^^^^^^^^^^^^
|
|
|
|
LdapCherry handles roles nesting:
|
|
|
|
.. sourcecode:: yaml
|
|
|
|
parent_role:
|
|
display_name: Role parent
|
|
description: The parent role
|
|
backends_groups:
|
|
backend_id_1:
|
|
- b1_group_1
|
|
- b1_group_2
|
|
backend_id_2:
|
|
- b2_group_1
|
|
- b2_group_2
|
|
subroles:
|
|
child_role_1:
|
|
display_name: Child role 1
|
|
description: The first Child Role
|
|
backends_groups:
|
|
backend_id_1:
|
|
- b1_group_3
|
|
child_role_2:
|
|
display_name: Child role 2
|
|
description: The second Child Role
|
|
backends_groups:
|
|
backend_id_1:
|
|
- b1_group_4
|
|
|
|
In that case, child_role_1 and child_role_2 will contain all groups of parent_role plus their own specific groups.
|
|
|
|
Main Configuration
|
|
------------------
|
|
|
|
Webserver
|
|
~~~~~~~~~
|
|
|
|
LdapCherry uses the embedded http server of CherryPy, however it has some limitations:
|
|
|
|
* no listening on port 80/443 (unless run as root, which is strongly discourage)
|
|
* no https
|
|
|
|
The simpler way to properly deploy LdapCherry is to run it listening only on localhost
|
|
with a port above 1024 and put it behind an http server like nginx, apache or lighttpd
|
|
acting as a reverse http(s) proxy.
|
|
|
|
+---------------------+---------+------------------------------------+--------------------------+--------------------------------------------+
|
|
| Parameter | Section | Description | Values | Comment |
|
|
+=====================+=========+====================================+==========================+============================================+
|
|
| server.socket_host | global | Listening IP | IP on which to listen | Use '0.0.0.0' to listen on any interfaces. |
|
|
+---------------------+---------+------------------------------------+--------------------------+--------------------------------------------+
|
|
| server.socket_port | global | Listening Port | TCP Port | |
|
|
+---------------------+---------+------------------------------------+--------------------------+--------------------------------------------+
|
|
| server.thread_pool | global | Number of threads created | Number of threads | |
|
|
| | | by the CherryPy server | threads | |
|
|
+---------------------+---------+------------------------------------+--------------------------+--------------------------------------------+
|
|
| tools.staticdir.on | /static | Serve static files through | True, False | These files could be server directly by an |
|
|
| | | LdapCherry | | HTTP server for better performance. |
|
|
+---------------------+---------+------------------------------------+--------------------------+--------------------------------------------+
|
|
| tools.staticdir.dir | /static | Directory containing LdapCherry | Path to static resources | |
|
|
| | | static resources (js, css, img...) | | |
|
|
+---------------------+---------+------------------------------------+--------------------------+--------------------------------------------+
|
|
|
|
example:
|
|
|
|
.. sourcecode:: ini
|
|
|
|
[global]
|
|
|
|
# listing interface
|
|
server.socket_host = '127.0.0.1'
|
|
# port
|
|
server.socket_port = 8080
|
|
# number of threads
|
|
server.thread_pool = 8
|
|
|
|
# enable cherrypy static handling
|
|
# to comment if static content are handled otherwise
|
|
[/static]
|
|
tools.staticdir.on = True
|
|
tools.staticdir.dir = '/usr/share/ldapcherry/static/'
|
|
|
|
Backends
|
|
~~~~~~~~
|
|
|
|
Backends are configure in the **backends** section, the format is the following:
|
|
|
|
|
|
.. sourcecode:: ini
|
|
|
|
[backends]
|
|
|
|
# backend python module path
|
|
<backend id>.module = <python.module.path>
|
|
|
|
# display name of the backend in forms
|
|
<backend id>.display_name = <display name of the backend>
|
|
|
|
# parameters of the module instance for backend <backend id>.
|
|
<backend id>.<param> = <value>
|
|
|
|
It's possible to instanciate the same module several times.
|
|
|
|
Authentication and sessions
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
LdapCherry supports several authentication modes:
|
|
|
|
+------------------------+---------+---------------------+------------------------------------------------+---------------------------------+
|
|
| Parameter | Section | Description | Values | Comment |
|
|
+========================+=========+=====================+================================================+=================================+
|
|
| auth.mode | auth | Authentication mode | * 'and' (user must auth on all backends) | |
|
|
| | | | * 'or' (user must auth on one of the backends) | |
|
|
| | | | * 'none' (disable auth) | |
|
|
| | | | * 'custom' (use custom auth module) | |
|
|
+------------------------+---------+---------------------+------------------------------------------------+---------------------------------+
|
|
| auth.module | auth | Custom auth module | python class path to module | only used if auth.mode='custom' |
|
|
+------------------------+---------+---------------------+------------------------------------------------+---------------------------------+
|
|
| tools.sessions.timeout | global | Session timeout in | Number of minutes | |
|
|
| | | minutes | | |
|
|
+------------------------+---------+---------------------+------------------------------------------------+---------------------------------+
|
|
|
|
Different session backends can also be configured (see CherryPy documentation for details)
|
|
|
|
.. sourcecode:: ini
|
|
|
|
[global]
|
|
# session configuration
|
|
# activate session
|
|
tools.sessions.on = True
|
|
# session timeout in minutes
|
|
tools.sessions.timeout = 10
|
|
# file session storage(to use if multiple processes,
|
|
# default is in RAM and per process)
|
|
#tools.sessions.storage_type = "file"
|
|
# session
|
|
#tools.sessions.storage_path = "/var/lib/ldapcherry/sessions"
|
|
|
|
[auth]
|
|
# Auth mode
|
|
# * and: user must authenticate on all backends
|
|
# * or: user must authenticate on one of the backend
|
|
# * none: disable authentification
|
|
# * custom: custom authentification module (need auth.module param)
|
|
auth.mode = 'or'
|
|
|
|
# custom auth module to load
|
|
#auth.module = 'ldapcherry.auth.modNone'
|
|
|
|
Logging
|
|
~~~~~~~
|
|
|
|
LdapCherry has two loggers, one for errors and applicative actions (login, del/add, logout...) and one for access logs.
|
|
|
|
Each logger can be configured to log to **syslog**, **file**, **stdout** or be disabled.
|
|
|
|
Logging parameters:
|
|
|
|
+--------------------+---------+---------------------------------+-------------------------------------------------+----------------------------------------+
|
|
| Parameter | Section | Description | Values | Comment |
|
|
+====================+=========+=================================+=================================================+========================================+
|
|
| log.access_handler | global | Logger type for access log | 'syslog', 'file', 'stdout', 'none' | |
|
|
+--------------------+---------+---------------------------------+-------------------------------------------------+----------------------------------------+
|
|
| log.error_handler | global | Logger type for applicative log | 'syslog', 'file', 'stdout', 'none' | |
|
|
+--------------------+---------+---------------------------------+-------------------------------------------------+----------------------------------------+
|
|
| log.access_file | global | log file for access log | path to log file | only used if log.access_handler='file' |
|
|
+--------------------+---------+---------------------------------+-------------------------------------------------+----------------------------------------+
|
|
| log.error_file | global | log file for applicative log | path to log file | only used if log.error_handler='file' |
|
|
+--------------------+---------+---------------------------------+-------------------------------------------------+----------------------------------------+
|
|
| log.level | global | log level of LdapCherry | 'debug', 'info', 'warning', 'error', 'critical' | |
|
|
+--------------------+---------+---------------------------------+-------------------------------------------------+----------------------------------------+
|
|
|
|
Example:
|
|
|
|
.. sourcecode:: ini
|
|
|
|
[global]
|
|
|
|
# logger syslog for access log
|
|
log.access_handler = 'syslog'
|
|
# logger syslog for error and ldapcherry log
|
|
log.error_handler = 'syslog'
|
|
# log level
|
|
log.level = 'info'
|
|
|
|
|
|
.. warning::
|
|
|
|
'debug' should not be used in production.
|
|
|
|
It tends to log a lot.
|
|
More significantly can represent a security issue,
|
|
as things like passwords will be logged 'clear text'.
|
|
|
|
Custom javascript
|
|
~~~~~~~~~~~~~~~~~
|
|
|
|
It's possible to add custom javascript to LdapCherry, mainly to add custom autofill functions.
|
|
|
|
Configuration:
|
|
|
|
+---------------------+---------+--------------------------------+--------------------------+------------------------------------------------------------+
|
|
| Parameter | Section | Description | Values | Comment |
|
|
+=====================+=========+================================+==========================+============================================================+
|
|
| tools.staticdir.on | /custom | Serve custom js files through | True, False | These files could be server directly by an |
|
|
| | | LdapCherry | | HTTP server for better performance. |
|
|
+---------------------+---------+--------------------------------+--------------------------+------------------------------------------------------------+
|
|
| tools.staticdir.dir | /custom | Directory containing custom js | Path to static resources | * custom js files must be put at the root if the directory |
|
|
| | | files | | * only files ending with ".js" are taken into account |
|
|
+---------------------+---------+--------------------------------+--------------------------+------------------------------------------------------------+
|
|
|
|
|
|
Other LdapCherry parameters
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
+---------------+-----------+--------------------------------+------------------------+
|
|
| Parameter | Section | Description | Values |
|
|
+===============+===========+================================+========================+
|
|
| template_dir | resources | LdapCherry template directory | path to template dir |
|
|
+---------------+-----------+--------------------------------+------------------------+
|
|
|
|
.. sourcecode:: ini
|
|
|
|
# resources parameters
|
|
[resources]
|
|
# templates directory
|
|
template_dir = '/usr/share/ldapcherry/templates/'
|
|
|