Preparation for the Kerberos lab

To get the "wow" factor for the initial exercises, showing how easy it is to add clients and servers to a Kerberised network, we need to have a Kerberos/LDAP environment already up and running.

Prepare the DNS

Build the NOC machine and ensure forward and reverse DNS is fully working, if not already done.

Create kdc1 as an alias to whatever machine will be running the primary KDC (probably also the NOC), and add the Kerberos service records.

# apt-get install bind9 bind9-utils
# editor /etc/bind/named.conf.local
zone "ws.nsrc.org"      { type master; file "/etc/bind/ws.nsrc.org"; };
zone "10.in-addr.arpa"  { type master; file "/etc/bind/10.in-addr.arpa"; };

# editor /etc/bind/ws.nsrc.org
$TTL    600
@       IN      SOA     noc.ws.nsrc.org. root.noc.ws.nsrc.org. (
                              1         ; Serial
                         604800         ; Refresh
                            600         ; Retry
                        2419200         ; Expire
                            600 )       ; Negative Cache TTL
@       IN      NS      noc.ws.nsrc.org.

_kerberos               IN      TXT     "WS.NSRC.ORG"
_kerberos-master._udp   IN      SRV     0 0 88 kdc1
_kerberos-adm._tcp      IN      SRV     0 0 749 kdc1
_kpasswd._udp           IN      SRV     0 0 464 kdc1
; List all active Kerberos servers here
_kerberos._udp          IN      SRV     0 0 88 kdc1
ldap                    IN      A       10.10.254.250

noc     IN      A       10.10.254.250
kdc1    IN      A       10.10.254.250
$GENERATE 1-20 $ IN PTR pc$.ws.nsrc.org.

# editor /etc/bind/10.in-addr.arpa
$TTL    600
@       IN      SOA     noc.ws.nsrc.org. root.noc.ws.nsrc.org. (
                              1         ; Serial
                         604800         ; Refresh
                            600         ; Retry
                        2419200         ; Expire
                            600 )       ; Negative Cache TTL
@       IN      NS      noc.ws.nsrc.org.

$GENERATE 1-20 $.1.10 IN PTR pc$.ws.nsrc.org.
250.254.10      IN      PTR     noc.ws.nsrc.org.

# editor /etc/resolv.conf
search ws.nsrc.org
nameserver 127.0.0.1

Test it:

# dig pc1
# dig -x 10.10.1.1
# dig _kerberos._udp.ws.nsrc.org. srv

If the NOC machine also has an entry for itself in /etc/hosts, make sure its FQDN is the first one listed.

# editor /etc/hosts
...
10.10.254.250  noc.ws.nsrc.org noc

Build slave DNS if desired

You like resilience don't you? :-) And it sets a good example!

Build primary KDC

See also the MIT Kerberos docs (esp. install guide) at http://web.mit.edu/kerberos/krb5-1.8/#documentation

Install ntp:

# apt-get install ntp

Install kdc packages:

# apt-get install krb5-kdc krb5-admin-server

Answer the annoying debconf questions:

Default Kerberos 5 realm:         [WS.NSRC.ORG]
Kerberos servers for your realm:  [kdc1.ws.nsrc.org]
Administrative server:            [kdc1.ws.nsrc.org]

Create the client library config:

# mv /etc/krb5.conf /etc/krb5.conf.example
# editor /etc/krb5.conf
[libdefaults]
default_realm = WS.NSRC.ORG
dns_lookup_realm = true
dns_lookup_kdc = true

[realms]
WS.NSRC.ORG = {
        admin_server = kdc1.ws.nsrc.org
}

(note that kadmin doesn't yet support looking up the admin server via DNS; hence we have to list it in krb5.conf)

Create Kerberos database:

kdb5_util create -r WS.NSRC.ORG -s
# You will be asked to choose a database master password. We use "abcd"

Create the ACL file and grant admin rights to all */admin principals:

# editor /etc/krb5kdc/kadm5.acl
*/admin@WS.NSRC.ORG    *

Now create some principals: a host principal for the host itself, putting the random key into its own keytab file; an instructor principal ("nsrc"); and an instructor KDC admin principal ("nsrc/admin")

# kadmin.local
addprinc -randkey host/noc.ws.nsrc.org
ktadd host/noc.ws.nsrc.org
addprinc nsrc
-- you'll be prompted to choose a password
addprinc nsrc/admin
-- you'll be prompted to choose a password
^D

Now start the daemons:

# /etc/init.d/krb5-kdc start
# /etc/init.d/krb5-admin-server start

At this point, you should be able to kinit nsrc and get a ticket. If you get "Cannot resolve network address for KDC" then check the DNS.

Note: new principals can now be added using kadmin instead of kadmin.local, and you can use it from any remote machine where you can kinit. (So you never need to do a local login to the KDC)

Build slave KDC if desired

If you want to build a slave KDC, see the instructions at http://web.mit.edu/kerberos/krb5-1.8/krb5-1.8.3/doc/krb5-install.html#Install%20the%20Slave%20KDCs

Add another _kerberos._udp srv entry in the DNS pointing to kdc2 so that clients know about both of them.

Enable Kerberized ssh

The first exercise requires students to make a single-signon ssh login.

Create a 'testuser' kerberos principal in the KDC, which the students will login as.

$ kadmin -p nsrc/admin
addprinc testuser
... choose a password which will be given to the students, e.g. nsrc2020
^D

On the machine(s) where the students will be allowed to login via kerberos, create a 'testuser' account (but don't set any local password) and enable Kerberos authentication for sshd. Note we're not doing LDAP yet.

# useradd -m -s /bin/bash testuser
# editor /etc/ssh/sshd_config
...
GSSAPIAuthentication yes
GSSAPIKeyExchange yes
...
# service ssh restart

Now we'll test it. You can either do this from the noc to itself, or you can use a separate throw-away client VM, or your own laptop. If using a separate machine you'll first have to make it a Kerberos client like this:

# apt-get install krb5-user
# mv /etc/krb5.conf /etc/krb5.conf.example
# editor /etc/krb5.conf
[libdefaults]
default_realm = WS.NSRC.ORG
dns_lookup_realm = true
dns_lookup_kdc = true

Check that /etc/ssh/ssh_config has GSSAPIAuthentication yes and if supported GSSAPIKeyExchange yes (On Mac OSX: /etc/ssh_config)

Now it should work:

$ kinit testuser
$ ssh testuser@noc

If it still doesn't work after this, Kerberos problems can be tricky to debug. First check both machines have accurately synced clocks, and that forward and reverse DNS is working. Then you can try starting another sshd in debug mode on another port:

# /usr/sbin/sshd -d -p99

Then on the client:

$ ssh -v -p99 nsrc@noc

Test with Kerberized Apache

If Apache isn't already installed on the noc, install it, and also curl for testing.

# apt-get install apache2 curl

Create a test directory and test page:

# mkdir /var/www/secure
# editor /var/www/secure/index.html
... whatever you like

-- check it works and is not yet protected
# curl http://noc.ws.nsrc.org/secure/

Now we're going to kerberize it.

# apt-get install libapache2-mod-auth-kerb
# editor /etc/apache2/conf.d/topsecret
<Location /secure>
  AuthName "Hello Kerberos World"
  AuthType Kerberos
  # Allow fallback to Basic Auth?
  KrbMethodK5Passwd Off
  KrbAuthRealms WS.NSRC.ORG
  Krb5Keytab /etc/apache2/krb5/krb5.keytab
  # require user nsrc@WS.NSRC.ORG
  require valid-user
</Location>

# service apache2 restart

Check that the page is no longer visible (curl gives a 403 error)

We now have to create a service principal, and extract its key into the keytab specified in the config above, readable to the apache daemon.

# mkdir /etc/apache2/krb5
# kadmin -p nsrc/admin
addprinc -randkey HTTP/noc.ws.nsrc.org
ktadd -k /etc/apache2/krb5/krb5.keytab HTTP/noc.ws.nsrc.org 
^D
# chown -R www-data:www-data /etc/apache2/krb5
# chmod 550 /etc/apache2/krb5
# chmod 440 /etc/apache2/krb5/krb5.keytab

Check that the page is visible while you have a ticket with a client which supports HTTP Negotiate (and also check it isn't after kdestroy)

# curl --negotiate -u: http://noc.ws.nsrc.org/secure/

If you want to test from Firefox or Chrome, see the presentation.

NOTE: testing suggests that modauthnzldap only does anonymous binds or fixed simple binds (i.e. I couldn't get it to use SASL, even if the www-data user has a ticket). We can gloss over this for now.

Configure master LDAP server

This is by far the hardest part of the operation, due to the cryptic way OpenLDAP 2.4 now stores its configs within LDAP instead of in a config file. See man slapd-config

There is a good series of articles here: http://www.opinsys.fi/en/setting-up-openldap-on-ubuntu-10-04-alpha2 But there are many others which user openldap <2.4 and slapd.conf

Install the slapd server and Kerberos bits:

# apt-get install slapd ldap-utils libsasl2-modules-gssapi-mit

Set up the service principal with keytab readable by slapd:

# mkdir /etc/ldap/krb5
# kadmin -p nsrc/admin
addprinc -randkey ldap/noc.ws.nsrc.org
ktadd -k /etc/ldap/krb5/krb5.keytab ldap/noc.ws.nsrc.org
^D
# chown -R openldap:openldap /etc/ldap/krb5
# chmod 550 /etc/ldap/krb5
# chmod 440 /etc/ldap/krb5/krb5.keytab
# editor /etc/default/slapd
...
export KRB5_KTNAME=/etc/ldap/krb5/krb5.keytab

# service slapd restart

Install the schemas we need:

# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/cosine.ldif
# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/nis.ldif
# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/inetorgperson.ldif
# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/misc.ldif

NOTE: For a real production LDAP server, read the files in /usr/share/doc/slapd carefully, especially README.Debian.gz and README.DB_CONFIG.gz

Now we need to run some scripts. First is create_database.sh

ldapadd -Y EXTERNAL -H ldapi:/// <<EOS
# Load hdb backend module
dn: cn=module{0},cn=config
objectClass: olcModuleList
cn: module
olcModulepath: /usr/lib/ldap
olcModuleload: {0}back_hdb
EOS

ldapadd -Y EXTERNAL -H ldapi:/// <<EOS
# Create the hdb database and place the files under /var/lib/ldap
dn: olcDatabase={1}hdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcHdbConfig
olcDatabase: {1}hdb
olcDbDirectory: /var/lib/ldap
olcSuffix: dc=ws,dc=nsrc,dc=org
olcDbConfig: {0}set_cachesize 0 2097152 0
olcDbConfig: {1}set_lk_max_objects 1500
olcDbConfig: {2}set_lk_max_locks 1500
olcDbConfig: {3}set_lk_max_lockers 1500
olcLastMod: TRUE
olcDbCheckpoint: 512 30
olcDbIndex: uid pres,eq
olcDbIndex: cn,sn,mail pres,eq,approx,sub
olcDbIndex: objectClass eq
EOS

(Note: we have no olcRootDN or olcRootPW. This is a pure Kerberos config)

Next is init_database.sh

ldapadd -Y EXTERNAL -H ldapi:/// <<EOS
dn: dc=ws,dc=nsrc,dc=org
objectClass: dcObject
objectclass: organization
o: ws.nsrc.org
dc: ws
description: LDAP root

dn: ou=People,dc=ws,dc=nsrc,dc=org 
objectClass: top
objectClass: organizationalUnit
ou: People 

dn: ou=Groups,dc=ws,dc=nsrc,dc=org
objectClass: top
objectClass: organizationalUnit
ou: Groups
EOS

And finally config.sh

# Because these are 'replace' operations it's safe to modify this script
# and re-run it
ldapmodify -Y EXTERNAL -H ldapi:/// <<EOS
dn: cn=config
replace: olcSaslSecProps
olcSaslSecProps: noanonymous,noplain,minssf=56

dn: olcDatabase={1}hdb,cn=config
replace: olcAccess
olcAccess: {0}to * by dn.regex="^uid=([^@,]+)/admin,cn=gssapi,cn=auth$" manage by users read
-
replace: olcRequires
olcRequires: SASL
EOS

The following tweak disables unused sasl mechanisms, and means that -Y GSSAPI can be omitted form the ldapsearch command line.

# editor /etc/ldap/sasl2/slapd.conf
mech_list: gssapi external

Test LDAP

(On the same machine, or on a separate client)

# apt-get install ldap-utils libsasl2-modules-gssapi-mit
# editor /etc/ldap/ldap.conf
BASE    dc=ws,dc=nsrc,dc=org
URI     ldap://ldap.ws.nsrc.org

$ kinit nsrc
$ ldapsearch [-Y GSSAPI] [-b "dc=ws,dc=nsrc,dc=org"]

This should dump back the (mostly empty) LDAP database, as long as you have a Kerberos ticket

Create user

We are going to create a central user called "ldapuser"

Firstly in Kerberos:

$ kadmin -p nsrc/admin
addprinc ldapuser
... password: foo123bar
^D

And now in LDAP:

$ kinit nsrc/admin
$ ldapadd <<EOS
dn: uid=ldapuser,ou=People,dc=ws,dc=nsrc,dc=org
objectClass: account
objectClass: posixAccount
cn: ldapuser
uid: ldapuser
uidNumber: 10004
gidNumber: 100
homeDirectory: /home/ldapuser
loginShell: /bin/bash
gecos: ldapuser
description: User account
EOS
$ kdestroy

Test NSS

Now configure LDAP nscd/nsswitch, as per part 2 of exercise 2.

To verify all is working:

$ id ldapuser

You should see a result with the uid and gid. Repeated operations should be quick as nscd will be caching them.

Troubleshooting:

For easier management you can install the ldapscripts package, but see the patches at the end of exercise 4.

Configure backup LDAP

OpenLDAP replication is left as an exercise to the reader. You can configure round-robin DNS for ldap.ws.nsrc.org and it should work.