Active Directory: Using Kerberos Keytabs to integrate non-Windows systems
Purpose
What is a keytab? It's basically a text file that contains a table of one or more user accounts (though 99% of the time just one account) with an encrypted hash of that user account's password. It is very useful when you want a server process running on a Linux or Unix system to automatically logon to Active Directory (AD) on startup, since those systems cannot be configured to run processes with a Windows service account. Typically when you want to integrate Linux\Unix to Active Directory you have two options: (1) type the password (in clear text) into a configuration file somewhere and maybe encrypt that - but many people don’t and leave the password exposed inside the config file, or (2) store an encrypted hash of the password in a keytab file. Option 2 is the more secure choice. More specifically, a keytab is a cryptographic file containing a representation of a Kerberos-protected service and its long-term key (what some not entirely correctly refer to as the password) of its associated service principal name in the Key Distribution Center, or KDC. In the Microsoft Windows enterprise network, that is a service which runs on an Active Directory domain controller. The service in this case "exists" in the directory as an SPN - service principal name. This makes keytabs especially useful for services running on a non-Windows platform protected by the Kerberos protocol - which is the second major use of it. In summary, keytabs are used to either (1) authenticate the service itself to another service on the network, or (2) decrypt the Kerberos service ticket of an inbound directory user to the service.
This article mainly delves into how a keytab is used in situations on mixed networks, where Microsoft Active Directory Domain is the KDC providing enterprise directory services for a heterogeneous network comprised of both Windows and non-Windows systems (such as Linux and Java-based application servers) and it is desired that AD users accessing some service (for example, HTTP) on a non-Windows system be silently authenticated (not challenged for credentials) into that system using their AD username. Since such a system might not be participating in the AD domain in any other way, there must be some common authentication mechanism to allow this to work. The Kerberos single sign-on (SSO) protocol accomplishes this task. Kerberos SSO onto Linux and Java-based systems to Active Directory is accomplished via multiple aspects, such as SPNEGO, GSSAPI, the SPN (Service Principal Name), and the keytab. Think of the SPN as the centerpiece to this arrangement, and the keytab as the glue. SPNs will be the topic of another article; we will focus only on the keytab in this conversation.
Windows-only Environments
Kerberos keytabs, also known as key table files, are only employed on non-Windows servers. In a homogenous Windows-only environment, keytabs will not ever be used, as the AD service account in conjunction with the Windows Registry and Windows security DLLs provide the Kerberos SSO foundation. This is also why Kerberos client configuration files, such as krb5.conf or krb5.ini, are not used in a Windows-only network.
Heterogeneous Environments
It is only when the Active Directory-based enterprise is interoperating with non-Windows systems, such as Apache HTTPD, Java J2EE servers (JBOSS and Tomcat), Linux and UNIX will keytabs ever be required. And then only in the case where the administrator wishes to integrate their application server to AD via Kerberos SSO. In other words, if you wish for your client systems to logon to the non-Windows system using their AD credentials via SSO (not challenged again for username and password) and be silently authenticated to the application server, a keytab will be required. The keytab doesn’t authenticate the users coming into the app server, that is the function of the Kerberos API, typically GSSAPI, in concert with the application code. What the keytab does do is decrypt the Kerberos service ticket and “tell” the application server who the user is. This is the critical role of the keytab during Kerberos authentication.
How to create the keytab – and what it contains
The Keytab must be generated on either a member server or a domain controller of the Active Directory domain using the ktpass.exe command. Use the Windows Server built-in utility ktpass.exe to create the keytab. The ktpass command must be run on either a member server or a domain controller of the Active Directory domain. Further, Keytabs must be created on a Windows Server operating system such as Windows Server 2008, 2012, or 2016. Keytabs cannot be created on a workstation operating system, such as Windows 7, 8 or Windows 10. When running ktpass.exe, the Command-line shell (cmd.exe) must be run under the context of an administrator account. If User Account Control (UAC) is enabled, that must be disabled. The keytab must be created in such a way that it contains the service principal name, realm name, and the encrypted hash of the password of the AD user or computer account to which the service principal inside of the keytab is related. The keytab is much more flexible if it is tied to an AD user (service) account than a computer account. Think of Keytabs as the “extension” of the AD service account. Because an AD service account cannot run on a non-Windows system, the keytab provides the function of the AD service account in its place. A keytab file is small – only 1 kilobyte in size. Note that if you re-create a keytab using the same SPN, you will need to (1) first ensure the application server config is pointed to the new keytab file name (if you've changed it) and (2) you will also need to restart the application service engine. For organizational purposes, I always save keytabs into a series of folders sorted by project name, and inside each folder I save a screenshot of both the keytab creation command syntax and its output for back-referencing. One further note about the most important feature inside the keytab. The keytab file itself contains a key (think of it as a "secret key", rather than the password) which is a one-way encrypted hash of the password of the principal to which the keytab is associated, and not of actual the password itself. Due to this, there is no known computational method to determine the un-encrypted value of that password/key. The below is a keytab creation command example. It is different from what you will see in just about every other example out on the Internet, but it is the way I have gotten used to creating them and the way I continue to create them. While the exact sequence order of the command arguments isn't important, what is important is that if are creating keytabs frequently, that you do so in a consistent manner, as it will make it much easier to troubleshoot Kerberos authentication problems down the road should the need arise.
ktpass.exe – Keytab Generation Example
ktpass -out centos1-dev-local.keytab -mapUser krbCentos@DEV.LOCAL +rndPass -mapOp set +DumpSalt -crypto AES256-SHA1 -ptype KRB5_NT_PRINCIPAL -princ HTTP/centos1.dev.local@DEV.LOCAL
The above command example successfully created a keytab for use in an AD domain named DEV.LOCAL. The below table breaks down the command syntax into its independent parts and explains each argument parameter.
Note1: Notice the use of the randomize password syntax (+rndPass). In my opinion, there is no need to specify a password in the keytab creation command syntax. Instead, it's better to allow the password to be randomized - that provides much better security since it prevents anyone from being able to manually logon as the account surreptitiously and bypass the keytab.
Note2: An error may occur in the keytab creation process: "Failed to set property 'servicePrincipalName' to 'HTTP/somehost.somedomain.name' on Dn 'CN=someuser,CN=Users,DC=somename,DC=somename': 0x13. WARNING: Unable to set SPN mapping data." This means the keytab won't work and you will need to re-create the keytab again. Follow these steps:
- Number one cause for this failure: This is a duplicate SPN. setspn -x will find the account holding the duplicate SPN. Proceed to Step #2.
- Remove the SPN from the other Active Directory account.
- Ensure ktpass is run on a server (or DC) of the domain (not a workstation, otherwise it will fail).
- Disable UAC (server will need to be restarted - perform this step only if you are sure duplicate SPN is not the problem).
- Open CMD.exe with Domain Admin credentials.
- Run ktpass again. You must run it again to place the desired SPN onto the desired Active Directory account!
Command syntax breakdown
Parameter | Explanation |
-out centos1-dev-local.keytab | A file named centos1-dev-local.keytab is created |
-mapUser krbCentos@DEV.LOCAL | The keytab is linked to AD account krbCentos@DEV.LOCAL |
+rndPass | The password of the AD account krbCentos is randomized |
-mapOp set | Links the SPN to the AD account |
+DumpSalt | Displays the MIT SALT generating the keytab |
-crypto AES256-SHA1 | AES256-SHA1 encryption support is built into the keytab |
-ptype KRB5_NT_PRINCIPAL | Principle type is Kerberos version 5 |
-princ HTTP/centos1.dev.local@DEV.LOCAL | The SPN in the keytab is HTTP/centos1.dev.local@DEV.LOCAL |
If you modify the keytab in any way after you create it, in my experience you will invalidate it and it won't work anymore. A new keytab would have to be generated to work with the service principal again. If you are on a Windows machine, use the widely-available Notepad++ editor to view the keytab contents rather than Notepad.exe, the latter of which is not good at rendering the keytab file contents.
There are two parts to a keytab. The keytab file itself, and the AD account it was associated with during the keytab creation process. What makes them "joined" is that fact that the SPN and long-term key are the same in both. That the long-term key is the same on both sides is the symmetric key cryptography aspect. The below image shows the AD user account associated with our keytab, with focus on the Account tab. After the keytab generation, the User logon name changes into an SPN, so it can be found by Kerberos clients looking it up. Note that the checkbox "This account supports Kerberos AES 256 bit encryption" under Account Options is selected. The checkbox must be manually selected after the keytab generation otherwise you'll receive an error along the lines of 'Cannot find key of appropriate type to decrypt AP REP...".
In typical scenarios, you will only need one keytab to authenticate users coming into an application server, such as for a garden-variety web server. If you later decide that you need the web server to listen on additional URL(s), simply add SPNs matching the FQDNs of the URL(s) to the same AD account linked to the keytab, so long as Kerberos is enabled at the web container level. If Kerberos is enabled at the web application level, as in the case when the web application is using Java's Spring Security, then you will likely need an additional keytab for each new SPN. You can have more than one encryption type built into a keytab, in particular, the “-crypto ALL” argument will place all available encryption types into the keytab. the client and server will agree on the strongest mutual encryption supported between themselves during the SPNEGO process and that will be the encryption in the Kerberos ticket presented to the application server during the authentication sequence. The following kinit command syntax, assuming you have the Java JRE or JDK installed, will allow you to test the keytab:
kinit -k -t centos1-dev-local.keytab HTTP/centos1.dev.local
Time spent learning about Kerberos interoperability inside Active Directory and heterogeneous environments will be well worth it.