This blog posting is a part of a series of blog postings:
- Part 1 – OpenLDAP setup
- Part 2 – SSL/TLS
- Part 3 – Schemas for samba, autofs and kerberos
- Part 4 – Kerberos setup
- Part 5 – DNS settings for kerberos using dnsmasq
- Part 6 – NFSv4 with kerberos
- Part 7 – Autofs
Next it’s time to finally get files moving between the servers. For this we use NFSv4 that supports kerberos out-of-the-box also in Ubuntu. This part is based on the newest Lucid packages in the repositories, which should be pretty close to alpha 3 now.
The following documents were used to get the configuration working:
- https://help.ubuntu.com/community/NFSv4Howto
- MIT Kerberos manual: Hostnames for KDCs
- Doug Potter: Kerberos/LDAP/NFSv4 HOWTO
The goal of the setup is to have a single file server that shares the following directories to clients over NFSv4 with kerberos authentication:
- /home/school1
- /home/school2
- /home/school3
The server will not allow root to access other users’ files which makes it possible to export the shares in potentially hostile environments as the compromise of a single client host does not expose all contents of the file server.
Server settings
The following packages are needed on the server:
apt-get install nfs-kernel-server nfs-common
Unlike NFSv3, NFSv4 uses a separate directory structure to share the directories. The actual content is mounted with mount –bind under this directory. Here we place the directories under /export:
sudo mkdir /export sudo mkdir /export/home
Then we instruct in /etc/fstab that /home should be mounted under /export/home. The following should be added in bottom of /etc/fstab:
/etc/fstab
/home /export/home none bind 0 0
After this /export/home can be mounted with the following command and it is also automatically mounted when the system boots:
sudo mount /export/home
Next configure the exports in /etc/exports to be exported to all nfs4 clients using kerberos:
/etc/exports
/export gss/krb5(rw,fsid=0,async,subtree_check,no_root_squash,crossmnt) /export/home gss/krb5(rw,async,subtree_check,no_root_squash) /export/home/school1 gss/krb5(rw,async,subtree_check,root_squash,crossmnt) /export/home/school2 gss/krb5(rw,async,subtree_check,root_squash,crossmnt) /export/home/school3 gss/krb5(rw,async,subtree_check,root_squash,crossmnt)
Next configure NFS to use kerberos:
/etc/default/nfs-common
NEED_STATD= STATDOPTS= NEED_IDMAPD=yes NEED_GSSD=yes
/etc/default/nfs-kernel-server
RPCNFSDCOUNT=10 RPCNFSDPRIORITY=0 RPCMOUNTDOPTS= NEED_SVCGSSD=yes RPCSVCGSSDOPTS=
idmapd.conf needs to configured with proper Domain name for user/group name mappings:
/etc/idmapd.conf
[General] Verbosity = 0 Pipefs-Directory = /var/lib/nfs/rpc_pipefs Domain = EDU.EXAMPLE.ORG [Mapping] Nobody-User = nobody Nobody-Group = nogroup
The NFS server version in Lucid supports only DES encryption which is not enabled by default. There is more information available in the bug reports:
For now DES can be enabled with the following settings:
/etc/krb5.conf
[libdefaults]
allow_weak_crypto = true
default_tgs_enctypes = des-cbc-crc
default_tkt_enctypes = des-cbc-crc
Next we need to create kerberos principals for the server and the clients. In this example all the principals are created on the server and copied to the clients. It is also possible to use kadmin remotely from the client machines.
sudo kadmin.local -q "addprinc -randkey nfs/server.edu.example.org" sudo kadmin.local -q "ktadd -e des-cbc-crc:normal nfs/server.edu.example.org" sudo kadmin.local -q "addprinc -randkey nfs/client1.edu.example.org" sudo kadmin.local -q "ktadd -e des-cbc-crc:normal -k client1.keytab nfs/client1.edu.example.org" sudo kadmin.local -q "addprinc -randkey nfs/client2.edu.example.org" sudo kadmin.local -q "ktadd -e des-cbc-crc:normal -k client2.keytab nfs/client2.edu.example.org"
Now copy the client1.keytab and client2.keytab to /etc/krb5.keytab on the client machines and make them only readable by root.
The server should now be ready after restarting the services:
sudo service gssd start sudo service rpc_pipefs start sudo /usr/sbin/rpc.gssd sudo service idmapd start sudo /etc/init.d/nfs-kernel-server restart
The server functionality can be tested by trying to mount one of the exported shares locally:
sudo mount -t nfs4 -o sec=krb5 server.edu.example.org:/home/school1 /mnt
Client settings
The following packages are needed on the client machines:
apt-get install nfs-common krb5-user
To avoid having to configure the kerberos server settings on each client separately, one can use DNS to store the settings as described in the previous posting.
/etc/krb5.conf
[libdefaults] default_realm = EDU.EXAMPLE.ORG allow_weak_crypto = true default_tgs_enctypes = des-cbc-crc default_tkt_enctypes = des-cbc-crc dns_lookup_kdc = true dns_lookup_realm = true
/etc/default/nfs-common – idmapd and gssd need to be enabled
NEED_STATD=
STATDOPTS=
NEED_IDMAPD=yes
NEED_GSSD=yes
RPCGSSDOPTS="-vvv -rrr" # for debugging
/etc/idmapd.conf – Domain must match the name defined on the server for user and group name mapping to work
[General]
Verbosity = 0
Pipefs-Directory = /var/lib/nfs/rpc_pipefs
Domain = EDU.EXAMPLE.ORG
[Mapping]
Nobody-User = nobody
Nobody-Group = nogroup
After configuration nfs-common needs to be restarted (modules need to be loaded if they haven’t been loaded automatically):
sudo modprobe nfs sudo modprobe rpcsec_gss_krb5 sudo service idmapd start sudo service gssd start sudo service portmap restart
Mounting the share should now work with mount command:
sudo mount -t nfs4 -o sec=krb5 server.edu.example.org:/home/school1 /home/school1
If there are problems, restarting the client machine may help as sometimes picking up the kerberos setting hasn’t worked for me. I’m probably missing some service that requires restarting..
At this point we have no kerberos ticket, so the user should not be able to enter his own home directory:
user$ cd /home/school1/user -bash: cd: /home/school1/user: Permission denied
After getting the ticket it should work:
user$ kinit user@EDU.EXAMPLE.ORG Password for user@EDU.EXAMPLE.ORG: user$ cd /home/school1/user
Root squash should also prevent root from entering directories for other users on the client machine:
user$ cd /home/school1/otheruser -bash: cd: /home/school1/otheruser: Permission denied # cd /home/school1/otheruser -bash: cd: /home/school1/otheruser: Permission denied
Now give it a reboot and try again. Everything should be now working.
Veli-Matti Lintu
Thanks for the great write-up! You’ve saved me at least 20 hours of hair-pulling getting this set up. The walk-through mostly worked for me, except to get the nfs-kernel-server to start on my machine, I had to export the nfs/server.edu.example.org and put it in the keytab on the NFS server. In my case, the NFS server and Kerberos server are on two different machines.
good information in the tutorial, but I was facing a problem: listing the mounted share was always empty!
Can you add in your tutorial that /etc/exports should use ”nohide” option 🙂
This will save 1 more hour for other users 🙂
When you say copy client1.keytab and client2.keytab to /etc/krb5.keytab
do you mean copy the contents to that file? Your description sounds like I should be copying them to a directory which doesn’t exist on my 10.04 server?
client1.keytab should be copied to client1 machine as file /etc/krb5.keytab and client2.keytab should be copied to client2 machine as file /etc/krb5.keytab. If file server is different from ldap/kerberos -server, nfs server settings need to be done there and the nfs server needs its own keytab files with nfs/nfs.domain.example.com@REALM principal.
How do I do this in an environment where the ldap and kerberos server are the same machine but the file server is different?
great guide, just a question: I don’t have very clear if the ticket must be requested by user manually (i.e. with kinit), or if after integration of pam and pam-krb5 the ticket is automatically obtained at login (thus allowing access to mounted home directory).
thank you
pam_krb5 requests the ticket when the user logs in, so there’s no need to run kinit manually. One just has to make sure that nothing requires access to home directory before the ticket is in place.