Running Wildfire with GSSAPI Authentication
Contents
Introduction
GSSAPI is the Generic Security Services Application Programing Interface. Its primary use today is with Kerberos authentication, but other mechanisms may use GSSAPI too, I just dont know of any. The XMPP protocol defines a way to log in using SASL, which allows multiple mechanisms to be used, including GSSAPI. Therefore, its possible to use Kerberos authentication with Jabber. All thats needed is a server and client that speak the right language. My patches greatly improve the SASL interface to Wildfire, allowing GSSAPI to be used. Kerberos is the primary authentication mechanism in Windows Active Directory, so this setup can be used for both Unix and Windows. Update: My patches have been included in Wildfire 3.0.0!
Install
Install Wildfire 3.0.0 or later as normal. Its often best to start from a working install and go from there. That way you at least know the server is functioning properly.
Kerberos Setup
The first thing you need to do is verify your Kerberos setup. This is slightly different between Unix and Windows, but the main ideas are the same. Use the klist command (native to Unix, availible in the Windows Resource Kit) to see that the logged in user has a ticket. If you don't have a Kerberos realm set up, do that now. Any Windows Active Directory is already using Kerberos, and your realm name should be the "Windows Domain Name." Its important that the realm be configured in all upper case letters. While it is perfectly valid to have a realm with lower case names, Java does not handle this well, and its very non-typical these days.
After you verify that Kerberos is working, you need to set up a principal and a keytab for Wildfire. This process is different for Unix and Windows.
Unix
On Unix, this is fairly easy. You need to have an admin account in your realm (typically user/[email protected]). Log into the kadmin command, and create a new xmpp service principal that is the servername used for wildfire. There are a few possibilities here. The server name might be the host name (zeus.example.com), a generic name (jabber.example.com), or just the root domain name (example.com). The service principal should be xmpp/[email protected] where jabber.example.com is what you choose your servername to be, and EXAMPLE.COM is your realm name. The typical command to do this is: addprinc -randkey xmpp/[email protected] but your command may be different depending on realm policy, and kerberos implementation. Next, you need to create a keytab file for Wildfire. Since its a bad idea to run Wildfire as root, the keytab will need to be in a seperate file from the host keytab (typically /etc/krb5.keytab). I suggest /etc/jabber.keytab. At present, Java can only understand a limited number of encryption types, so you may need to make a des3-hmac-sha1 keytab. It looks like Java 6 will support AES encryption giving more flexability. In either case, its also possible you need to download the unlimited strength Java Cryptography Extension (JCE), but this is subject to US Export Control, so be sure to follow the rules for your country. I created my keytab from kadmin with this command: ktadd -k /etc/jabber.keytab -e des3-hmac-sha:normal xmpp/[email protected]
Windows
Windows by default creates a principal for each user you create. So you need to create a new user for this service principal. The username should reflect what you are doing, but the naming rules prevent you from using a username exactly the same as the principal in this case. I created a user named "xmpp-hostname" where hostname is the name of the host wildfire will be running on. Then, you need to run the ktpass tool to map the username xmpp-hostname to the principal xmpp/[email protected] where servername is the name of the server wildfire runs as and EXAMPLE.COM is the name of your realm. Servernames might be the host name (zeus.example.com), a generic name (jabber.example.com), or just the root domain name (example.com). ktpass will create a keytab file at the same time. You need to transfer the keytab file to the host that will run wildfire. The security of this file is of the most importance! Do not just use Windows Network Neighborhood to transfer the file, you should either put it on a external disk and move the disk over (floppy, USB, CDROM, etc) or use some encrypted network protocol. I recomend naming the keytab jabber.keytab and putting it in C:\Program Files\Wildfire\resources\ . Example ktpass usage: Ktpass princ xmpp/[email protected] mapuser jabber-username -pass password out jabber.keytab See http://www.microsoft.com/technet/prodtechnol/windows2000serv/howto/kerbstep.mspx for more documentation.
Mixed Windows/Unix
If you have Windows as your KDC, and Unix as your server, then follow the procedure for generating the keytab on Windows, and securely transfer it to the Unix host and follow the directions there on where to install it. Or the other way around, if you are that unlucky
DNS Setup
DNS is very important when using Kerberos. You must make sure that the name of your principal created matches a DNS entry pointing to the same host. Failure to do so will likely break things in odd ways. Reverse DNS is also a really good idea.
Time Setup
Kerberos is a time sensitive protocol. Its in your best interest to make sure your Wildfire server's clock is synconized with the KDC. Clients are often given a 5 minute clock-skew, but its best if they can be syncronized even closer. NTP is the most common way of accomplishing this, but other methods may exist.
Wildfire Setup
Setting up Wildfire is mostly the same for Unix and Windows. This is mostly due to the fact that on Windows we create a service principal that can be exported to Unix. At this point in time, almost all configuration options are in the wildfire.xml configuration, and some in a seperate configuration file for java (gssapi.conf). Work will be done to move as many of these properties to standard JiveGlobal properties so a web interface can be created. First things first, this guide assumes you already set up a working Wildfire server, and you have a user and auth provider already working before you applied the patches. If you have not already set the rest of your server up, do so now according to the official Wildfire documentation. You wont be able to test your setup until you complete the rest of this procedure.
See an example configuration file here: wildfire.xml
SASL Setup
The wildfire.xml gets a new section named sasl. Most of our configuration goes into this section. First, we need to list what mechanisms Wildfire will advertise to clients. The mechanisims property is a comma/space seperated list of mechanisms. Make sure GSSAPI is listed. You can add other mechanisms if you want, in order to support non GSSAPI clients, or clients who cannot authenticate to the realm (like Windows 9X, off site, etc). Keep in mind that by allowing other mechanisms you are compromising the security of your realm. Be sure to talk to the Security Officer/Directory/Manager/Administrator about any policies your organization may have before enabling less secure mechanisims. By removing PLAIN and ANONYMOUS from the list, you will also disable non-SASL authentications. The order you list the mechanisms in is important. Clients should try to use the first mechanism they support. Not all will, however. Some clients will try to use the most secure first. Its still a good idea to put GSSAPI first in the list, though.
Next, you need to set the realm. Other SASL methods may use the concept of a realm, and this service should use the same realm for all SASL mechanisms.
Then, add a gssapi section, and inside that section set a few things:
- config : The location of the gssapi.conf file that Java will use. Putting it in the same directory as the wildfire.xml is a good idea.
useSubjectCredsOnly : Sets the system property with the same name. Read here for details: http://java.sun.com/j2se/1.4.2/docs/api/org/ietf/jgss/package-summary.html
- debug : True to turn on debugging information. It will clutter your log files a lot, but in the initial setup it can help you spot any problems sooner.
Thats it for the gssapi and sasl sections of the config.
Provider Setup
There is a new provider you need to set also:
provider.authorization.classList : The class name of the AuthorizationProvider's you wish to use. This class provides an authorization mapping between authenticated principals and usernames. A comma or space seperated list is fine here. If you leave this provider out, the default will be used, which may be fine for many installations. Here is a list of availible providers:
- TODO: Finish list
GSSAPI Setup
Next, you need to configure the gssapi.conf file for java. This file is pretty easy to figure out. Here is an example:
/** * Login Configuration for JASS. */ com.sun.security.jgss.accept { com.sun.security.auth.module.Krb5LoginModule required storeKey=true keyTab="/etc/jabber.keytab" doNotPrompt=true useKeyTab=true realm="EXAMPLE.COM" principal="xmpp/[email protected]" debug=true; };
Things you should change in this file are:
- keyTab : the location of the keytab you created earlier
- realm : the name of your realm
- principal : the name of the principal you created earlier
- debug : leave it at true while setting up, set it to false later.
Its important to leave the rest of this file alone. For complete documentation of this file, go here: http://java.sun.com/j2se/1.4.2/docs/guide/security/jgss/tutorials/LoginConfigFile.html
Testing
After all this, you will want to do some testing. A simple Smack program with debugging can show you what is happening at the stream level. You should see the mechanisms being advertised by the server including GSSAPI. The client should respond with an <auth type="GSSAPI"> packet with lots of base64 stuff in it. Generally there are going to be 6 packets exchanged just for authentication, if you see something much different, something went wrong.
Debugging
Things to check when it goes wrong:
- Can the client run kinit and klist?
- Does Java have the ability to understand the encrpytion type Kerberos is using in the client credential cache? If not, maybe Java 6 can.
- Does Java have the ability to understand the encryption type Kerberos is using in the server keytab? If not, maybe Java 6 can.
- In Windows2003 AD, you might need to set the users to "Allow DES encryption for this user"
- You might need to install the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files (found on the same download page as Java- but not availible in all countries)
- Does the User running Wildfire have the ability to read the keytab (filesystem permissions)
- Does Java know how to read the Kerberos Credential Cache?
- Windows XP might need to tell Java that its OS name is "Windows 2000" in order to access the native credential cache (use -Dos.name="Windows 2000" on the java commandline)
- Some Unix's might need to force the credential cache to a certain file by setting the environment variable KRB5CCNAME to "/tmp/krb5cc_$UID"