Set up kerberos to use OpenLdap as backend¶
kerberos can store user login and password. But often we already have OpenLDAP set up for other things,
such as storing users and groups, adding the Kerberos attributes can be beneficial, providing an integrated story.
-
Pros:
- OpenLDAP replication is faster and more robust than the native Kerberos one, based on a cron job
- Single source for user account management(e.g. pwd, groups, etc.)
-
Cons: - Setting up the LDAP backend isn’t a trivial task and shouldn’t be attempted by administrators without prior knowledge of OpenLDAP. - since krb5kdc is single-threaded there may be
higher latency in servicing requestswhen using the OpenLDAP backend
Prerequisite¶
Here, we suppose you already have - openldap server - kerberos server(e.g. kdc, admin-server)
For the openldap server, we suppose - the base cn: dc=casd,dc=local - the admin account: cn=admin,dc=casd,dc=local
1. Configure Openldap to work with Kerberos¶
We need to install the below packages
sudo apt install krb5-kdc-ldap krb5-admin-server
- krb5-kdc-ldap: This package provides the LDAP backend plugin for the Kerberos Key Distribution Center (KDC). It allows Kerberos to use OpenLDAP or another LDAP server to store
- krb5-admin-server: This package provides the Kerberos admin service (kadmind), which allows administrators to manage the Kerberos database remotely.
1.1 Install kerberos schema in openldap server¶
Openldap needs a Kerberos schema to be able to store the necessary object classes and attributes that
allow LDAP to store Kerberos principals and related data, such as encryption keys, expiration dates, and policy information.
Kerberos provides an integrated ldap backend as a database if you are in this situation. You don't need this step.
After installing krb5-kdc-ldap, you should find the kerberos schema in /usr/share/doc/krb5-kdc-ldap/kerberos.schema.gz
# copy and unzip the schema
sudo cp /usr/share/doc/krb5-kdc-ldap/kerberos.schema.gz /etc/ldap/schema/
sudo gunzip /etc/ldap/schema/kerberos.schema.gz
# convert the schema into ldif format, then load the schema to ldap server
sudo apt install schema2ldif
sudo ldap-schema-manager -i kerberos.schema
# now you should see below output
# SASL/EXTERNAL authentication started
# SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
# SASL SSF: 0
# executing 'ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/kerberos.ldif'
# SASL/EXTERNAL authentication started
# SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
# SASL SSF: 0
# adding new entry "cn=kerberos,cn=schema,cn=config"
1.2 Optimize the backend db index of ldap server¶
With the new schema loaded, let’s index an attribute often used in searches:
$ sudo ldapmodify -Q -Y EXTERNAL -H ldapi:/// <<EOF
dn: olcDatabase={1}mdb,cn=config
add: olcDbIndex
olcDbIndex: krbPrincipalName eq,pres,sub
EOF
# output example
modifying entry "olcDatabase={1}mdb,cn=config"
1.3 Create kerberos service account in Openldap¶
As kerberos need to contact the Openldap server to perfrom operations, we need to create two service accounts:
- kdc-service: needs to have
read rights on the realm container, principal container and realm sub-trees. If disable_last_success and disable_lockout are not set, however, thenkdc-service needs write access to the Kerberos containerjust like the admin DN below. - kadmind-service: needs to have read and write rights on the realm container, principal container and realm sub-trees
You can use the below command to add the two service accounts.
# we use the admin account to run the add script
ldapadd -x -D cn=admin,dc=casd,dc=local -W <<EOF
dn: uid=kdc-service,dc=casd,dc=local
uid: kdc-service
objectClass: account
objectClass: simpleSecurityObject
userPassword: {CRYPT}x
description: Account used for the Kerberos KDC
dn: uid=kadmin-service,dc=casd,dc=local
uid: kadmin-service
objectClass: account
objectClass: simpleSecurityObject
userPassword: {CRYPT}x
description: Account used for the Kerberos Admin server
EOF
# you will be prompted to enter the password of the two accounts
Enter LDAP Password:
adding new entry "uid=kdc-service,dc=casd,dc=local"
adding new entry "uid=kadmin-service,dc=casd,dc=local"
You can always reset the password by using the below command
ldappasswd -x -D cn=admin,dc=casd,dc=local -W -S uid=kdc-service,dc=casd,dc=local
# you will be prompted to enter the password
New password:
Re-enter new password:
Enter LDAP Password:
You can test these accounts
ldapwhoami -x -D uid=kdc-service,dc=casd,dc=local -W
1.4 update the Access Control Lists (ACL) of Openldap server¶
This step can be tricky, as it highly depends on what you have defined already. By default, the slapd package configures your database with the following ACLs:
olcAccess: {0}to attrs=userPassword by self write by anonymous auth by * none
olcAccess: {1}to attrs=shadowLastChange by self write by * read
olcAccess: {2}to * by * read
We need to insert new rules before the final to * by * read one, to control access to the Kerberos related entries and attributes:
# add acl for krb service accounts
$ sudo ldapmodify -Q -Y EXTERNAL -H ldapi:/// <<EOF
dn: olcDatabase={1}mdb,cn=config
add: olcAccess
olcAccess: {2}to attrs=krbPrincipalKey
by anonymous auth
by dn.exact="uid=kdc-service,dc=casd,dc=local" read
by dn.exact="uid=kadmin-service,dc=casd,dc=local" write
by self write
by * none
-
add: olcAccess
olcAccess: {3}to dn.subtree="cn=kerberos,dc=casd,dc=local"
by dn.exact="uid=kdc-service,dc=casd,dc=local" read
by dn.exact="uid=kadmin-service,dc=casd,dc=local" write
by * none
EOF
# output example
modifying entry "olcDatabase={1}mdb,cn=config"
Here, we define the dn of kerberos container as
cn=kerberos,dc=casd,dc=local, all the entries related to kerberos which are generated automatically should be stored in the kerberos container.
After the modification, the existing {2} rule become {4}.:
$ sudo slapcat -b cn=config
# the output below was reformatted a bit for clarity
olcAccess: {0}to attrs=userPassword
by self write
by anonymous auth
by * none
olcAccess: {1}to attrs=shadowLastChange
by self write
by * read
olcAccess: {2}to attrs=krbPrincipalKey by anonymous auth
by dn.exact="uid=kdc-service,dc=casd,dc=local" read
by dn.exact="uid=kadmin-service,dc=casd,dc=local" write
by self write
by * none
olcAccess: {3}to dn.subtree="cn=kerberos,dc=casd,dc=local"
by dn.exact="uid=kdc-service,dc=casd,dc=local" read
by dn.exact="uid=kadmin-service,dc=casd,dc=local" write
by * none
olcAccess: {4}to * by * read
2. Configure kerberos to use openldap¶
2.1 Install or reconfigure kerberos¶
# to get a good starting point with /etc/krb5.conf, you can reconfigure kerberos
sudo dpkg-reconfigure krb5-config
2.2 Configure kerberos to use openldap as backend¶
Now edit /etc/krb5.conf by adding the database_module option to the CASD.LOCAL realm section:
[realms]
CASD.LOCAL = {
kdc = 10.50.5.57
admin_server = 10.50.5.57
default_domain = casd.local
database_module = openldap_ldapconf
}
database_module = openldap_ldapconf:
[dbdefaults]
ldap_kerberos_container_dn = cn=kerberos,dc=casd,dc=local
[dbmodules]
openldap_ldapconf = {
db_library = kldap
# if either of these is false, then the ldap_kdc_dn needs to
# have write access
disable_last_success = true
disable_lockout = true
# this object needs to have read rights on
# the realm container, principal container and realm sub-trees
ldap_kdc_dn = "uid=kdc-service,dc=casd,dc=local"
# this object needs to have read and write rights on
# the realm container, principal container and realm sub-trees
ldap_kadmind_dn = "uid=kadmin-service,dc=casd,dc=local"
ldap_service_password_file = /etc/krb5kdc/service.keyfile
ldap_servers = ldapi:///
ldap_conns_per_server = 5
}
2.3 Create the realm in openldap server¶
Use the kdb5_ldap_util utility to create the realm in openldap server
sudo kdb5_ldap_util -D cn=admin,dc=casd,dc=local create -subtrees dc=casd,dc=local -r CASD.LOCAL -s -H ldapi:///
# output example
Password for "cn=admin,dc=casd,dc=local":
Initializing database for realm 'CASD.LOCAL'
You will be prompted for the database Master Password.
It is important that you NOT FORGET this password.
Enter KDC database master key:
Re-enter KDC database master key to verify:
after this command, you should see
cn=CASD.LOCAL,cn=kerberos,dc=casd,dc=localin the openldap server.
2.4 Create a stash of the password used to bind to the LDAP server.¶
sudo kdb5_ldap_util -D cn=admin,dc=casd,dc=local stashsrvpw -f /etc/krb5kdc/service.keyfile uid=kdc-service,dc=casd,dc=local
sudo kdb5_ldap_util -D cn=admin,dc=casd,dc=local stashsrvpw -f /etc/krb5kdc/service.keyfile uid=kadmin-service,dc=casd,dc=local
sudo kdb5_ldap_util -D cn=admin,dc=casd,dc=local stashsrvpw -f /etc/krb5kdc/service.keyfile cn=admin,dc=casd,dc=local
The /etc/krb5kdc/service.keyfile file now contains clear text versions of the passwords used by the KDC to contact the LDAP server!
2.5 create acl file for admin server¶
$ sudo vim /etc/krb5kdc/kadm5.acl
# add the below line
*/admin@CASD.LOCAL *
# start or restart the krb services
sudo systemctl start krb5-kdc.service krb5-admin-server.service
2.6 Test the binding¶
Login to the krb admin
# login to admin server
sudo kadmin.local
# now you will have a krb admin server prompt, you can use the kerberos admin command now
# Below are some command examples, you can type ? to have all the command list
# list the existing principals(user account)
list_principals
# add new principals
addprinc test
The above command will create an
testprincipal with a DN of krbPrincipalName=test@CASD.LOCAL,cn=CASD.LOCAL,cn=krbContainer,dc=casd,dc=local.
2.7 Use the existing user account of openldap server¶
Let’s say, however, that you already have a user in your directory, and it’s in uid=pengfei,ou=people,dc=casd,dc=local. How can you add the Kerberos attributes to it? You use the -x parameter to specify the location. For the ldap_kadmin_dn to be able to write to it, we first need to update the ACLs:
sudo ldapmodify -Q -Y EXTERNAL -H ldapi:/// <<EOF
dn: olcDatabase={1}mdb,cn=config
add: olcAccess
olcAccess: {4}to dn.subtree=“ou=people,dc=casd,dc=local”
by dn.exact=”uid=kdc-service,dc=casd,dc=local” read
by dn.exact=”uid=kadmin-service,dc=casd,dc=local” write
by * break
EOF
Now you can create a principal which matches with an existing openldap user account. Suppose the dn of the user account
is uid=pengfei,ou=people,dc=casd,dc=local.
# login to admin server
sudo kadmin.local
# the kadmin-service must have write access on the target dn, otherwise you will get an Insufficient access error
addprinc -x dn=uid=pengfei,ou=people,dc=casd,dc=local pengfei/admin
addprinc -x dn=uid=test,ou=people,dc=casd,dc=local test
# you can check the details of a principal by
getprinc pengfei/admin
if the
dnexists,kadmin.localwill just add the required Kerberos attributes to this existing entry. If it didn’t exist,it would be created from scratch, with only the Kerberos attributes.
3. Test the principal via a kerberos client¶
Goto another server
# step1: install packages
sudo apt install krb5-user
# if it's the first time, you will see three prompt
# 1. enter default Realm: CASD.LOCAL
# 2. enter kdc url: kdc01.casd.local or 10.50.5.57
# 3. enter admin server url: kdc01.casd.local or 10.50.5.57
# if you already have the client, you can re-configure the krb client, you should see the three prompt.
sudo dpkg-reconfigure krb5-config
# After the prompt, the config file `/etc/krb5.conf` file for your Realm. You should have entries similar to the following:
[libdefaults]
default_realm = CASD.LOCAL
...
[realms]
CASD.LOCAL = {
kdc = 10.50.5.57
admin_server = 10.50.5.57
}
# step3: Test the configuration by requesting a ticket using the kinit utility
kinit pengfei/admin@CASD.LOCAL
# step4: setup a default principal
vim ~/.k5identity
pengfei/admin@CASD.LOCAL
4. GSSAPI for¶
The below olc_enable_gssapi.ldif enables GSSAPI authentication in the openldap server
dn: cn=config
changetype: modify
add: olcAuthzRegexp
olcAuthzRegexp: uid=([^,]+),cn=casd.local,cn=gssapi,cn=auth
uid=$1,ou=people,dc=casd,dc=local
-
#2. Configurer the domain SASL (Simple Authentication and Security Layer) of kerberos
add: olcSaslRealm
olcSaslRealm: CASD.LOCAL
$ldapmodify -QY EXTERNAL -H ldapi:/// -f olc_enable_gssapi.ldif
# login to admin server
sudo kadmin.local
# create a principal kerberos to connect to ldap
addprinc -randkey ldap/ldap.casd.local@CASD.LOCAL
# Update the Keytab: Export the principal to the keytab file so the LDAP server can use it:
ktadd -k /etc/krb5.keytab ldap/ldap.casd.local@CASD.LOCAL
ldapsearch -H ldap://ldap.casd.local -Y GSSAPI -b "dc=casd,dc=local"
ssh -o GSSAPIAuthentication=yes -o GSSAPIDelegateCredentials=yes test@10.50.5.92
bkp¶
sudo apt install krb5-pkinit libsasl2-modules-gssapi-mit
-
krb5-pkinit: This package enables
PKINIT (Public Key Cryptography for Initial Authentication)in Kerberos. PKINIT allows Kerberos authenticationusing X.509 certificates instead of passwords, which is useful for environments that requiresmart card loginorcertificate-based authentication. -
libsasl2-modules-gssapi-mit: This package provides the GSSAPI (Generic Security Services Application Program Interface) module for SASL (Simple Authentication and Security Layer) using the MIT Kerberos implementation.