Pages

Thursday, March 27, 2014

(MIT) Kerberos for Slackware

With this article I want you to show how to set up Kerberos in Slackware. I have setup two VM's to write this article. The first VM is named kdc01 and will be the Kerberos server. The second VM is named kdc02 and will be the Kerberos client. This article contains the following sections:

1. Install and configure the Kerberos server (kdc01)
1.1. Install Kerberos
1.2. Configure Kerberos
2. Install and configure the Kerberos client (kdc02)
2.1. Install Kerberos
2.2. Configure Kerberos
2.3. Install PAM
2.4. Configure PAM for Kerberos

The overall process isn't to hard but there are still some pits. Perhaps this article clears up a few things.
Let's get started!

1. Install and configure the Kerberos server (kdc01)

1.1. Install Kerberos

First create a directory where you can store all your sources, eg /usr/src/krb5:

# mkdir /usr/src/krb5

Then change into the source directory and grab a copy of the Kerberos sources from ...:

# cd /usr/src/krb5
# wget -c "http://web.mit.edu/Kerberos/dist/krb5/1.12/krb5-1.12.1-signed.tar"

...

After the download has finished extract the source package:

# tar xf krb5-1.12.1-signed.tar

The tar package contains the gzipped sources and a gnupg file. To continue with the installation extract the source package:

# tar xf krb5-1.12.1.tar.gz

Change into the newly created directory:

# cd /usr/src/krb5/krb5-1.12.1/src

And for 64Bit systems run:

# ./configure --prefix=/usr --libdir=/usr/lib64 --sysconfdir=/etc --localstatedir=/var/krb5 --datarootdir=/usr/share/krb5

In case that you're still using a 32Bit system run:

# ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var/krb5 --datarootdir=/usr/share/krb5

Then run make to compile the source and to install the binaries etc.:

# make && make install
...
That's it, Kerberos has been installed.

1.2. Configure Kerberos

After the installation has finished create a configuration file:

# vi /etc/krb5.conf
[kdcdefaults]
  kdc_ports = 88

[libdefaults]
  default_realm = KARELLEN.LOCAL

[realms]
  KARELLEN.LOCAL = {
    kdc = 192.168.1.26:88
    kadmind_port = 749
    admin_server = 192.168.1.26:749
    acl_file = /etc/kadm5.acl
  }

[domain_realm]
  .karellen.local = KARELLEN.LOCAL

[logging]
  kdc = FILE:/var/log/krb5/krb5kdc.log
  admin_server = FILE:/var/log/krb5/kadmin.log
  default = FILE:/var/log/krb5/krb5.log


The above configuration file is a very simple example and contains some information about the IP, ports and the realm we want to use. Just keep in mind that the IP is the IP of the server where you installed Kereberos itself. For your realm use any name that fits your needs (the realm name is independant from your origin domain).
To get logging working you need to create the log directory first:

# mkdir /var/log/krb5

Also a acl file is needed:

# vi /etc/kadm5.acl
*/admin@KARELLEN.LOCAL     *


The above acl will allow all principals (users) with a admin role to change everything. I will show you later how to setup a admin principal etc.
Finally you're ready to create the initial database (you must be patient here a little):

# kdb5_util create -s
Loading random data
Initializing database '/var/krb5/krb5kdc/principal' for realm 'KARELLEN.LOCAL',
master key name 'K/M@KARELLEN.LOCAL'
You will be prompted for the database Master Password.
It is important that you NOT FORGET this password.
Enter KDC database master key: It'satrap!
Re-enter KDC database master key to verify: It'satrap!


Now you're ready to use the administrative tool kadmin.local to add, modify, delete principals, policies etc:

# kadmin.local
Authenticating as principal root/admin@KARELLEN.LOCAL with password.


Before you add new prinicipals create a default password policy:

kadmin.local:  add_policy -maxlife 30days -minlife 1days -minlength 8 default

The above policy will force users to change their password every 30 days. The password can only be changed once a day and must have at least 8 characters.
Next add your first administrative principal:

kadmin.local:  addprinc karellen/admin
NOTICE: no policy specified for karellen/admin@KARELLEN.LOCAL; assigning "default"
Enter password for principal "karellen/admin@KARELLEN.LOCAL": It'satrap!
Re-enter password for principal "karellen/admin@KARELLEN.LOCAL": It'satrap!
Principal "karellen/admin@KARELLEN.LOCAL" created.


After all that you need to start the krb5kdc daemon. You can use the following RC script to start and stop the krb5kdc daemon:

# vi /etc/rc.d/rc.krb5kdc
#!/bin/bash
bin="/usr/sbin/krb5kdc"
pid_file="/var/run/krb5kdc.pid"

function start_krb5kdc {
  echo "Starting krb5kdc: $bin -P $pid_file"
  $bin -P $pid_file
}

function stop_krb5kdc {
  if [[ -f $pid_file ]]; then
    kill -15 `cat $pid_file`
    sleep 1
    if [[ `ps -ef | grep "$bin" | grep \`cat $pid_file\`` == "" ]]; then
      rm $pid_file
    else
      kill -9 `cat $pid_file`
      rm $pid_file
    fi
  fi
}

case "$1" in
  'start')
    start_krb5kdc
    ;;
  'stop')
    stop_krb5kdc
    ;;
  'restart')
    stop_krb5kdc
    start_krb5kdc
    ;;
  *)
    echo "usage $0 start|stop|restart"
    ;;
esac


Make it executable and start it:

# chmod 755 /etc/rc.d/rc.krb5kdc
# /etc/rc.d/rc.krb5kdc start
Starting krb5kdc: /usr/sbin/krb5kdc -P /var/run/krb5kdc.pid


In case that nothing has gone wrong so far you should be able to request your first Kerberos TGT:

# kinit karellen/admin
Password for karellen/admin@KARELLEN.LOCAL: It'satrap!


Check your TGT with klist:

# klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: karellen/admin@KARELLEN.LOCAL

Valid starting       Expires              Service principal
03/02/2014 19:38:15  03/03/2014 19:38:15  krbtgt/KARELLEN.LOCAL@KARELLEN.LOCAL


At this point you're ready to create a normal principal (any user). First destroy your current TGT:

# kdestroy

Next use the kadmin.local tool again:

# kadmin.local
Authenticating as principal root/admin@KARELLEN.LOCAL with password.


Next I assume you have a normal user with the UID 100. Mine is sneill. Every user that needs access to Kerberos needs a principal. Also make sure that the password for the principal sneill is the same as the shadow password!
To create the principal sneill type:

kadmin.local:  addprinc sneill
NOTICE: no policy specified for sneill@KARELLEN.LOCAL; assigning "default"
Enter password for principal "sneill@KARELLEN.LOCAL": It'satrap!
Re-enter password for principal "sneill@KARELLEN.LOCAL": It'satrap!
Principal "sneill@KARELLEN.LOCAL" created.


Quit kadmin.local and request a TGT for sneill:

# kinit sneill
Password for sneill@KARELLEN.LOCAL: It'satrap!


Check the TGT with klist again and check the default principal:

# klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: sneill@KARELLEN.LOCAL

Valid starting       Expires              Service principal
03/02/2014 19:44:54  03/03/2014 19:44:54  krbtgt/KARELLEN.LOCAL@KARELLEN.LOCAL


If you've done it so far then you're ready to install the Kerberos client.

2. Install and configure the Kerberos client (kdc02)

2.1. Install Kerberos

Unfortunately every Slackware machine which needs Kerberos access needs the Kerberos binaries. That means that you've to compile the source package everytime or you just create a Slackware package once and install it on every machine.
In case that you haven't created a Slackware package follow th whole instruction as described in 1.1 (see above): copy the sources, unpack them, run the configure script followed by make and make install! Don't configure Kerberos on the client yet! Ignore paragraph 1.2!

2.2. Configure Kerberos

The Kerberos configuration file for the client looks a little different:

# vi /etc/krb5.conf
[libdefaults]
  default_realm = KARELLEN.LOCAL

[realms]
  KARELLEN.LOCAL = {
    kdc = kdc01:88
    admin_server = kdc01:749
  }

[domain_realm]
  .karellen.local = KARELLEN.LOCAL

[logging]
  kdc = FILE:/var/log/krb5/krb5kdc.log
  admin_server = FILE:/var/log/krb5/kadmin.log
  default = FILE:/var/log/krb5/krb5.log


The section [realms] only tells the client where to find the Kerberos server. The rest is identical.
No service needs to be started and nothing more needs to be configured. If you create a Slackware package for yourself it might be handy to have the configuration file shipped with your package.
Let's do some testing again and request a TGT for sneill:

# kinit sneill
Password for sneill@KARELLEN.LOCAL: It'satrap!


Check the TGT with klist again and check the default principal:

# klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: sneill@KARELLEN.LOCAL

Valid starting       Expires              Service principal
03/17/2014 18:57:11  03/18/2014 18:57:11  krbtgt/KARELLEN.LOCAL@KARELLEN.LOCAL


And you're done. Your Kerberos client is setup and can reqeuest a TGT from your Kerberos Server.
Onward into battle with PAM.

2.3. Install PAM

PAM is needed when a user (sneill) logs into the client (kdc02) to request a TGT automatically during login.
Download a copy, extract it and compile it:

# cd /usr/src/krb5
# wget -c "http://www.linux-pam.org/library/Linux-PAM-1.1.8.tar.bz2"
...
# tar xf Linux-PAM-1.1.8.tar.bz2
# cd Linux-PAM-1.1.8


For 64Bit systems run:

# ./configure --prefix=/usr --libdir=/lib64  --disable-static --enable-shared
...


And for 32Bit system run:

# ./configure --prefix=/usr --libdir=/lib --disable-static --enable-shared
...


Then compile the source and install the binaries:

# make && make install
...


After the compile finished you should have at least the directory /lib/security/ (or /lib64/security) with a few PAM libraries/modules in.
Now you need to recompile the shadow package provided with Slackware. Download or copy the complete source tree for the shadow package (I copied it from the ISO):

# mkdir -p /mnt/loop
# mount slackware-14.1-source-dvd.iso /mnt/loop/ -o loop,ro -t iso9660
# cp -r /mnt/loop/source/a/shadow/ /usr/src/krb5/
# umount /mnt/loop/


Now go to the source directory. Edit the build script and add to the configure options the --with-libpam switch that it looks like this:

# cd /usr/src/krb5/shadow
# vi shadow.SlackBuild
...
./configure \
  --prefix=/usr \
  --sysconfdir=/etc \
  --mandir=/usr/man \
  --docdir=/usr/doc/shadow-$VERSION \
  --disable-shared \
  --without-libcrack \
  --with-libpam \
  --build=$ARCH-slackware-linux
...


Save the script and exit vi, then run the script:

# sh shadow.SlackBuild
...
Slackware package /tmp/shadow-4.1.5.1-x86_64-2.txz created.


When the compile finished, you should have a new shadow package under /tmp. Check that it contains the login and su binary:

# tar tfv /tmp/shadow-*.txz | grep bin
...
-rws--x--x root/root     36913 2011-11-12 14:00 bin/su
-rwxr-xr-x root/root     43720 2011-11-12 14:00 bin/login
...


Now remove the old shadow package and replace it with the new package with PAM support:

# removepkg shadow
...
# installpkg /tmp/shadow-*.txz
...

Next you need to configure each authentication mechanism you want to provide for PAM. If you want to use the normal console login, then you need to configure /etc/pam.d/login. If you want to use ssh, then you need to configure /etc/pam.d/sshd and so on. The new shadow package comes already with a few rule sets which can be found under /etc/pam.d. I don't like them so I always make a backup of them and use my own:

# mkdir /etc/pam.d/orig
# mv /etc/pam.d/* /etc/pam.d/orig


Here is my sample for /etc/pam.d/login:

# vi /etc/pam.d/login
auth            include         common-auth
account         include         common-account
session         include         common-session


And my common PAM rules (which will be adjusted later for use with Kerberos):

# vi /etc/pam.d/common-auth
auth            sufficient      pam_unix.so
auth            required        pam_deny.so

# vi /etc/pam.d/common-account
account         sufficient      pam_unix.so
account         required        pam_permit.so

# vi /etc/pam.d/common-password
password        sufficient      pam_unix.so
password        required        pam_deny.so

# vi /etc/pam.d/common-session
session         sufficient      pam_mkhomedir.so skel=/etc/skel umask=0022
session         sufficient      pam_unix.so
session         required        pam_deny.so


The first file is for the login mechanism it self. PAM provides 4 modules (auth, account, password and session). I created for each module a seperate file with their own mechanisms (common-auth, common-account, common-password and common-session). Each module can be controlled by 4 mechanism (requisite, required, sufficient and optional). The example above is only for the login on a console. You can try to log in now:

# login
configuration error - unknown item 'FAILLOG_ENAB' (notify administrator)
...
configuration error - unknown item 'ENVIRON_FILE' (notify administrator)
blog01 login: root
Password:


One thing: the configuration error messages that appear can be disabled by editing the file /etc/login.defs. Just comment them out:

# vi /etc/login.defs
...
#FAILLOG_ENAB           yes
...


When the root login worked, try to login as user sneill:

# login
kdc02 login: sneill
Password:
Creating directory '/home/sneill'.
$


To allow your users to use passwd and su, you need two more pam rules for passwd and su:

# vi /etc/pam.d/passwd
auth            include         common-auth
account         include         common-account
password        include         common-password

# vi /etc/pam.d/su   
auth            sufficient      pam_rootok.so
auth            include         common-auth
account         include         common-account
session         include         common-session


With these rulesets root and normal users can change their password, root can su to a normal user and normal users may switch to root. To login via ssh you have to recompile the ssh package and create a pam ruleset for sshd. Before you recompile the ssh package make sure that you can login on a console or via telnet. You can recompile and reinstall the ssh package using ssh but when something goes wrong then you may loose your connection and your control about the server. To recompile ssh mount the CD (or DVD) again and copy the source:

# mkdir -p /mnt/loop
# mount slackware-14.1-source-dvd.iso /mnt/loop/ -o loop,ro -t iso9660
# cp -r /mnt/loop/source/n/openssh/ /usr/src/krb5/
# umount /mnt/loop/


Next edit the build script again and replace the --without-pam option with the --with-pam option:

# cd /usr/src/krb5/openssh/
# vi openssh.SlackBuild
...
# Compile package:
CFLAGS="$SLKCFLAGS" \
./configure \
  --prefix=/usr \
  --mandir=/usr/man \
  --sysconfdir=/etc/ssh \
  --with-pam \
  --with-md5-passwords \
  --with-tcp-wrappers \
  --with-default-path=/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin \
  --with-privsep-path=/var/empty \
  --with-privsep-user=sshd \
  --build=$ARCH-slackware-linux
...


Start the script to recompile ssh with pam support:

# sh openssh.SlackBuild
...
Slackware package /tmp/openssh-6.3p1-x86_64-1.txz created.


Check that the package contains the ssh binaries:

# tar tfv /tmp/openssh-*.txz | grep "bin/ssh"
...
-rwxr-xr-x root/root    356828 2011-11-13 10:53 usr/bin/ssh
-rwxr-xr-x root/root    444684 2011-11-13 10:53 usr/sbin/sshd


Then remove the ssh package and install the new package with pam support:

# removepkg openssh
...
# installpkg /tmp/openssh-*.txz
...


Edit the sshd configuration and activate pam:

# vi /etc/ssh/sshd_config
...
#UsePAM no
UsePAM yes
...


Save your configuration and restart the ssh daemon:

# /etc/rc.d/rc.sshd restart
WARNING: killing listener process only.  To kill every sshd process, you must
         use 'rc.sshd stop'.  'rc.sshd restart' kills only the parent sshd to
         allow an admin logged in through sshd to use 'rc.sshd restart' without
         being cut off.  If sshd has been upgraded, new connections will now
         use the new version, which should be a safe enough approach.


The last step is to create a pam ruleset for ssh. If you are lazy (like me) then just copy the ruleset for login to sshd (don't forget the d at the end of sshd):

# cp /etc/pam.d/login /etc/pam.d/sshd

Finally you should be able to login as root and normal users via ssh again:

# ssh sneill@kdc02
Password: It'satrap!
...


After all that your authentication mechanism was changed to PAM.

2.4. Configure PAM for Kerberos

One last step to request a TGT during login. For that you need another PAM module. Yeah, more sources to download and to compile. The module pam_krb5-2.3.1-3+ldap can be found on http://www.sourceforge.net. Download a copy, save it to /usr/src/krb5 and extract it:

# cd /usr/src/krb5
# tar xf pam_krb5-2.3.1-3+ldap.tgz


Change into the new directory and run the configure script:

./configure --prefix=/usr --libdir=/lib64; make; make installation
...


For 32Bit system run this:

./configure --prefix=/usr --libdir=/lib; make; make install
...


Next compile the sources and install the binaries:

# make && make install
...


After the installation has finished check that the library was installed:

# ls -lah /lib64/security/*krb*
-rwxr-xr-x 1 root root  850 Mar  3 12:21 /lib64/security/pam_krb5.la*
-rwxr-xr-x 1 root root 387K Mar  3 12:21 /lib64/security/pam_krb5.so*
...


Now it is time to adjust the PAM rules a little and to add the pam_krb5 module:

# vi common-account
account         required        pam_unix.so broken_shadow
account         required        pam_permit.so

# vi common-auth
auth            sufficient      pam_krb5.so minimum_uid=100
auth            sufficient      pam_unix.so try_first_pass
auth            required        pam_deny.so

# vi common-password
password        sufficient      pam_krb5.so minimum_uid=100
password        sufficient      pam_unix.so try_first_pass
password        required        pam_deny.so

# vi common-session
session         optional        pam_krb5.so minimum_uid=100
session         sufficient      pam_unix.so
session         sufficient      pam_mkhomedir.so skel=/etc/skel umask=0022
session         required        pam_deny.so


After you have modified the PAM rules try to login as user sneill via ssh on kdc02:

$ ssh sneill@kdc02
Password:
...


Finally run klist to check if you've received a new TGT:

sneill@kdc02:~$ klist
Ticket cache: FILE:/tmp/krb5cc_100_u0vBmm
Default principal: sneill@KARELLEN.LOCAL

Valid starting       Expires              Service principa
l
03/26/2014 18:26:02  03/27/2014 18:26:01  krbtgt/KARELLEN.LOCAL@KARELLEN.LOCAL


And that's it - Kerberos on Slackware!