Introduction

The latest stable release of Debian GNU/Linux, 3.0r2 "Woody", can easily be setup as a DAS client. All of the required packages can be installed with the built-in Advanced Package Tool, or APT. Updated Kerberos, PAM, and NIS packages are available. Configuration is fairly simple. Debian also supports the Name Service Cache Daemon, or NSCD. NSCD reduces the load on the NIS servers and the network by caching lookups for a period of time. It also helps with performance when the DAS-M (master) is unavailable.

Assumptions

These Debian GNU/Linux client instructions assume the following:

The last point is VERY important. If you are running telnet, ftp, rlogind, Apache, etc. with those services configured to allow authentication of users with plaintext over the network, there is not much point in using Kerberos for secure authentication. The assumption is that you will only be logging in remotely via SSH2 or SSL/TLS encrypted sessions. This does NOT, however, preclude you from using Kerberized versions of TELNET or RLOGIN as long as they are configured to disallow plaintext authentication methods.

Reference Setup

My reference setup for these instructions was Debian 3.0r2 (Woody) using the 2.4.18-bf2.4 kernel on i686.

Step-by-step Instructions

Step 1: Software Installation

Most of the basic packages you will need are available on the Debian 3.0r2 CDs if you have them. However, if you configure your APT repositories for network retrieval and security updates, then you will not have to use the CDs and your packages will be up to date when they are installed. You will need the following packages:

There are many ways to ensure the packages are installed. For example, NIS can easy be selected from the deselect tool during install. You can check for the required packages using the dpkg -l | grep pkgname command.

In order to install the missing packages, just run apt-get update followed by apt-get install packagename [packagename] command. Here is an example of installing all the required packages and verifying the installation of the Kerberos packages afterwards:

deb:/etc# apt-get install portmap
deb:/etc# apt-get install nis
deb:/etc# apt-get install nscd
deb:/etc# apt-get install ntpdate
deb:/etc# apt-get install krb5-user
deb:/etc# apt-get install krb5-clients
deb:/etc# apt-get install krb5-doc
deb:/etc# apt-get install libpam-krb5

deb:/etc# dpkg -l | grep krb
ii  krb5-clients   1.2.4-5woody4  Secure replacements for ftp, telnet and rsh
ii  krb5-config    1.4            Configuration files for Kerberos Version 5
ii  krb5-doc       1.2.4-5woody4  Documentation for krb5
ii  krb5-user      1.2.4-5woody4  Basic programs to authenticate using MIT Ker
ii  libkrb53       1.2.4-5woody4  MIT Kerberos runtime libraries
ii  libpam-krb5    1.0-7          PAM module for MIT Kerberos

deb:/etc# dpkg -l | grep kadm
ii  libkadm55      1.2.4-5woody4  MIT Kerberos administration runtime librarie

Notes:

Step 2: Modify Configuration Files

Here is a list of the config files that must be modified:

Before you do anything else, backup the orginal config files to another directory, or add the .org extension to them.

First, let's add entries in /etc/hosts for the DAS servers. These will be used by ypbind (the NIS client):

10.10.22.42 das-m
10.10.22.40 das-s

Now, let's configure /etc/yp.conf with information about our NIS servers. This file is used by the ypbind daemon.

#
# yp.conf       Configuration file for the ypbind process. You can define
#               NIS servers manually here if they can't be found by
#               broadcasting on the local net (which is the default).
#
#               See the manual page of ypbind for the syntax of this file.
#
# IMPORTANT:    For the "ypserver", use IP addresses, or make sure that
#               the host is in /etc/hosts. This file is only interpreted
#               once, and if DNS isn't reachable yet the ypserver cannot
#               be resolved and ypbind won't ever bind to the server.
 
# ypserver ypserver.network.com
 
ypserver das-m
ypserver das-s

Since we are setting up NIS client services for the first time, we must use the domainname command to set the NIS domain. Example:

deb:~# domainname kerb.org
deb:~# domainname
kerb.org

In order to set the NIS domain name correctly on system boot, we need make sure that the /etc/defaultdomain config file has a single line with the following entry:

kerb.org

The next item is the /etc/nsswitch.conf file. Here is what it should look like:

# /etc/nsswitch.conf
#
# Example configuration of GNU Name Service Switch functionality.
# If you have the `glibc-doc' and `info' packages installed, try:
# `info libc "Name Service Switch"' for information about this file.
 
passwd:         compat nis
group:          compat nis
shadow:         compat
 
hosts:          files dns nis
networks:       files
 
protocols:      db files
services:       db files
ethers:         db files
rpc:            db files
 
netgroup:       nis

Next, we need to edit or create the /etc/krb5.conf file. It should look like this:

[logging]
 default = FILE:/var/log/krb5libs.log
 kdc = FILE:/var/log/krb5kdc.log
 admin_server = FILE:/var/log/kadmind.log
 
[libdefaults]
 ticket_lifetime = 24000
 default_realm = KERB.ORG
 dns_lookup_realm = false
 dns_lookup_kdc = false
 forwardable = true
 
 
[realms]
 KERB.ORG = {
         kdc = das-m.kerb.org:88
         kdc = das-s.kerb.org:88
         admin_server = das-m.kerb.org:749
         default_domain = kerb.org
}
 
[domain_realm]
 
 .kerb.org = KERB.ORG
 kerb.org = KERB.ORG
 
[kdc]
 profile = /var/kerberos/krb5kdc/kdc.conf
 
[appdefaults]
 pam = {
   debug = false
   ticket_lifetime = 36000
   renew_lifetime = 36000
   forwardable = true
   krb4_convert = false
}

Now, all we have left is the PAM configuration. Unfortunately, Debian does not come with a single system-auth file that most PAM modules reference. This means that each individual PAM config file must be modified to support Kerberos. In our case, we are only interested in console logins, sshd, and cron. You may need to configure other PAM configuration files, like gdm or xdm for graphical console logins, or password-protected screensavers. In any event, you will need to modify the /etc/pam.d config files to support your particular needs. Don't forget to backup the original config files before modifying them!

/etc/pam.d/login

#
# /etc/pam.d/login Modified for DAS use
#
auth      required    pam_issue.so issue=/etc/issue
auth      requisite   pam_securetty.so
auth      requisite   pam_nologin.so
 
auth      required    pam_env.so
auth      sufficient  pam_unix.so likeauth
auth      sufficient  pam_krb5.so use_first_pass minimum_uid=5000
auth      required    pam_deny.so
 
account   sufficient  pam_unix.so
account   required    pam_krb5.so minimum_uid=5000
 
password  sufficient  pam_unix.so obscure min=6 max=10 md5
password  required    pam_deny.so
 
session   optional    pam_motd.so
session   optional    pam_lastlog.so
session   optional    pam_mail.so standard noenv
session   required    pam_mkhomedir.so skel=/etc/skel/ umask=007
session   sufficient  pam_unix.so
session   required    pam_krb5.so minimum_uid=5000

Warning:  When you are altering the PAM config files, keep a root console open and test all your changes. Otherwise, you may be locked out of your own system.

Note: The "mkhomedir" PAM module is included so that every DAS user will automatically be given a home directory after their first console login to the system. If you do not want this behavior, simply comment the line out.

/etc/pam.d/ssh

#
# /etc/pam.d/ssh Modified for DAS use
#
auth       required     pam_env.so
auth       required     pam_nologin.so
auth       sufficient   pam_unix.so likeauth
auth       sufficient   pam_krb5.so use_first_pass minimum_uid=5000
auth       required     pam_deny.so
 
account    sufficient   pam_unix.so
account    required     pam_krb5.so minimum_uid=5000
 
password   sufficient   pam_unix.so obscure min=6 max=10 md5
password   required     pam_deny.so
 
session    optional     pam_motd.so
session    optional     pam_lastlog.so
session    optional     pam_mail.so standard noenv
session    sufficient   pam_krb5.so minimum_uid=5000
session    required     pam_unix.so

/etc/pam.d/cron

#
# The PAM configuration file for the cron daemon
# Modified for DAS use
#
account    sufficient   pam_unix.so
account    required     pam_krb5.so minimum_uid=5000

Note:   I am not sure why this is required, but cron jobs for DAS users will not work otherwise.

Step 3: Start the DAS client services, and configure them to start automatically during boot

Even though some of the services were started during the installation scripts, we have modified quite a few config files and should restart the services:

deb:/etc/pam.d# /etc/init.d/portmap restart
Stopping portmap daemon: portmap.
Starting portmap daemon: portmap.
deb:/etc/pam.d# /etc/init.d/nis restart
Starting NIS services: ypbind
deb:/etc/pam.d# /etc/init.d/nscd restart
Stopping Name Service Cache Daemon: nscd.
Starting Name Service Cache Daemon: nscd.

deb:/etc/pam.d# netstat -tunap
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:932             0.0.0.0:*               LISTEN      2871/ypbind
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN      2853/portmap
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      293/sshd
tcp        0    144 10.10.22.68:22        10.10.22.41:46569     ESTABLISHED 2033/sshd
udp        0      0 0.0.0.0:929             0.0.0.0:*                           2871/ypbind
udp        0      0 0.0.0.0:937             0.0.0.0:*                           2871/ypbind
udp        0      0 0.0.0.0:111             0.0.0.0:*                           2853/portmap

Now, let's make sure that the services will start automatically at boot time. We can do this with any of three methods:

Debian defaults to booting into runlevel 2. The portmapper package, once installed, will automatically start at boot time. I recommend using rcconf to designate NIS (ypbind) and nscd to start automatically. On my test system, these were automatically setup to start at runlevel 2 when they were installed.

Step 4: Make Sure System Clock is Synchronized

You can setup time synchronization by setting up ntpd, or by using ntpdate. Please refer to the Client Time Synchronization section for details.

Step 5: Test

First, make sure that the host is able to bind to the NIS domain. This can be done with the following command:

deb:~# ypwhich
das-m

You should see "das-m" or "das-s". You can test NIS client functionality with the following additional commands:

If you are not having any luck with this, use the ps and netstat commands to check that the portmapper and ypbind are both running.

NIS testing example:

deb:~# ypwhich -m
hosts.byaddr das-m.kerb.org
hosts.byname das-m.kerb.org
group.bygid das-m.kerb.org
group.byname das-m.kerb.org
passwd.byname das-m.kerb.org
ypservers das-m.kerb.org
passwd.byuid das-m.kerb.org

deb:~# ypcat hosts
4.2.2.3       genuity
10.10.22.1    defgate
10.10.22.68   oscar
10.10.230.60  rat
10.10.22.90   printer
4.2.2.2       genuity-alt

deb:~# yppoll hosts.byname
Domain kerb.org is supported.
Map hosts.byname has order number 1082010515. [Thu Apr 15 14:28:35 2004]
The master server is das-m.kerb.org.

deb:~# id kitty
uid=6000(kitty) gid=50000(labuser) groups=50000(labuser)

deb:~# getent hosts
127.0.0.1     mysql
10.10.22.68   deb.kerb.org deb
10.10.22.42   das-m
10.10.22.40   das-s
4.2.2.3       genuity
10.10.22.1    defgate
10.10.22.68   oscar
10.10.230.60  rat
10.10.22.90   printer
4.2.2.2       genuity-alt

deb:~# rpcinfo -p
   program vers proto   port
    100000    2   tcp    111  portmapper
    100000    2   udp    111  portmapper
    100007    2   udp    965  ypbind
    100007    1   udp    965  ypbind
    100007    2   tcp    968  ypbind
    100007    1   tcp    968  ypbind

Getent is an excellent tool. It returns the information for nsswitch.conf entities and includes info from files, NIS, or any other configured name service. For example, getent hosts will show you the local hosts file with the NIS host file appended. Use the command man getent for more details.

Next, make sure than you can login as a DAS user to the Kerberos realm with kinit. You should do this as a local user; root or another one will work just as well. Here is an example:

deb:~# kinit kitty
Password for kitty@KERB.ORG:
deb:~# klist -e
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: kitty@KERB.ORG
                                                                                                  
Valid starting     Expires            Service principal
04/27/04 11:09:34  04/27/04 21:09:34  krbtgt/KERB.ORG@KERB.ORG
        Etype (skey, tkt): Triple DES cbc mode with HMAC/sha1, Triple DES cbc mode with HMAC/sha1
                                                                                                  
Kerberos 4 ticket cache: /tmp/tkt0
klist: You have no tickets cached
deb:~# kdestroy
deb:~# klist -e
klist: No credentials cache found (ticket cache FILE:/tmp/krb5cc_0)
                                                                                                  
Kerberos 4 ticket cache: /tmp/tkt0
klist: You have no tickets cached

Now you know that the Kerberos client programs are working correctly. Next, we will make sure that NIS, PAM, and Kerberos together can login a user from a console or SSH login. You will do this by obtaining a console login prompt. Enter the user "kitty" and then your Kerberos password. You should be logged on. Type klist and make sure that you have a Kerb ticket. Use the kpasswd command to change your Kerb password. Now logout, and try logging back in. You should have no problems.

You will also want to make sure that you can login as a local user or as root from the console. Now, from a remote machine, SSH to the Debian host and login as a local user. Then logout, and login as user "kitty". You should be able to login with your Kerb password.

If you need to do any troubleshooting with the client side of PAM/Kerberos authentication, look at the /var/log/auth.log log file.

Step 6: Security

First of all, you should probably consider using a packet-filter like iptables on your Debian machine to limit who can connect to which ports, as well as shutting off any unnecessary services. Whether you use a packet filter or not, the TCP Wrappers system can be used to add some security. In our case, the use of NIS and the Portmapper have added a potentially vulnerable service to our system. We can minimize the portmapper vulnerability by restricting who can connect to it with TCP wrappers. To do this, all you need to do is create (or edit) the /etc/hosts.allow file so that it looks like this:

# /etc/hosts.allow: list of hosts that are allowed to access the system.
#                   See the manual pages hosts_access(5), hosts_options(5)
#                   and /usr/doc/netbase/portmapper.txt.gz
#
#
# If you're going to protect the portmapper use the name "portmap" for the
# daemon name. Remember that you can only use the keyword "ALL" and IP
# addresses (NOT host or domain names) for the portmapper. See portmap(8)
# and /usr/doc/portmap/portmapper.txt.gz for further information.
#
 
portmap : 127. 10.10.22. : ALLOW
portmap : ALL : DENY

This limits who can connect to the portmapper to the loopback and the 10.10.22.0/24 network. Of course, you may have other restricted services listed in the file.

Using the iptables host-based packet filter/firewall is usually a good idea. UDP requests and replies must be handled correctly to support NIS, Kerberos, NTP, and DNS traffic. When you install Debian, you should specify that you want to include iptables as well as support for connection tracking and logging. For this example, I also enabled inbound SSH.

Traffic that orginates elsewhere can connect to the host only if it is explicitly allowed in the firewall rules. Below are the most important configuration statements from my iptables configuration file:

iptables -P INPUT DROP
iptables -A INPUT -i lo  -j ACCEPT
iptables -A INPUT -i $IFACE -p tcp ! --syn -m state --state NEW -j DROP
 
iptables -A INPUT -s $LABNET -d $IPADDR -p icmp --icmp-type echo-request -j ACCEPT
iptables -A INPUT -s any/0 -d $IPADDR -p icmp --icmp-type destination-unreachable -j ACCEPT
iptables -A INPUT -s any/0 -d $IPADDR -p icmp -m state --state ESTABLISHED,RELATED -j ACCEPT
 
iptables -A INPUT -s $DASNET -d $IPADDR -p tcp --dport 22 -j ACCEPT
 
iptables -A INPUT -s any/0 -d $IPADDR -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -s any/0 -d $IPADDR -p udp -m state --state ESTABLISHED -j ACCEPT

Here is the what the running iptables config looks like:

deb:~/FW# iptables -L -n -v
Chain INPUT (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
   90  8008 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0
    5   216 DROP       tcp  --  eth0   *       0.0.0.0/0            0.0.0.0/0          tcp flags:!0x16/0x02 state NEW
    0     0 ACCEPT     icmp --  *      *       10.10.0.0/16       10.10.22.68      icmp type 8
    0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            10.10.22.68      icmp type 3
    0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            10.10.22.68      state RELATED,ESTABLISHED
 6758  503K ACCEPT     tcp  --  *      *       10.10.22.0/24      10.10.22.68      tcp dpt:22
  658  324K ACCEPT     tcp  --  *      *       0.0.0.0/0            10.10.22.68      state RELATED,ESTABLISHED
 4380  280K ACCEPT     udp  --  *      *       0.0.0.0/0            10.10.22.68      state ESTABLISHED
    0     0 DROP       tcp  --  *      *       0.0.0.0/0            10.10.22.255
    0     0 DROP       tcp  --  *      *       0.0.0.0/0            255.255.255.255
40465 5342K DROP       udp  --  *      *       0.0.0.0/0            10.10.22.255
16520 4193K DROP       udp  --  *      *       0.0.0.0/0            255.255.255.255
    0     0 DROP       tcp  --  *      *       0.0.0.0/0            10.10.22.68      tcp dpt:135
    0     0 DROP       all  --  *      *       0.0.0.0/0            224.0.0.0/4
    0     0 LOG        udp  --  *      *       0.0.0.0/0            0.0.0.0/0          LOG flags 0 level 6 prefix `FW UDP: '
    0     0 DROP       udp  --  *      *       0.0.0.0/0            0.0.0.0/0
    0     0 LOG        tcp  --  *      *       0.0.0.0/0            0.0.0.0/0          LOG flags 0 level 6 prefix `FW TCP: '
    0     0 REJECT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0          reject-with icmp-port-unreachable
    0     0 LOG        icmp --  *      *       0.0.0.0/0            0.0.0.0/0          LOG flags 0 level 6 prefix `FW ICMP: '
    0     0 DROP       icmp --  *      *       0.0.0.0/0            0.0.0.0/0
    0     0 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0          LOG flags 0 level 6 prefix `FW Prot-X: '
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0

To see the complete iptables firewall config I am using, click here. If you do setup iptables, you will need to modify your init scripts to use your custom configuration.

Final Note:  If you write your own firewall script and then have problems with your DAS client, such as NIS or Kerberos errors, try removing the firewall before diving into any other troubleshooting.

The iptables -L -n -v command can also be a useful way of determining whether or not the packet filter is to blame.

Step 7: Create Home Directories for DAS Users (optional)

Debain includes the pam_mkhomedir PAM module. As long as you include it in your /etc/pam.d/login config file, you will not manually have to create directories and skeleton entries for DAS users before they can use any given DAS Client host. However, you may want to control who can use the system by creating the home directories manually for those who need them. As root, here is how you would do that:

deb:~# cd /home
deb:/home# rm -rf kitty
deb:/home# mkdir /home/kitty
deb:/home# cp -rv /etc/skel/.[a-z]* /home/kitty
`/etc/skel/.alias' -> `/home/kitty/.alias'
`/etc/skel/.bash_profile' -> `/home/kitty/.bash_profile'
`/etc/skel/.bashrc' -> `/home/kitty/.bashrc'
`/etc/skel/.cshrc' -> `/home/kitty/.cshrc'
deb:/home# id kitty
uid=6000(kitty) gid=50000(labuser) groups=50000(labuser)
deb:/home# chown -R kitty:labuser /home/kitty
deb:/home# chmod 0750 /home/kitty
deb:/home# ls -ald /home/kitty
drwxr-x---    2 kitty    labuser      4096 Apr 27 11:47 /home/kitty

Operational/Performance Notes

Note 1 - Client performance was very responsive when the DAS-M server was unavailable and the DAS-S server was available.

Note 2 - When both DAS servers are unavailable, boot, local user, and root logins are successful. Local user login is delayed about 5 seconds.

Note 3 - If the Debian host boots while the DAS servers are unavailable, ypbind may not start. Once the DAS servers are available again over the network, you can restore DAS functionality to the client by executing the /etc/init.d/nis script as root.

Note 4 - In any situtation where one or both DAS servers are unavailable, using nscd improves responsiveness, since it caches both postive and negative queries.

Note 5 - Disk quotas for DAS users worked correctly, whether DAS servers were available or not. While the DAS servers are not available, root will not be able to edit a DAS user's quota. Quota, repquota, and edquota all use the Name Service Switch system that is configured by /etc/nsswitch.conf.

Note 6 - cron and at may not work for a DAS user when the DAS servers are unavailable. Mail delivery will fail if the output of a job is to be mailed to the local host with a "no such user" type of error. Also, crond may consider the cron job of a DAS user to be "orphaned" if it cannot find the name. If this happens, crond will continue processing other crontabs, but will stop processing the crontabs of DAS users. When the DAS is available again, the DAS user can fix this by deleting his cron job and re-submitting it. Another alternative is for the root user on the host to restart crond. In all cases, checking /var/log/syslog should give you some clues.

Note 7 - If you must do administrative work on a DAS client host while it is disconnected from the network, it may cause some annoying delays with some tasks. If this is an issue, simply stop the ypbind daemon. You could also reconfigure the /etc/nsswitch.conf file so that NIS is not referenced.

Note 8 - Kerberized rlogin client sessions were tested for a DAS user. Both the encrypted and non-encrypted versions worked without any problems. telnet -x and ftp -x were also tested successfully. For ftp -x, you need to make sure that passive mode (PASV) is toggled on your FTP client to get through the iptables firewall.

Note 9 - You can setup public SSH keys for authentication, but you will not be granted any Kerberos tickets when you login. In order to use any Kerberized "SSO" clients, you will have to use kinit to get a ticket.

Note 10 - With this configuration, if the Kerberos password expires, you will get a warning, then login will fail. Password aging is problematic with DAS, since it seems to be handled differently based on PAM version, distribution, and application (like SSH). For now, password min/max life are not supported.

Note 11 - The kadmin program works fine from Debian.


References

Debian Documentation Page