I've selected Twiki as it's touted as an appropriate wiki for corporate environments. I like the idea of an open wiki like Wikipedia, but I'm a realist and know that _some_ control is required in an office setting. It's collaboration with structure. If Twiki doesn't work out, I'll try another one on.
Since I already manage several password stores (and scores more personal passwords), I don't want to maintain another set of credentials. I also want to easily enable this new wiki for my users without them needing to login with a new ID. It's a struggle sometimes to strike that fine balance between security and usability, but it's not impossible. To that end, I've decided to integrate Twiki with Active Directory; my users will be able to log in to the wiki using their workstation credentials once for their entire session. To do this, I need to kerberize Apache. If you're new to Kerberos, see my previous post for a beginner's overview.
What follows is a brain dump of my trials to achieve this goal.
There are several online pages that provide information on this subject, some more relevant or verbose than others. However, I did not find any single source that provided all the steps I needed to get this working, nor the fixes for some snags I encountered. Hopefully, this helps you.
Assumptions
- You're familiar enough with Linux/UNIX systems to administrate them (i.e. edit config files, compile source code, restart services)
- You're comfortable working in Windows environments (GUI and command line) and you're familiar with administration tools such as the Active Directory Users and Computers MMC Snap-in
- You _have_ a Linux system, running Apache, and you want to kerberize it!
Steps
Configure Kerberos
Build the Apache module 'mod_auth_kerb'
Active Directory and Service Principals
Creating Service Principals with ktpass
Configure mod_auth_kerb to Authenticate Against AD
VirtualHost Caveat
----------||----------
Configure Kerberos
Edit the Kerberos configuration file (typically /etc/krb5.conf; check your distro). The notable bits are in bold:
[logging]Confirm successful authentication using a known-good account (like your own!)...
default = FILE:/var/log/krb5libs.log
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log
[libdefaults]
default_realm = MYDOMAIN.COM
dns_lookup_realm = false
dns_lookup_kdc = false
ticket_lifetime = 24h
forwardable = yes
[realms]
MYDOMAIN.COM = {
kdc = dc1.mydomain.com:88
kdc = dc2.mydomain.com:88
admin_server = myadmin.mydomain.com:749
default_domain = mydomain.com
}
[domain_realm]
.mydomain.com = MYDOMAIN.COM
mydomain.com = MYDOMAIN.COM
[kdc]
profile = /var/kerberos/krb5kdc/kdc.conf
[appdefaults]
pam = {
debug = false
ticket_lifetime = 36000
renew_lifetime = 36000
forwardable = true
krb4_convert = false
}
[root@logjam]# kinit jdoe@MYDOMAIN.COMAs long as 'kinit' doesn't present any errors, you're good to go. You can confirm that you've been granted a ticket-granting ticket (TGT) with 'klist':
Password for jdoe@MYDOMAIN.COM:
[root@logjam]# klist -5Destroy the Kerberos ticket; we don't need it:
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: jdoe@MYDOMAIN.COM
Valid starting Expires Service principal
08/07/08 15:07:13 08/08/08 01:07:43 krbtgt/MYDOMAIN.COM@MYDOMAIN.COM
renew until 08/08/08 15:07:13
[root@logjam]# kdestroyBuild the Apache module 'mod_auth_kerb'
Apache natively supports a few authentication protocols such as Basic and Digest but we want to use Kerberos. In order to add in that functionality, we'll need to install the module 'mod_auth_kerb'. I downloaded the source (current package == mod_auth_kerb-5.3) from Sourceforge. Unpack the code in your favorite build directory; I like '/usr/local/src':
[root@logjam src]# tar zxf mod_auth_kerb-5.3.tar.gzAnd change into the source directory:
[root@logjam src] # cd mod_auth_kerb-5.3Configure the package for installation. If you have a custom location for your Apache location, be sure to specify that with the
--with-apache=
argument so that the module will get installed in the correct location (i.e. /usr/local/apache2/modules). I also like to explicitly disable Kerberos 4 support and make sure my Kerberos 5 binaries/libraries are found for linking:[root@logjam mod_auth_kerb-5.3]# ./configure \Assuming that 'configure' hasn't complained about missing support for anything, build and install the module:
> --with-apache=/usr/local/apache2 \
> --with-krb4=no \
> --with-krb5=/usr/kerberos
[root@logjam mod_auth_kerb-5.3]# makeNext, tell Apache to load in the module to provide support for Kerberos authentication. Edit the Apache config file, httpd.conf, and add the following line in the section where modules are explicitly loaded:
[root@logjam mod_auth_kerb-5.3]# make install
LoadModule auth_kerb_module modules/mod_auth_kerb.soRestart the Apache service and check for errors.
Active Directory and Service Principals
This is the part I spent most of my time with. Apache's been kerberized and now I need a valid service principal to allow my users to authenticate from Twiki. From my research I found that Microsoft, in their usual wisdom, decided that they would implement their own flavor of Kerberos. They adhere to the protocol (as much as I can tell considering I've not bothered to read the RFCs in full!) except for one critical convention that was staring me in the face the whole time and didn't fully regsiter: Windows account names are different from strict Kerberos principals. This note from Step-by-Step Guide to Kerberos 5 (krb5 1.0) Interoperability explains it (emphasis mine):
Windows 2000 account names are not multipart as are Kerberos principal names. Because of this, it is not possible to directly create an account of the name host/hostname.dns.com. Such a principal instance is created through service principal name mappings. In this case, an account is created with a meaningful name hostname and a service principal name mapping is added for host/hostname.dns.com. This is the purpose of using Ktpass with the princ and mapuser switches.To summarize, AD creates account names (loosely, principals, in this context) using the convention
username@domain.tld
and Kerberos is looking for principals whose convention is service/hostname@REALM
. (Sidenote: Bascially, a Windows domain and Kerberos realm are synonymous. Both require a functioning DNS implementation. At the least, some DNS server needs to know about your domain and can return records so that AD and Kerberos work.) So we need to do a few things to ensure interoperability:- Create a user account that will act as the Linux host's principal (i.e. computer account). Some folks suggest installing Samba and joining the doman, but it doesn't need to be that complicated.
- Create a second user account that will be used to create the service principal that Apache will depend on for authentication.
- twiki = Host principal (i.e. "machine"/computer account)
- twikiService = Service principal (account for the web service, Apache)
service/hostname@REALM
?). And since we don't have Samba installed so that our Linux box can join the AD domain, we're effectively tricking AD into believing we've got a computer account that matches the hostname in our service principal. This will become clearer as we progress.Creating Service Principals with ktpass
Now we need to generate the service principals using 'ktpass'. This command is available on domain controllers or in the Windows Resource Kit. 'ktpass' can also generate a keytab (key table) file that we'll use later. The keytab file allows a service to request tickets without needing to send a password for each request. We'll start with the host principal. We'll create a principal named HOST/twiki.mydomain.com@MYDOMAIN.COM and map it to the user account twiki. The
-princ
and -mapuser
arguments to 'ktpass' create the service principal and map the user account, respectively.In some cases, I've explicitly specified arguments whose values are the same as the command's defaults; I've done this so that the reader can see exactly what's happening. Of note is the +rndpass argument, however. It tells ktpass to generate a random password. You don't need this password to match the account's password. This also allows you to change the account's password without affecting the keytab file and hence authentication by the service.
The command and its output are below (line breaks added for easier reading where necessary):
C:\Resource Kit>ktpass -princ HOST/twiki.mydomain.com@MYDOMAIN.COMIf you're running a Windows 2000 Active Directory domain, ignore errors regarding the key version number (aka kvno). They're harmless.
-mapuser twiki -mapop add -out twikiHOST.keytab +rndpass -crypto DES-CBC-CRC
+desonly -ptype KRB5_NT_PRINCIPAL +dumpsalt
Targeting domain controller: dc1.MYDOMAIN.COM
Using legacy password setting method
Successfully mapped HOST/twiki.mydomain.com to twiki.
Failed to retrieve values for property msDS-KeyVersionNumber: 0x10.
The msDS-KeyVersionNumber attribute does not exist on the target DC.
Assuming this is a Windows 2000 domain, and setting
the Key Version Number in the Keytab to 1.
Supply "/kvno 1" on the command line to skip this message.
Failed to retrieve values for property msDS-KeyVersionNumber: 0x10.
Building salt with principalname HOST/twiki.mydomain.com and domain MYDOMAIN.COM...
Hashing password with salt "MYDOMAIN.COMHOSTtwiki.mydomain.com".
Key created.
Output keytab to twikiHOST.keytab:
Keytab version: 0x502
keysize 69 HOST/twiki.mydomain.com@MyDOMAIN.COM ptype 1
(KRB5_NT_PRINCIPAL) vno 1 etype 0x1 (DES-CBC-CRC) keylength 8 (0xc49754ce6e15e902)
Account twiki has been set for DES-only encryption.
To confirm that the service principal has been created, you can use the 'setspn' command (also available on domain controllers and the resource kit). Pass
-L accountName
to the command to display the service principal it's mapped to:C:\Resource Kit\>setspn -L twikiNext, we'll create the service principal for Apache. The service name will be HTTP so that the service principal will look like this: HTTP/twiki.mydomain.com@MYDOMAIN.COM. Using 'ktpass', we'll map this service principal to the account named twikiService.
Registered ServicePrincipalNames for CN=twiki,OU=Service_Accounts,DC=MYDOMAIN,DC=com:
HOST/twiki.mydomain.com
C:\Resource Kit>ktpass -princ HTTP/twiki.mydomain.com@MYDOMAIN.COMRun 'setspn' again to confirm the service principal is mapped:
-mapuser twikiService -mapop add -out twikiHTTP.keytab +rndpass -crypto DES-CBC-CRC
+desonly -ptype KRB5_NT_PRINCIPAL +dumpsalt
Targeting domain controller: dc1.MYDOMAIN.COM
Using legacy password setting method
Successfully mapped HTTP/twiki.mydomain.com to twikiService.
Failed to retrieve values for property msDS-KeyVersionNumber: 0x10.
The msDS-KeyVersionNumber attribute does not exist on the target DC.
Assuming this is a Windows 2000 domain, and setting
the Key Version Number in the Keytab to 1.
Supply "/kvno 1" on the command line to skip this message.
Failed to retrieve values for property msDS-KeyVersionNumber: 0x10.
Building salt with principalname HTTP/twiki.mydomain.com and domain MYDOMAIN.COM...
Hashing password with salt "MYDOMAIN.COMHTTPtwiki.mydomain.com".
Key created.
Output keytab to twikiHTTP.keytab:
Keytab version: 0x502
keysize 69 HTTP/twiki.mydomain.com@MYDOMAIN.COM ptype 1
(KRB5_NT_PRINCIPAL) vno 1 etype 0x1 (DES-CBC-CRC) keylength 8 (0xe0374fc44373f138)
Account twikiService has been set for DES-only encryption.
C:\Resource Kit>setspn -L twikiServiceNote the keytab output (twikiHTTP.keytab). We'll need that file in the next section.
Registered ServicePrincipalNames for CN=twikiService,OU=Service_Accounts,DC=MYDOMAIN,DC=com:
HTTP/twiki.mydomain.com
Configure mod_auth_kerb to Authenticate Against AD
Now that we have our keytab file, we need to securely transfer it to our Apache host. I used the PuTTY SSH command suite (pscp in this example):
C:\PuTTY>pscp twikiHTTP.keytab me@logjam:Move/copy this file to the root of your Apache installation (or whereever you prefer) and secure the file for reading only by the Apache service:
me@logjam's password:
twikiHTTP.keytab | 0 kB | 0.1 kB/s | ETA: 00:00:00 | 100%
[root@logjam apache2]# mv ~me/twikiHTTP.keytab .Make sure that you can grab a ticket-granting ticket using the 'kinit' command:
[root@logjam apache2]# chown apache:apache twikiHTTP.keytab
[root@logjam apache2]# chmod 600 twikiHTTP.keytab
[root@logjam apache2]# kinit -k -t twikiHTTP.keytab HTTP/twiki.mydomain.com@MYDOMAIN.COMConfirm that the we have a ticket-granting ticket (TGT):
[root@logjam apache2]# klist -5And destroy the TGT; we don't need it:
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: HTTP/twiki.mydomain.com@MYDOMAIN.COM
Valid starting Expires Service principal
08/08/08 14:35:33 08/09/08 00:35:33 krbtgt/MYDOMAIN.COM@MYDOMAIN.COM
renew until 08/09/08 14:35:33
[root@logjam apache2]# kdestroyIf you encounter any issues with the kinit command, you may want to check the logs on your domain controllers for more information.
Now that we have a working keytab file, we need to configure the mod_auth_kerb module within Apache's configuration file. Add the following lines within the
Directory
block where the main Twiki site exists:Order Deny, AllowBe sure to comment out the line
Allow from all
AuthType Kerberos
KrbAuthRealms MYDOMAIN.COM
KrbServiceName HTTP
Krb5Keytab /usr/local/apache2/twikiHTTP.keytab
KrbMethodNegotiate on
KrbMethodK5Passwd on
Require valid-user
AuthType Basic
to disable Basic authentication.At this point, when accessing the main Twiki page, users should be prompted for a username and password. Their AD credentials will get them logged in for the entire session.
VirtualHost Caveat
Well, the story isn't quite over. Even after all the above steps, I continued to run into an issue preventing me from logging into my Twiki site. My Apache error_log file was full of the following message:
[Fri Aug 08 16:19:41 2008] [error] [client 1.2.3.4] failed to verify krb5 credentials:The reason for this error was that I'm hosting Twiki in an Apache instance that serves other websites as well. In other words, Twiki is defined as a virtual host in a
Server not found in Kerberos database
VirtualHost
block. Its DNS name (twiki.mydomain.com) is not the same as the physical host (logjam.mydomain.com) running Apache. What really bit me was that my /etc/hosts
file had an entry for the local host in it (common for most Linux distros):1.2.3.4 logjam.mydomain.comSo, anytime mod_auth_kerb tried to authenticate, it was passing HTTP/logjam.mydomain.com@MYDOMAIN.COM to my domain controllers and they kept replying that they did not know who/what logjam.mydomain.com was. I commented that line out of the hosts file and all is well.
Now, some may argue that I should just have created the service principal for logjam.mydomain.com; but I'm inclined towards flexibility and want to be ready for the chance that I may indeed move my Twiki site to a dedicated host that uses the same fully qualified domain name (FQDN). If that happens, I'm all set. If not, or I migrate it to another multi-site host, I'll just refer back to this page!
No comments:
Post a Comment