Collaboration with Directory Service (opsi-directory-connector)
Introduction
The opsi directory connector transfers data from an LDAP directory service to an opsi installation. This way it is no longer necessary to manage data on multiple systems—the automatic synchronisation reduces the administration effort. Since the directory connector uses LDAP in the background, it works with Active Directory as well as with Samba 4.
Prerequisites
This module is a paid extension. This means that you need an activation file to unlock it. You will receive this file after you have purchased the extension. For evaluation purposes, we’re happy to provide you with a temporary license free of charge. Please contact us via email. |
General Requirements
-
The directory service on the machine serving as the source must implement the LDAP protocol.
-
The target system must run opsi 4.0.7 or later. Older versions may work; however, we have not tested this.
-
The machine running the directory connector must have network access to the machine running the directory service and to the opsi-Server.
You can run all components on the same machine. However, let’s assume for now that there are multiple machines involved. |
Installation
To install the Directory Connector, first add the opsi repository (see the chapter Server Installation, sections on Debian/Ubuntu, openSUSE/SLES, and ALMA/Rocky/RHEL). Next, install the package opsi-directory-connector
via the package manager of your distribution.
For example, on Debian-based systems, use this command:
apt-get install opsi-directory-connector
Configuration
The Directory Connector offers a wide range of settings to adapt it to very different environments. The configuration file /etc/opsi/opsidirectoryconnector-custom.conf
is in JSON format and must contain valid JSON (key-value pairs). For boolean values use true
or false
; text is enclosed in double quotes (e.g. "this is text"
).
Our package contains an example configuration. You can use the file /usr/share/opsi-directory-connector/opsi-directory-connector.example.conf as a template for your own configuration:
|
cp /usr/share/opsi-directory-connector/opsi-directory-connector.example.conf /etc/opsi/opsidirectoryconnector-custom.conf
Connection to the Directory Service (directory
)
In the directory
section you configure the connection to the directory service. Here you can also limit the search scope to certain areas and objects.
{
"directory": {
"address": "ldap://192.168.12.34",
"user": "DOMAIN\\opsiconnector",
"password": "insertpasswordhere",
"passwordFile": "",
"search_base": "dc=testcompany,dc=local",
"search_query_computers": "(objectClass=computer)",
"identifying_attribute": "dn",
"connection_options": {
"paged_search_limit": 768
}
},
…
}
Enter the address of the LDAP server after address
. If the protocol ldaps
or the port 636
is used, then the communication is SSL-encrypted:
"address": "192.168.12.34:636",
In addition, enter the username (user
) and password (password
) for authentication to the directory service.
To increase security, we recommend using a dedicated user account. |
Instead of a password, you can enter the path to a file containing the password after passwordFile
. The advantage is that the password is not stored in plain text in the configuration file. A password read from passwordFile
overwrites any values set for password
.
The format of the username depends on the directory service application in use and its configuration: Down-Level Logon Name: DOMAIN\username User Principal Name (UPN): user@domain Distinguished Name (DN): uid=opsiconnect,cn=users,dc=test,dc=intranet
|
Specify the point from which the connector looks for matching entries behind search_base
.
The filter used to search for clients can be configured via search_query_computers
.
From version 23, the optional key identifying_attribute
specifies which attribute should be used for the unique identification of a client. The default setting is dn
. A common alternative is distinguishedName
, which is mainly used in the Microsoft’s Active Directory.
The key connection_options
defines additional options for the connection. For example, you can determine via verify
whether or not the certificate is to be validated for an SSL connection. In addition, you can specify the path to a Certificate Authority (CA); enter the name of the file you want to use for verification here. If the connection is started via the unencrypted port 389, then start_tls
determines whether a secure connection is started after the login. By default, start_tls
is enabled for port 389, but the certificate is not checked.
If multiple queries are used to read the elements from the directory, then define the number behind the optional key paged_search_limit
. The value must be an integer. The feature has been supported since version 20.
Are you missing a connection option? If possible, we will implement further features on request. Please feel free to contact us via email. |
Since version 14 you can use the parameter --check-directory to test the connection to the directory without connecting to the opsi-Server.
|
Connection to Univention Corporate Server
For a connection to Univention Corporate Server (UCS), enter the Distinguished Name (DN) as the username. It has the following syntax:
uid=<username>,cn=users,dc=company,dc=mydomain
On UCS, LDAP is accessible via ports 7389 (unsecured) or 7636 (SSL-secured).
If Samba is also installed on the server and set up as an AD-compatible domain controller, it listens on ports 389 (unsecured) or 636 (SSL-secured).
To use the SSL-secured ports, set the start_tls
connection option to true
.
The two possible connections also differ as far as the login name is concerned:
-
LDAP:
uid=…
-
Samba:
dn=…
Normally, a search for computer objects takes place in the computers
container.
The following command prints the matching value for search_base
:
echo "cn=computers,$(ucr get ldap/base)"
To search for Windows clients, enter (objectClass=univentionWindows)
as the value for search_query_computers
.
The article Cool Solution - LDAP search user / simple authentication account in the Univention Knowledge Base explains how to create a user with read-only access. |
Behaviour Settings (behaviour
)
These settings control the behaviour of the Directory Connector:
{
…
"behaviour": {
"write_changes_to_opsi": true,
"root_dir_in_opsi": "clientdirectory",
"update_existing_clients": true,
"prefer_location_from_directory": true,
"group_handling": "dn",
"group_description": "dn",
"override_root_dir": true,
"delete_empty_groups": false,
"skip_adding_clients": false,
},
…
}
If you set write_changes_to_opsi
to false
, no data will be written to opsi. This is useful, for example, if you want to check the connection settings.
root_dir_in_opsi
specifies which group in opsi should be used as root group. Make sure that this group exists.
The management interface opsi-configed shows the group clientdirectory as DIRECTORY . So if clients or groups should appear directly below DIRECTORY , enter clientdirectory as the value for root_dir_in_opsi .
|
If you set update_existing_clients
to false
, then clients already existing in opsi will not be changed. If, on the other hand, this value is set to true
, then any manually set data will be overwritten with the values from the directory service.
If prefer_location_from_directory
is set to true
, clients in opsi will be moved to the position they have in the directory service. Set the value to false
to disable the behaviour.
Since version 31, the group handling is controlled by the optional key group_handling
.
The default setting is dn
. Groups are derived from the DN (Distinguished Name) of a computer and created accordingly as part of the opsi directory service. A client can only be a member of one single group.
If you activate delete_empty_groups
, then groups which are empty after synchronisation are also deleted from the opsi directory service. Only groups below root_dir_in_opsi
are considered in that case.
With skip_adding_clients
you skip the creation of clients in opsi completely. You can use this option, for example, in conjunction with prefer_location_from_directory
so that only existing clients are moved.
Settings for UCS@school
Set the key group_handling
to ucsatschool
to adapt the behaviour for UCS@school environments. The Directory Connector then automatically searches for schools and determines their rooms. Afterwards, the synchronisation with opsi takes place.
For each school a group is created in opsi. In UCS@school, however, a computer can be a member in more than one room. Therefore, the Directory Connector does not create the groups as a group in the opsi directory service, but as a normal group. In this way, a client can also be in multiple groups in opsi.
If the UCS@school groups are to be created in the opsi directory service after all, set the key override_root_dir
to false
. The key override_root_dir
is only available for "group_handling": "ucsatschool"
. The default value is true
.
If override_root_dir
is set to false
, then make sure that each school computer is only assigned to one room.
Via group_description
you can customise the description of the opsi groups. The following values are possible:
-
dn
: The distinguished name of the group will be stored in opsi as the group description. -
directory
: The group description is read from the fielddescription
of the directory service group. -
If the value is not set or is set differently, the name of the group is entered as the description.
…
"behaviour": {
"group_handling": "ucsatschool",
…
"group_not_in_directory": true,
"opsi_clients_to_ignore": {
"clients": ["win1.uib.local","win2.uib.local","win3.uib.local"],
"groups": ["server"]
}
}
…
If group_not_in_directory
is set to true
, then all clients which aren’t available in the directory service are added to the group not_in_directory
. This option is only available with the setting "group_handling": "uscatschool"
. With the parameter opsi_clients_to_ignore
you can exclude clients or whole groups from this rule.
A short description of all configuration options can also be found in the sample configuration file (/usr/share/opsi-directory-connector ).
|
Matching Attributes (mapping
)
Since a directory service is an extremely flexible system, the Directory Connector needs precise information about the attributes and which of them are to be matched to the attributes in opsi itself. For this reason there is a mapping for client attributes.
{
…
"mapping": {
"client": {
"id": "name",
"description": "description",
"notes": "",
"hardwareAddress": "",
"ipAddress": "",
"inventoryNumber": "",
"oneTimePassword": ""
}
},
…
}
The key is always the attribute in opsi, and the value is the attribute from the directory service. If the value is empty, no mapping takes place.
If the value read from the directory for the client ID is not recognisable as FQDN, a corresponding FQDN is created. The domain part is generated from the DC values of the element. |
On Univention Corporate Server (UCS), the value macAddress can be specified for hardwareAddress if the connection is established via LDAP (port 7389 or 7636).
|
Mapping clients and depots
In the mapping
section you can also define the mapping of clients to depots. Currently there is only one mapping type, network
.
A client is assigned to a depot if the IP address of the client matches the network address range (networkAddress
) of the depot.
Alternatively, you can also assign a list of network ranges to a depot: |
{
…
"mapping": {
…
"depot": {
"type": "network",
"test-depot1.test.local": ["192.168.24.0/24","192.168.25.0/24"],
"test-depot1.test.local": ["192.168.27.0/24","192.168.28.0/24"]
}
},
…
}
Manually assign Group Names
Group names are usually applied without modifications. However, it’s possible that you encounter group names which are invalid in opsi. In this case you can assign group names manually. This is possible from version 23.
To do this, define a subsection group_name
in the mapping
section. Now assign the names from the directory service to the names of the opsi environment. Always use lowercase letters for the group names. The following example assigns the opsi group server
to the group _server
from the directory service:
{
…
"mapping": {
"client": {
…
},
"group_name": {
"_server": "server"
}
},
…
}
Please be careful when assigning the names manually, as this may have undesired side effects. Therefore, use this mapping option only in exceptional cases! |
Connection to opsi (opsi
)
In the opsi
section you define how the Directory Connector connects to opsi.
{
…
"opsi": {
"address": "https://localhost:4447",
"username": "syncuser",
"password": "secret",
"exit_on_error": false,
"passwordFile": "",
"connection_options": {
"verify_certificate": true
}
}
}
The opsi-Server address is specified after address
. Don’t forget to enter the port!
A proxy server for the connection can be set via the environment variable HTTPS_PROXY .
|
The two keys username
and password
contain the credentials for authentication at opsi-Server. Instead of a password, you can enter the path to a file containing the password after passwordFile
. The advantage is that the password is not stored in plain text in the configuration file. A password read from passwordFile
overwrites any values set for password
.
To increase security, we recommend using a dedicated user account. |
If the key exit_on_error
is set to true
, then problems updating the data in opsi will cause the connection to be terminated. This happens, for example, when invalid values are transmitted. On the other hand, if this is set to false
, errors are logged, but the connection stays open.
Specify options for the connection to the opsi-Server under connection_options
. Enable the verify_certificate
setting to validate the server certificate. This value should be set to false
when using self-signed certificates.
Since version 14 it is possible to test the connection to the opsi-Server via the parameter --check-opsi without establishing a connection to the directory service.
|
Running the Dierectory Connector
The installation package contains the binary opsi-directory-connector
. It expects the path to the configuration file after the --config
switch:
opsi-directory-connector --config /etc/opsi/opsi-directory-connector-custom.conf
The user running the command does not need access to the opsi system because the credentials are stored in the configuration file. |
The Directory Connector synchronises the data every time it runs. To set up a regular synchronisation, you can either use systemd or create a cronjob. The next two sections show how to set this up.
Recurring Synchronisation: how to set up systemd Units
We recommend setting up systemd units because, unlike cronjobs, systemd prevents simultaneous runs. The example shown here executes the Directory Connector five minutes after a machine has started. After that, it runs regularly every hour.
To do this, set up two user-defined systemd units in the /etc/systemd/system/
directory, a timer
unit and a service
unit.
Timer
Unit
The Timer
unit defines the recurring execution of the job; the file /etc/system/system/opsi-directory-connector.timer
has the following content:
[Unit]
Description=Start the opsi-directory-connector in regular intervals
[Timer]
OnBootSec=5min
OnUnitActiveSec=1hour
[Install]
WantedBy=timers.target
Recurring Synchronisation: how to set up a Cronjob
As an alternative to the two systemd units, you can automate the regular synchronisation with the Directory Connector via a cronjob.
Select the synchronisation interval so that no simultaneous synchronisation can run. Alternatively, use systemd as shown in the previous section. |
Call the command crontab -e
to create a new crontab or edit an existing one. The crontab contains information about the executable program. You also define when and how often a cronjob should run. In our example, we add the following line:
0 * * * * /usr/bin/opsidirectoryconnector --config /etc/opsi/opsidirectoryconnector-custom.conf
In this case, synchronisation always takes place on the hour. The first field defines minute 0
; all other fields (hour, day, month, and weekday) contain *
as a placeholder.
Command Line Arguments
The Directory Connector supports the following parameters and options:
Usage: __main__.py [-h] [--version] [--log-level {0,1,2,3,4,5,6,7,8,9}]
[--log-level-stderr {0,1,2,3,4,5,6,7,8,9}]
[--log-level-file {0,1,2,3,4,5,6,7,8,9}]
[--log-file LOG_FILE]
[--max-log-size MAX_LOG_SIZE]
[--keep-rotated-logs KEEP_ROTATED_LOGS]
[--check-directory | --check-opsi | --delete-clients DELETE_CLIENTS [DELETE_CLIENTS …]]
[--dry-run] --config
CONFIG
If an arg is specified in more than one place, then command line values override environment
variables which override defaults.
optional arguments:
-h, --help
show this help message and exit
--version
show program's version number and exit
--log-level {0,1,2,3,4,5,6,7,8,9}
Sets how much information will be logged. [env var: OPDC_LOG_LEVEL]
(default: 4)
--log-level-stderr {0,1,2,3,4,5,6,7,8,9}, -l {0,1,2,3,4,5,6,7,8,9}
Sets how much information will be logged. [env var:
ODC_LOG_LEVEL_STDERR] (default: 4)
--log-level-file {0,1,2,3,4,5,6,7,8,9}
Sets how much information will be logged to the log file. [env var:
ODC_LOG_LEVEL_FILE] (default: 5)
--log-file LOG_FILE
Sets log file path. [env var: ODC_LOG_FILE] (default:
/var/log/opsi/directory-connector.log)
--max-log-size MAX_LOG_SIZE
Limit the size of logfiles to SIZE megabytes.Setting this to 0 will
disable any limiting. [env var: ODC_MAX_LOG_SIZE] (default: 5.0)
--keep-rotated-logs KEEP_ROTATED_LOGS
Number of rotated log files to keep. [env var: ODC_KEEP_ROTATED_LOGS]
(default: 1)
--check-directory
Check if a connection to the directory can be established and if items
will be received. (default: False)
--check-opsi
Check if a connection to the opsi server can be established. (default:
False)
--delete-clients DELETE_CLIENTS [DELETE_CLIENTS …]
Delete list of clients from directory. (default: None)
--dry-run
Print what would be done. (default: False)
--config CONFIG
Path to the config. (default: None)
From version 39, the Directory Connector uses the opsi logger (log level 0 to 9). By default, the tool logs to /var/log/opsi-directory-connector
and writes errors to stderr
. To influence the log level for the two logs, use the parameters --log-level-stderr
or --log-level-file
. The switch --log-file
defines a different logfile.
By default, the logfile is rotated when it reaches 5 MB, and one of the rotated logs is kept at a time. The parameters --max-log-size
and --keep-rotated-logs
override these default values.
In addition to the command line parameters, you can also set some of the values as keys in the configuration file or via environment variables. The following order applies: |
-
Parameters overwrite everything.
-
Environment variables overwrite the configuration file and the default values.
-
The configuration file overwrites the default values.
Example configuration:
{
…
"log-level-stderr": 6,
"log-level-file": 3,
"keep-rotated-logs": 4
…
}
Test Run (--dry-run
)
You can call opsi-directory-connector
with the parameter --dry-run
to start a test run. You will see the individual steps in the output; changes in opsi will not be made:
---------- opsi actions ----------
Creating client client1.opsidc.intranet.
Creating client ds-win-client-2.opsidc.intranet.
Creating client ds-win-client-1.opsidc.intranet.
Creating client mac-client-1.opsidc.intranet.
Creating client windows-client-1.opsidc.intranet.
Creating client raspberrypi-1.opsidc.intranet.
Adding mac-client-1.opsidc.intranet to opsitestschool-mac pool.
Adding windows-client-1.opsidc.intranet to opsitestschool-pc pool og1.
Adding ds-win-client-2.opsidc.intranet to depotschule-pool-1.
Adding ds-win-client-1.opsidc.intranet to depotschule-pool-1.
----------------------------------
---------- summary ---------------
Create 6 clients and 0 groups.
0 clients removed from group.
Adding 4 clients to a new group.
----------------------------------
Unlike the setting "write_changes_to_opsi": false
, which does not write any data to opsi, the switch --dry-run
adjusts the output. This gives a better overview of the actions.
Deleting Clients from the Directory
By default, the Directory Connector has read-only access to the directory. If you call the program with the parameter --delete-clients
, an independent run starts which tries to delete the given objects from the directory:
opsi-directory-connector --config config.conf --delete-clients client1
In this case, the Directory Connector searches for objects with cn=client1
in the defined search area. If there is a single hit, then the object is deleted. If, however, the program finds several matching objects, then it prints an error message and does not delete anything.
You can specify the objects to be deleted even more precisely:
opsi-directory-connector --config config.conf --delete-clients computers/test-clients/client1
The object cn=client1,ou=test-clients,ou=computers,dc=example,dc=org
would be a hit and deleted, but cn=client1,ou=clients,ou=computers,dc=example,dc=org
would not.
You can also specify multiple clients:
opsi-directory-connector --config config.conf --delete-clients computers/clients/client1 client2 client3
Always use the parameter --delete-clients with caution! For safety, you can combine the switch with --dry-run and check beforehand whether the correct objects are found.
|