(>> deutsche version)

Setting up a FreeBSD NFSv4 client with Kerberos and AutoFS in the Linux network

This HowTo is intended for the experienced Linux administrators who wish to mount a Linux NFSv4 directory with Kerberos protection and optional AutoFS using FreeBSD. Requirement:

An working network with Kerberos and NFSv4 and NTP. In our scenario, the Kerberos KDC, Kerberos admin, and NFSv4 server are installed on the same host, called nasserver. The users and their principals are created and checked. The domain should be named example.net and the realm EXAMPLE.NET.

User name, UID and GID are identical on the Linux server "
nasserver" and the FreeBSD client "nasclient". This can be achieved by, for example, NIS, ldap or manual setup. In this case, the manual creation of the user is sufficient. Our virtual user is called "nasuser" with the UID 1001 and GID 1001.

nasclient$ adduser

Username: nasuser
Full name: nasuser
Uid (Leave empty for default):
Login group [nasuser]:
Login group is jru. Invite nasuser into other groups? []: wheel
Login class [default]:
Shell (sh csh tcsh zsh nologin) [sh]: bash
Home directory [/home/nasuser]:
Home directory permissions (Leave empty for default):
Use password-based authentication? [yes]:
Use an empty password? (yes/no) [no]:
Use a random password? (yes/no) [no]:
Enter password:
Enter password again:
Lock out the account after creation? [no]:
Username   : nasuser
Password   : ****
Full Name  : nas
Uid        : 1001
Class      :
Groups     : nasuser wheel
Home       : /home/nasuser
Shell      : /usr/local/bin/bash
Locked     : no
OK? (yes/no): yes
adduser: INFO: Successfully added (nasuser) to the user database.
Add another user? (yes/no): no
Goodbye!
$

Necessary is the complete (including domain) hostname of the FreeBSD client, a working DNS service in the network or at least a maintained /etc/hosts on the client and the server. Our computer is called "nasclient", the domain "example.net".

nasclient$ nano /etc/rc.conf

hostname = nasclient.example.net #lowercase letters !

nasclient$ nano /etc/hosts

192.168.0.1 nasclient.example.net
192.168.0.2 nasserver.example.net


The FreeBSD Kerberos client has Heimdal as standard, our Linux KDC is a MIT Kerberos KDC. We install MIT first:

nasclient$ pkg install krb5

Then we create or copy the /etc/krb5.conf with our realm EXAMPLE.NET

nasclient$ nano /etc/krb5.conf

[libdefaults]

default_realm = EXAMPLE.NET

# The following krb5.conf variables are only for MIT Kerberos.

kdc_timesync = 1
ccache_type = 4

forwardable = true
proxiable = true

[realms]

EXAMPLE.NET = {

kdc = nasserver.example.net
admin_server = nasserver.example.net
}

………


The principal of the nfs service on nasclient still needs to be generated. This we do on the Linux (Debian) host.

#nasserver$ kadmin -p admin/admin
#kadmin> addprinc -randkey host/nasclient.example.net
#kadmin> addprinc -randkey nfs/nasclient.example.net

Then we test our configuration on the FreeBSD client:

nasclient$ kinit nasuser

password for nasuser@EXAMPLE.NET:


nasclient$ klist

principal: nasuser@EXAMPLE.NET ...


For a working NFSv4 with Kerberos, you need the gssd service, which accesses the file /etc/krb5.keytab for the keys. (see man gssd)
Important ! The gssd service requires lowercase hostnames for proper work.

MIT programs are located in /usr/local/bin, so nasclient$ ktutil starts the Heimdal version. We want MIT.

nasclient$ /usr/local/bin/kadmin -p admin/admin
$kadmin> ktadd host/nasclient.example.net
$kadmin> ktadd nfs/nasclient.example.net

Password for admin/admin@EXAMPLE.NET:
Entry for principal host/nasclient.example.net@EXAMPLE.NET with kvno 2,enc
Entry for principal host/nasclient.example.net@EXAMPLE.NET with kvno 2,enc
Entry for principal host/nasclient.example.net@EXAMPLE.NET with kvno 2,enc
Entry for principal host/nasclient.example.net@EXAMPLE.NET with kvno 2,enc
Entry for principal nfs/nasclient.example.net@EXAMPLE.NET with kvno 2,enc
Entry for principal nfs/nasclient.example.net@EXAMPLE.NET with kvno 2,enc
Entry for principal nfs/nasclient.example.net@EXAMPLE.NET with kvno 2,enc
Entry for principal nfs/nasclient.example.net@EXAMPLE.NET with kvno 2,enc


Let's check the /etc/krb5.keytab on nasclient:

nasclient$ ktutil list (Heimdal is also ok)

Vno  Type                    Principal
2    aes256-cts-hmac-sha1-96 host/nasclient.beispiel.net@BEISPIEL.NET
2    arcfour-hmac-md5        host/nasclient.beispiel.net@BEISPIEL.NET
2    des3-cbc-sha1           host/nasclient.beispiel.net@BEISPIEL.NET
2    des-cbc-crc             host/nasclient.beispiel.net@BEISPIEL.NET
2    aes256-cts-hmac-sha1-96 nfs/nasclient.beispiel.net@BEISPIEL.NET
2    arcfour-hmac-md5        nfs/nasclient.beispiel.net@BEISPIEL.NET
2    des3-cbc-sha1           nfs/nasclient.beispiel.net@BEISPIEL.NET
2    des-cbc-crc             nfs/nasclient.beispiel.net@BEISPIEL.NET

Or with MIT.

nasclient$ /usr/local/bin/ktutil


ktutil:  rkt /etc/krb5.keytab
ktutil:  list
slot KVNO Principal
---- ---- ---------------------------------------------------------------------
1    2    host/nasclient.beispiel.net@BEISPIEL.NET
2    2    host/nasclient.beispiel.net@BEISPIEL.NET
3    2    host/nasclient.beispiel.net@BEISPIEL.NET
4    2    host/nasclient.beispiel.net@BEISPIEL.NET
5    2    nfs/nasclient.beispiel.net@BEISPIEL.NET
6    2    nfs/nasclient.beispiel.net@BEISPIEL.NET
7    2    nfs/nasclient.beispiel.net@BEISPIEL.NET
8    2    nfs/nasclient.beispiel.net@BEISPIEL.NET
   

Nasclient needs three more services that we add to /etc/rc.conf.

gssd = the security service
nfsuserd= is needed for GID/UID mapping
nfscbd = callback from NFSv4-Server to the NFSv4-Client


nasclient$ nano /etc/rc.conf

nfsuserd_enable=“YES“
nfscbd_enable="YES"
gssd_enable="YES"
gssd_flags="-h"

For testing, we start gssd with verbose, debug and the "host-based initiator creditals support" , which means Kerberos NFS mounts are allowed when the service principal "nfs/nasclient.example.net@EXAMPLE.NET" is allready in the /etc/krb5.keytab.

nasclient$ gssd -vhd

If faultless, we can start the services.

nasclient$service nfsuserd start
nasclient$service nfscbd start
nasclient$service gssd start

Suppose our /etc/exports on the NFSv4-Server is like this:

nasserver# cat /etc/exports

/nas           192.168.0.0/24(sec=krb5:krb5i,rw,fsid=0,insecure,no_subtree_check,sync)
/nas/share 192.168.0.0/24(sec=krb5:krb5i,rw,no_root_squash,nohide,insecure,no_subtree_check,sync)

If the rights of nasuser (UID 1001/GID 1001) for the share directory are set correctly and the ticket is still valid, then you should mount the share /mnt/share. (vfs.usermount=1 and vfs.nfs.enable_uidtostring are set in sysclt.conf)

nasclient$ mount_nfs -o sec=krb5,vers=4,soft,intr,gssname=nfs nasserver.example.net:/share /mnt/share

nasclient $ nano /etc/fstab

nasserver.example.net:/share /mnt/share nfs  bg,rw,soft,sec=krb5,nfsv4,gssname=nfs,late  0 0  

Optional : Login with pam_krb5 (see man pam_krb5)

nasclient$ pkg install pam_krb5

and switch on PAM-Kerberos in /etc/pam.d/system.

nasclient$ nano /etc/pam.d/system

# auth
auth            sufficient      pam_opie.so                    no_warn no_fake_prompts
auth            requisite       pam_opieaccess.so        no_warn allow_local
auth            sufficient      pam_krb5.so                    no_warn try_first_pass
#auth          sufficient      pam_ssh.so                     no_warn try_first_pass
auth            required       pam_unix.so                    no_warn try_first_pass

# account

#account       required        pam_krb5.so
account       required        pam_login_access.so
account       required        pam_unix.so
account       required        pam_krb5.so           try_first_pass #!!!

# session
#session       optional        pam_ssh.so              want_agent
session         required       pam_lastlog.so          no_fail


# password
password       sufficient      pam_krb5.so                   no_warn try_first_pass
password       requiered     pam_unix.so                   no_warn try_first_pass

Attention ! If a /root/.k5login is present, check it for a correct principal, otherwise you will be locked out! If this is the case then boot in "single user mode" and make the partition writable with /sbin/mount -u /.

From now on, the ticket should be generated upon login.


Automatically mount network shares with AutoFS


Automount is the optimal supplement. With autofs (man autofs) you can easily integrate devices or network shares when needed. In contrast to static integration, unmounting is done automatically without access. Autofs reads in the /etc/auto_master the mountpoints and its map-file. The map-file contains the mount command. Another advantage is, that for NFS the mount commands for BSD and Linux are almost identical. In our scenario we want to mount the share "share" under the mountpoint "/mnt/NFSv4/".


nasclient$ mkdir /mnt/NFSv4/
nasclient$ nano /etc/auto_master

#mountpoint    map-file
/mnt/NFSv4 /etc/nfs.auto

nasclient$ nano /etc/nfs.auto

# share    mount-command
nasserver/share -fstype=nfs,sec=krb5,vers=4,gssname=nfs nasserver.beispiel.net:/share

On FreeBSD, you have to enable autofs in the /etc/rc.conf.


nasclient$ nano /etc/rc.conf

autofs_enable = "YES"

nasclient$ service automount onestart
nasclient$ service automountd onestart
nasclient$ service autounmountd onestart


If automount fails, you can use nasclient $ automount -v and nasclient $ tail /var/log/ messages to narrow down the error. Often, only the Kerberos ticket is invalid. A kdestroy and kinit are then the solution. For computers that are continuously in operation, you should possibly extend the ticket periodically with a cronjob.


0 * * * * /usr/local/bin/kinit -R #MIT

Test environment: Wheezy/Jessie,Ascii FreeBSD 11.2/12 (10/20)

(>> deutsche version)