<?xml version="1.0" encoding="UTF-8"?>
<!--
  Kerberos 5 installation guide on Debian GNU

  http://techpubs.spinlocksolutions.com/dklar/kerberos.xml
  http://techpubs.spinlocksolutions.com/dklar/kerberos.html
  http://techpubs.spinlocksolutions.com/dklar/kerberos.tgz

  (C) 2006-2010 Davor Ocelic, docelic@spinlocksolutions.com

  SPINLOCK, http://www.spinlocksolutions.com/ - advanced
  infrastructure-based Unix solutions for commercial and
  education sectors.


 This documentation is free; you can redistribute it and/or modify
 it under the terms of the &GNU; General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 It is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.


  To build the HTML version of the article, download
  http://techpubs.spinlocksolutions.com/dklar/kerberos.tgz , 
  save the following as Makefile and run 'make kerberos.html':

%.html: %.xml
	xsltproc -o $@ \
	-stringparam html.stylesheet DKLAR.css \
	/usr/share/xml/docbook/stylesheet/nwalsh/html/docbook.xsl $<

-->
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"docbook/docbookx.dtd" [
<!ENTITY DEB "<ulink url='http://www.debian.org/'>Debian GNU</ulink>">
<!ENTITY GNU "<ulink url='http://www.gnu.org/'>GNU</ulink>">
<!ENTITY KRB "<ulink url='http://web.mit.edu/kerberos/'>MIT Kerberos</ulink>">
<!ENTITY LDA "<ulink url='http://www.openldap.org/'>OpenLDAP</ulink>">
<!ENTITY AFS "<ulink url='http://www.openafs.org/'>OpenAFS</ulink>">
<!ENTITY RAD "<ulink url='http://www.freeradius.org/'>FreeRADIUS</ulink>">
<!ENTITY DLH "<ulink url='http://colt.projectgamma.com/debian-ldap-howto/'>Debian-LDAP Howto</ulink>">
<!ENTITY PAM "<ulink url='http://www.kernel.org/pub/linux/libs/pam/'>Linux-PAM</ulink>">
<!ENTITY PSY "<ulink url='http://www.kernel.org/pub/linux/libs/pam/Linux-PAM-html/sag-configuration-file.html'>PAM Configuration File Syntax</ulink>">
<!ENTITY NSS "<ulink url='http://www.gnu.org/software/libc/manual/html_node/Name-Service-Switch.html'>NSS</ulink>">
<!ENTITY SUN "<ulink url='http://www.sun.com/'>Sun Microsystems</ulink>">
<!ENTITY HDL "<ulink url='http://www.pdc.kth.se/heimdal/'>Heimdal Kerberos</ulink>">
<!ENTITY DOCBK "<ulink url='http://www.docbook.org/'>DocBook</ulink>">
<!ENTITY SL "<ulink url='http://www.spinlocksolutions.com/'>Spinlock Solutions</ulink>">
<!ENTITY SHELL_GLOBBING "<ulink url='http://tldp.org/LDP/abs/html/globbingref.html'>shell globbing</ulink>">
<!ENTITY KRBC "<ulink url='http://www.kerberos.org/'>Kerberos consortium</ulink>">
<!ENTITY PRINCIPAL "<ulink url='http://kerberos.org/software/tutorial.html#1.3.2'>principal</ulink>">
<!ENTITY SECRET_KEY "<ulink url='http://kerberos.org/software/tutorial.html#1.3.4'>secret key</ulink>">
<!ENTITY KERBEROS_DATABASE "<ulink url='http://kerberos.org/software/tutorial.html#1.3.5.1'>Kerberos database</ulink>">
<!ENTITY REALM "<ulink url='http://kerberos.org/software/tutorial.html#1.3.1'>realm</ulink>">
<!ENTITY KERBEROS-SPECIFIC "<ulink url='http://kerberos.org/software/tutorial.html#1.3.5.1'>Kerberos-specific</ulink>">
<!ENTITY KDC "<ulink url='http://kerberos.org/software/tutorial.html#1.3.5'>KDC</ulink>">
<!ENTITY TGT "<ulink url='http://kerberos.org/software/tutorial.html#1.5.1'>TGT</ulink>">
<!ENTITY KERBEROS_RELEASE "<ulink url='http://web.mit.edu/Kerberos/dist/index.html'>Kerberos release</ulink>">
<!ENTITY DKLAR_DEB "<ulink url='http://techpubs.spinlocksolutions.com/dklar/debian.html'>Debian GNU Guide</ulink>">
<!ENTITY DKLAR_KRB "<ulink url='http://techpubs.spinlocksolutions.com/dklar/kerberos.html'>MIT Kerberos 5 Guide</ulink>">
<!ENTITY DKLAR_LDA "<ulink url='http://techpubs.spinlocksolutions.com/dklar/ldap.html'>OpenLDAP Guide</ulink>">
<!ENTITY DKLAR_AFS "<ulink url='http://techpubs.spinlocksolutions.com/dklar/afs.html'>OpenAFS Guide</ulink>">
<!ENTITY DKLAR_RAD "<ulink url='http://techpubs.spinlocksolutions.com/dklar/radius.html'>FreeRADIUS Guide</ulink>">
<!ENTITY DOC "<ulink url='http://web.mit.edu/kerberos/krb5-1.8/'>http://web.mit.edu/kerberos/krb5-1.8/</ulink>">
<!ENTITY MLS "<ulink url='http://web.mit.edu/kerberos/mail-lists.html'>http://web.mit.edu/kerberos/mail-lists.html</ulink>">
]>
<article id="debian-kerberos">
  <articleinfo>
    <!--
	<mediaobject>
		<imageobject><imagedata fileref="images/logo-debian.png"
			format="JPG" width="120px" scalefit="1" /></imageobject>
	</mediaobject>
	-->

    <title>Debian GNU: Setting up MIT Kerberos 5</title>

    <titleabbrev>debian-kerberos</titleabbrev>

    <copyright>
      <year>2006-2010</year>

      <holder>Davor Ocelic</holder>
    </copyright>

    <authorgroup>
      <author>
        <firstname>Davor</firstname>

        <surname>Ocelic</surname>

        <email>docelic@spinlocksolutions.com</email>

        <affiliation><ulink
        url="http://www.spinlocksolutions.com/">SPINLOCK</ulink>— advanced
        GNU/Linux and Unix solutions for commercial and education
        sectors.</affiliation>
      </author>
    </authorgroup>

    <legalnotice>
      <para>Last update: Mar 22, 2010. — Maintain everything up to date
      (Kerberos 1.6, 1.7 and 1.8), add links to other documentation</para>

      <para>This documentation is free; you can redistribute it and/or modify
      it under the terms of the &GNU; General Public License as published by
      the Free Software Foundation; either version 2 of the License, or (at
      your option) any later version.</para>

      <para>It is distributed in the hope that it will be useful, but WITHOUT
      ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
      more details.</para>
    </legalnotice>

    <abstract>
      <para>The purpose of this article is to give you a straight-forward,
      Debian-friendly way of installing and configuring MIT Kerberos 5.</para>

      <para>By the end of this guide, you will have a functional Kerberos
      environment and one Kerberized service — the ability to login remotely
      to other machines in the network in a secure, encrypted and transparent
      way, without the need for typing in any passwords.</para>

      <para>This article is part of &SL;'s practical 5-piece introductory
      series to infrastructure-based Unix networks, containing &DKLAR_DEB;,
      &DKLAR_KRB;, &DKLAR_LDA;, &DKLAR_AFS; and &DKLAR_RAD;.</para>
    </abstract>
  </articleinfo>

  <section id="intro">
    <title>Introduction</title>

    <para>Kerberos is a service that has been traditionally captivating system
    administrators' and advanced users' interest, but its (seemingly or not)
    high entry barrier and infrastructure requirements have been preventing
    many from using it.</para>

    <para>Kerberos has already been the topic of numerous publications. Here,
    we will present only the necessary summary; enough information to
    establish the context and to achieve practical results.</para>

    <para>You do not need to follow any external links; however, the links
    have been provided both throughout the article and listed all together at
    the end, to serve as pointers to more precise technical treatment of
    individual topics.</para>

    <section id="intro-krb">
      <title>The role of Kerberos within a network</title>

      <para><inlinemediaobject>
          <imageobject>
            <imagedata fileref="images/logo-kerberos.jpg" format="JPG"
                       scalefit="1" width="120px" />
          </imageobject>
        </inlinemediaobject> Kerberos is intended to centrally authenticate
      users, hosts and services on the network by verifying them against
      entries in the &KERBEROS_DATABASE;.</para>

      <para>These entries (called "&PRINCIPAL;s") consist of principal names,
      &SECRET_KEY;s, key aging information and &KERBEROS-SPECIFIC; data.
      They're created or modified using a Kerberos-specific administrative
      tool.</para>

      <para>When users type in their principal name and password anywhere on
      the network (within a Kerberos &REALM;), their input is authenticated
      against the Kerberos database. In case of a successful authentication,
      the &KDC; ("<literal>Key Distribution Center</literal>") will
      <emphasis>issue</emphasis> users a "confirmation", called the &TGT;
      ("<literal>Ticket-Granting Ticket</literal>"). From that point on, and
      until their ticket expires, users will be transparently granted access
      to all network services they'll wish to use. (Here, the TGT will not
      grant access by itself — instead, it will be used in place of a password
      to automatically create further, service-specific tickets. Hence its
      name, the "Ticket-granting Ticket").</para>

      <para>While the idea of a centralized network authentication is not
      unique, let's quickly identify Kerberos-specific elements in the
      authentication process:</para>

      <itemizedlist>
        <listitem>
          <para>Kerberos is not in any way related to traditional system
          usernames or other data; Kerberos identity (or tickets) are obtained
          using a separate, Kerberos-specific mechanism. Arbitrary system user
          can obtain arbitrary Kerberos identity (provided they know the
          correct password).</para>

          <para>Often times, however, the Kerberos identity is obtained during
          log-in to the system and, for convenience, an assumption is made
          that the person's system login name matches the Kerberos principal
          name. <!-- 
	(In case
	of services, an assumption is made that the service principal matches 
	form <literal><replaceable>SERVICE-TYPE</replaceable>/<replaceable>FQDN</replaceable></literal>).
	--></para>
        </listitem>

        <listitem>
          <para>The &KERBEROS_DATABASE; only contains the information
          necessary for Kerberos authentication; it does not (and can not)
          contain any other information, such as people's real names, Unix
          user and group IDs etc. This makes Kerberos well-defined and easy to
          fit in a network infrastructure.</para>

          <para>When a central directory is required for users' real names,
          IDs, meta information and other network information, &LDA; is often
          used in combination and installed after Kerberos as explained in
          another article from the series, the &DKLAR_LDA;.</para>
        </listitem>

        <listitem>
          <para>Thanks to the design of the protocol, users' passwords never
          travel the wire in any form; Kerberos thus allows for secure
          authentication in and over untrusted networks.</para>
        </listitem>

        <listitem>
          <para>Kerberos requires mutual authentication of users and services,
          preventing stealing of information.</para>

          <para>To achieve this, Kerberos uses its database to store host and
          service principals alongside the "real", person-owned principals.
          This is normal behavior and indeed, the host and service principals
          will account for the majority of output when you list database
          entries for the first time.</para>
        </listitem>

        <listitem>
          <para>As users are only required to type in their password once
          (after which the TGT is used in place of the password to create
          further tickets), Kerberos offers a true SSO ("<literal>Single
          Sign-On</literal>") network solution.</para>
        </listitem>
      </itemizedlist>

      <para>You can find the complete Kerberos documentation at the &KRB;
      website. Their on-line documentation is, however, only generated in
      multi-page HTML format — other more convenient formats (such as
      PostScript) are available within &KERBEROS_RELEASE; tarballs.</para>
    </section>

    <section>
      <title>Glue layer: integrating Kerberos with system software</title>

      <para>On all GNU/Linux-based platforms, &PAM; is available for
      service-specific authentication configuration. &PAM; is an
      implementation of PAM ("<literal>Pluggable Authentication
      Modules</literal>") from &SUN;.</para>

      <para>Network services, instead of having hard-coded authentication
      interfaces and decision methods, invoke PAM through a standard,
      pre-defined interface. It is then up to PAM to perform any and all
      authentication-related work, and report the result back to the
      application.</para>

      <para>Exactly how PAM reaches the decision is none of the service's
      business. In traditional set-ups, that is most often done by asking and
      verifying usernames and passwords. In advanced networks, that could be
      retina scans or — Kerberos tickets.</para>

      <para>PAM will allow for inclusion of Kerberos into the authentication
      path of all services, regardless of whether they natively support
      Kerberos or not.</para>

      <para>You can find the proper introduction (and complete documentation)
      on the &PAM; website. Pay special attention to the &PSY; page. Also take
      a look at the <citerefentry>
          <refentrytitle>Linux-PAM</refentrytitle>

          <manvolnum>7</manvolnum>
        </citerefentry> and <citerefentry>
          <refentrytitle>pam</refentrytitle>

          <manvolnum>7</manvolnum>
        </citerefentry> manual pages.</para>
    </section>

    <section id="conventions">
      <title>Conventions</title>

      <para>It's quite disappointing when you are not able to follow the
      instructions found in the documentation. Let's agree on a few points
      before going down to work:</para>

      <itemizedlist>
        <listitem>
          <para>Our platform of choice, where we will demonstrate a practical
          setup, will be &DEB;.</para>
        </listitem>

        <listitem>
          <para>Install <application>sudo</application>. Sudo is a program
          that will allow you to carry out system administrator tasks from
          your normal user account. All the examples in this article requiring
          root privileges use <application>sudo</application>, so you will be
          able to copy-paste them to your shell. <programlisting>
su -c 'apt-get install sudo'
</programlisting> (If asked for a password, type in the root user's
          password.)</para>

          <para>To configure sudo, add the following line to your
          <filename>/etc/sudoers</filename>, replacing
          <literal>$USERNAME</literal> with your login name: <programlisting>
$USERNAME ALL=(ALL) NOPASSWD: ALL
</programlisting></para>
        </listitem>

        <listitem>
          <para>Debian packages installed during the procedure will ask us a
          series of questions through the so-called
          <emphasis>debconf</emphasis> interface. To configure debconf to a
          known state, run: <programlisting>
sudo dpkg-reconfigure debconf
</programlisting> When asked, answer
          <emphasis>interface</emphasis>=<literal>Dialog</literal> and
          <emphasis>priority</emphasis>=<literal>low</literal>.</para>
        </listitem>

        <listitem>
          <para>Monitoring log files is crucial in detecting problems. The
          straight-forward, catch-all routine to this is opening a terminal
          and running: <programlisting>
cd /var/log; sudo tail -F daemon.log sulog user.log auth.log debug kern.log syslog dmesg messages kerberos/{krb5kdc,kadmin,krb5lib}.log
</programlisting></para>

          <para>The command will keep printing log messages to the screen as
          they arrive.</para>
        </listitem>

        <listitem>
          <para>Our test system will be called
          <literal>monarch.spinlock.hr</literal> and have an IP address of
          <literal>192.168.7.12</literal>. Both the server and the client will
          be installed on the same machine. However, to differentiate between
          client and server roles, the client will be referred to as
          <literal>monarch.spinlock.hr</literal> and the server as
          <literal>krb1.spinlock.hr</literal>. The following addition will be
          made to <filename>/etc/hosts</filename> to completely support this
          scheme: <screen>
<replaceable>192.168.7.12</replaceable>	<replaceable>monarch.spinlock.hr</replaceable> <replaceable>monarch</replaceable> krb1<replaceable>.spinlock.hr</replaceable> krb1
</screen></para>

          <caution>
            <para>Note that in some Debian installations the system's network
            hostname is assigned to the localhost address
            <literal>127.0.0.1</literal>. This can and will cause problems for
            network operations, so make sure that your "localhost" entry in
            <filename>/etc/hosts</filename> looks exactly like the following
            (nothing more, nothing less): <screen>
127.0.0.1  localhost  localhost.localdomain
</screen></para>
          </caution>

          <para>Finally, test that the network setup is as expected. Pinging
          the hostnames should report proper FQDNs and IPs as shown: <screen>
<userinput>ping -c1 localhost</userinput>
PING localhost (127.0.0.1) 56(84) bytes of data.
....

<userinput>ping -c1 <replaceable>monarch</replaceable></userinput>
PING <replaceable>monarch.spinlock.hr</replaceable> (<replaceable>192.168.7.12</replaceable>) 56(84) bytes of data.
....

<userinput>ping -c1 krb1</userinput>
PING krb1.<replaceable>spinlock.hr</replaceable> (<replaceable>192.168.7.12</replaceable>) 56(84) bytes of data.
....
</screen></para>
        </listitem>

        <!--
<listitem><para>
Finally, a word on colors:
	<itemizedlist>
		<listitem><para>
			<userinput>White-on-black</userinput> signifies the system commands
			you need to run, or the answers you need to type in.
		</para></listitem>
		<listitem><para>
			<replaceable>Italic light-blue</replaceable>,
			<userinput><replaceable>on any background</replaceable></userinput>,
			signifies parts of system commands
			or answers that you should adjust to match your environment. For example,
			you will probably want to always replace say,
			<replaceable>SPINLOCK.HR</replaceable>, with your own domain name
			in uppercase.
		</para></listitem>
		<listitem><para>
<screen>Normal text on gray background, with a teal stripe to the left
presents output of a real shell session, or the contents of
a file. Parts of the input carrying special meaning are depicted using the
rules above, such as <userinput><replaceable>SPINLOCK.HR</replaceable></userinput>.
</screen>
		</para></listitem>
		<listitem><para>
		Text in an <literal>orange-like color</literal> signifies literal values
		that are, for a reason, worth of emphasizing in the context of text flow.
		</para></listitem>
		<listitem><para>
		Text in the <errortext>red color</errortext> signifies exact error
		text as reported from applications. With the exception of
		system-specific values printed in error messages,
		this text could be taken verbatim and looked up on Web
		search engines.
		</para></listitem>
	</itemizedlist>
</para></listitem>
-->
      </itemizedlist>
    </section>
  </section>

  <section id="kerberos">
    <title>Kerberos 5</title>

    <para>Now when everything has been properly prepared, let's move
    forward.</para>

    <section id="krb-install">
      <title>Server installation</title>

      <para>Kerberos server installation basically consists of just two
      packages — the KDC (Key Distribution Center), which takes care of
      handling authentication requests and issuing Kerberos tickets, and
      kadmind (Kerberos master server), which allows <emphasis>remote
      administration access</emphasis> to the Kerberos database and carrying
      out of administrative tasks. <programlisting>
sudo apt-get install krb5-{admin-server,kdc}
</programlisting> Here are the Debconf answers for reference. The listing here
      includes all questions; some were asked in Kerberos 1.6 packages and
      some are asked only in Kerberos 1.7 and newer, and their order has
      changed a little as well. In any case, it's no problem — just answer the
      subset of questions you are asked: <screen>
Default Kerberos version 5 realm? <userinput><replaceable>SPINLOCK.HR</replaceable></userinput>
# (Your domain name in uppercase - a standard for naming Kerberos realms)

Does DNS contain pointers to your realm's Kerberos Servers? <userinput>No</userinput>
# (No DNS configuration is required for our setup)

Add locations of default Kerberos servers to /etc/krb5.conf? <userinput>Yes</userinput>
# (Adding entries to krb.conf instead of DNS)

Create the Kerberos KDC configuration automatically? <userinput>Yes</userinput>

Kerberos4 compatibility mode to use: <userinput>none</userinput>
# (No krb4 compatibility needed in our setup)

Run a Kerberos V5 to Kerberos V4 ticket conversion daemon? <userinput>No</userinput>

Should the data be purged as well as the package files? <userinput>No</userinput>

Run the Kerberos V5 administration daemon (kadmind)? <userinput>Yes</userinput>

Kerberos servers for your realm: <userinput>krb1.<replaceable>spinlock.hr</replaceable></userinput>
# (Make sure your DNS resolves krb1.<replaceable>spinlock.hr</replaceable> to
# the NETWORK IP of the server, NOT 127.0.0.1!). Hint is given in
# <xref linkend="conventions" />.

Administrative server for your Kerberos realm: <userinput>krb1.<replaceable>spinlock.hr</replaceable></userinput>
# (Make sure your DNS resolves krb1.<replaceable>spinlock.hr</replaceable> to
# the NETWORK IP of the server, NOT 127.0.0.1!). Same hint as above.

Create the Kerberos KDC configuration automatically? <userinput>Yes</userinput>
# New question added in Kerberos 1.7 and newer packages
</screen> As soon as the installation is done, the Kerberos admin server
      (<command>kadmind</command>) and the KDC will start. Kadmind will fail
      as, initially, there are no Kerberos &REALM;s created.</para>
    </section>

    <section id="krb-initial-cfg">
      <title>Initial configuration</title>

      <para>To create the Kerberos realm, invoke Debian-specific command
      <command>krb5_newrealm</command>. <programlisting>
sudo krb5_newrealm
</programlisting> The command will first ask for the master password, and then
      proceed with creating the realm using the name we defined earlier in the
      Debconf step
      (<literal><replaceable>SPINLOCK.HR</replaceable></literal>). Make sure
      to pick a good password, and possibly write it down for later reference
      as it is hardly ever used, yet very important.</para>

      <para>After the realm is created, we will need to adjust the Kerberos
      config file, <filename>/etc/krb5.conf</filename>. That file also needs
      to be the same on all Kerberos servers and clients belonging to the same
      realm.</para>

      <para><filename>/etc/krb5.conf</filename> is split into sections; you
      should search for section "<literal>[domain_realm]</literal>" and append
      your definition: <screen>
.<replaceable>spinlock.hr</replaceable> = <replaceable>SPINLOCK.HR</replaceable>
<replaceable>spinlock.hr</replaceable> = <replaceable>SPINLOCK.HR</replaceable>
</screen></para>

      <para>At the bottom of the file, you should add the logging section:
      <screen>
[logging]
	kdc = FILE:/var/log/kerberos/krb5kdc.log
	admin_server = FILE:/var/log/kerberos/kadmin.log
	default = FILE:/var/log/kerberos/krb5lib.log
</screen> To create the logging directory and set up permissions, run:
      <programlisting>
sudo mkdir /var/log/kerberos
sudo touch /var/log/kerberos/{krb5kdc,kadmin,krb5lib}.log
sudo chmod -R 750  /var/log/kerberos
</programlisting></para>

      <para>Don't forget to also restart the log monitoring command you ran
      earlier (see <xref linkend="conventions" />) — the
      <command>tail</command> program needs to pick up the new log files from
      the <filename class="directory">kerberos/</filename> directory.</para>

<para>
It is also a good idea to disallow "weak enctypes" in Kerberos. These are the
cryptographic algorithms that are no longer considered secure (or at
least robust), and currently include all single-DES enctypes.
The option called "<literal>allow_weak_crypto</literal>" was added in Krb 1.7,
defaulting to true.  In Kerberos 1.8 and later, weak enctypes are disabled
by default and no manual setting is necessary.
</para>

<para>So, if you are using Kerberos 1.7, search for the section called
"<literal>[libdefaults]</literal>" in
<filename>/etc/krb5.conf</filename> (usually at the top of the file) and
append the following definition: <screen>
allow_weak_crypto = false
</screen>
</para>

      <para>Finally, to apply all changes, run: <programlisting>
sudo invoke-rc.d krb5-admin-server restart
sudo invoke-rc.d krb5-kdc restart
</programlisting></para>

    </section>

    <section id="krb-test1">
      <title>Initial test</title>

      <para>It is already the time to test the installation. We assume that
      both the admin server and the KDC can be restarted with no errors (which
      should be no problem to determine if you're monitoring the log files as
      advised).</para>

      <para>As the first test, we will run command
      <command>kadmin.local</command> on the server.</para>

      <para>Start <command>kadmin.local</command>, then type
      <userinput>listprincs</userinput>. That command should print out the
      list of principals (user, host and service accounts) in the database.
      The whole session should look like this: <screen>
<userinput>sudo kadmin.local</userinput>
Authenticating as principal root/admin@<replaceable>SPINLOCK.HR</replaceable> with password.

kadmin.local:  <userinput>listprincs</userinput>

K/M@<replaceable>SPINLOCK.HR</replaceable>
kadmin/admin@<replaceable>SPINLOCK.HR</replaceable>
kadmin/changepw@<replaceable>SPINLOCK.HR</replaceable>
kadmin/history@<replaceable>SPINLOCK.HR</replaceable>
kadmin/krb1.<replaceable>SPINLOCK.HR</replaceable>@<replaceable>SPINLOCK.HR</replaceable>
krbtgt/<replaceable>SPINLOCK.HR</replaceable>@<replaceable>SPINLOCK.HR</replaceable>

kadmin.local:  <userinput>quit</userinput>
</screen> The <command>kadmin</command> command ordinarily requires principal
      name and password before letting anyone access the administrative
      interface. However, <command>kadmin.local</command> is a variant of the
      command that must be run locally on the same machine as the KDC, and
      with administrator privileges. It is then able to open the Kerberos
      database file directly (taking advantage of Unix file permissions),
      without requiring extra privileges and without using the
      <command>kadmind</command> (Kerberos master server) daemon.</para>
    </section>

    <section id="krb-princnames">
      <title>Principal Names</title>

      <para>In the test step above, you might have noticed &PRINCIPAL; names
      similar to
      <literal>kadmin/admin@<replaceable>SPINLOCK.HR</replaceable></literal>.
      The general naming syntax for principals is
      <literal><replaceable>SPEC</replaceable>@<replaceable>REALM</replaceable></literal>,
      where <replaceable>SPEC</replaceable> by convention consists of
      components separated by "<literal>/</literal>", and the default
      <replaceable>REALM</replaceable> can be omitted.</para>

      <para>In the case of user names, the first component identifies the user
      name, and the second component, if present, identifies user role. For
      regular users, there will usually be one principal with no special role,
      named simply <literal><replaceable>USERNAME</replaceable></literal>. But
      when administrative or other roles are required, there will be no need
      to condense them all to one "<literal>root</literal>" prinicpal — each
      user can simply be given conveniently named additional principals with
      special privileges, such as
      <literal><replaceable>USERNAME</replaceable>/admin</literal>.</para>

      <para>In the case of service names, the components will be used to
      identify service and hostname, such as
      <literal>host/<replaceable>monarch.spinlock.hr</replaceable></literal>
      or
      <literal>ldap/<replaceable>monarch.spinlock.hr</replaceable></literal>.
      ("host" is somewhat of a misnomer from today's perspective — it has
      nothing to do with host per-se, but is actually the service name for all
      remote shell protocols, such as rsh, rlogin and ssh).</para>
    </section>

    <section id="krb-access">
      <title>Access rights</title>

      <para>Let's take a look at the
      <filename>/etc/krb5kdc/kadm5.acl</filename> file; it defines user access
      rights for the Kerberos database. For regular users with no special
      privileges, no action will be required. For admin users, we will want to
      grant all privileges, as hinted earlier in <xref
      linkend="krb-princnames" />. To do this, make sure the following line is
      present in the file and enabled (that is, without the comment
      '<literal>#</literal>' character at the beginning): <screen>
*/admin *
</screen> (While the above syntax might remind you of &SHELL_GLOBBING;,
      unfortunately it does not work that way at all. The only matching
      character supported is the asterisk ("<literal>*</literal>"), it does
      not match multiple components, and it can only be used in form of
      "<literal><replaceable>component1</replaceable>/*</literal>" or
      "<literal>*/<replaceable>component2</replaceable></literal>".)</para>

      <para>Make sure to restart the admin server to apply
      <filename>/etc/krb5kdc/kadm5.acl</filename> changes: <programlisting>
sudo invoke-rc.d krb5-admin-server restart
</programlisting></para>
    </section>

    <section>
      <title>Kerberos policies</title>

      <para>Kerberos "policies" offer an elegant way to sort principals into a
      kind of categories and to automatically apply corresponding defaults
      onto newly created principals.</para>

      <para>Let's create four basic policies: for admins, hosts, services and
      users. In this example, each policy will define minimum password
      strength (measured in number of character classes present in the
      password, from 1 to 5), but a few other options can be set — run
      <userinput>addpol</userinput> (the supported abbreviation of add_policy)
      if you're curious. <screen>
<userinput>sudo kadmin.local</userinput>
Authenticating as principal root/admin@<replaceable>SPINLOCK.HR</replaceable> with password.

kadmin.local:  <userinput>add_policy -minlength 8 -minclasses 3 admin</userinput>
kadmin.local:  <userinput>add_policy -minlength 8 -minclasses 4 host</userinput>
kadmin.local:  <userinput>add_policy -minlength 8 -minclasses 4 service</userinput>
kadmin.local:  <userinput>add_policy -minlength 8 -minclasses 2 user</userinput>

kadmin.local:  <userinput>quit</userinput>
</screen></para>
    </section>

    <section id="krb-adduser-priv">
      <title>Creating first privileged principal</title>

      <para>As you might have noticed, the <command>kadmin.local</command>
      command identified us as the principal <literal>root/admin</literal>.
      Still, that principal does not actually exist in the database so we
      might as well create it now. Once the principal is actually there, we'll
      be able to connect to the administrative server using
      <command>kadmin</command> from any machine within the Kerberos realm,
      and not just by using <command>kadmin.local</command> on the Kerberos
      server.</para>

      <para>Creating a principal based on your regular identity (such as
      <literal><replaceable>USERNAME</replaceable>/admin</literal>) is
      preferred over creating one called <literal>root/admin</literal>, so
      feel free to subsitute "<literal>root</literal>" in the following
      transcript (and the rest of the guide) with your username: <screen>
<userinput>sudo kadmin.local</userinput>
Authenticating as principal root/admin@<replaceable>SPINLOCK.HR</replaceable> with password.

kadmin.local:  <userinput>addprinc -policy admin root/admin</userinput>

Enter password for principal "root/admin@<replaceable>SPINLOCK.HR</replaceable>": <userinput><replaceable>PASSWORD</replaceable></userinput>
Re-enter password for principal "root/admin@<replaceable>SPINLOCK.HR</replaceable>": <userinput><replaceable>PASSWORD</replaceable></userinput>
Principal "root/admin@<replaceable>SPINLOCK.HR</replaceable>" created.

kadmin.local:  <userinput>quit</userinput>
</screen></para>
    </section>

    <section id="krb-test2">
      <title>Kadmin test</title>

      <para>Now that the <literal>root/admin</literal> principal exists in the
      Kerberos database, we should be able to use <command>kadmin</command>
      just as we used <command>kadmin.local</command>. The only exception, of
      course, is that <command>kadmin</command> will prompt for a password to
      connect to the Kerberos admin server.</para>

      <para>Double-check that all the permissions are granted to admin roles
      in the <filename>/etc/krb5kdc/kadm5.acl</filename> (as explained in
      <xref linkend="krb-access" />), and that the admin server has been
      restarted to read the new configuration; then proceed to test
      <command>kadmin</command> connection:</para>

      <para><screen>
<userinput>sudo kadmin -p root/admin</userinput>
Authenticating as principal root/admin@<replaceable>SPINLOCK.HR</replaceable> with password.

Password for root/admin@<replaceable>SPINLOCK.HR</replaceable>: <userinput><replaceable>PASSWORD</replaceable></userinput>

kadmin:  <userinput>listprincs</userinput>

K/M@<replaceable>SPINLOCK.HR</replaceable>
root/admin@<replaceable>SPINLOCK.HR</replaceable>
kadmin/admin@<replaceable>SPINLOCK.HR</replaceable>
kadmin/changepw@<replaceable>SPINLOCK.HR</replaceable>
kadmin/history@<replaceable>SPINLOCK.HR</replaceable>
kadmin/krb1.<replaceable>SPINLOCK.HR</replaceable>@<replaceable>SPINLOCK.HR</replaceable>
krbtgt/<replaceable>SPINLOCK.HR</replaceable>@<replaceable>SPINLOCK.HR</replaceable>

kadmin:  <userinput>quit</userinput>
</screen></para>
    </section>

    <section id="krb-adduser-ticket">
      <title>Creating first unprivileged principal</title>

      <para>Let's add a principal that will correspond to your regular,
      unprivileged user account. In our example, the username will be called
      "<literal>mirko</literal>". We've essentially performed this procedure
      for the <literal>root/admin</literal> principal above, but we'll repeat
      it here for your regular user account, using a different policy,
      replacing <replaceable>mirko</replaceable> with your username: <screen>
<userinput>sudo kadmin -p root/admin</userinput>
Authenticating as principal root/admin@<replaceable>SPINLOCK.HR</replaceable> with password.

Password for root/admin@<replaceable>SPINLOCK.HR</replaceable>: <userinput><replaceable>PASSWORD</replaceable></userinput>

kadmin:  <userinput>addprinc -policy user <replaceable>mirko</replaceable></userinput>

Enter password for principal "mirko@<replaceable>SPINLOCK.HR</replaceable>": <userinput><replaceable>PASSWORD</replaceable></userinput>
Re-enter password for principal "mirko@<replaceable>SPINLOCK.HR</replaceable>": <userinput><replaceable>PASSWORD</replaceable></userinput>
Principal "mirko@<replaceable>SPINLOCK.HR</replaceable>" created.

kadmin:  <userinput>quit</userinput>
</screen></para>
    </section>

    <section id="krb-obtain-ticket">
      <title>Obtaining Kerberos ticket</title>

      <para>As hinted in the introduction, each user is expected to type in
      the password once, to obtain the initial TGT (Ticket-granting Ticket).
      Obtained tickets are saved to a so-called <emphasis>ticket
      cache</emphasis>, which is most commonly a file named
      <literal>/tmp/krb5cc_*</literal>, stored on the user's
      workstation.</para>

      <para>Let's run the <command>klist</command> command to inspect our
      ticket cache (run this command under your regular, non-privileged
      username). As one might guess, since we did not obtain any tickets yet,
      the cache will be empty: <screen>
<userinput>klist -5f</userinput>

klist: No credentials cache found (ticket cache FILE:/tmp/krb5cc_0)
</screen> Let's use <command>kinit</command> now to obtain the ticket, and
      then re-inspect the ticket cache. If the command seemingly "hangs" and
      does nothing, wait a few seconds — DNS misconfiguration may cause a
      delay. <screen>
<userinput>kinit</userinput>

Password for mirko@<replaceable>SPINLOCK.HR</replaceable>: <userinput><replaceable>PASSWORD</replaceable></userinput>
</screen> <screen>
<userinput>klist -5f</userinput>

Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: mirko@<replaceable>SPINLOCK.HR</replaceable>

Valid starting     Expires            Service principal
11/22/06 22:30:36  11/23/06 08:30:33  krbtgt/<replaceable>SPINLOCK.HR</replaceable>@<replaceable>SPINLOCK.HR</replaceable>
        renew until 11/23/06 22:30:34, Flags: FPRIA
</screen> If you remember the story from the beginning, you will recognize the
      "<literal>krbtgt</literal>" to be the Ticket-granting Ticket.</para>

      <para><command>klist</command> switch <literal>-f</literal> produced the
      "renew until..." line. The meanings of each flag letter are not
      important at this stage, but long-term it is useful to get into the
      habit of using <literal>-f</literal>, and the flags descriptions can be
      looked up in the <citerefentry>
          <refentrytitle>klist</refentrytitle>

          <manvolnum>1</manvolnum>
        </citerefentry> manpage.</para>

      <para>All great. Let's run <userinput>kdestroy</userinput> to terminate
      the ticket now.</para>
    </section>

    <section id="krb-inst-krberized">
      <title>Installing kerberized services</title>

      <para>To actually use Kerberos, we need to install kerberized versions
      of the standard services.</para>

      <para>Each service may support Kerberos authentication either by having
      native Kerberos support, or by delegating the authentication work to the
      PAM subsystem (and since all relevant services support PAM, this means
      it is possible to Kerberize all network services).</para>

      <para>In your &DEB; repository, there will be packages like
      <literal>krb-ftpd</literal>, <literal>krb5-telnetd</literal> and
      <literal>krb5-rsh-server</literal>. Those are replacement services for
      ftp, telnet and rsh with native Kerberos (and encryption)
      support.</para>

      <caution>
        <para>The mentioned <literal>krb-ftpd</literal>,
        <literal>krb5-telnetd</literal> and <literal>krb5-rsh-server</literal>
        are still part of Kerberos for traditional reasons, but they contain
        known implementation flaws and their removal has been discussed a
        couple of times. We will use still use
        <literal>krb5-rsh-server</literal> here because that is the most
        straight-forward during learning phase, but removing
        <literal>krb5-rsh-server</literal> and setting up
        <literal>ssh</literal> is covered in later chapters of this
        Guide.</para>
      </caution>

      <para>So let's install the <literal>krb5-rsh-server</literal>. After
      installation, ensure that the service runs. It is started from
      <command>inetd</command>, so <command>inetd</command> must be running
      and the <literal>kshell</literal> and <literal>eklogin</literal>
      services need to be enabled in <filename>/etc/inetd.conf</filename>.
      <programlisting>
sudo apt-get install openbsd-inetd
sudo apt-get install krb5-rsh-server

sudo update-rc.d -f openbsd-inetd remove
sudo update-rc.d openbsd-inetd defaults

sudo update-inetd --enable kshell
sudo update-inetd --enable eklogin

sudo invoke-rc.d openbsd-inetd restart
</programlisting></para>

      <para>To connect to a certain service, the service must have a
      corresponding principal in the Kerberos database. This is because the
      Kerberos server acts as a trusted 3rd party and performs mutual
      authentication of the user and the service as explained in <xref
      linkend="intro-krb" />. The generic service name for telnet, rsh, ssh
      and related protocols is "<literal>host</literal>", so let's create the
      necessary principal with a randomly-generated password. Make sure that
      you export the key to a keytab file as shown (that is, within the same
      invocation of <command>kadmin</command>) to save yourself from getting
      an error about the "Key version number" being incorrect: <screen>
<userinput>sudo kadmin -p root/admin</userinput>
Authenticating as principal root/admin@<replaceable>SPINLOCK.HR</replaceable> with password.

Password for root/admin@<replaceable>SPINLOCK.HR</replaceable>: <userinput><replaceable>PASSWORD</replaceable></userinput>

kadmin:  <userinput>addprinc -policy service -randkey host/<replaceable>monarch.spinlock.hr</replaceable></userinput>

Principal "host/<replaceable>monarch.spinlock.hr</replaceable>@<replaceable>SPINLOCK.HR</replaceable>" created.

kadmin:  <userinput>ktadd -k /etc/krb5.keytab -norandkey host/<replaceable>monarch.spinlock.hr</replaceable></userinput>
Entry for principal host/<replaceable>monarch.spinlock.hr</replaceable>@<replaceable>SPINLOCK.HR</replaceable> with kvno 3, encryption type AES-256 CTS mode with 96-bit SHA-1 HMAC added to keytab WRFILE:/etc/krb5.keytab.
Entry for principal host/<replaceable>monarch.spinlock.hr</replaceable>@<replaceable>SPINLOCK.HR</replaceable> with kvno 3, encryption type ArcFour cbc mode with HMAC/md5 added to keytab WRFILE:/etc/krb5.keytab.
Entry for principal host/<replaceable>monarch.spinlock.hr</replaceable>@<replaceable>SPINLOCK.HR</replaceable> with kvno 3, encryption type Triple DES cbc mode with HMAC/sha1 added to keytab WRFILE:/etc/krb5.keytab.
Entry for principal host/<replaceable>monarch.spinlock.hr</replaceable>@<replaceable>SPINLOCK.HR</replaceable> with kvno 3, encryption type DES cbc mode with CRC-32 added to keytab WRFILE:/etc/krb5.keytab.

kadmin:  <userinput>quit</userinput>
</screen> <warning id="randkey-1.7">
          <para>With Kerberos 1.7 version 1.7dfsg~beta3-1 (and possibly
          others), you will see the following error when assigning -randkey
          passwords to principals with minimum character classes set above
          1:</para>

          <para><screen>
kadmin:  <userinput>addprinc -policy service -randkey host/<replaceable>monarch.spinlock.hr</replaceable></userinput>

<errortext>
add_principal: Password does not contain enough character classes while creating "host/<replaceable>monarch.spinlock.hr</replaceable>"
</errortext>
</screen></para>

          <para>This is due to a bug introduced in -randkey operation during
          addition of UTF-8 support. Status report on the issue can be tracked
          under <ulink
          url="http://krbdev.mit.edu/rt/Ticket/Display.html?id=6568">RT Ticket
          #6568</ulink>, but your immediate short term solution is to just
          reduce the corresponding policy's -minclasses to 1 as follows:
          <screen>
kadmin:  <userinput>modpol -minclasses 1 host</userinput>
kadmin:  <userinput>modpol -minclasses 1 service</userinput>
</screen></para>
        </warning> Finally, ensure that this keytab file,
      <filename>/etc/krb5.keytab</filename>, is <emphasis
      role="bold">moved</emphasis> to the rsh server machine. If the rsh
      server and the Kerberos server are the same machine, no copying to the
      remote location is necessary.</para>
    </section>

    <section id="krb-service">
      <title>Installing kerberized clients</title>

      <para>Let's install kerberized versions of the basic client programs:
      <programlisting>
sudo apt-get install krb5-clients
</programlisting> One of the client programs, <command>krb5-rsh</command>,
      will allow you connect to the secure rsh server, automatically and
      without asking for any user names or passwords. The connection will also
      be encrypted as long as the <literal>-x</literal> switch is used.</para>

      <para>As we have taken care of all the pre-requisites, we can try
      connecting:</para>

      <para>Obtain Kerberos ticket: <screen>
<userinput>kinit</userinput>

Password for USERNAME@<replaceable>SPINLOCK.HR</replaceable>: <userinput><replaceable>PASSWORD</replaceable></userinput>
</screen></para>

      <para>Connect: <screen>
<userinput>krb5-rsh -x -PN krb1.<replaceable>spinlock.hr</replaceable></userinput>

This rlogin session is encrypting all data transmissions.
Last login: Mon Nov 27 16:49:49 from monarch
Linux monarch 2.4.27-2-686 #1 Mon May 16 17:03:22 JST 2005 i686 GNU/Linux

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
You have new mail.

<userinput>logout</userinput>
Connection closed.
</screen></para>

      <para><emphasis role="bold">Congratulations! You have a working Kerberos
      setup</emphasis>.</para>

      <para>If anything is not working, proceed right to <xref
      linkend="krb_troubleshooting" /> — it contains an extensive list of
      possible errors and the corresponding solutions!</para>

      <para>If everything is working, then you can skip that section for now
      and head directly to <xref linkend="PAM_configuration" />.</para>
    </section>
  </section>

  <section id="krb_troubleshooting">
    <title>Troubleshooting Kerberos connection</title>

    <section id="err_no_tickets_cached">
      <title>Error: Trying krb4 rlogin... krb_sendauth failed: You have no
      tickets cached</title>

      <para><screen>
<userinput>krb5-rsh -x -PN krb1.<replaceable>spinlock.hr</replaceable></userinput>

<errortext>
Trying krb4 rlogin...
krb_sendauth failed: You have no tickets cached
</errortext>
</screen> You have no valid Kerberos tickets, which can be verified by running
      <command>klist -5</command> (the output will either be empty or show
      expired tickets). Obtain a new ticket using <command>kinit</command>:
      <screen>
<userinput>kinit <replaceable>PRINCIPAL_NAME</replaceable></userinput>
</screen></para>
    </section>

    <section id="err_connection_refused">
      <title>Error: Connection Refused</title>

      <para><screen>
<userinput>krb5-rsh -PN krb1.<replaceable>spinlock.hr</replaceable></userinput>

<errortext>
connect to address 192.168.7.12: Connection refused
Trying krb4 rlogin...
connect to address 192.168.7.12: Connection refused
trying normal rlogin (/usr/bin/netkit-rlogin)
exec: No such file or directory
</errortext>
</screen> Let's take a look at this. First of all, you can see that
      <command>krb5-rsh</command> has some fallbacks built-in. It first tries
      to connect using the Kerberos 5 protocol, then Kerberos 4, and then
      using the normal, non-kerberized rsh. We are only interested in the krb5
      result. If any of the other two methods succeed (the krb4 or plain rsh),
      it's still not what we want (and you will probably want to disable them
      somehow, because no one setting up a new Kerberos realm in the 21st
      century should be running either krb4 or unprotected rsh).</para>

      <para>So where's the problem? Assuming that you did everything right
      (installed krb5-rsh-server and restarted inetd), the problem is very
      simple. Namely, by default, kerberized servers in Debian do not accept
      unencrypted connections! So, on next attempt, add <literal>-x</literal>
      on the command line. <screen>
<userinput>krb5-rsh -PN -x krb1.<replaceable>spinlock.hr</replaceable></userinput>
</screen></para>
    </section>

    <section id="err_server_not_found">
      <title>Error: Server not found in Kerberos database</title>

      <para><screen>
<userinput>krb5-rsh -PN -x krb1.<replaceable>spinlock.hr</replaceable></userinput>

<errortext>
error getting credentials: Server not found in Kerberos database
</errortext>
</screen> As explained in <xref linkend="intro-krb" />, both the users and the
      services must have an appropriate principal entry in the Kerberos
      database. While users are in form of
      <replaceable>NAME/ROLE</replaceable>, services are in form
      <replaceable>SERVICE-NAME/HOSTNAME</replaceable>. So we need to add a
      principal for service "<literal>host</literal>" (common name for all
      shell services), on host where the service is provided —
      <replaceable>monarch.spinlock.hr</replaceable>. (Strictly, the service
      is provided on the server, on
      krb1.<replaceable>spinlock.hr</replaceable>, but in a single-machine
      setup, the hostname's FQDN returns
      <replaceable>monarch.spinlock.hr</replaceable> so we must use
      that).</para>

      <para>Within the same session, you will almost always want to export
      that principal's key to a keytab file. Exporting will not work as
      intended if the key was not created in a single
      <command>kadmin</command> session, so the below solution deletes the
      existing key (if any), creates it anew and exports it to a file. As to
      what you need to do with the keytab file after creation — you need to
      move it from the Kerberos server onto the machine providing the service.
      If that is the same machine, no moving is necessary.</para>

      <para>As most of the errors really boil down to this step, we also take
      care of re-initializing the ticket properly, to minimize the chance of a
      mistake: <screen>
<userinput>rm /etc/krb5.keytab</userinput>

<userinput>kdestroy</userinput>

<userinput>sudo kadmin.local</userinput>
Authenticating as principal root/admin@<replaceable>SPINLOCK.HR</replaceable> with password.

kadmin.local:  <userinput>delprinc host/<replaceable>monarch.spinlock.hr</replaceable></userinput>
Are you sure you want to delete the principal "host/<replaceable>monarch.spinlock.hr@SPINLOCK.HR</replaceable>"? (yes/no): <userinput>yes</userinput>
Principal "host/<replaceable>monarch.spinlock.hr@SPINLOCK.HR</replaceable>" deleted.
Make sure that you have removed this principal from all ACLs before reusing.

kadmin.local:  <userinput>addprinc -randkey host/<replaceable>monarch.spinlock.hr</replaceable></userinput>

WARNING: no policy specified for host/<replaceable>monarch.spinlock.hr</replaceable>@<replaceable>SPINLOCK.HR</replaceable>; defaulting to no policy
Principal "host/<replaceable>monarch.spinlock.hr</replaceable>@<replaceable>SPINLOCK.HR</replaceable>" created.

kadmin.local:  <userinput>ktadd -k /etc/krb5.keytab -norandkey host/<replaceable>monarch.spinlock.hr</replaceable></userinput>

kadmin.local: <userinput>quit</userinput>

<userinput>kinit root/admin</userinput>
</screen></para>
    </section>

    <section id="err_no_such_file_or_directory">
      <title>Error: No such file or directory</title>

      <para><screen>
<userinput>krb5-rsh -PN -x krb1.<replaceable>spinlock.hr</replaceable></userinput>

<errortext>
Couldn't authenticate to server: Server rejected authentication (during sendauth exchange)
Server returned error code 60 (Generic error (see e-text))
Error text sent from server: No such file or directory
</errortext>
</screen> The above error indicates that we should pay attention to the
      "e-text" (error text returned to the client). The error text tells us,
      in kind of a confusing way (since — you see — there is no filename
      reported), that the <filename>/etc/krb5.keytab</filename> file on the
      rsh server is missing altogether. This file needs to exist and contain
      the service key. The way to obtain the file and the key is to follow the
      recipe from <xref linkend="err_server_not_found" />.</para>
    </section>

    <section id="err_key_table_entry_not_found">
      <title>Error: Key table entry not found</title>

      <para><screen>
<userinput>krb5-rsh -PN -x krb1.<replaceable>spinlock.hr</replaceable></userinput>

<errortext>
Couldn't authenticate to server: Server rejected authentication (during sendauth exchange)
Server returned error code 60 (Generic error (see e-text))
Error text sent from server: Key table entry not found
</errortext>
</screen> The server did accept the connection, but the e-text "Key table
      entry not found" indicates that the service principal (created earlier,
      <literal>host/<replaceable>monarch.spinlock.hr</replaceable></literal>)
      is not listed in the keytab file on rsh server. Follow the recipe in
      <xref linkend="err_server_not_found" />.</para>
    </section>

    <section id="err_key_version_number_incorrect">
      <title>Error: Key version number for principal in key table is
      incorrect</title>

      <para><screen>
<userinput>krb5-rsh -PN -x krb1.<replaceable>spinlock.hr</replaceable></userinput>

<errortext>
Couldn't authenticate to server: Server rejected authentication (during sendauth exchange)
Server returned error code 60 (Generic error (see e-text))
Error text sent from server: Key version number for principal in key table is incorrect
</errortext>
</screen> The service key has changed on the Kerberos server, and the service
      did not succeed in proving its identity to the Kerberos server — the
      file <filename>/etc/krb5.keytab</filename> on the service did not
      contain the correct key. Have in mind that the key changes if you run
      <literal>ktadd</literal> from within the <command>kadmin</command>
      shell, and the only way to prevent that from happening is to use
      <command>kadmin.local</command> interface and use <userinput>ktadd
      -norandkey</userinput> in it. If curious, read up on
      <literal>ktadd</literal> behavior in <citerefentry>
          <refentrytitle>kadmin</refentrytitle>

          <manvolnum>8</manvolnum>
        </citerefentry>. Follow the recipe in <xref
      linkend="err_server_not_found" />.</para>
    </section>

    <section id="err_client_not_found">
      <title>Error: Client not found in Kerberos database while getting
      initial credentials</title>

      <para><screen>
<userinput>kinit <replaceable>root/admin</replaceable></userinput>

<errortext>
kinit(v5): Client not found in Kerberos database while getting initial credentials
</errortext>
</screen> This is Kerberos way of saying "User not found". You either
      misspelled the principal name ("<literal>root/admin</literal>" in this
      case), or you didn't add the principal to the kerberos database in the
      first place. Adding a principal is performed using the
      <command>addprinc</command> command as shown in <xref
      linkend="krb-adduser-priv" /> or <xref
      linkend="krb-adduser-ticket" />.</para>
    </section>

    <section id="err_kadm_client_not_found">
      <title>Error: Client not found in Kerberos database while initializing
      kadmin interface</title>

      <para><screen>
<userinput>sudo kadmin -p <replaceable>root/admin</replaceable></userinput>

<errortext>
kadmin: Client not found in Kerberos database while initializing kadmin interface
</errortext>
</screen> This is Kerberos way of saying "User not found". You either
      misspelled the principal name ("<literal>root/admin</literal>" in this
      case), or you didn't add the principal to the kerberos database in the
      first place. Adding a principal is performed using the
      <command>addprinc</command> command as shown in <xref
      linkend="krb-adduser-priv" /> or <xref
      linkend="krb-adduser-ticket" />.</para>
    </section>

    <section id="err_decrypt_integrity_check_failed">
      <title>Error: Decrypt integrity check failed</title>

      <para><screen>
<userinput>krb5-rsh -PN -x krb1.<replaceable>spinlock.hr</replaceable></userinput>

<errortext>
Couldn't authenticate to server: Server rejected authentication (during sendauth exchange)
Server returned error code 31 (Decrypt integrity check failed)
Error text sent from server: Decrypt integrity check failed
</errortext>
</screen> This is Kerberos way of saying "Password incorrect". In this case,
      it means that the service key changed on the server, and your your
      ticket cache no longer contains the ticket with the correct key. Running
      <userinput>kdestroy; kinit</userinput> should obtain a new ticket and
      solve the problem.</para>
    </section>
  </section>

  <section id="PAM_configuration">
    <title>PAM configuration</title>

    <para>The final step in this article pertains to integrating Kerberos into
    the system authentication procedure. We want Kerberos tickets to be issued
    for users as they log in, without the need to run <command>kinit</command>
    manually after login.</para>

    <para>On GNU/Linux and derivatives, this is done by simply altering &PAM;
    configuration in <filename class="directory">/etc/pam.d/</filename> on all
    machines where the users are logging in.</para>

    <para>As we have explained in <xref linkend="intro-krb" />, Kerberos alone
    does not help replace the usual password files
    (<filename>/etc/passwd</filename>, <filename>/etc/shadow</filename> or
    <filename>/etc/group</filename>). For now, your "kerberized" users will
    have to be present in both system password files and in Kerberos.</para>

    <para>This will lead to users having two passwords and two password aging
    settings — one in <filename>/etc/shadow</filename> and one in the Kerberos
    database. Our &PAM; configuration will be defined so that
    <emphasis>either</emphasis> the usual password authentication
    <emphasis>or</emphasis> Kerberos authentication will need to succeed for
    the user to log in. This way, both users that will have no Kerberos entry
    (the system ones, such as <literal>root</literal>,
    <literal>daemon</literal>, <literal>bin</literal>,
    <literal>sync</literal>, <literal>sys</literal>, ...) and those that will
    (regular user accounts), will be able to log in.</para>

    <para>System password in <filename>/etc/shadow</filename> will be tried
    first. If you want Kerberos tickets to be issued, this type of
    authentication <emphasis role="bold">must fail</emphasis> for regular
    users (otherwise their "system login" would succeed — resulting in the
    Kerberos part being skipped altogether and no tickets issued).</para>

    <para>The most common way to make regular users have only one password
    (and that one being in Kerberos) is to replace their system password in
    <filename>/etc/shadow</filename> with a literal "<literal>*K*</literal>",
    which is not a valid password and also by spoken convention indicates that
    the "real" password is stored in Kerberos. This password can be set either
    by editing <filename>/etc/shadow</filename> file directly (i.e. with
    <userinput>sudo vipw -s</userinput>) or by invoking <userinput>sudo
    usermod -p '*K*' <replaceable>USERNAME</replaceable></userinput>.</para>

    <para>Let's install the necessary Kerberos PAM module: <programlisting>
sudo apt-get install libpam-krb5
</programlisting></para>

    <para>Let's configure &PAM;. PAM configuration is quite fragile, so use
    the provided examples that have been verified to work. For any
    modifications, you will want to look at &PSY; and pay special attention to
    seemingly insignificant variations — with PAM, they often make a whole
    world of difference.</para>

    <para>To minimize the chance of locking yourself out of the system during
    PAM configuration phase, ensure right now that you have at least one root
    terminal window open and a copy of the files available
    <emphasis>before</emphasis> starting on PAM configuration changes. To do
    so, execute the following in a cleanly started shell and leave the
    terminal open: <programlisting>
sudo su -
cd /etc
cp -a pam.d pam.d,orig
</programlisting></para>

    <note>
      <para>If you break logins with an invalid PAM configuration, the above
      will allow you to simply revert to a known-good state by using the open
      root terminal and executing: <programlisting>
cp -a pam.d,orig/* pam.d/
</programlisting></para>
    </note>

     The following PAM examples are complete; you should replace your existing configuration with the one shown below: 

    <section>
      <title>/etc/pam.d/common-account</title>

      <para>
        <screen>
account sufficient        pam_unix.so
account sufficient        pam_krb5.so
account required          pam_deny.so
</screen>
      </para>
    </section>

    <section>
      <title>/etc/pam.d/common-auth</title>

      <para>
        <screen>
auth    sufficient        pam_unix.so nullok_secure
auth    sufficient        pam_krb5.so use_first_pass
auth    required          pam_deny.so
</screen>
      </para>
    </section>

    <section>
      <title>/etc/pam.d/common-password</title>

      <para>
        <screen>
password  sufficient   pam_unix.so nullok obscure md5
password  sufficient   pam_krb5.so use_first_pass
password  required     pam_deny.so
</screen>
      </para>
    </section>

    <section>
      <title>/etc/pam.d/common-session</title>

      <para>
        <screen>
session required pam_limits.so
session optional pam_krb5.so
session optional pam_unix.so
</screen>
      </para>
    </section>

    <para>After you've edited PAM configuration, restart the services you will
    be connecting to. This isn't strictly necessary, but it ensures that the
    services will re-read the PAM configuration and not use any cached
    information.</para>
  </section>

  <section>
    <title>Conclusion</title>

    <para>DONATE_LINK</para>

    <para>At this point, you have a functional Kerberos installation!</para>

    <para>You can rely on either system login or manually running
    <command>kinit</command> in obtaining Kerberos tickets and accessing
    Kerberized services. One of those services is the passwordless,
    Kerberos-secured rsh login that we've demonstrated in this guide.</para>

    <para>Remember that, as explained in this Guide, your user accounts still
		need to be created locally on
    all hosts the users wish to access. To solve that problem and achieve true
    centralized logins, follow the next article in the series, the
    &DKLAR_LDA;.</para>

    <para>If you've followed this &DKLAR_KRB; only as a pre-requisite for
    installing OpenAFS and do not want to use LDAP in combination, proceed to
    another article in the series, the &DKLAR_AFS;.</para>

		<para>
		<emphasis role='bold'>With a good foundation we've built, for further
		information on Kerberos, please refer to other available resources:</emphasis>

		<itemizedlist>
			<listitem><para>
			Official documentation: &DOC;
			</para></listitem>
			<listitem><para>
			Mailing lists: &MLS;
			</para></listitem>
			<listitem><para>
			IRC: channel #kerberos at the FreeNode network (irc.freenode.net)
			</para></listitem>
		</itemizedlist>
		</para>
		<para>
		For commercial consultation and infrastructure-based networks containing
		Kerberos, contact &SL;.
		</para>

  </section>

  <section>
    <title>Links</title>

    <para>Platforms:<sbr /> &GNU; <sbr /> &DEB; <sbr /><sbr />
    Kerberos:<sbr /> &KRB; <sbr /> &HDL; <sbr /> &KRBC; <sbr /><sbr />
    Kerberos specifics:<sbr /> &KERBEROS_RELEASE; <sbr /> &KERBEROS_DATABASE;
    <sbr /> &REALM; <sbr /> &KDC; <sbr /> &PRINCIPAL; <sbr /> &SECRET_KEY;
    <sbr /> &TGT; <sbr /><sbr /> Glue layer:<sbr /> &PAM; <sbr /> &PSY;
    <sbr /><sbr /> Related infrastructural technologies:<sbr /> &LDA; <sbr />
    &AFS; <sbr /> &RAD; <sbr /><sbr /> Commercial support:<sbr /> &SL;
    <sbr /><sbr /> Misc:<sbr /> &DOCBK; <sbr /></para>
  </section>
</article>
