On 6/2/05, Kenneth Porter <shiva@xxxxxxxxxxxxxxx> wrote:
> Agreed. I'm trying to get up to speed on deploying OpenLDAP together with
> the Samba schema to get single sign-on and a global address book, but it's
> been tough marshaling all the HOWTO's to figure out what's really required.
> I went down a wrong path using the PADL scripts bundled with OpenLDAP
> (because I failed to select the "enhanced" schema in the common config
> file) and they also fail badly on the /etc/services file due to the
> presence of Apple protocols. So far the best information for initial setup
> seems to be in the HOWTO's at <http://samba.idealx.org/>, but I'm still
> working through it to understand how to migrate my existing setup.
Single sign-on doesn't require a LDAP server, but some kind of central
identity magament which can be supplied by using a Kerberos V KDC like
the Kerberos V MIT implementation that comes in the form of krb5-*
packages for Fedora Core.
Once upon I time I wrote the attached document which enumerates all
the steps I had to perform in order to set up a Kerberos V KDC and how
to configure services like OpenSSH to support single sign-on. HTH.
- Sunday, 20 April 2003
Add support to our LAN for MIT Kerberos V5
Well, I've been playing around with Kerberos V5 and I think it's simply
wonderful. It's the single-sign-on came true. So, I've decided to deploy
it on my LAN.
REQUISITES
----------
NTP (Network Time Protocol, a protocol used to synchronize the clock
of the computer)should be setup and working properly. Kerberos is a
time-sensitive network authentication protocol. Authentication won't
work if the clock skews between computers in more than +/- 5 minutes.
CONCEPTS
--------
KEYTAB:
A keytab file contains the secret keys of hosts so they can communicate
between them. Kerberos uses symmetric cryptography based on a shared-
secret key. Those shared-secret keys must be kept in a file, which must
be secured properly so no one, except "root" and the Kerberos services
could read it.
A host shared-secret key is created when the host principal is first
created using the "addprinc" command of the KAdmin service. Normally,
the "-randkey" argument is used so the key is generated randomly instead
of being interactively prompted (and confirmed). Normally, security
principals are *never* assigned random keys, and they are assigned by
the administrator and later, optionally, changed by theit owner.
It's very important that the keytab file is properly secured, although
it must be shared between all servers of a Kerberos realm, let they be
KDC server or standard Kerberos servers (like SSH or Kerberized FTP
servers). Clients don't access to the keytab. The keytab is usually
placed at "/etc/krb5.keytab" and contains several records for each host
principal. Normally, two records exist for each host, one for DES and
another one for Triple-DES. Also, each record has a version number that
is increased at the moment of adding the host to the keytab file using
the "ktadd" command. If the version number of a host differs between
keytabs, no communication will take place. Every time "ktadd" is used,
the host principal is written to the keytab, but it's version number
is increased. This could lead to different version numbers across some
keytabs.
The "kvno" command can be used to check the version number of a host
principal, for example:
# kvno host/kerberos.felipe-alfaro.com
host/kerberos.felipe-alfaro.com@xxxxxxxxxxxxxxxxx: kvno = 3
TICKET GRANTING TICKET (TGT):
A host needs a Kerberos ticket in order to access a network server
that relies on Keberos V5 for authentication. To be able to obtain
an specific ticket for a network service, the client needs to
request such ticket to the Key Distrution Center (KDC). However,
the client needs to authenticate against the KDC. This is done only
once: the client first authenticates against the KDC, normally by
supplying a security principal name and a password and, if both
are checked to be correct, the KDC sends a Ticket Granting Ticket
(TGT) to the client. The client will then use this TGT when
requesting additional tickets for servers in the network. Simply
by presenting the TGT to any KDC, the KDC can expedite an specific
ticket granting communication between that client and a network
server (for example, an SSH or FTP server).
INSTRUCTIONS
------------
The first step is to deploy the Kerberos V5 Key Distribution Center (KDC)
on a computer that has 24h365d uptime, so the ideal candidate is "small".
Since Engarde Linux doesn't have a Kerberos V5 KDC server by default, I
had to download it from "ftp://ftp.engardelinux.org/pub/engarde/contrib".
To install it:
# lidsadm -S -- -LIDS_GLOBAL
# rpm -ivh krb5-libs-1.2.2-4.i386.rpm
# rpm -ivh krb5-workstation-1.2.2-4.i386.rpm
# rpm -ivh krb5-server-1.2.2-4.i386.rpm
Before we re-enable LIDS, some file tweaking must be done as init scripts
for the KDC and KAdmin have some glitches:
1. The Kerberos V5 contrib packages deploy the service scripts at the
incorrect directory. So, we need to move all files from
"/etc/rc.d/init.d" to "/etc/init.d".
2. Remove "/etc/rc.d/init.d" and "/etc/rc.d" (they should be empty now).
3. Edit "/etc/init.d/kadmin" and "/etc/init.d/krb5kdc" and then remove
the lines that source "/etc/sysconfig/network" and the ${NETWORKING]
check at the beginning.
4. In "/etc/init.d/krb5kdc" replace "/etc/rc.d/init.d/functions" at the
beginning of the file with "/etc/rc.d/functions".
Now, we can re-enable LIDS:
# /usr/sbin/config_lids.pl
# lidsadm -S -- +LIDS_GLOBAL
So, we have Kerberos V5 installed. We should make sure it's started
automagically if the machine is rebooted:
# chkconfig --add kadmin
# chkconfig --add krb5kdc
# chkconfig --level 345 kadmin on
# chkconfig --level 345 krb5kdc on
We can't start Kerberos services yet. First, we need to create the needed
entries in our DNS server. Although I've been unable to completely avoid
text-based configuration files and use DNS completely for KDC and realm
lookups, maybe one day I guess it. For now, we need to add the following
entries to our master "db.felipe-alfaro.com" database.
NOTE: Don't forget to increase in one the serial number of the zone, so
all our slave DNS servers will get informed of the changes and be able to
perform an incremental zone transfer (IXFR).
kerberos.felipe-alfaro.com. IN CNAME small.felipe-alfaro.com.
Out KDC will have the canonical name "kerberos" which is the recommended
by the MIT. It's simply a pointer to our real KDC located at "small".
_kerberos.felipe-alfaro.com. IN TXT "FELIPE-ALFARO.COM"
This entry is *theoretically* used by Kerberos clients to guess the realm
from the FQDN of a host name. The client will look up a TXT record in DNS
composed of "_kerberos" plus the FQDN of the host. For example, if a client
is trying to access the machine "foo.felipe-alfaro.com", it will try to
locate a TXT record called "_kerberos.foo.felipe-alfaro.com". If the record
can't be found, the client will fall back and will try with the domain name
part of the host, that is, "_kerberos.felipe-alfaro.com". If still no record
can be found, a look up will be sent for "_kerberos.com" and so on until a
TXT record is found or no more fallback is possible. If a TXT record is
found, the contents (descriptive text) of the record is assumed to be the
Kerberos realm for that host.
In our case, we won't mantain TXT records for every host, so we'll depend
on fallback, "_kerberos" plus the FQDN, that is, "_kerberos.felipe-alfaro.com".
_kerberos._udp.felipe-alfaro.com. IN SRV 0 0 88 kerberos.felipe-alfaro.com.
This record is used to locate all the KDCs. Note that the domain name
appended to "_kerberos._udp" is the lower case representation of the Kerberos
realm and does *not* need to necessarily be equal to the DNS domain name, In
our case, the DNS domain name and Kerberos realms are identical. As we do only
have one KDC, only one record is used. If we had two more KDC servers, we
would add two more records for them.
_kerberos-master._udp.felipe-alfaro.com. IN SRV 0 0 88 kerberos.felipe-alfaro.com.
This record points to the master KDC. Kerberos is similar to DNS, NIS and
LDAP in which a master server is the only one in charge for database updates
which are then replicated to slave servers.
_kerberos-adm._tcp.felipe.alfaro.com. IN SRV 0 0 749 kerberos.felipe-alfaro.com.
This record points the Kerberos V5 KAdmin server, the one that is used to
administer Kerberos (for example, adding new principals, policies, etc.)
_kpasswd._udp.felipe-alfaro.com. IN SRV 0 0 464 kerberos.felipe-alfaro.com.
This is used to the kpasswd service that allows principals to change their
passwords without full access to the KAdmin service.
The next step is to reload the DNS server for it to pick up the changes:
# service named reload
or
# service named restart
Now that we have the DNS infraestructure in place, we need to edit the
configuration files. First, we'll edit "/etc/krb5.conf":
# cat /etc/krb5.conf
[logging]
default = FILE:/var/log/krb5libs.log
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log
[libdefaults]
ticket_lifetime = 24000
default_realm = FELIPE-ALFARO.COM
dns_lookup_realm = false
dns_lookup_kdc = false
[realms]
FELIPE-ALFARO.COM = {
kdc = kerberos.felipe-alfaro.com:88
admin_server = kerberos.felipe-alfaro.com:749
default_domain = felipe-alfaro.com
}
[domain_realm]
.felipe-alfaro.com = FELIPE-ALFARO.COM
felipe-alfaro.com = FELIPE-ALFARO.COM
[kdc]
profile = /var/kerberos/krb5kdc/kdc.conf
[pam]
debug = true
ticket_lifetime = 36000
renew_lifetime = 36000
forwardable = true
krb4_convert = false
The "[realms]" section defines the know Kerberos realms and should be
superseded by DNS sometime in the future (when I guess how to use DNS
for KDC and realm lookups). The "[domain_realms]" provides the needed
translations between DNS domain names and Kerberos realms. Don't forget
to define "default_realm" correctly.
Next, we'll edit "/var/kerberos/krb5kdc/kdc.conf":
# cat /var/kerberos/krb5kdc/kdc.conf
[kdcdefaults]
acl_file = /var/kerberos/krb5kdc/kadm5.acl
dict_file = /usr/share/dict/words
admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab
[realms]
FELIPE-ALFARO.COM = {
master_key_type = des-cbc-crc
supported_enctypes = des-cbc-crc:normal des3-cbc-raw:normal des3-cbc-sha1:normal des-cbc-crc:v4 des-cbc-crc:afs3
}
And now, we'll define the ACL used to allow any principal with the admin
role access to the KAdmin server:
# cat /var/kerberos/krb5kdc/kadm5.acl
*/admin@xxxxxxxxxxxxxxxxx *
Now, we'll create the Kerberos database using "kdb5_util" tool:
# /usr/kerberos/sbin/kdb5_util create -r FELIPE-ALFARO.COM -s
This will create the database for the FELIPE-ALFARO.COM Kerberos realm
and its corresponding stash file (currently don't know what it's used
for, but...) During the process, we'll be asked for the master password
used for recovery and backup purpouses.
Once the database has been created, we'll add the "admin/admin" security
principal used to access the KAdmin service, but since Kerberos is not
fully operational and KAdmin is not started, we'll use a special version
of the "kadmin" tool called "kadmin.local" that doesn't require Kerberos
to be started:
# /usr/kerberos/sbin/kadmin.local
kadmin.local: addprinc admin/admin
Now, we'll add the "kadmin/admin" and "kadmin/changepw" principals to
the KAdmin keytab file, which are used by the "KAdmin" and "kpasswd"
services respectively. The KAdmin keytab is *not* the same standard
keytab used for standard services, and it's usually located at
"/var/kerberos/krb5kdc/kadm5.keytab":
kadmin.local: ktadd -k /var/kerberos/krb5kdc/kadm5.keytab \
kadmin/admin kadmin/changepw
Now, we can start the KDC and KAdmin servers:
# /etc/init.d/kadmin start
# /etc/init.d/krb5kdc start
# tail /var/log/kadmin.log
... small.felipe-alfaro.com kadmind[27420](info): starting
# tail /var/log/krb5kdc.log
... small.felipe-alfaro.com krb5kdc[27441](info): commencing operation
We have to add all security principals that we will use with Kerberos.
Security principals can be of different kind, but mainly we'll use two
types: host principals and security principals. The former is used to
perform authentication and ticket granting at the host level, while the
latter is used by processes, tasks or processes to authenticate to a
Kerberos KDC.
The principals are added using the KAdmin service. We'll need to identify
to the KAdmin service using the "admin/admin" security principal we added
before:
# /usr/kerberos/sbin/kadmin -p admin/admin
We'll now add all out host principals:
kadmin: addprinc -randkey host/kerberos.felipe-alfaro.com
kadmin: addprinc -randkey host/small.felipe-alfaro.com
kadmin: addprinc -randkey host/glass.felipe-alfaro.com
kadmin: addprinc -randkey host/linux.felipe-alfaro.com
kadmin: addprinc -randkey host/teapot.felipe-alfaro.com
kadmin: addprinc -randkey host/compaq.felipe-alfaro.com
The next step is adding the security principals for "kerberos" and the
host itself to the standard keytab file, usually "/etc/krb5.keytab":
kadmin: ktadd host/kerberos.felipe-alfaro.com
kadmin: ktadd host/small.felipe-alfaro.com
Each host is in fact a security (host) principal and has a symmetric,
secret key shared between the host and the KDC. So, only that host
and the KDC know the key. The KDC does already know that key, as we
specified it (well, not exactly: we told the KDC to generate a random
key by using -randkey during the principal creation using "addprinc")
when creating the host principal, and then exported it to the KDC
local keytab file. However, we must now find a way to send that key
to the host itself for it to store. That key must be kept in a "keytab"
file and sent to the host securely. So for each computer that will
host a service that relies upon Kerberos authentication, we will need
to create a keytab with that host's secret key and send that keytab
file to the host using a secure method (for example, on a disk or a
secure network connection).
We will generate the keytab file using the "kadmin" administrative
interface:
kadmin: ktadd -k "/path/to/keytab/for/the/host" "host/principal"
And then we will transfer the keytab file to the corresponding host
and storing it usually as "/etc/krb5.keytab", or another place where
only the Kerberized service itself can access the keytab file
securely.
For example, "glass" will host an OpenSSH server (sshd) with Kerberos
V5 support. To generate its keytab file, we execute the following
command from within "kadmin" (or "kadmin.local"):
kadmin: ktadd -k /root/glass.krb5.keytab host/glass.felipe-alfaro.com
This will create the file "/root/glass.krb5.keytab" containing the
secret key for the "KDC-glass" association. Then, we will transfer
the "/root/glass.krb5.keytab" file to the host "glass" securely. The
keytab file should be stored as "/etc/krb5.keytab" within its file-
system, or a more secure place where only the OpenSSH "sshd" daemon
can access it (I yet have to find how to tell OpenSSH how to search an
specific file for its keytab),
Once the keytab files have been distributed to all network servers
that will host Kerberos-based services, we have to configure all of
them. First, we'll need to install krb5-libs and krb5-workstation
packages (if not already installed) and then edit the "/etc/krb5.conf"
file on all of them. The file should look similar to:
[logging]
default = FILE:/var/log/krb5libs.log
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log
[libdefaults]
ticket_lifetime = 24000
default_realm = FELIPE-ALFARO.COM
dns_lookup_realm = true
dns_lookup_kdc = true
[realms]
FELIPE-ALFARO.COM = {
kdc = kerberos.felipe-alfaro.com:88
admin_server = kerberos.felipe-alfaro.com:749
default_domain = felipe-alfaro.com
}
[domain_realm]
.felipe-alfaro.com = FELIPE-ALFARO.COM
felipe-alfaro.com = FELIPE-ALFARO.COM
[kdc]
profile = /var/kerberos/krb5kdc/kdc.conf
[appdefaults]
pam = {
debug = true
ticket_lifetime = 36000
renew_lifetime = 36000
forwardable = true
krb4_convert = false
}
Now, we'll need to add all security principals that we'll be using:
# kadmin -p admin/admin
kadmin: addprinc falfaro
kadmin: addprinc test
...
At this point, Kerberos should be usable from any of the configured
network servers. To test, we'll use "kinit" to check the TGT service
is running properly:
# kinit
If everything is correct, "klist" should display our newly acquired
TGT:
# klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: root@xxxxxxxxxxxxxxxxx
Valid starting Expires Service principal
04/21/03 00:21:29 04/21/03 10:21:29 krbtgt/FELIPE-ALFARO.COM@xxxxxxxxxxxxxxxxx
Kerberos 4 ticket cache: /tmp/tkt0
klist: You have no tickets cached
Finally, we can enable Kerberos V5 authentication for PAM. To do so,
we can run "authconfig" and select Kerberos V5, or we can manually
modify "/etc/pam.d/system-auth" and add the following lines:
auth sufficient /lib/security/$ISA/pam_krb5.so use_first_pass
account [default=bad success=ok user_unknown=ignore service_err=ignore system_err=ignore] /lib/security/$ISA/pam_krb5.so
password sufficient /lib/security/$ISA/pam_krb5.so use_authtok
session optional /lib/security/$ISA/pam_krb5.so
The "use_first_pass" of "pam_krb5.so" first tries to use local password
(files) authentication before trying Kerberos.
Using separate keytab files for each Kerberized service
--------------------------------------------------------
There are times when we want to use separate keytab files for each
Kerberized service, for example, when each service runs with a
different set of credentials. For example, OpenSSH runs as "root",
but OpenLDAP runs as "ldap". Since the keytab file must be readable
by the service, we could either give the keytab file world readable
permissions (which is NOT a good idea), or else we could use separate
keytab files, one for each service.
By default, the keytab file is located at "/etc/krb5.keytab", but
can be overriden by using the "KRB5_KTNAME" environment variable.
By setting this variable and then exporting it to the Kerberized
server process, we can force it to search for the keytab at an
specific location. For example, if we do
export KRB5_KTNAME="FILE:/etc/openldap/ldap.keytab"
in the init.d script for the OpenLDAP service, we can tell the
"slapd" daemon to look for the keytab file in
"etc/openldap/ldap.keytab".
SAMPLE NETWORK SERVICE: OpenSSH
-------------------------------
To configure OpenSSH for Kerberos support, first we must be sure that
the OpenSSH version we're using has been Kerberized, that is, compiled
with Kerberos support. For example, Engarde Linux OpenSSH is not
Kerberos-aware, so we won't be able to leverage Kerberos authentication
unless we recompile it.
As a side note, it seems that as of OpenSSH 3.5, the implementation of
the SSH protocol version 2 does not still support Kerberos authentication
so we'll fallback to version 1. Yes, I know it's less secure, and it took
me a while to discover this: I had to look at the OpenSSH sources just
to discover that krb5_auth was only implemented for the version 1 of the
protocol.
To enable Kerberos, edit "/etc/ssh/sshd_config" and make sure the
following lines are present by either uncommenting them or adding them:
Protocol 1
PasswordAuthentication no
KerberosAuthentication yes
KerberosTicketCleanup yes
KerberosTgtPassing yes
Now, simply by restarting the "sshd" daemon, Kerberos should be fully
functional. It's not so difficult at a first sight, but facts like
different versions of the keytab file, or improper configuration, can
lead to an administrative nightmare while trying to make SSH work. It
took me a while to do it.
--
fedora-devel-list mailing list
fedora-devel-list@xxxxxxxxxx
http://www.redhat.com/mailman/listinfo/fedora-devel-list