How to set up a realm
*********************

     Who willed you? or whose will stands but mine?
     There's none protector of the realm but I.
     Break up the gates, I'll be your warrantize.
     Shall I be flouted thus by dunghill grooms?
     --- King Henry VI, 6.1

How to set up the kerberos server
=================================

Choose a realm name
-------------------

A realm is an administrative domain.  Kerberos realms are usually written in uppercase and consist of a Internet domain name (Using lowercase characters in the realm name might break in mysterious ways. This really should have been fixed, but has not.). Call your realm the same as your Internet domain name if you do not have strong reasons for not doing so.  It will make life easier for you and everyone else.

Choose a kerberos server
------------------------

You need to choose a machine to run the kerberos server program.  If the kerberos database residing on this host is compromised, your entire realm will be compromised.  Therefore, this machine must be as secure as possible.  Preferably it should not run any services other than Kerberos.  The secure-minded administrator might only allow logins on the console.

This machine has also to be reliable.  If it is down, you will not be able to use any kerberised services unless you have also configured a slave server (see Install a slave kerberos server).

Running the kerberos server requires very little CPU power and a small amount of disk. An old PC with some hundreds of megabytes of free disk space should do fine. Most of the disk space will be used for various logs.

Install the configuration files
-------------------------------

There are two important configuration files: /etc/krb.conf and /etc/krb.realms.

The krb.conf file determines which machines are servers for different realms.  The format of this file is:

     THIS.REALM
     SUPP.LOCAL.REALM
     THIS.REALM              kerberos.this.realm admin server
     THIS.REALM              kerberos-1.this.realm
     SUPP.LOCAL.REALM        kerberos.supp.local.realm admin server
     ANOTHER.REALM           kerberos.another.realm

The first line defines the name of the local realm. The next few lines optionally defines supplementary local realms. The rest of the file defines the names of the kerberos servers and the database administration servers for all known realms. You can define any number of kerberos slave servers similar to the one defined on line four. Clients will try to contact servers in listed order.

The admin server clause at the first entry states that this is the master server (the one to contact when modifying the database, such as changing passwords). There should be only one such entry for each realm.

In the original MIT Kerberos 4 (as in most others), the server specification could only take the form of a host-name. To facilitate having kerberos servers in odd places (such as behind a firewall), support has been added for ports other than the default (750), and protocols other than UDP.

The formal syntax for an entry is now [PROTO/]HOST[:PORT]. PROTO is either UDP, TCP, or HTTP, and PORT is the port to talk to. Default value for PROTO is UDP and for PORT whatever kerberos-iv is defined to be in /etc/services or 750 if undefined. If PROTO is HTTP, the default port is 80. An http entry may also be specified in URL format.

If the information about a realm is missing from the krb.conf file, or if the information is wrong, the following methods will be tried in order.

 1. If you have an SRV-record (RFC 2052) for your realm it will be used. This record should be of the form kerberos-iv.PROTOCOL.REALM, where PROTO is either UDP, TCP, or HTTP. (Note: the current implementation does not look at priority or weight when deciding which server to talk to.)

 2. If there isn't any SRV-record, it tries to find a TXT-record for the same domain. The contents of the record should have the same format as the host specification in krb.conf. (Note: this is a temporary solution if your name server doesn't support SRV records. The clients should work fine with SRV records, so if your name server supports them, they are very much preferred.)

 3. If no valid kerberos server is found, it will try to talk UDP to the service kerberos-iv with fall-back to port 750 with kerberos.REALM (which is also assumed to be the master server), and then kerberos-1.REALM, kerberos-2.REALM, and so on.

SRV records have been supported in BIND since 4.9.5T2A.  An example would look like the following in the zone file:

     kerberos-iv.udp.foo.se.  1M IN SRV  1 0 750 kerberos-1.foo.se.
     kerberos-iv.udp.foo.se.  1M IN SRV  0 0 750 kerberos.foo.se.

We strongly recommend that you add a CNAME kerberos.REALM pointing to your kerberos master server.

The krb.realms file is used to find out what realm a particular host belongs to.  An example of this file could look like:

     this.realm            THIS.REALM
     .this.realm           THIS.REALM
     foo.com               SOME.OTHER.REALM
     www.foo.com           A.STRANGE.REALM
     .foo.com              FOO.REALM

Entries starting with a dot are taken as the name of a domain. Entries not starting with a dot are taken as a host-name. The first entry matched is used. The entry for this.realm is only necessary if there is a host named this.realm.

If no matching realm is found in krb.realms, DNS is searched for the correct realm. For example, if we are looking for host a.b.c, krb4-realm.a.b.c is first tried and then krb4-realm.b.c and so on. The entry should be a TXT record containing the name of the realm, such as:

     krb4-realm.pdc.kth.se.  7200    TXT     "NADA.KTH.SE"

If this didn't help the domain name sans the first part in uppercase is tried.

The plain vanilla version of Kerberos doesn't have any fancy methods of getting realms and servers so it is generally a good idea to keep krb.conf and krb.realms up to date.

In addition to these commonly used files, /etc/krb.extra holds some things that are not normally used. It consists of a number of VARIABLE = VALUE pairs, blank lines and lines beginning with a hash (#) are ignored.

The currently defined variables are:

kdc_timeout
     The time in seconds to wait for an answer from the KDC (the default is 4 seconds).

kdc_timesync
     This flag enables storing of the time differential to the KDC when getting an initial ticket. This differential is used later on to compute the correct time. This can help if your machine doesn't have a working clock.

firewall_address
     The IP address that hosts outside the firewall see when connecting from within the firewall. If this is specified, the code will try to compute the value for reverse_lsb_test.

krb4_proxy
     When getting tickets via HTTP, this specifies the proxy to use. The default is to speak directly to the KDC.

krb_default_tkt_root
     The default prefix for ticket files.  The default is /tmp/tkt. Normally the uid or tty is appended to this prefix.

krb_default_keyfile
     The file where the server keys are stored, the default is /etc/srvtab.

nat_in_use
     If the client is behind a Network Address Translator (NAT).

reverse_lsb_test
     Reverses the test used by krb_mk_safe, krb_rd_safe, krb_mk_priv, and krb_rd_priv to compute the ordering of the communicating hosts. This test can cause truble when using firewalls.

Updating /etc/services
----------------------

You should append or merge the contents of services.append to your /etc/services files or NIS-map. Remove any unused factory installed kerberos port definitions to avoid possible conflicts.

Most of the programs will fall back to the default ports if the port numbers are not found in /etc/services, but it is convenient to have them there anyway.

Install the kerberos server
---------------------------

You should have already chosen the machine where you want to run the kerberos server and the realm name.  The machine should also be as secure as possible (see Choose a kerberos server) before installing the kerberos server.  In this example, we will install a kerberos server for the realm FOO.SE on a machine called hemlig.foo.se.

Setup the server
----------------

Login as root on the console of the kerberos server.  Add /usr/athena/bin and /usr/athena/sbin to your path.  Create the directory /var/kerberos (mkdir /var/kerberos), which is where the database will be stored.  Then, to create the database, run kdb_init:

     hemlig# mkdir /var/kerberos
     hemlig# kdb_init
     Realm name [default  FOO.SE ]:
     You will be prompted for the database Master Password.
     It is important that you NOT FORGET this password.

     Enter Kerberos master password:
     Verifying password
     Enter Kerberos master password:

If you have set up the configuration files correctly, kdb_init should choose the correct realm as the default, otherwise a (good) guess is made.  Enter the master password.

This password will only be used for encrypting the kerberos database on disk and for generating new random keys.  You will not have to remember it, only to type it again when you run kstash.  Choose something long and random.  Now run kstash using the same password:

     hemlig# kstash

     Enter Kerberos master password:

     Current Kerberos master key version is 1.

     Master key entered.  BEWARE!
     Wrote master key to /.k

After entering the same master password it will be saved in the file /.k and the kerberos server will read it when needed. Write down the master password and put it in a sealed envelope in a safe, you might need it if your disk crashes or should you want to set up a slave server.

kdb_init initializes the database with a few entries:

krbtgt.REALM
     The key used for authenticating to the kerberos server.

changepw.kerberos
     The key used for authenticating to the administrative server, i.e. when adding users, changing passwords, and so on.

default
     This entry is copied to new items when these are added.  Enter here the values you want new entries to have, particularly the expiry date.

K.M
     This is the master key and it is only used to verify that the master key that is saved un-encrypted in /.k is correct and corresponds to this database.

kstash only reads the master password and writes it to /.k.  This enables the kerberos server to start without you having to enter the master password.  This file (/.k) is only readable by root and resides on a ``secure'' machine.

Add a few important principals
------------------------------

Now the kerberos database has been created, containing only a few principals.  The next step is to add a few more so that you can test that it works properly and so that you can administer your realm without having to use the console on the kerberos server.  Use kdb_edit to edit the kerberos database directly on the server.

kdb_edit is intended as a bootstrapping and fall-back mechanism for editing the database.  For normal purposes, use the kadmin program (see Add users to the database).

The following example shows the adding of the principal nisse.admin into the kerberos database.  This principal is used by nisse when administrating the kerberos database.  Later on the normal principal for nisse will be created.  Replace nisse and password with your own username and password.

     hemlig# kdb_edit -n
     Opening database...
     Current Kerberos master key version is 1.

     Master key entered.  BEWARE!
     Previous or default values are in [brackets] ,
     enter return to leave the same, or new value.

     Principal name: <nisse>
     Instance: <admin>

     <Not found>, Create [y] ? <>

     Principal: nisse, Instance: admin, kdc_key_ver: 1
     New Password: <password>
     Verifying password
     New Password: <password>

     Principal's new key version = 1
     Expiration date (enter yyyy-mm-dd) [ 2000-01-01 ] ? <>
     Max ticket lifetime (*5 minutes) [ 255 ] ? <>
     Attributes [ 0 ] ? <>
     Edit O.K.
     Principal name: <>

kdb_edit will loop until you hit the return key at the ``Principal name'' prompt. Now you have added nisse as an administrator.

Start the server
----------------

     hemlig# /usr/athena/libexec/kerberos &
     Kerberos server starting
     Sleep forever on error
     Log file is /var/log/kerberos.log
     Current Kerberos master key version is 1.

     Master key entered.  BEWARE!

     Current Kerberos master key version is 1
     Local realm: FOO.SE

Try to get tickets
------------------

You can now verify that these principals have been added and that the server is working correctly.

     hemlig# kinit
     eBones International (hemlig.foo.se)
     Kerberos Initialization
     Kerberos name: <nisse.admin>
     Password: <password>

If you do not get any error message from kinit, then everything is working (otherwise, see Common error messages).  Use klist to verify the tickets you acquired with kinit:

     hemlig# klist
     Ticket file:    /tmp/tkt0
     Principal:      nisse.admin@FOO.SE

     Issued           Expires          Principal
     May 24 21:06:03  May 25 07:06:03  krbtgt.FOO.SE@FOO.SE

Create initial ACL for the admin server
---------------------------------------

The admin server, kadmind, uses a series of files to determine who has the right to perform certain operations.  The files are: admin_acl.add, admin_acl.get, admin_acl.del, and admin_acl.mod.  Create these with nisse.admin@FOO.SE as the contents.

     hemlig# echo "nisse.admin@FOO.SE" >> /var/kerberos/admin_acl.add
     hemlig# echo "nisse.admin@FOO.SE" >> /var/kerberos/admin_acl.get
     hemlig# echo "nisse.admin@FOO.SE" >> /var/kerberos/admin_acl.mod
     hemlig# echo "nisse.admin@FOO.SE" >> /var/kerberos/admin_acl.del

Later on you may wish to add more users with administration privileges. Make sure that you create both the administration principals and add them to the admin server ACL.

Start the admin server
----------------------

     hemlig# /usr/athena/libexec/kadmind &
     KADM Server KADM0.0A initializing
     Please do not use 'kill -9' to kill this job, use a
     regular kill instead

     Current Kerberos master key version is 1.

     Master key entered.  BEWARE!

Add users to the database
-------------------------

Use the kadmin client to add users to the database:

     hemlig# kadmin -p nisse.admin -m
     Welcome to the Kerberos Administration Program, version 2
     Type "help" if you need it.
     admin:  <add nisse>
     Admin password: <nisse.admin's password>
     Maximum ticket lifetime?  (255)  [Forever]
     Attributes?  [0x00]
     Expiration date (enter yyyy-mm-dd) ?  [Sat Jan  1 05:59:00 2000]
     Password for nisse:
     Verifying password Password for nisse:
     nisse added to database.

Add whatever other users you want to have in the same way.  Verify that a user is in the database and check the database entry for that user:

     admin:  <get nisse>
     Info in Database for nisse.:
     Max Life: 255 (Forever)   Exp Date: Sat Jan  1 05:59:59 2000

     Attribs: 00  key: 0 0
     admin:  <^D>
     Cleaning up and exiting.

Automate the startup of the servers
-----------------------------------

Add the lines that were used to start the kerberos server and the admin server to your startup scripts (/etc/rc or similar).

Install the client programs
===========================

Making a machine a kerberos client only requires a few steps.  First you might need to change the configuration files as with the kerberos server.  (see Install the configuration files and see Install the /etc/services.) Also you need to make the programs in /usr/athena/bin available.  This can be done by adding the /usr/athena/bin directory to the users' paths, by making symbolic links, or even by copying the programs.

You should also verify that the local time on the client is synchronised with the time on the kerberos server by some means. The maximum allowed time difference between the participating servers and a client is 5 minutes. One good way to synchronize the time is NTP (Network Time Protocol), see http://www.eecis.udel.edu/~ntp/.

If you need to run the client programs on a machine where you do not have root-access, you can hopefully just use the binaries and no configuration will be needed.  The heuristics used are mentioned above (see Install the configuration files).  If this is not the case and you need to have krb.conf and/or krb.realms, you can copy them into a directory of your choice and set the environment variable KRBCONFDIR to point at this directory.

To test the client functionality, run the kinit program:

     foo$ kinit
     eBones International (foo.foo.se)
     Kerberos Initialization
     Kerberos name: <nisse>
     Password: <password>

     foo$ klist
     Ticket file:    /tmp/tkt4711
     Principal:      nisse@FOO.SE

     Issued           Expires          Principal
     May 24 21:06:03  May 25 07:06:03  krbtgt.FOO.SE@FOO.SE

Install the kerberised services
===============================

These includes rsh, rlogin, telnet, ftp, rxtelnet, and so on.

First follow the steps mentioned in the prior section to make it a client and verify its operation.  Change inetd.conf next to use the new daemons.  Look at the file etc/inetd.conf.changes to see the changes that we recommend you perform on inetd.conf.

You should at this point decide what services you want to run on each machine.

rsh, rlogin, and rcp
--------------------

These exist in kerberised versions and ``old-style'' versions.  The different versions use different port numbers, so you can choose none, one, or both.  If you do not want to use ``old-style'' r* services, you can let the programs output the text ``Remote host requires Kerberos authentication'' instead of just refusing connections to that port. This is enabled with the -v option.  The kerberised services exist in encrypted and non-encrypted versions.  The encrypted services have an ``e'' prepended to the name and the programs take -x as an option indicating encryption.

Our recommendation is to only use the kerberised services and give explanation messages for the old ports.

telnet
------

The telnet service always uses the same port and negotiates as to which authentication method should be used.  The telnetd program has an option ``-a user'' that only allows kerberised and authenticated connections.  If this is not included, it falls back to using clear text passwords.  For obvious reasons, we recommend that you enable this option.  If you want to use one-time passwords (see One-Time Passwords) you can use the ``-a otp'' option which will allow OTPs or kerberised connections.

ftp
---

The ftp service works as telnet does, with just one port being used.  By default only kerberos authenticated connections are allowed.  You can specify additional levels that are thus allowed with these options:

-a otp
     Allow one-time passwords (see One-Time Passwords).

-a ftp
     Allow anonymous login (as user ``ftp'' or ``anonymous'').

-a safe
     The same as -a ftp, for backwards compatibility.

-a plain
     Allow clear-text passwords.

-a none
     The same as -a ftp -a plain.

-a user
     A no-op, also there for backwards compatibility reasons.

When running anonymous ftp you should read the man page on ftpd which explains how to set it up.

pop
---

The Post Office Protocol (POP) is used to retrieve mail from the mail hub.  The popper program implements the standard POP3 protocol and the kerberised KPOP.  Use the -k option to run the kerberos version of the protocol. This service should only be run on your mail hub.

kx
--

kx allows you to run X over a kerberos-authenticated and encrypted connection.  This program is used by rxtelnet, tenletxr, and rxterm.

If you have some strange kind of operating system with X libraries that do not allow you to use unix-sockets, you need to specify the -t option to kxd.  Otherwise it should be sufficient by adding the daemon in inetd.conf.

kauth
-----

This service allows you to create tickets on a remote host.  To enable it just insert the corresponding line in inetd.conf.

srvtabs
=======

In the same way every user needs to have a password registered with the kerberos server, every service needs to have a shared key with the kerberos server.  The service keys are stored in a file, usually called /etc/srvtab.  This file should not be readable to anyone but root, in order to keep the key from being divulged.  The name of this principal in the kerberos database is usually the service name and the hostname.  Examples of such principals are pop.HOSTNAME and rcmd.HOSTNAME.  (rcmd comes from ``remote command''.)  Here is a list of the most commonly used srvtab types and what programs use them.

rcmd.HOSTNAME
     rsh, rcp, rlogin, telnet, kauth, su, kx

rcmd.kerberos
     kprop

pop.HOSTNAME
     popper, movemail, push

sample.HOSTNAME
     sample_server, simple_server

changepw.kerberos
     kadmin, kpasswd

krbtgt.REALM
     kerberos (not stored in any srvtab)

ftp.HOSTNAME
     ftp (also tries with rcmd.HOSTNAME)

zephyr.zephyr
     Zephyr

afs or afs.CELLNAME
     Andrew File System

To create these keys you will use the the ksrvutil program. Perform the following:

     bar# ksrvutil -p nisse.admin get
     Name [rcmd]: <>
     Instance [bar]: <>
     Realm [FOO.SE]: <>
     Is this correct? (y,n) [y] <>
     Add more keys? (y,n) [n] <>
     Password for nisse.admin@FOO.SE: <nisse.admin's password>
     Written rcmd.bar
     rcmd.bar@FOO.SE
     Old keyfile in /etc/srvtab.old.

Complete test of the kerberised services
----------------------------------------

Obtain a ticket on one machine (foo) and use it to login with a kerberised service to a second machine (bar).  The test should look like this if successful:

     foo$ kinit nisse
     eBones International (foo.foo.se)
     Kerberos Initialization for "nisse"
     Password: <nisse's password>
     foo$ klist
     Ticket file:    /tmp/tkt4711
     Principal:      nisse@FOO.SE

     Issued           Expires          Principal
     May 30 13:48:03  May 30 23:48:03  krbtgt.FOO.SE@FOO.SE
     foo$ telnet bar
     Trying 17.17.17.17...
     Connected to bar.foo.se
     Escape character is '^]'.
     [ Trying mutual KERBEROS4 ... ]
     [ Kerberos V4 accepts you ]
     [ Kerberos V4 challenge successful ]
     bar$

You can also try with rsh, rcp, rlogin, rlogin -x, and some other commands to see that everything is working all right.

Install a slave kerberos server
===============================

It is desirable to have at least one backup (slave) server in case the master server fails. It is possible to have any number of such slave servers but more than three usually doesn't buy much more redundancy.

First select a good server machine.  (see Choose a kerberos server).

On the master, add a rcmd.kerberos (note, it should be literally ``kerberos'') principal (using ksrvutil get). The kprop program, running on the master, will use this when authenticating to the kpropd daemons running on the slave servers.  The kpropd on the slave will use its rcmd.hostname key for authenticating the connection from the master.  Therefore, the slave needs to have this key in its srvtab, and it of course also needs to have enough of the configuration files to act as a server.  See Install the kerberised services for information on how to do this.

To summarize, the master should have a key for rcmd.kerberos and the slave one for rcmd.hostname.

The slave will need the same master key as you used at the master.

On your master server, create a file, e.g. /var/kerberos/slaves, that contains the hostnames of your kerberos slave servers.

Start kpropd with kpropd -i on your slave servers.

On your master server, create a dump of the database and then propagate it.

     foo# kdb_util slave_dump /var/kerberos/slave_dump
     foo# kprop

You should now have copies of the database on your slave servers. You can verify this by issuing kdb_util dump FILE on your slave servers, and comparing with the original file on the master server. Note that the entries will not be in the same order.

This procedure should be automated with a script run regularly by cron, for instance once an hour.

Since the master and slave servers will use copies of the same database, they need to use the same master key.  Add the master key on the slave with kstash. (see Set up the server)

To start the kerberos server on slaves, you first have to copy the master key from the master server. You can do this either by remembering the master password and issuing kstash, or you can just copy the keyfile. Remember that if you copy the file, do so on a safe media, not over the network. Good means include floppy or paper. Paper is better, since it is easier to swallow afterwards.

The kerberos server should be started with -s on the slave servers. This enables sanity checks, for example checking the time since the last update from the master.

All changes to the database are made by kadmind at the master, and then propagated to the slaves, so you should not run kadmind on the slaves.

Finally add the slave servers to /etc/krb.conf. The clients will ask the servers in the order specified by that file.

Consider adding CNAMEs to your slave servers, see Install the configuration files.

Cross-realm functionality
=========================

Suppose you are residing in the realm MY.REALM, how do you authenticate to a server in OTHER.REALM? Having valid tickets in MY.REALM allows you to communicate with kerberised services in that realm. However, the computer in the other realm does not have a secret key shared with the kerberos server in your realm.

It is possible to add a shared key between two realms that trust each other. When a client program, such as telnet, finds that the other computer is in a different realm, it will try to get a ticket granting ticket for that other realm, but from the local kerberos server. With that ticket granting ticket, it will then obtain service tickets from the kerberos server in the other realm.

To add this functionality you have to add a principal to each realm. The principals should be krbtgt.OTHER.REALM in MY.REALM, and krbtgt.MY.REALM in OTHER.REALM. The two different principals should have the same key (and key version number).  Remember to transfer this key in a safe manner. This is all that is required.

     blubb$ klist
     Ticket file:    /tmp/tkt3008
     Principal:      joda@NADA.KTH.SE

       Issued           Expires          Principal
     Jun  7 02:26:23  Jun  7 12:26:23  krbtgt.NADA.KTH.SE@NADA.KTH.SE
     blubb$ telnet agat.e.kth.se
     Trying 130.237.48.12...
     Connected to agat.e.kth.se.
     Escape character is '^]'.
     [ Trying mutual KERBEROS4 ... ]
     [ Kerberos V4 accepts you ]
     [ Kerberos V4 challenge successful ]
     Last login: Sun Jun  2 20:51:50 from emma.pdc.kth.se

     agat$ exit
     Connection closed by foreign host.
     blubb$ klist
     Ticket file:    /tmp/tkt3008
     Principal:      joda@NADA.KTH.SE

       Issued           Expires          Principal
     Jun  7 02:26:23  Jun  7 12:26:23  krbtgt.NADA.KTH.SE@NADA.KTH.SE
     Jun  7 02:26:50  Jun  7 12:26:50  krbtgt.E.KTH.SE@NADA.KTH.SE
     Jun  7 02:26:51  Jun  7 12:26:51  rcmd.agat@E.KTH.SE