In this article, I demonstrate a systematic method to configure LDAP user and group synchronization in Red Hat OpenShift, as well as OpenShift role-based access control (RBAC) for these LDAP users and groups. Following these steps makes the management of your LDAP users and groups within OpenShift much easier. I achieve this goal by demonstrating:
- How to validate your
ldap
parameters withldaptool
prior to installing OpenShift. - How to enable LDAP authentication in OpenShift for specific LDAP groups and organization units.
- The scripts and commands that let you synchronize members of your LDAP groups to OpenShift, which in turn lets you apply custom OpenShift RBAC rules on specific users or groups.
My assumptions
For the purpose of this article, I assume the following:
- You have a working LDAP service.
- The only two LDAP groups allowed to authenticate to your OpenShift environment are
ocp-cluster-admins
andocp-cluster-users
and are associated withou=OPENSHIFT
in your ldap tree. - You have assigned
ocp-cluster-admins
to userocpadminuser1
, andocp-cluster-users
to userocpuser1.
This article shows one of the many ways to configure LDAP for OpenShift. Because different users in ocp-cluster-users
will have different roles within your Red Hat OpenShift environment, this task can be automated or centrally managed, but that process will not be discussed in detail here.
Note that this article deliberately uses mixed cases (upper- and lowercase) in various sections to demonstrate case sensitivity within OpenShift versus LDAP. However, if you wish to minimize problems with OpenShift's case sensitivity, stick to lowercase for everything.
LDAP details
Identify all of your LDAP details prior to commencing your OpenShift installation. For this article, I use the following details:
ldap hostname: myldap.mydomain ldap bind dn: CN=OPENSHIFT-BU,ou=users,o=MyOrg ldap bind password: mypassword ldap ocp admins group DN: cn=ocp-cluster-admins,ou=OPENSHIFT,o=MyOrg ldap ocp users group DN: cn=ocp-cluster-users,ou=OPENSHIFT,o=MyOrg
Ideally, all your secret credentials should be managed via Red Hat Ansible Vault.
LDAP parameter and credential testing
For your tests to provide reliable results, confirm you have users in both groups. Before defining the OpenShift inventory parameters and the scripts used to synchronize ldap
groups, it is important to ensure all of your ldap
settings are correct, independent of OpenShift.
I tested my ldap
connection with the details mentioned in the previous section using ldapsearch
, and I also wanted to make sure that I could see the users in my groups, as this is what OpenShift will be seeing:
$ ldapsearch -x -LLL -D "CN=OPENSHIFT-BU,ou=users,o=MyOrg" -w mypassword -H ldap://myldap.mydomain:389 -b ou=users,o=MyOrg -s sub "(|(memberof=cn=ocp-cluster-admins,ou=OPENSHIFT,o=MyOrg)(memberof=cn=ocp-cluster-users,ou=OPENSHIFT,o=MyOrg))" "CN" dn: cn=ocp-cluster-admins,ou=OPENSHIFT,o=MyOrg CN: adminuser1 dn: cn=ocp-cluster-users,ou=OPENSHIFT,o=MyOrg CN: ocpuser1
After that, it is important to identify what ldap
fields are listed when you perform an ldap
search for one of your users (e.g., ocpuser1
):
$ ldapsearch -x -LLL -h myldap.mydomain -D "CN=OPENSHIFT-BU,ou=users,o=MyOrg" -w mypassword -b "ou=users,o=MyOrg" -s sub "cn=ocpuser1" dn: CN=ocpuser1,ou=users,o=MyOrg groupMembership: cn=ocp-cluster-users,ou=OPENSHIFT,o=MyOrg UID: myuid DESCRIPTION: OpenShift Cluster User 1 SN: ocpuser1 OBJECTCLASS: top OBJECTCLASS: person cn: ocpuser1
Note that these values can be different based on your LDAP schema and design. In this case, the attributes of interest are DN
, UID
, and CN
.
Red Hat OpenShift inventory parameters
Reference:
I personally find LDAP connection information in OpenShift inventories very confusing. Here, I deconstruct it for clarity (notice the "attributes" section below):
openshift_master_identity_providers=[ { 'name': 'myldap', 'challenge': 'true', 'login': 'true', 'kind': 'LDAPPasswordIdentityProvider', 'attributes': {'DN' : ['DN'], 'UID': ['UID'], 'CN': ['CN']}, 'bindDN': 'CN=OPENSHIFT-BU,ou=users,o=MyOrg', 'bindPassword': 'mypassword', 'ca': '', 'insecure': 'true', 'url': 'ldap://myldap.mydomain:389/ou=users,o=MyOrg?CN?? (| (memberof=cn=ocp-cluster-admins,ou=OPENSHIFT,o=MyOrg) (memberof=cn=ocp-cluster-users,ou=OPENSHIFT,o=MyOrg) )' } ]
Then, once I have all my details clear, I remove all of the new lines and unnecessary spaces. The code becomes:
openshift_master_identity_providers=[{'name': 'myldap', 'challenge': 'true', 'login': 'true', 'kind': 'LDAPPasswordIdentityProvider', 'attributes': {'DN' : ['DN'], 'UID': ['UID'], 'CN': ['CN']}, 'bindDN': 'CN=OPENSHIFT-BU,ou=users,o=MyOrg', 'bindPassword': 'mypassword', 'ca': '', 'insecure': 'true', 'url': 'ldap://myldap.mydomain:389/ou=users,o=MyOrg?CN??(|(memberof=cn=ocp-cluster-admins,ou=OPENSHIFT,o=MyOrg)(memberof=cn=ocp-cluster-users,ou=OPENSHIFT,o=MyOrg))'}]
If you wish to add htpasswd
authentication for contingency (for example, just to have a local admin user), include it as another identity provider. For example:
openshift_master_identity_providers=[{htpasswd fileds},{ldap fields}]
Red Hat OpenShift post-install configuration
Once installation completes, ldap
users in the groups identified earlier can authenticate to the master API (with the oc login
command) but will not have any access by default. If you want your users to have proper role based access, you will need to perform two steps. The first is synchronizing LDAP groups to OpenShift groups. This task needs to be done periodically, or every time a new user is added to ldap
(either via crontab
or a CI/CD pipeline). Doing so allows Red Hat OpenShift to see the LDAP groups and users as its own users.
Second, RBAC rules need to be granted to OpenShift groups or users, synchronized from ldap
. I demonstrate this manually, but ideally, you should automate this process.
Step 1: Synchronize ldap
groups
Reference:
Create the file /root/ldap_group_sync.yml
on your master node with the following content (the comments are not part of the file, but instead are there for elaboration):
# LDAP is case insensitive, but OpenShift is not, so all LDAP parameters have been converted to lower case as per https://access.redhat.com/solutions/3232051 (under "Case Sensitivity") kind: LDAPSyncConfig apiVersion: v1 url: ldap://myldapserver:389 insecure: true ca: "" bindDN: "cn=openshift-bu,ou=users,o=MyOrg" bindPassword: "mypassword" rfc2307: groupsQuery: baseDN: "ou=openshift,o=MyOrg" scope: sub filter: (|(cn=ocp-cluster-admins)(cn=ocp-cluster-users)) derefAliases: never timeout: 0 pageSize: 0 groupUIDAttribute: dn groupNameAttributes: [ cn ] groupMembershipAttributes: [ member ] usersQuery: basedn: "ou=users,o=MyOrg" scope: sub derefAliases: never pageSize: 0 userUIDAttribute: dn userNameAttributes: [ cn ] tolerateMemberNotFoundErrors: true tolerateMemberOutOfScopeErrors: true
Run a test:
[root@master ~]# oc adm groups sync --sync-config=/root/ldap_groups.yml apiVersion: v1 items: - apiVersion: user.openshift.io/v1 kind: Group metadata: annotations: openshift.io/ldap.sync-time: 2019-07-21T07:16:1101000 openshift.io/ldap.uid: cn=ocp-cluster-admins,OU=OPENSHIFT,o=MyOrg openshift.io/ldap.url: myldapserver:389 creationTimestamp: null labels: openshift.io/ldap.host: myldapserver name: ocp-cluster-admins users: - ocpadminuser1 - apiVersion: user.openshift.io/v1 kind: Group metadata: annotations: openshift.io/ldap.sync-time: 2019-07-21T07:16:1101000 openshift.io/ldap.uid: cn=ocp-cluster-users,OU=OPENSHIFT,o=MyOrg openshift.io/ldap.url: myldapserver:389 creationTimestamp: null labels: openshift.io/ldap.host: myldapserver name: ocp-cluster-users users: - ocpuser1 kind: List metadata: {}
If you get the following error, you can find the fix here:
For group ignoring member search for entry with dn would search outside of the base dn specified
If you run the command above, this will only be a dry run. To ensure it actually performs the user and group synchronization, add --confirm
to the end:
[root@master ~]# oc adm groups sync --sync-config=/root/ldap_groups.yml --confirm group/ocp-cluster-admins group/ocp-cluster-users
Now, check to see your groups:
# oc get groups NAME USERS ocp-cluster-admins ocpadminuser1 ocp-cluster-users ocpuser1
Step 2: Create custom OpenShift RBAC rules for synchronized LDAP users and groups
Ideally, you should automate and centrally manage this process. One of the many ways to automate the assignment of roles for all your different users would be via Red Hat Ansible. However, because we have only two users, doing this manually is not too painful. I want my ocp-cluster-admins
group to have the cluster-admin
role, and my ocp-cluster-users
to have the project edit role:
root@master ~]# oc adm policy add-cluster-role-to-group cluster-admin ocp-cluster-admins role "cluster-admin" added: "ocp-cluster-admins" [root@master ~]# oc adm policy add-role-to-group edit ocp-cluster-users role "edit" added: "ocp-cluster-users"
Conclusion
To ensure you have a relatively smooth experience with OpenShift RBAC for your LDAP groups and users, validate all your LDAP details with ldaptool
. Additionally, it is best to adopt the lower case for all your parameters (except passwords) to avoid future problems caused by differing case-sensitivity between systems (e.g., ldap
vs. OpenShift). Finally, automation of roles for different users is the best way forward.