EDQ running on Unix
If the server is running on Unix, it must use an account in AD to set up the accept credentials. It validates the request using the encrypted account password read from a Kerberos key table (keytab). Setting up a valid key table is an essential step in configuring SSO on Unix.
What is in the keytab?
A Kerberos key table contains encrypted passwords for one or more Kerberos principals. The DC normally supports a number of different encryption algorithms (DES3, AES, RC4 etc) and the entry for a principal will include keys for each of these algorithms. The client will pick the best algorithm available for communication with the DC.
The service requested using GSSAPI is identified by a service principal name (SPN).Normally this will be a reference to a particular service type at a machine hostname. Examples of service types are HOST (for general access such as ssh), HTTP (for SSO from browsers) and LDAP (for LDAP servers such as AD domain controllers). An SPN is usually displayed as:
service/hostname
For example:
HOST/testserver.example.com
Each entry in a keytab also includes a 'key version number' (KVNO). This is a version number which is incremented whenever the password for the principal is changed in the DC. The keytab must contain the correct KVNO for authentication to succeed.
On most Unix systems, the default location of the system Kerberos keytab is:
/etc/krb5.keytab
The Java Kerberos implementation does not have a default keytab location and this must be set in loign.properties:
keytab = path to keytab
If the path is not absolute, it is relative to the security folder containing login.properties.
The klist command can be used to list the contents of a keytab:
klist –k [file] klist –ke [file] klist –keK [file]
A file name can be provided if the keytab is not in the default location. The first form just lists the principals; the second also includes the encryption algorithms and the third also includes the key values in hexadecimal.
Here's some example output from klist -ke:
Keytab name: FILE:/etc/krb5.keytab KVNO Principal ---- -------------------------------------------------------------------------- 5 ALTAIR$@EXAMPLE.COM (des-cbc-crc) 5 ALTAIR$@EXAMPLE.COM (des-cbc-md5) 5 ALTAIR$@EXAMPLE.COM (des3-cbc-sha1) 5 ALTAIR$@EXAMPLE.COM (aes128-cts-hmac-sha1-96) 5 ALTAIR$@EXAMPLE.COM (aes256-cts-hmac-sha1-96) 5 ALTAIR$@EXAMPLE.COM (arcfour-hmac) 5 HOST/altair@EXAMPLE.COM (des-cbc-crc) 5 HOST/altair@EXAMPLE.COM (des-cbc-md5) 5 HOST/altair@EXAMPLE.COM (des3-cbc-sha1) 5 HOST/altair@EXAMPLE.COM (aes128-cts-hmac-sha1-96) 5 HOST/altair@EXAMPLE.COM (aes256-cts-hmac-sha1-96) 5 HOST/altair@EXAMPLE.COM (arcfour-hmac) 5 HOST/altair.EXAMPLE.COM@EXAMPLE.COM (des-cbc-crc) 5 HOST/altair.EXAMPLE.COM@EXAMPLE.COM (des-cbc-md5) 5 HOST/altair.EXAMPLE.COM@EXAMPLE.COM (des3-cbc-sha1) 5 HOST/altair.EXAMPLE.COM@EXAMPLE.COM (aes128-cts-hmac-sha1-96) 5 HOST/altair.EXAMPLE.COM@EXAMPLE.COM (aes256-cts-hmac-sha1-96) 5 HOST/altair.EXAMPLE.COM@EXAMPLE.COM (arcfour-hmac)
In a normal Kerberos system using a standard Kerberos Domain Controller (KDC) each SPN is a separate principal with a different password. In Active Directory, SPNs are essentially 'aliases' of a single account, stored as values of the AD servicePrincipalName LDAP attribute. When a computer account is created in AD, SPNs for the HOST service are created automatically. If additional services such as IIS or SQLserver are installed on the server, additional SPNs will be added to the account.
The Windows setspn command can be run on an AD server to manage the SPNs for an account. For example:
setspn -A HTTP/altair.example.com altair$
The first command adds an HTTP SPN to the machine account for altair. (The Windows account name for a computer always ends with $).
Creating keytabs using existing tools
In a normal Kerberos system, keytab entries are created using the ktadd subcommand of the Kerberos administration tool kadmin. AD does not provide a Kerberos administration server so other approaches are required.
The keytab contains the encrypted password for the account so for each method either the password for the account must be known in advance, or it must be run with privileges to change the account password.
The method to use depends on the system configuration. Some existing options are:
-
Samba: If the system has been registered with AD using the Samba suite, the net ads keytab command can be used to create and update the keytab. This works because Samba has set the password for the account and stored it in a secret location.
-
ktpass: The Windows ktpass command can run by an AD administrator to generate keytab entries. Unless there is no other alternative, do not use this command. It is complex and very difficult to use reliably. It will update the password of the account, thus rendering any previous keytab useless.
-
msktutil: This is an open source application for Unix which can be used to manage keytabs.
Creating keytabs using winktab
winktab is a Java application which can be used to create a keytab for an account in AD. It contacts AD to determine the KVNO for the account and to determine the SPNs associated with the account. If run with an administrator account, it can reset the account password to a random value; alternatively the account password can be supplied to the command.
winktab can be run on any system which can connect to the AD server.
To create a keytab for a machine account and reset the password to a random value:
java -jar stuff.jar winktab -o ktfile -domain DOMAIN -server adserver -user aduser -pw adpw -tls machinename To create a keytab for a machine account using a known password: java -jar stuff.jar winktab -o ktfile -accpw accpw -domain DOMAIN -server adserver -user aduser -pw adpw [-tls] machinename
The parameters are:
-
ktfile: the keytab is written to this file
-
accpw: the password for the machine or user account; if a single dash (-) is used the command will prompt for the password without echo
-
DOMAIN: the AD domain name
-
adserver: the host name or IP address of an AD server for the domain
-
aduser, adpw: the user name and password of an AD account which is used to connect to the server for queries. The user name must be:
user@DOMAIN
or SHORTDOMAIN\user
If a single dash (-) is given as the password the command will prompt for it without echo.
If the account password is set to a fixed (-setpw used) or random (-setpw and -accpw omitted), the user must have administrator privileges.
-
machinename: the name of a computer account. The internal AD account name will be machinename$. The internal AD account name is stored in the sAMAccountName LDAP attribute.
Use the -tls switch if the AD server requires authenticated connections. Windows requires an encrypted connection if an account password is being reset so -tls must be used if the password is being reset to a random or known value.
Example for the domain EXAMPLE.COM, split over several lines for clarity:
java -jar stuff.jar winktab -o altair.keytab -setpw altair \ -domain EXAMPLE.COM -server dc1.example.com \ -user "example\Admin" -tls altair
Create a keytab for a machine account, setting the password to a known value and prompting for the administrator password.
Check the Unix Kerberos configuration
The Kerberos configuration used by commands such as kinit and the Java runtime is read from a global configuration file, normally stored at /etc/krb5.conf. This contains references to the domain controllers and mappings between DNS and Kerberos domains. Here's an example for the domain EXAMPLE.COM:
[logging] default = FILE:/var/log/krb5libs.log kdc = FILE:/var/log/krb5kdc.log admin_server = FILE:/var/log/kadmind.log [libdefaults] default_realm = EXAMPLE.COM dns_lookup_realm = false dns_lookup_kdc = false ticket_lifetime = 24h renew_lifetime = 7d forwardable = yes [realms] EXAMPLE.COM = { kdc = dc1.example.com:88 } [domain_realm] .example.com = EXAMPLE.COM example.com = EXAMPLE.COM
The [realms] section lists the KDCs by host or IP for each domain; the [domain_realm] section maps DNS host names to Kerberos domains.
krb5.conf must be checked and adjusted for the configuration of the target domain. If it is not possible to update a file in /etc, store the file elsewhere and inform the Java runtime of the location via a system property. To do this, edit or create the file jvm.properties in the EDQ local configuration directory and add the line:
java.security.krb5.conf = absolute path to modified krb5.conf
Java Encryption
Java runtime environments do not ship with support for high-strength ciphers by default. For example AES with 256-bit keys is not supported. Active Directory and Kerberos support a full set of ciphers and it may be that your key table contains entries not supported by Java. In this case you should install the JCE Unlimited Strength Jurisdiction Policy Files, if permitted in your location.
Changes to login.properties
In this example, the server running EDQ is assumed to be altair.example.com.
-
Global Settings:
realms = internal, ad spn = HOST/altair.example.com@EXAMPLE.COM keytab = /etc/krb5.keytab ldap.prof.useprimarygroup = false
The 'spn' property sets the Service Principal to use for the GSSAPI accept context. The value shown here is the default and can be omitted if the Unix server's DNS domain the same as the AD domain. Sometimes Unix servers are in a separate DNS domain and the 'spn' property is then required.
The 'keytab' property sets the location of the Kerberos key table. Java does not default this to the standard location and this property is always required.
-
LDAP server settings:
ad.ldap.server = dc1.example.com ad.ldap.spn = "ALTAIR$@EXAMPLE.COM"
Set the server name and Kerberos principal used to connect to Active Directory. The principal should be the key table entry containing the actual machine account name. As before the server can be omitted if it can be determined from DNS.
-
Putting it all together:
This is the complete login.properties used for the Active Directory + Kerberos integration example:
# EXAMPLE.COM LDAP integration with Kerberos realms = internal, ad spn = HOST/altair.example.com@EXAMPLE.COM ldap.prof.useprimarygroup = false keytab = /etc/krb5.keytab ad.realm = EXAMPLE.COM ad.label = Example, Inc. Active directory ad.ldap.server = dc1.example.com ad.ldap.spn = "ALTAIR$@EXAMPLE.COM" ad.ldap.security = tls ad.auth = ldap ad.auth.bindmethod = simple ad.auth.binddn = search: dn ad.ldap.profile = adsldap ad.ldap.prof.defaultusergroup = edqusers ad.ldap.prof.groupsearchfilter = (cn=edq*)
With this login.properties in place, a Windows user in the EXAMPLE.COM domain should be able to login to an EDQ application without supplying additional credentials. The user must of course have the permission in EDQ to use the application.