Configure an LDAP identity provider and automate group synchronization between OpenShift OAuth and an LDAP server.
After the installation of a new Red Hat OpenShift Container Platform (RHOCP) cluster, only a kubeadmin user exists.
A cluster administrator must next create users and groups, or more commonly, integrate a business system that both provides these entities and manages authentication.
In doing so, an OpenShift cluster adopts a consistent corporate network authentication approach with other business systems, and inherits the existing security implementations in place, such as the company access restrictions that are available through a VPN-based connection.
Integrating an existing authentication method, and available users and groups in your organization, by using a Lightweight Directory Access Protocol (LDAP) server, is a common approach for many businesses. An LDAP directory server defines a standard application protocol for querying the system to authenticate users and groups. Additionally, LDAP integrations enable the use of Red Hat Identity Management (IdM) and Microsoft Active Directory (AD) services that many organizations use for managing authentication.
An LDAP server can be configured as an Identity Provider (IdP) for authentication bindings between the LDAP identity entries and cluster users through the OpenShift OAuth server. When users enter credentials for the cluster, the OAuth server initiates a connection and a corresponding query to the LDAP server, and creates bindings when matching unique entries are found.
Although this implementation is sufficient for authenticating the user, it is still necessary to define the access for the user, based on group memberships and roles. Furthermore, configuration within the OpenShift cluster is required to synchronize groups from the LDAP database, as well as to define the appropriate access and permissions for each group.
This section does not cover LDAP administration in depth, but only the necessary information for configuring LDAP integrations in an RHOCP cluster.
The LDAP protocol defines a query language to retrieve information from database entries of a remote LDAP server, which can contain entries for users and groups within the organization. When implemented as an OpenShift OAuth IdP, the cluster can rely on the LDAP server to validate user-provided login credentials for the cluster.
An LDAP URI exists and uses a standard syntax for connection parameters to an LDAP server, and is necessary when configuring client connections to an LDAP server.
To perform queries, the URI includes the search criteria to match with entries in the LDAP database.
Many LDAP servers also require the use of an administrative bind DN, which is a set of privileged credentials with access to perform queries.
This set of privileged credentials is included in the URI, when implemented.
A correctly formed search string describes the LDAP endpoint and the specific set of credentials, or a set of search criteria, such as user or group names, along with the bind Distinguished Name (bindDN) credentials when required for the interaction.
An LDAP URI is formed with the following standardized syntax:
ldap://host:port/basedn?attribute?scope?filter
The following table describes the components of the LDAP URI:
| URI object | Description |
|---|---|
ldap
| The LDAP protocol designation.
For LDAP over SSL, use the ldaps protocol.
Red Hat recommends using StartTLS over regular ldap. |
host:port
| The LDAP server name and listening port.
The default for ldap is localhost:389, and for ldaps is localhost:636. |
basedn
| The DN of the directory where a query begins. This directory is used as the root location for the search. |
attribute
| The target for the search, with the default as uid, which the LDAP lookup is intended to return.
Multiple attributes are provided by a comma-separated list. |
scope
| The scope of the LDAP lookup.
The scope is either one or sub.
The default is sub if unspecified. |
filter
| An LDAP filter refines the results for the query.
If omitted, the filter defaults to (objectClass=*). |
The following table provides an example set of information for an LDAP lookup for a specific username:
| URL object | Value |
|---|---|
| Connection protocol |
ldap
|
| Server name and port |
ldap.example.com:389
|
| Base DN |
cn=administrator,dc=example,dc=com
|
| Attribute |
users
|
| Query filter |
uid=payden.tomcheck
|
The preceding information would result in the following URL for an LDAP lookup:
ldap://ldap.example.com:389/cn=administrator,dc=example,dc=com?users?(uid=payden.tomcheck)
The result of this lookup returns one or more usernames from directory entries that match the given uid value in the LDAP server.
In an OpenShift cluster, when a new user provides login credentials for the cluster, the OAuth LDAP IdP searches for the identity by using the configured LDAP search account.
This LDAP search account is configured during the OAuth IdP configuration, and contains a Bind Distinguished Name (Bind DN) and a Bind Password.
On a unique match from the search, the provided credentials are submitted to the LDAP server in a second interaction, and an authentication binding is created between an OpenShift user resource and the returned LDAP id and preferredUsername values.
If an authentication request has no matching result, then the query fails and no bind occurs.
Whereas the LDAP server provides the validation to create an authentication binding for the identity, a cluster administrator must also grant appropriate cluster roles for the identity through the OpenShift Role Based Access Controls (RBAC) settings. A new user configuration is complete when the binding and role are in place.
An administrator must synchronize groups from an LDAP server as an additional cluster-side configuration before a full LDAP IdP configuration is complete. It is necessary to create a cluster cron job to routinely query the LDAP server and to update the OpenShift groups to ensure consistency within the cluster to any organizational updates to the LDAP group entries.
Although this course does not provide guidelines for LDAP administration, a tool is needed to inspect and validate available LDAP connectivity during cluster configuration.
The ldapsearch command is available from the openldap-clients RPM package, and provides a command-line query utility for LDAP interactions.
The following example illustrates the format for an LDAP query that uses the ldapsearch command:
[user@host ~]$ ldapsearch -x -D <bind_dn> -H <ldap_host_URI> -b <search_base> \
--filter <filter> --requestedAttribute <attributes> -WIn this example, the following parameters are used:
The -x option specifies using simple authentication.
The -W option prompts you to provide the bindPassword secret for the specific -D <bind_dn> option.
The -b <search_base> option denotes the root location for the lookup.
The --filter and --requestedAttribute options provide further criteria to refine the search.
This approach provides a method for testing credentials for the LDAP server from the CLI, as well as retrieving listings for various LDAP entries, such as any defined groups.
Although the previous example is too broad to provide meaningful results or detailed information, this approach establishes the validity of the credentials.
Specifying additional attributes and filters returns more specific information, such as refining the query to search for an account with uid=1001, as shown in the following example:
[user@host ~]$ ldapsearch -x -D "cn=administrator,dc=example,dc=com" \
-H ldap://ldap.example.com -b "uid=1001" -W "objectclass=account" uid
Enter Password:
# extended LDIF
#
# LDAPv3
# base <uid=1001> (default) with scope subtree
# filter: (objectclass=account)
# requesting: ALL
# example.com
dn: dc=example,dc=com
...output omitted...The options for ldapsearch queries, and their resulting output, are consistent with the needed information for the configuration of an LDAP server as an OAuth IdP.
The organizational units that describe the path to the correct location for an information lookup within the LDAP system are similar to the structure of directories and files within a file system.
The following example DN shows the uid, ou, and dc values for information within the LDAP server:
dn: uid=ptomchek,ou=users,dc=ocp4,dc=redhat,dc=com
The following commands illustrate a corresponding organizational structure for the same information within a file system:
[user@host ~]$ mkdir -p ocp4.redhat.com/users
[user@host ~]$ touch ocp4.redhat.com/users/ptomchek
[user@host ~]$ tree ocp4.redhat.com/
ocp4.redhat.com/
└── users
└── ptomchekFor more information about LDAP administration and the ldapsearch command, refer to the Red Hat Directory Server documentation at https://access.redhat.com/documentation/en-us/red_hat_directory_server/11/html-single/administration_guide/index#Examples-of-common-ldapsearches
Integrating an LDAP server as an IdP for an OpenShift cluster requires the following process:
Create an OpenShift secret resource to store the password for LDAP queries.
This OpenShift secret resource contains the base64-encoded secret in the bindPassword field.
Create an OpenShift configuration map resource that contains the certificate authority bundle (if the LDAP server uses encryption).
Create this configuration map resource only if your LDAP IdP has a CA certificate that is not present in the default system keystore.
This OpenShift ConfigMap resource belongs in the openshift-config namespace.
Update the CR to add the LDAP configuration to the existing OpenShift OAuth IdP entries.
Redeploy the IdP CR to the cluster with the added LDAP IdP.
The bindPassword for the IdP configuration is stored in an OpenShift secret resource.
The following example is a YAML file for creating the bindPassword secret for an LDAP IdP:
apiVersion: v1
kind: Secret
metadata:
name: ldap-secret
namespace: openshift-config
type: Opaque
data:
bindPassword: <base64_encoded_bind_password>
oc create secret generic ldap-secret \
--from-literal=bindPassword=<secret> -n openshift-configLDAP configurations for OAuth IdPs use an OpenShift configuration map resource in the openshift-config namespace to define the certificate authority bundles.
Create an OpenShift configuration map resource that contains the certificate authority.
You must store the certificate authority in the ca.crt key of the configuration map resource.
The following example is a YAML file that defines how to create a configuration map resource for the certificate bundle:
apiVersion: v1
kind: ConfigMap
metadata:
name: ca-config-map
namespace: openshift-config
data:
ca.crt: |
<CA_certificate_PEM>The following example shows the configuration for defining an LDAP IdP in the OAuth CR YAML file:
apiVersion: config.openshift.io/v1 kind: OAuth metadata: name: cluster spec: identityProviders: - name: ldapidpmappingMethod: claim
type: LDAP ldap: attributes: id:
- dn email:
- mail name:
- cn preferredUsername:
- uid bindDN: ""
bindPassword:
name: ldap-secret ca:
name: ca-config-map insecure: false
url: "ldaps://ldaps.example.com/ou=users,dc=acme,dc=com?uid"
Provider names are shown on the web console login screen and in the list of configured IdPs. | |
Controls how mappings are established between this provider's identities and user objects. | |
List of attributes where the first non-empty attribute is used. At least one attribute is required. If none of the listed attributes has a value, then authentication fails. | |
List of attributes to use as the email address. The first non-empty attribute is used. | |
List of attributes to use as the display name. The first non-empty attribute is used. | |
List of attributes to use as the preferred username when provisioning a user for this identity. The first non-empty attribute is used. | |
Required DN that is used during the search phase, unless anonymous searches are allowed.
Must be set if the | |
Required OpenShift secret resource that contains the bind password, unless anonymous searches are allowed.
Must be set if the | |
Optional: Reference to an OpenShift configuration map resource that contains the privacy enhanced mail (PEM) encoded certificate authority bundle to validate server certificates for the configured URL. Used only when the insecure option is false. | |
When true, no TLS connection is made to the server.
When false, | |
An RFC 2255 URL, which specifies the LDAP host and maps the identity parameters in the LDAP database schema.
This |
The OAuth CR contains all configured IdPs. Any additional IdP that is configured is appended to the CR. Replacing or removing any entries can result in the loss of access to your cluster.
After you update the OAuth CR, the new LDAP IdP is available to the cluster.
The IdP Name is shown among any other configured IdPs on the web console login page, as well as in the list of configured OAuth IdPs.
Log in with this added LDAP IdP by using the oc login command or the added selection from the OpenShift web console, and by providing a username and password that are available through the LDAP server.
During authentication, OpenShift generates a search filter by combining the attribute and filter in the configured OAuth CR url parameter, with the provided username.
Then, OpenShift applies this filter to the LDAP directory to find a unique entry.
From the preceding configuration example, if the user enters payden.tomcheck as a username, then a query for that value is sent to the LDAP server.
This query attempts to find a unique match in the uid LDAP field that the OAuth CR url value "ldaps://ldaps.example.com/ou=users,dc=acme,dc=com?uid" specifies.
If you configure the mappingMethod parameter for the LDAP IdP entry in the OAuth CR as claim or add, then OpenShift uses the resulting LDAP identity to create a cluster User resource on the first attempt to access the cluster.
Authentication fails if the LDAP lookup does not return a unique match. In this case, no binding is created, no user is added to the cluster, and access is denied.
Configuring an OAuth IdP for an LDAP server provides only a mechanism to validate and create users in the cluster, based on entries that are provided through the LDAP instance. Businesses also rely on LDAP to provide the groups that are used throughout the organization and to define appropriate RBAC configurations. By configuring LDAP group synchronization, a business can manage group memberships in a single location, and OpenShift can use these groups within the cluster.
OpenShift can synchronize groups from an LDAP server, which enables you to mirror the available LDAP groups within the cluster. LDAP group synchronization requires a sync configuration file with a client configuration and a query definition. Additionally, user-defined mappings can optionally provide granular details for establishing the custom relationships between group entries in the LDAP server and the corresponding OpenShift groups that you require.
Group synchronization requires a project where the pods run, a service account to perform the work, a cluster role where the right permissions are defined, and cluster role binding to associate the cluster role with the service account. When the synchronization configuration is in place, the synchronization of groups is automated by using a cron job to schedule the recurring execution of the synchronization task.
To synchronize LDAP groups, create an LDAPSyncConfig resource that contains the client LDAP configuration details and query definition for the LDAP group entities that are needed within OpenShift.
The LDAP client configuration part defines the connection parameters for the LDAP server, as well as the bindDN account and bindPassword secret for performing queries.
This configuration uses the same connection and credentials that are used during the OAuth LDAP IdP implementation.
The following YAML code is an example of LDAP client configuration details:
url: ldap://1.2.3.4:389 bindDN: cn=administrator,dc=example,dc=com bindPassword: <password> insecure: false ca: ca-bundle.crt
The LDAP query definition part describes the format of entries within the LDAP server that provide the groups to mirror to the OpenShift cluster.
The following YAML code is an example of an LDAP query definition:
baseDN: ou=groups,dc=example,dc=com scope: sub derefAliases: never timeout: 0 filter: (objectClass=group) pageSize: 0
By assembling the client configuration details together with the query definition, you can create an LDAPSyncConfig resource by using the parameters for your LDAP server:
kind: LDAPSyncConfig apiVersion: v1 url: ldap://example.com:389 insecure: falserfc2307: groupsQuery: baseDN: "ou=groups,dc=example,dc=com" scope: sub derefAliases: never pageSize: 0 groupUIDAttribute: dn
groupNameAttributes: [ cn ]
groupMembershipAttributes: [ member ] usersQuery: baseDN: "ou=users,dc=example,dc=com" scope: sub derefAliases: never pageSize: 0 userUIDAttribute: dn
userNameAttributes: [ mail ]
tolerateMemberNotFoundErrors: false tolerateMemberOutOfScopeErrors: false
When true, no TLS connection is made to the server.
When false, | |
The field that corresponds to the unique identifier field on the LDAP server for a group. | |
The attribute for the name of the group. | |
The field that corresponds the unique identifier field of the LDAP server for a user. | |
The attribute for the name of the user. |
Active Directory (AD) is another source for providing group definitions for an OpenShift cluster. The AD configuration requires an LDAP query definition and attributes to represent users within the OpenShift group definitions.
The following YAML code is an example LDAP synchronization configuration for an AD schema:
kind: LDAPSyncConfig
apiVersion: v1
url: ldap://ad.example.com:389
activeDirectory:
usersQuery:
baseDN: "ou=users,dc=example,dc=com"
scope: sub
derefAliases: never
filter: (objectclass=person)
pageSize: 0
userNameAttributes: [ mail ]
groupMembershipAttributes: [ memberOf ] 
The attribute to use as the username in the OpenShift group record. | |
The attribute on the user that stores the group membership information. |
Note the schema that AD uses to map users to the corresponding group membership through the memberOf attribute.
After the LDAPSyncConfig file is created, an administrator can use the file to synchronize groups from the LDAP server to the OpenShift cluster.
The following example command uses the oc adm groups sync command to synchronize all groups from the LDAP server to the cluster by using the config.yaml file that contains the LDAPSyncConfig details:
[user@host ~]$ oc adm groups sync --sync-config=config.yaml --confirmIf the --confirm parameter is omitted, then the command performs a dry run of the operation.
An initial dry run is advised when testing a new configuration, and to review the resulting groups that the cluster will inherit.
LDAP group synchronizations are automated through the use of a cron job. Configure this cron job from within a designated OpenShift project for this purpose. Execute the job by using a service account with administrative access to the cluster to manage groups.
Start by creating the project for the cron job to run.
The following command creates a project named ldap-group-sync for this purpose:
[user@host ~]$ oc new-project ldap-group-syncThe client bindPassword secret resource and the configuration map resource that are used during the configuration of the LDAP IdP are also needed for this task.
Additionally, create a service account with an appropriate cluster role and cluster role binding for the synchronization.
The following YAML code shows an example definition for creating a service account named ldap-group-sync-acct:
kind: ServiceAccount apiVersion: v1 metadata: name: ldap-group-sync-acct namespace: ldap-group-sync
Next, define a cluster role, as shown in the following example:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: ldap-group-sync-acct
rules:
- apiGroups:
- ''
- user.openshift.io
resources:
- groups
verbs:
- get
- list
- create
- updateThen, define a cluster role binding to bind the previous cluster role to the existing service account.
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: ldap-group-sync-acct
subjects:
- kind: ServiceAccount
name: ldap-group-sync-acct
namespace: ldap-group-sync
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ldap-group-sync-acctThe cluster is configured to communicate with the LDAP IdP, and a service account is available to configure OpenShift groups from the LDAP group entities. The following YAML code is an example configuration map file to specify the sync configuration:
kind: ConfigMap
apiVersion: v1
metadata:
name: ldap-group-sync-acct
namespace: ldap-group-sync
data:
sync.yaml: |
kind: LDAPSyncConfig
apiVersion: v1
url: ldaps://1.2.3.4:389
insecure: false
bindDN: cn=administrator,dc=example,dc=com
bindPassword:
file: "/etc/secrets/bindPassword"
ca: /etc/ldap-ca/ca.crt
rfc2307:
groupsQuery:
baseDN: "ou=groups,dc=example,dc=com"
scope: sub
filter: "(objectClass=groupOfMembers)"
derefAliases: never
pageSize: 0
groupUIDAttribute: dn
groupNameAttributes: [ cn ]
groupMembershipAttributes: [ member ]
usersQuery:
baseDN: "ou=users,dc=example,dc=com"
scope: sub
derefAliases: never
pageSize: 0
userUIDAttribute: dn
userNameAttributes: [ uid ]
tolerateMemberNotFoundErrors: false
tolerateMemberOutOfScopeErrors: falseFinally, define and deploy a cron job for the LDAP group synchronization. The following YAML code is an example cron job definition that could be customized, such as by adapting the cron-specified schedule to meet business needs:
kind: CronJob apiVersion: batch/v1 metadata: name: ldap-group-sync-acct namespace: ldap-group-sync spec: schedule: "*/30 * * * *"concurrencyPolicy: Forbid jobTemplate: spec: backoffLimit: 0 ttlSecondsAfterFinished: 1800
template: spec: containers: - name: ldap-group-sync image: "registry.redhat.io/openshift4/ose-cli:latest" command: - "/bin/bash" - "-c" - "oc adm groups sync --sync-config=/etc/config/sync.yaml --confirm"
volumeMounts: - mountPath: "/etc/config" name: "ldap-sync-volume" - mountPath: "/etc/secrets" name: "ldap-bind-password" - mountPath: "/etc/ldap-ca" name: "ldap-ca" volumes: - name: "ldap-sync-volume" configMap: name: "ldap-group-sync-acct" - name: "ldap-bind-password" secret: secretName: "ldap-secret"
- name: "ldap-ca" configMap: name: "ca-config-map" restartPolicy: "Never" terminationGracePeriodSeconds: 30 activeDeadlineSeconds: 500 dnsPolicy: "ClusterFirst" serviceAccountName: "ldap-group-sync-acct"
The defined schedule for the job in | |
The time, in seconds, to keep completed sync information, to correspond to the preceding cron schedule | |
The LDAP group sync command to execute by using the sync configuration file that is defined in the configuration map | |
The LDAP IdP |
After the file is created, the configured cron job executes the group synchronization command during the specified schedule to ensure that consistent group configurations that are available from the LDAP IdP are added to the OpenShift cluster.
This job runs within the project namespace, by using the service account, at an interval that the cron time spec defines in the CronJob definition.
For more information about integrating LDAP IdP for a RHOCP cluster, refer to the Configuring LDAP Identity Providers section in the Authentication and Authorization chapter in the Red Hat OpenShift Container Platform 4.14 OpenShift Container Platform documentation at https://access.redhat.com/documentation/en-us/openshift_container_platform/4.14/html-single/authentication_and_authorization/index#configuring-ldap-identity-provider