V4/Kerberos principal aliases
Contents
Overview
According to RFC 6806 a single Kerberos principal may have one or more additional aliases referencing to the same set of Kerberos keys. The client can then use any of these alternative names as a principal name when sending authentication request to KDC, and KDC will use this name to look up the correct key associated with the client principal. Depending on whether the canonicalization was requested by the client, KDC will issue TGT containing either the principal alias sent in the authentication request, or the canonical form of the principal name which can be used by other services to make authorization decision based on the issued ticket. Moreover, when canonicalization is requested KDC will perform case-insensitive search for the client principal name eliminating the need to exactly match correct case of the principal name when performing authentication.
The combination of principal aliases and canonicalization machinery can be leveraged for a number of interesting uses, e.g. allowing users to log in to their workstations using e-mail address instead of assigned login ID (see the Use Cases section). However, FreeIPA is significantly lacking in the support of these use cases. First, the support for principal alias is implemented only for service principals using custom objectclass (ipaKrbPrincipal
) providing a 'single valued' ipaKrbPrincipalAlias
attribute with case insensitive matching rule defined. The multi-valued krbPrincipalName
is used to hold the canonical principal name and restricted to single value at the management framework level instead of using krbCanonicalName
. Thus it follows that, theoretically, services support a single principal alias, while hosts and users do not support them at all. Clearly a reimplementation of Kerberos principal handling is required at all layers of FreeIPA server architecture and this task is the subject of this document.
Use Cases
- as an administrator I want to assign multiple names to a machine in a cloud environment or behind a load balancer while still using Kerberos for authentication
- as an administrator I want to be able to assign different names to a Kerberized service running on a server enrolled in FreeIPA domain
- as a user I want be able to have my login changed while being able to use my old login name to authenticate against our corporate domain
- as an administrator I want my users to be able to authenticate against Kerberized applications using their e-mail addresses as login
Design
High Level Overview
This design document proposes the following scheme for handling the principal aliases in LDAP backend and management framework:
- each newly created entity (user, host, and service) will have
krbCanonicalName
attribute set upon creation krbPrincipalName
attribute value equal to the canonical principal name will be populated at the entity creation- renaming the entity will lead to change of
krbCanonicalName
and the corresponding value ofkrbCanonicalName
- in other cases the canonical principal name will be treated as immutable and no interface to change its value will be provided
- an API will be provided to add and remove aliases to
krbPrincipalName
attribute will be provided - during manipulation of principal aliases at least one value will be present at the entry and its value must be equal to that of the canonical principal name
To reflect these changes, the client principal lookup during AS_REQ processing will be updated according to the workflow displayed below.
Note, however, that the alias handling when canonicalization is not requested is currently subject to discussion and further research. According to Section 6 of RFC 6806 the KDC may include the list of principal aliases in the reply using AD-LOGIN-ALIAS element. This behavior is currently not supported by IPA KDB driver and would require additional effort to implement it. Also note that MIT Kerberos KDC does not support authentication with an alias without canonicalization set to on (see the following test case).
During TGS request processing the service principals will be always matched case-insensitively so that the interoperability with implementations that use case-insensitive principals (such as AD) is preserved.
The following sections describe in greater details steps that need to be done in order to implement the above design considerations.
LDAP Schema
The ipaKrbPrincipal
object class and ipaKrbPrincipalAlias
will be marked as deprecated and not used by new FreeIPA installations. To maintain backwards compatibility with older masters/clients, the attributes will be kept on existing entries, but they will be not added to newly created Kerberos principals. krbPrincipalName
attribute (provided by krbPrincipalAux
object class) will now contain the list of principal aliases for given entry, while krbCanonicalName
(provided by the same objectclass) will hold the value of canonical name. These attributes will be populated either by FreeIPA's KDB DAL driver or by the management framework depending on the point of origin of the new entry.
LDAP backend configuration
krbPrincipalName
attribute uses caseExactIA5Match
matching rule (OID 1.3.6.1.4.1.1466.109.114.1) by default. Since the KDB is expected to perform case insensitive principal name lookup when canonicalization is requested, the krbPrincipalName
index will be extended to use also caseIgnoreIA5Match
matching rule. For performance reasons the LDAP backend should support using indexed search when custom matching rule is requested in the search filter (see #Implementation section for more detail).
The relevant Directory Server plugins will be configured to handle krbCanonicalName
attribute during MODRDN operations on entries (e.g. renaming user entries should set the canonical principal name to use new user ID) and to set this attribute on hosts enrolled by ipa-join
command.
KDB DAL driver
The Kerberos principal lookup will still use ipaKrbPrincipalAlias
in the matching filter in order to maintain backwards compatibility. However, when principal canonicalization will be requested by the client, the driver will use case insensitive matching rule for krbPrincipalName
. Upon successful lookup, the driver will replace the incoming principal name either with the canonical principal name or with matched alias if krbCanonicalName
is not present.
When creating new principal using kadmin.addprincipal
subcommand, the driver will not add deprecated objectclass/attribute to the new entry. Instead, both krbPrincipalName
and krbCanonicalName
attributes equal in value will be added to the entry.
Management framework
FreeIPA API commands will set krbCanonicalName
attribute on each newly created user, host, and service entry and add the same principal to the krbPrincipalName
attribute. Newly created service entries will have to keep ipaKrbPrincipal
objectclass for backwards compatibility reasons, but its usage will be slowly deprecated.
The krbPrincipalName
attribute is currently restricted to be single-valued and immutable by the management framework. These restrictions will be lifted so that new aliases may be added/removed from the entries as long as the attribute contains at least a single value that is equal to the krbCanonicalName
. This restriction will ensure the backward compatibility with older client code which may be using only krbPrincipalName
attribute for the principal lookup.
Care has to be taken to correctly handle renaming of the user entry: if the principal name is generated from the entry's primary key (e.g. user ID), the rename operation should set the canonical principal name to the new value generated from the primary key, as well as add the new principal to the list of aliases. The old aliases will be kept unchanged so that the user can continue to use old credentials for authentication. This logic will not be implemented for hosts and services since the framework does not support rename operation on them.
When issuing enterprise principal aliases for the users (e.g. using e-mail as alias in the form login\@domain@REALM
), the framework must not accept suffixes that overlap with the realm names and UPN suffixes defined for trusting AD forests/domains.
Implementation
The performance of the Kerberos principal lookup shall be similar regardless of whether the canonicalization is requested or not. This depends on the ability of Directory Server backend to use multiple matching rules to construct an attribute index, and on the ability to use the index depending on the matching rule specified in the search filter. This effort is monitored in the project's tickets 48270, 48745, and 48746.
Feature Management
UI
TBD
CLI
Enhanced commands
Number of commands will behave differently after the reimplementation of principal alias handling.
{user,host,service}-add
krbCanonicalName
attribute will be generated by the management framework and displayed in the command output
{user,host,service}-show
- the command output will list all principal aliases associated with the entry
New commands
{user,host,service}-add-principal PRIMARY_KEY PRINCIPAL[, PRINCIPAL, ...]
- auxiliary commands to add one or more principal aliases to user/host/service entry
PRIMARY_KEY
.
{user,host,service}-remove-principal PRIMARY_KEY PRINCIPAL[, PRINCIPAL, ...]
- auxiliary commands to remove one or more principal aliases to user/host/service entry
PRIMARY_KEY
. However, a singlekrbPrincipalName
value equal to canonical name must remain on the entry after the operation. An error will be raised otherwise.
Upgrade
Since only entries added on new/upgraded replicas will behave according to updated schema and older entries will be untouched, the interoperability between new and old masters will remain unaffected. No special upgrade procedure shall be necessary.
How to Test
The following examples are mostly for user principals, although services and hosts behave much the same
- create a test subject for our nefarious experiments
[root@ipamaster ~]# ipa user-add tuser --first test --last user --password Password: <enter Secret123> Enter Password again to verify: <enter Secret123> ------------------ Added user "tuser" ------------------ User login: tuser First name: test Last name: user Full name: test user Display name: test user Initials: tu Home directory: /home/tuser GECOS: test user Login shell: /bin/sh Principal name: tuser@TEST.REALM Principal alias: tuser@TEST.REALM Email address: tuser@test.realm UID: 719200029 GID: 719200029 Password: True Member of groups: ipausers Kerberos keys available: True
- verify that we can kinit as the user. Change his password if necessary
[root@ipamaster ~]# kinit tuser Password for tuser@TEST.REALM: <enter Secret123> Password expired. You must change it now. Enter new password: <enter Secret1234> Enter it again: <enter Secret1234>
- switch back to admin credentials and add a simple alias and enterprise principal alias to `tuser`. Be careful to escape '@' in the enterprise principal name, otherwise the framework will complain about bad realm
[root@ipamaster ~]# ipa user-add-principal tuser talias talias@tupn.test ipa: ERROR: The realm for the principal does not match the realm for this IPA server [root@ipamaster ~]# ipa user-add-principal tuser talias talias\\@tupn.test --------------------------------- Added new aliases to user "tuser" --------------------------------- User login: tuser Principal alias: talias@TEST.REALM, talias\@tupn.test@TEST.REALM, tuser@TEST.REALM
- verify that you can now kinit using both aliases. Be sure to use '-C' flag when alias is used and '-E' flag when using enterprise principal name. Note that in both cases KDC returns TGT containing canonical principal name
[root@ipamaster ~]# echo "Secret1234" | kinit -C talias Password for talias@TEST.REALM: [root@ipamaster ~]# klist Ticket cache: KEYRING:persistent:0:krb_ccache_zYVMfOo Default principal: tuser@TEST.REALM Valid starting Expires Service principal 07/01/2016 15:25:45 07/02/2016 15:25:45 krbtgt/TEST.REALM@TEST.REALM [root@ipamaster ~]# echo "Secret1234" | kinit -C -E talias@tupn.test Password for talias\@tupn.test@TEST.REALM: [root@ipamaster ~]# klist Ticket cache: KEYRING:persistent:0:krb_ccache_KQ8VBt3 Default principal: tuser@TEST.REALM Valid starting Expires Service principal 07/01/2016 15:27:38 07/02/2016 15:27:38 krbtgt/TEST.REALM@TEST.REALM
- also note that you have to use the respective flags when authenticating with aliases/enterprise principals, otherwise KDC cannot resolve them properly:
[root@ipamaster ~]# echo "Secret1234" | kinit talias kinit: Client 'talias@TEST.REALM' not found in Kerberos database while getting initial credentials [root@ipamaster ~]# echo "Secret1234" | kinit -C talias@tupn.test kinit: Cannot find KDC for realm "tupn.test" while getting initial credentials
- If you have established an IPA-AD trust, the framework will refuse to create an enterprise principal whose suffix matches (case-insensitively) an UPN suffix or netbios name of trusted AD forest:
[root@ipamaster ~]# ipa user-add-principal tuser tuser\\@trusted.upn ipa: ERROR: invalid 'krbprincipalname': realm or UPN suffix overlaps with trusted domain namespace [root@ipamaster ~]# ipa user-add-principal tuser talias\\@TRUSTED.UPN ipa: ERROR: invalid 'krbprincipalname': realm or UPN suffix overlaps with trusted domain namespace [root@ipamaster ~]# ipa user-add-principal tuser tuser\\@AD-NETBIOS ipa: ERROR: invalid 'krbprincipalname': realm or UPN suffix overlaps with trusted domain namespace
- now remove the aliases we added from the test user
[root@ipamaster ~]# ipa user-show tuser User login: tuser First name: test Last name: user Home directory: /home/tuser Login shell: /bin/sh Principal name: tuser@TEST.REALM Principal alias: talias@TEST.REALM, talias\@tupn.test@TEST.REALM, tuser@TEST.REALM Email address: tuser@test.realm UID: 719200029 GID: 719200029 Account disabled: False Password: True Member of groups: ipausers Kerberos keys available: True [root@ipamaster ~]# ipa user-remove-principal tuser talias talias\\@tupn.test --------------------------------- Removed aliases from user "tuser" --------------------------------- User login: tuser Principal alias: tuser@TEST.REALM
- for compatibility reasons there must be at least one alias present on the entry which is equal to the canonical principal name. The framework will refuse to remove this alias if it is among the values to remove from entry.
[root@ipamaster ~]# ipa user-remove-principal tuser tuser ipa: ERROR: invalid 'krbprincipalname': at least one value equal to the canonical principal name must be present
Test Plan
The existing XMLRPC tests for management of users, hosts, and services will have to be modified to expect krbCanonicalName
attribute in the output of entity-{add,mod,show}
commands,