Syncing Groups and Users from LDAP/AD using 'mi-ldap-usersync' script
Note: mi-ldap-usersync script needs to be executed from the web
container.
Note: Beginning v6.4.3 User Group membership assignment on initial login is controlled by the System Variable INITIAL_USER_LOGIN_EXTERNAL_SYNC. The two available options are:
- LDAP: References LDAP / Active Directory to identify the User’s Groups and assigns the User to corresponding Groups in Metric Insights.
- Custom Script: Assigns Group membership based on a User Access Dataset tied to a Custom Script.
In addition to configuring LDAP/AD authentication in Metric Insights, you can also sync LDAP/AD groups and users by using the following script:
/opt/mi/bin/mi-ldap-usersync
The script is built to sync groups first - and therefore the users in those groups - versus syncing users first. General script logic is as follows:
- Group: Groups are added to Metric Insights and any users in that group can also be added. Groups created in Metric Insights will be named as they are in the LDAP/AD server. The mapping is 1:1.
- Users: If a user in a group that is being synced does not yet exist in Metric Insights, the user will be created in MI (if so desired)
-
Default user settings for new users: The type of a user created in MI with mi-ldap-usersync script is specified by the
--user-type
parameter; if this parameter is not provided, the created user is a regular user with no default settings. Only informational data for the user's profile (user ID, email address, first name, last name) is set, along with group membership.
As an example, if you're syncing all users from an LDAP/AD group called 'SomeADGroup', mi-ldap-usersync will create a corresponding group called 'SomeADGroup' in Metric Insights. Then, for each user in the LDAP/AD group, mi-ldap-usersync will create a corresponding MI user and make sure the MI user is in the MI group called 'SomeADGroup'.
Subsequent syncs will continue to sync the group and the users in that group as well as adding (if so desired) any new users in that same LDAP/AD group.
Here's what covered in this article:
Provision vs Deprovision
The 'mi-ldap-usersync' script is governed by 2 basic commands: provision and deprovision. Provision creates while deprovision disables / removes users from Metric Insights. Note, you must be careful with deprovisioning users as any inadvertent removals will reassign all of their content. Our general recommendation is provision frequently and deprovision infrequently.
Provisioning Groups and Users
As stated above, provisioning is the action of creating and syncing LDAP/AD groups and users in Metric Insights. Using the mi-ldap-usersync script, here's an example of a very basic provisioning command:
mi-ldap-usersync provision CN=some_group,OU=groups,OU=business_org,DC=global,DC=myorg,DC=com --ldap-host="ldaps://ldap.internal.myorg.com" --ldap-user="cn=miadmin,cn=users,dc=global,dc=myorg,dc=com" --ldap-pass="password" --verbose
Note that in order provision the group named 'some_group' we need a few bits of information, namely the group's full DN, the LDAP server URL, the LDAP user to query with, and the LDAP user's password. Notice the following abbreviations used in both the group and user names (standard LDAP terminology):
- CN (Common Name)
- OU (Organizational Unit)
- DC (Domain Component)
- DN (Distinguished Name)
Like a 'tree', these abbreviations are used to define the structure of groups and users, or the full DN (Distinguished Name). In the example above, notice the group name is as follows:
- CN = some_group
- OU = groups
- OU = business_org
- DC = global
- DC = myorg
- DC = com
Using the 'tree' analogy here, we see that myorg.com serves as the root, with subsequent branches defining the organizational unit, groups list, and group name.
We see the same for the LDAP user 'miadmin' and it's full DN:
- CN = miadmin
- CN = users
- DC = global
- DC = myorg
- DC = com
Now that we have a basic understanding of what's required to run mi-ldap-usersync provision, here's a more complex example of a provisioning command where mi-ldap-usersync is run from inside a shell script:
#!/bin/bash
groups="$(cat /opt/mi/scripts/LDAPGroupsToSync.txt)"
host=ldaps://global.myorg.com
ldap_user=cn=miadmin,cn=users,dc=global,dc=myorg,dc=com
ldap_pass="$(cat /opt/mi/custom/pwd.txt)"
echo "MI LDAP sync starting..."
echo $(date '+%Y %b %d %H:%M') running on: $HOSTNAME
echo " "
echo "Group sync starting..."
/opt/mi/bin/mi-ldap-usersync
provision $groups -H $host --username-attr sAMAccountName --first-name-attr givenName --last-name-attr sn --email-attr userPrincipalName --auto-create groups --ldap-user $ldap_user --ldap-pass $ldap_pass --base-dn='OU=groups,DC=business_org,DC=global,DC=myorg,DC=com' --full-summary
echo "Group sync completed successfully..."
Notice we've created variables for the groups list file, the LDAP server, the LDAP user, and LDAP user password. Then, before the provisioning command is run, we echo a simple message to help with identifying when the provisioning action starts (if you wish to write the shell script to some log file for tracking).
The actual provisioning command points to the groups list file (variable $groups) and is set to "auto create groups but add only existing users" (--auto-create groups). It's also pointing to the base DN where we would find the groups listed in the groups list file (--base-dn). Without defining the base DN, mi-ldap-usersync is unable to pull back group information.
Next, see a variation of the script above where, instead of syncing groups listed in some text file, we are instead bringing in groups that are filtered for a specific prefix.
#!/bin/bash
host=ldaps://global.myorg.com
ldap_user=cn=miadmin,cn=users,dc=global,dc=myorg,dc=com
ldap_pass="$(cat /opt/mi/custom/pwd.txt)"
echo "MI LDAP sync starting..."
echo $(date '+%Y %b %d %H:%M') running on: $HOSTNAME
echo " "
echo "GRP_* group sync starting..."
/opt/mi/bin/mi-ldap-usersync
provision -H $host --username-attr sAMAccountName --first-name-attr givenName --last-name-attr sn --email-attr userPrincipalName --auto-create groups --ldap-user $ldap_user --ldap-pass $ldap_pass --base-dn='OU=groups,DC=business_org,DC=global,DC=myorg,DC=com' --chunk-by-alphabet-attr "CN" --chunk-by-alphabet-prefix "GRP_" --full-summary
echo "GRP_* group sync completed successfully..."
Notice here that we are syncing for groups that start with GRP_ (--chunk-by-alphabet-prefix). To lessen the query load on the LDAP/AD server, we're also querying in chunks by applying an alphabetical filter to the group prefix attribute (--chunk-by-alphabet-attr).
In short, using the available parameters with mi-ldap-usersync provision, you can get quite creative on how you sync groups and users in Metric Insights.
mi-ldap-usersync provision parameters (-h)
Deprovisioning Groups and Users
By default, the deprovision command only disables user accounts rather than deleting them. To remove user accounts from the database completely, make sure to use the --delete parameter.
Example:
mi-ldap-usersync deprovision CN=some_group,OU=business_group,DC=global,DC=myorg,DC=com objectClass=person --verbose --ldap-host="ldaps://ldap.internal.myorg.com" --ldap-user="cn=miadmin,cn=users,dc=global,dc=myorg,dc=com" --ldap-pass="password" --delete-orphan-groups --delete-empty-groups --delete
When a user is deleted via ldap-usersync, the system re-assigns Categories and Notification Schedules to Admin with the lowest ID number to make sure content does not get lost.
mi-ldap-usersync deprovision parameters (-h)
Using standard LDAP search filters to sync for specific Groups and Users
If you want to filter for certain groups and users, use standard LDAP search parameters. Here are some examples:
- User filter: (&(objectClass=user)(sAMAccountName=%s))
- where %s is the username you want to filter for
- Filter that verifies a user is NOT in a group being synced: (&(objectClass=user)(sAMAccountName=%s)(!memberOf=cn=GroupName,...))
- If you want to sync for users in specific groups, you use use the same example above but without the the logical NOT operation (!):
- (&(objectClass=user)(sAMAccountName=%s)(memberOf=cn=GroupName,...))
For more information, please see LDAP query basics.
Running mi-ldap-usersync on a Schedule
For Metric Insights version 6.1+
For Simple Installs (single server)
The best method is to create a cron job on the host server, similar to the cron job for version 5.x (see below). The only difference is the addition of an additional command to execute the job through the Web container (where mi-ldap-usersync lives).
Contents of /etc/cron.d/ldap-sync
:
SHELL=/bin/bash
05 1 * * * root /opt/mi/bin/ldap_usersync_script.sh &> /tmp/mi-ldap-usersync.log
Contents of /opt/mi/bin/ldap_usersync_script.sh
:
#!/bin/bash
groups="$(cat /opt/mi/data/custom/scripts/LDAPGroupsToSync.txt)"
host=ldaps://global.myorg.com
ldap_user=cn=miadmin,cn=users,dc=global,dc=myorg,dc=com
ldap_pass="$(cat /opt/mi/data/custom/pwd.txt)"
/opt/mi/bin/mi-control exec -T web /opt/mi/bin/mi-ldap-usersync provision \
--ldap-host $host \
--ldap-user $ldap_user \
--ldap-pass $ldap_pass \
--base-dn='OU=groups,DC=business_org,DC=global,DC=myorg,DC=com' \
--full-summary \
--auto-create groups \
$groups \
--username-attr sAMAccountName \
--first-name-attr givenName \
--last-name-attr sn
--email-attr userPrincipalName \
-v
Few things to note here:
- The variables are pointing to text files stored on the host (not inside the Web container)
- Familiarize yourself with the --auto-create parameter. In the example above, it's set to "auto create groups but add only existing users" (--auto-create groups).
-
The utility used to execute the mi-ldap-usersync provision command is
/etc/mi/bin/mi-control
. Running/opt/mi/bin/mi-control exec -T web
means execute the following command inside the Web container. Our mi-control utility is a wrapper for docker-compose.
For Amazon ECS
Use the ECS Scheduler to run your shell script. The shell script must live on an EFS mounted volume like /opt/mi/data/custom/script. For more information, please see: https://docs.aws.amazon.com/AmazonECS/latest/userguide/scheduled_tasks.html
For Kubernetes
For Kubernetes, use the K8 CronJob service. You will have to create a yaml file for the mi-ldap-usersync job + a .spec section to set the schedule. For more information, please see: https://kubernetes.io/docs/tasks/job/automated-tasks-with-cron-jobs/
For Metric Insights version 5.x
To run mi-ldap-usersync on a schedule, the best method is to create a shell script to save your usersync command with a list of groups you want to sync. Then, schedule the running of that shell script using cron on the Metric Insights application server.
Create the cron job and save it to /etc/cron.d/ on the application server. Running the usersync overnight is best. You can run it more frequently as well as long as the job does not conflict with data collections, distributions, and active users.
Here's an example of a cron job (/etc/cron.d/ldap-sync
) that runs a shell script (saved to /opt/mi/bin
) with your stored mi-ldap-usersync command. Notice the job's output is being saved to a log file named mi-ldap-usersync.log (for post run review) and the job is set to run at 1:05 am, daily:
SHELL=/bin/bash
05 1 * * * root /opt/mi/bin/ldap_usersync_script.sh &> /tmp/mi-ldap-usersync.log