Getting Started with Kerberos


Requirements: IPWorks Auth

Introduction

The Kerberos component can be used to implement a Kerberos 5.0 client, facilitating secure authentication within a network environment. This component enables seamless integration into various network architectures, allowing users to securely authenticate across distributed systems. This guide will cover the basics of performing such authentication.

Contents

Authentication

Before authenticating, the following properties must be set:

Property NameDescription
KDCHostThis property must be set to the IP address of the KDC host.
KDCPortThis property must be set to the port the KDCHost is listening on. This is set to 88 by default.
SPNThis property must be set to the SPN (Service Principal Name) of the service the user is attempting to access.
UserThis property must be set to the user attempting access to the service.
PasswordThis property must be set to the password of the set user.

After the above properties are set, Authenticate can be called to retrieve an authentication token. This token may then be used to access protected resources. Please see below for a simple example of the authentication process:

Kerberos kerberos = new Kerberos(); kerberos.KDCHost "10.0.1.226"; kerberos.User = "testuser@EXAMPLE.COM"; kerberos.Password = "testpassword"; kerberos.SPN = "ldap/ldap-server.example.com"; kerberos.Authenticate(); Console.WriteLine(kerberos.AuthToken);

Credential Cache

As an alternative to providing credentials via the User and Password properties, the component supports reading credentials from both FILE and DIR credential cache types.

To read from a FILE credential cache type, the CredentialsCacheFile configuration setting should be set to the local file containing the relevant credentials.

To read from a DIR credential cache type, the CredentialsCacheFile configuration setting should be set to the local directory containing the relevant credentials. In this case, DIR: should prefix the directory path. Please see below for an example of both cases:

Kerberos kerberos = new Kerberos(); kerberos.KDCHost "10.0.1.226"; kerberos.SPN = "ldap/ldap-server.example.com"; //kerberos.User = "testuser" // optional // FILE kerberos.Config("CredentialsCacheFile=C:\\CacheFile.txt"); kerberos.Authenticate(); Console.WriteLine("Token obtained from FILE: " + kerberos.AuthToken); // DIR kerberos.Config("CredentialsCacheFile=DIR:C:\\CacheDir\\"); kerberos.Authenticate(); Console.WriteLine("Token obtained from DIR: " + kerberos.AuthToken);

In some cases, a credential cache can contain entries for multiple users. In these cases, the User property can be set to locate the cache entry associated with the user. If User is not specified, or no user is matched, then the first entry in the cache will be used instead.

Keytab File

As an alternative to setting the Password property, the component also supports setting a keytab file via the KeytabFile property. Assuming an entry exists for the specified user and the server supports the relevant encryption type, this could look like the following:

Kerberos kerberos = new Kerberos(); kerberos.KDCHost "10.0.1.226"; kerberos.User = "testuser@EXAMPLE.COM"; kerberos.SPN = "ldap/ldap-server.example.com"; kerberos.KeytabFile = "C:\\testuser.keytab"; kerberos.Authenticate(); Console.WriteLine(kerberos.AuthToken);

Cross-Realm Authentication

In the previous examples, the user is attempting to access a service hosted within their realm. It may be that the user wishes to access a service within a separate realm. In this case, the component must be configured for cross-realm authentication.

Basic Trusts

There are a few different scenarios when performing cross-realm authentication. This depends on existing trusts between the realm of the user and the realm of the service. The most basic scenario of cross-realm authentication occurs when a user in one realm attempts to access a service in another realm, and a trust exists between said realms. To configure the component for this scenario, the following configuration settings should be set:

Config NameDescription
TGSRealm This config must be set to domain or realm the SPN (or service) exists within.
TGSKDCHostThis config must be set to the IP address of the KDC host existing within the TGSRealm.
TGSKDCPortThis config must be set to the port the TGSKDCHost is listening on. This is set to 88 by default.

As an example, say a user in the realm example1.com wishes to access a service in the realm example2.com. To perform cross-realm authentication, the component should be configured like so:

Kerberos kerberos = new Kerberos(); kerberos.KDCHost "10.0.1.226"; // KDC host in example1.com kerberos.User = "testuser@EXAMPLE1.COM"; // User in example1.com kerberos.Password = "testpassword"; kerberos.SPN = "ldap/ldap-server.example2.com"; // Service in example2.com // Location of service kerberos.Config("TGSRealm=example2.com"); kerberos.Config("TGSKDCHost=10.0.1.227"); kerberos.Config("TGSKDCPort=88"); kerberos.Authenticate(); Console.WriteLine(kerberos.AuthToken);

In the above case, the component will first communicate with the KDC in the local realm, example1.com. Assuming a trust is set up between example1.com and example2.com, the KDCHost will return an inter-realm trust key. Afterward, the component will authenticate with the KDC host identified by the TGS* configuration settings. If successful, the user may access the service within example2.com.

Complex Trusts

More complex cases of cross-realm authentication may arise when a direct trust is not set up between the realm of the user and the realm of the service. As an example, let's say realms example1.com, example2.com, and example3.com exist. One trust is set up between example1.com and example2.com, another between example2.com and example3.com.

A user within example1.com wishes to access a service within example3.com, however, no direct trust exists between these two realms. That said, the user may still access the service by first obtaining the credentials from example2.com. Then, using those credentials, they can then obtain the credentials from example3.com, which are necessary for accessing the service. In this case, example2.com is considered to be an intermediate realm, or a realm facilitating cross-realm authentication between a user's realm and a service's realm. A separate set of configuration settings exist to specify intermediate realms:

Config NameDescription
IntermediateTGSCount This config specifies the number of intermediate realms.
IntermediateTGSRealms[i] This config must be set to the name of the intermediate realm.
IntermediateTGSKDCHosts[i]This config must be set to the IP address of the KDC host of the intermediate realm.
IntermediateTGSKDCPorts[i]This config must be set to the port the intermediate realm's KDC is listening on. This is set to 88 by default.

Note that the TGS* configuration settings must be set to the realm of the SPN for cross-realm authentication to occur. For example:

Kerberos kerberos = new Kerberos(); kerberos.KDCHost "10.0.1.226"; // KDC host in example1.com kerberos.User = "testuser@EXAMPLE1.COM"; // User in example1.com kerberos.Password = "testpassword"; kerberos.SPN = "ldap/ldap-server.example3.com"; // Service in example3.com // Intermediate realms kerberos.Config("IntermediateTGSCount=1"); kerberos.Config("IntermediateTGSRealms[0]=example2.com") kerberos.Config("IntermediateTGSKDCHosts[0]=10.0.1.227"); kerberos.Config("IntermediateTGSKDCPorts[0]=88"); // Location of service kerberos.Config("TGSRealm=example3.com"); kerberos.Config("TGSKDCHost=10.0.1.228"); kerberos.Config("TGSKDCPort=88"); kerberos.Authenticate(); Console.WriteLine(kerberos.AuthToken);

Kerberos Configuration Files

The component supports reading various client configurations from a Kerberos configuration file (krb5.conf) as defined by MIT. To do so, the Krb5Config configuration setting should be set to the local configuration file.

When specified, the component will first attempt to resolve the default_realm entry present in the configuration file. The default realm will be used during authentication unless a domain/realm is specified in the User property. Note that in this case, the User property may be set to only a username to allow the component to use the appropriate default realm.

Assuming a default realm is found, the primary KDC associated with this realm will be used during authentication, assuming KDCHost is not specified. Additional KDCs associated with this realm will be used only if authentication with the primary KDC fails. If no KDCs are specified for a given realm, and the dns_lookup_kdc entry is set to true, the component will perform a DNS query in an attempt to resolve the realm's KDC hostnames and ports. To clarify, the component will attempt to look up the SRV records stored on the realms administration server, identified by the admin_server entry.

All additional realms found within the file will be stored as intermediate realms in the case cross-realm authentication is required.

The below example portrays the case described in the Complex Trusts section, simplified with the associated krb5.conf file.

Kerberos kerberos = new Kerberos(); kerberos.User = "testuser"; // User in example1.com kerberos.Password = "testpassword"; kerberos.SPN = "ldap/ldap-server.example3.com"; // Service in example3.com kerberos.Config("Krb5Config=C:\\krb5.conf"); // See below // Location of service kerberos.Config("TGSRealm=example3.com"); kerberos.Authenticate(); Console.WriteLine(kerberos.AuthToken);

Below is the sample krb5.conf associated with the above code.

[libdefaults] default_realm = EXAMPLE1.COM dns_lookup_kdc = true [realms] EXAMPLE1.COM = { kdc = kdc01.example1.com kdc = kdc02.example1.com admin_server = example1.com } EXAMPLE2.COM = { admin_server = example2.com # DNS lookup will occur here, as no KDC is defined } EXAMPLE3.COM = { kdc = kdc01.example3.com admin_server = example3.com } [domain_realm] .example1.com = EXAMPLE1.COM example1.com = EXAMPLE1.COM .example2.com = EXAMPLE2.COM example2.com = EXAMPLE2.COM .example3.com = EXAMPLE3.COM example3.com = EXAMPLE3.COM

We appreciate your feedback. If you have any questions, comments, or suggestions about this article please contact our support team at support@nsoftware.com.