freeipa/doc/designs/rbcd.md
Alexander Bokovoy 0bf0b2d251 doc/designs/rbcd.md: document use of S-1-18-* SIDs
Fixes: https://pagure.io/freeipa/issue/9354

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2023-04-05 14:55:22 -04:00

25 KiB

Constrained delegation for Kerberos services

Overview

The purpose of this document is to describe an integration of two constrained delegation mechanisms FreeIPA provides for Kerberos services:

  • general constrained delegation, available since FreeIPA 3.0.0;
  • resource-based constrained delegation, introduced with this design document.

Both constrained delegation mechanisms apply when Kerberos services implement S4U2Proxy extensions as described in MS-SFU specification. MIT Kerberos project has its own page that describes Services for User integration. FreeIPA work relies on the MIT Kerberos facilities to support S4U extensions, including S4U2Proxy.

A general constrained delegation mechanism described here for the sake of completeness. The description is based on the original design document published originally at FreeIPA wiki page.

A general overview of a constrained delegation from Microsoft point of view can be found in this document.

Introduction

Services for User extensions were introduced as a part of Kerberos implementation in Microsoft's Active Directory. They aim to achieve two specific goals:

  • allow Kerberos services to accept requests authenticated via a different protocol. A Kerberos service can ask the Kerberos KDC to issue a ticket to itself on behalf of a user, thus performing a protocol transition. The resulting service ticket is issued to the service itself, hence S4U2Self extension name.

  • allow a Kerberos service to request a service ticket to a different Kerberos service on behalf of the original user, hence S4U2Proxy extension name. The original service ticket must be forwardable. The resulting ticket can be presented in the communication to that different Kerberos service and will show both the original user principal and a Kerberos service operating on its behalf.

The S4U2Proxy feature eliminates the need for the user to delegate their ticket granting ticket (TGT). FreeIPA uses the S4U2Proxy feature to allow the web server framework to obtain an LDAP service ticket on the user's behalf. Similarly, it is also used by the FreeIPA's trust to Active Directory feature to allow the web server framework to obtain an SMB service ticket on the user's behalf when configuring Samba and a trust to Active Directory through Samba.

Kerberos KDC has control over the issuance of service tickets for both S4U2Self and S4U2Proxy extensions. The usage of S4U2Proxy is called "constrained delegation"; the two mechanisms that represent constrained delegation usage have different rules associated with them.

The access control for general constrained delegation is controlled by several LDAP entries, rules and targets, contained in cn=s4u2proxy,cn=etc,$SUFFIX.

Rule LDAP entry defines two elements:

  • Kerberos principals to be impersonated (defaults to every principal),

  • Kerberos services that can impersonate them.

Target LDAP entry defines the list of Kerberos services to which the impersonator Kerberos services can delegate credentials.

These rules are controlled by the administrators of FreeIPA and cannot be controlled by the services themselves.

The access control for the resource-based constrained delegation rules is placed within the LDAP entries of the target Kerberos services. Kerberos service which supports resource-based constrained delegation will only be able to request a service ticket to a Kerberos service that explicitly allows this service to ask for a constrained delegation for itself. The rules are controlled by the services' administrators (by default, the host service controls services associated with the host). This reduces an administrative overhead and delegates decision-making to the application administrators.

Use cases

The table below summarizes three types of the Kerberos delegation approaches.

A 'forest' concept in the table is an Active Directory term. FreeIPA does not have a mechanism to place multiple AD-like domains into the same forest. All systems which deployed to the same FreeIPA deployment are part of the same FreeIPA domain and the same FreeIPA forest. In terms of Active Directory, FreeIPA forest represents a single Active Directory domain, the root domain of the forest. In Kerberos terms all these domains represent separate Kerberos realms, within or across multiple forests.

Impersonator account in the table corresponds to the application which is using the delegated credential. In case of a constrained delegation, it is an application performing S4U2Proxy request.

Resource-based constrained delegation is only supported when FreeIPA is compiled against MIT Kerberos 1.19 or later.

TGT forwarding, unconstrained (by policy) General constrained delegation Resource-based constrained delegation
Delegation attributes set on and managed by admin of Impersonator account (to anyone) Impersonator account (to a list of resources) Resource account (to a list of impersonators)
Delegation within a domain, client from the local forest yes yes yes
Delegation within a domain, client from another forest yes [1] yes yes
Delegation across a domain trust within the same forest, client from the local forest yes no yes
Delegation across a domain trust within the same forest, client from another forest yes [1] no yes
Delegation across forest trust, client from the forest of the impersonator yes no yes
Delegation across forest trust, client from the forest of the resource yes [1] no no [2]
  • [1] With Windows updates in 2019, tgt-forwarding when the client and impersonator are in different forests no longer works unless explicitly allowed. Microsoft has issued a guidance that details the behavior. Additionally, there is a Microsoft Word document describing a KDC behavior.

  • [2] Refer to the KDC paper from above for the description of "round-trip authentication across trusts".

General constrained delegation

General constrained delegation is often utilized in a multi-service environment where a frontend service acts on behalf of a user against backend services.

For example, the server side implementation of IPA API framework uses the delegation of a ticket presented to the web service to act on behalf of this user when talking to LDAP service.

Use cases for resource-based constrained delegation

Typical use case is to allow users from the trusted Active Directory forest to access their network shares while logging into FreeIPA client systems. NFS server would be enrolled either into Active Directory or the FreeIPA deployment, FreeIPA client system would be enrolled into FreeIPA deployment. On FreeIPA client, a user's home directory would be configured to automount NFS share for the user and use GSSAPI authentication with the help of GSSProxy. GSSProxy can be configured to use both S4U2Self and S4U2Proxy. This use case is described in detail in GSSProxy documentation.

When NFS server is located in the same Kerberos realm as the FreeIPA client system, this use case can be implemented with general constrained delegation.

When the target service (NFS server) and the proxy service (NFS client) are in different realms, MS-SFU specification prevents issuance of a service ticket using S4U2Proxy extension unless there is a resource-based constrained delegation rule defined for the target service, as outlined in the MS-SFU 3.2.5.2.3.

As a result, in order to allow delegation of user credentials across the forest boundary, resource-based constrained delegation must be supported both by the impersonating (proxy) service and by the KDC of the user forest.

Design

MS-SFU specification defines that for full support of all S4U functionality an account database needs to support four elements of information for each principal, as outlined in MS-SFU 3.2.1.

FreeIPA account database is not compatible with Active Directory on LDAP level, thus implementation is slightly different.

Unconstrained delegation

IPA API provides a way to record unconstrained delegation permission in both host and service command families. The following commands have option --ok-as-delegate=BOOL:

  • ipa host-add and ipa service-add
  • ipa host-mod and ipa service-mod

S4U2Self design

Kerberos service is allowed to request a service ticket to itself on behalf of any user. However, to make it usable for S4U2Proxy (constrained delegation), the service ticket must be forwardable. In such case the Kerberos service would be able to impersonate user and requires an explicit administrative permission.

IPA API provides a way to record this permission in both host and service command families. The following commands have option --ok-to-auth-as-delegate=BOOL:

  • ipa host-add and ipa service-add
  • ipa host-mod and ipa service-mod

This flag is equivalent to MS-SFU's TrustedToAuthenticationForDelegation boolean setting.

General constrained delegation design

General constrained delegation uses two objects: a rule and a target. All entries are stored in the same LDAP container and the only real distinguishing feature between a rule and a target is the objectClass ipaKrb5DelegationACL:

  • a rule will have these objectClasses: top, groupOfPrincipals, ipaKrb5DelegationACL.

  • a target will have these objectClasses: top, groupOfPrincipals.

Kerberos KDC database driver (KDB) uses a special filter to exclude ipaKrb5DelegationACL when searching for the target.

Both a rule and a target specify affected principals with memberPrincipal attribute.

This combination of rules and targets allows FreeIPA to implement an equivalent of MS-SFU's ServicesAllowedToSendForwardedTicketsTo information.

Management of the general constrained delegation rules and targets is done with ipa servicedelegation commands.

Command Description
servicedelegationrule-add Create a new service delegation rule.
servicedelegationrule-add-member Add member to a named service delegation rule.
servicedelegationrule-add-target Add target to a named service delegation rule.
servicedelegationrule-del Delete service delegation.
servicedelegationrule-find Search for service delegations rule.
servicedelegationrule-remove-member Remove member from a named service delegation rule.
servicedelegationrule-remove-target Remove target from a named service delegation rule.
servicedelegationrule-show Display information about a named service delegation rule.
servicedelegationtarget-add Create a new service delegation target.
servicedelegationtarget-add-member Add member to a named service delegation target.
servicedelegationtarget-del Delete service delegation target.
servicedelegationtarget-find Search for service delegation target.
servicedelegationtarget-remove-member Remove member from a named service delegation target.
servicedelegationtarget-show Display information about a named service delegation target.

Resource-based constrained delegation design

Resource-based constrained delegation stores information in the target service LDAP entry. This information is represented with memberPrincipal attribute and is allowed with objectClass resourceDelegation. If a Kerberos principal is mentioned in the memberPrincipal attribute of the LDAP entry and objectClass resourceDelegation is present in the same entry, KDB driver will use information from the memberPrincipal attribute to check whether a service asking for S4U2Proxy extension is allowed to send a forwarded user ticket to this service.

This approach allows implementing MS-SFU's ServicesAllowedToReceiveForwardedTicketsFrom information.

Management of the resource-based constrained delegation is integrated into ipa host and ipa service commands.

Command Description
service-add-delegation Add new resource delegation to a service
service-allow-add-delegation Allow users, groups, hosts or host groups to handle a resource delegation of this service.
service-disallow-add-delegation Disallow users, groups, hosts or host groups to handle a resource delegation of this service.
service-remove-delegation Remove resource delegation from a service
host-add-delegation Add new resource delegation to a host
host-allow-add-delegation Allow users, groups, hosts or host groups to handle a resource delegation of this host.
host-disallow-add-delegation Disallow users, groups, hosts or host groups to handle a resource delegation of this host.
host-remove-delegation Remove resource delegation from a host

The *-allow-add-delegation and *-disallow-add-delegation commands aim to provide a way to extend list of actors allowed defining delegation access control. By default, only host and service owners (the host and service themselves, as well as those objects defined by managedBy attribute) allowed to control the delegation. Additional users, groups, hosts or host groups can be allowed to set the delegation ACL. The purpose of these commands is to allow a flexible management without giving a control over the whole host or service entry.

Implementation

IPA API commands

In both general constrained delegation and resource-based constrained delegation rules, targets, and delegation permission details are expressed with memberPrincipal attribute. Since IPA's standard LDAPAddMember and LDAPRemoveMember classes operate on DNs for the members, they need to be overridden to represent Kerberos principals. The principal might be not present in the IPA realm and thus cannot be represented as an LDAP object to which DN could be constructed.

Management of a general constrained delegation

In case of general constrained delegation a special handling is added to LDAPAddMember and LDAPRemoveMember classes to handle memberPrincipal. The add/remove methods assume, and require via asserts, that all members be a DN. get_member_dns() needs to ignore any memberPrincipal values and return only the DN-based values when adding targets to rules to let the standard mechanics of LDAP*Member do their work.

In order to handle the memberPrincipal values a post_callback() is required. This also means that there be at worst two writes per membership update. Given that this feature is not expected to be frequently used then speed and efficiency are not a factor.

Similarly, we enforce that only a target is a member of a rule, and not another rule. That would be an undefined relationship. To do this each member needs to be retrieved and evaluated before adding as a member.

A referential integrity rule is needed for ipaallowedtarget.

A referential integrity rule is needed, but is not possible, for memberPrincipal. It is not possible because it is not a DN. This adds the potential to have dangling pointers. In practice, this has not been a problem for S4U2Proxy usage as administrators rarely add the constrained delegation rules.

The ACL system also provides a means of limiting which user's a ticket may be obtained for using the ipaAllowToImpersonate attribute. This is not implemented.

In order to maintain basic functionality, FreeIPA must have entries for S4U2Proxy operations between IPA API framework, LDAP service, and CIFS service on IPA server. These entries are ipa-http-delegation rule and ipa-ldap-delegation-targets and ipa-cifs-delegation-targets targets.

To grant this access, two LDAP entries are required. The first is a rule which defines the ACL:

 dn: cn=ipa-http-delegation,...
 objectClass: ipaKrb5DelegationACL
 objectClass: groupOfPrincipals
 cn: ipa-http-delegation
 memberPrincipal: HTTP/ipaserver.example.com@EXAMPLE.COM
 ipaAllowedTarget: cn=ipa-ldap-delegation-targets,...

The second LDAP entry is a target of this rule which defines which principals may be obtained:

 dn: cn=ipa-ldap-delegation-targets,...
 objectClass: groupOfPrincipals
 cn: ipa-ldap-delegation-targets
 memberPrincipal: ldap/ipaserver.example.com@EXAMPLE.COM

Both types of entries contain members in the form of memberPrincipal. In the case of a rule these are the members that the rule applies to. In the case of a target the members are the targets of the delegation. In this case the rule has a member of HTTP/ipaserver.example.com@EXAMPLE.COM and a rule with a member of ldap/ipaserver.example.com@EXAMPLE.COM which means that the HTTP principal can obtain an LDAP service ticket on behalf of the bound user.

The same approach is used to allow the IPA API framework to obtain a service ticket on behalf of a user to Samba when a trust to Active Directory is established. In this case, instead of ldap/ipaserver.example.com@EXAMPLE.COM, a target principal of cifs/ipaserver.example.com@EXAMPLE.COM is used.

These two rules are configured by default in the FreeIPA deployment.

Resource-based constrained delegation

Resource-based constrained delegation relies on a memberPrincipal attribute in the target service's LDAP object. To manage this attribute, we extend LDAPAddAttribute and LDAPRemoveAttribute classes. Both classes were added after general constrained delegation was implemented and present a better abstraction to handle member principals.

To control validity of the member principals, a method that checks realms against a list of trusted domains is added. This allows to set up resource-based constrained delegation for cross-forest services.

Access control for resource-based constrained delegation is performed in the following way. A service can modify own delegation list and specify which Kerberos principals are allowed to delegate to the service. Host where service is located can manage the service as well.

Administrators can grant other users, groups, hosts, or services permissions to handle resource-based constrained delegation of a host or a service.

Kerberos KDC implementation

KDB API provides two callbacks for the database drivers to implement access control checks for constrained delegation.

General constrained delegation callback check_allowed_to_delegate() allows checking whether a server is allowed to obtain tickets from client to a target service. This is implemented by loading constrained delegation LDAP rules and targets associated with the target service and the proxy server and checking that they match.

Resource-based constrained delegation callback allowed_to_delegate_from() allows checking whether a target service allows a server to delegate a ticket. This is implemented in two parts:

  • first, memberPrincipal attribute in the principal is loaded and added to TL data of the principal object in KDC under KRB5_TL_CONSTRAINED_DELEGATION_ACL type.

  • second, the resource-based constrained delegation callback retrieves KRB5_TL_CONSTRAINED_DELEGATION_ACL TL data and validates that a server is present in the list of principals.

Since KRB5_TL_CONSTRAINED_DELEGATION_ACL TL data might be present in the Kerberos principal KDC object, destructor for the Kerberos principal is extended to free the associated memory.

Finally, KDB driver follows requirements for MS-SFU 3.2.5.1.2 and adds SIDs S-1-18-1 or S-1-18-2 to the MS-PAC structure's extraSids field depending on how identity was verified:

  • for non-S4U2Self operation initial PAC structure population includes a SID S-1-18-1, as a AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY,

  • for S4U operation, instead, a SID S-1-18-2 is added, as a SERVICE_ASSERTED_IDENTITY.

Test Plan

General constrained delegation is already used by the IPA management framework and thus being tested with every IPA API call.

For resource-based constrained delegation cases defined in the use case summary table. Since FreeIPA currently does not have support for IPA to IPA trust and does not provide a working two-way trust with Active Directory, it is not possible to test a scenario where RBCD is applied cross-realm by FreeIPA itself but the proxy service is in a trusted realm. When IPA to IPA trust or proper two-way trust to Active Directory would be implemented, this scenario could be tested.

Thus, a primary RBCD scenario to test is an interoperability with another RBCD-enabled realm (e.g. Active Directory) where IPA client is used to initiate the S4U2Proxy operation against a resource (service) in a trusted realm. In this case Kerberos library on the IPA client should set RBCD support flag in the PAC structure and trigger S4U2Proxy request. A trusted realm's KDC will do its check and allow or deny the access request.

Usage examples for RBCD

Setup RBCD for a service

Let's consider a case where a web frontend needs to connect to an internal SMB server running on another IPA server on behalf of a user. This is similar to a default setup in FreeIPA with general constrained delegation but on a different host and using a different service.

  • a host web-service.example.test would run a web server and use HTTP/web-service.example.test service principal.

  • a host file.example.test would be a Samba server running on IPA-enrolled client. Its SMB server uses cifs/file.example.test service principal.

In RBCD model, the control over who can delegate user resources to the service would be defined at the service side, in this case at cifs/file.example.test. An RBCD access control for cifs/file.example.test would need to mention HTTP/web-service.example.test principal to allow the web server to delegate user's credentials to the Samba server.

Example 1: Administrator can set RBCD ACL directly:

$ kinit admin
$ ipa service-add-delegation cifs/file.example.test HTTP/web-service.example.test

Example 2: Host file.example.test can use a host keytab to define RBCD ACL directly because a host always manages the services running on it:

# kinit -k
# ipa service-add-delegation cifs/file.example.test HTTP/web-service.example.test

Example 3: Allow users from a group storage-admins to define RBCD ACLs to cifs/file.example.test:

$ kinit admin
$ ipa service-allow-add-delegation cifs/file.example.test --groups=storage-admins

Then, a user some-user from storage-admins group can add a delegation ACL:

$ kinit some-user
$ ipa service-add-delegation cifs/file.example.test HTTP/web-service.example.test

Example 4: Remove permission to add RBCD ACLs for cifs/file.example.test from members of the storage-admins group:

$ kinit admin
$ ipa service-disallow-add-delegation cifs/file.example.test --groups=storage-admins

Now a user some-user from storage-admins group cannot add a delegation ACL:

$ kinit some-user
$ ipa service-add-delegation cifs/file.example.test HTTP/web-service.example.test
.. ERROR ..

Example 5: Test RBCD access by service HTTP/web-service.example.test to cifs/file.example.test. In this example we assume that an RBCD ACL created in examples 1-3 exists, there is a keytab /path/to/web-service.keytab for HTTP/web-service.example.test, and a cifs/file.example.test service was created with ipa-install-samba tool which ensures a keytab was obtained for Samba service as well. The presence of keytabs ensures corresponding Kerberos services have all needed Kerberos keys so that service tickets can be created by KDC.

In the example below we are delegating user some-user credentials to the service cifs/file.example.test. First, we pretend our web service has authenticated the user with some mechanism. Then we aquire a service ticket to ourselves (HTTP/web-service.example.test) with the help of kvno -U username command. Finally, we use kvno -P option to ask for S4U2Proxy operation and specify for which services tickets will be asked using constrained delegation.

# kvno -U some-user -k /path/to/web-service.keytab \
       -P HTTP/web-service.example.test cifs/file.example.test