View on GitHub

tbellembois.github.io

Thomas Bellembois

NFS4/Kerberos/Active Directory - the last crusade

Emergency to do list

In case of kerberos problem check (on both clients and servers) that:

Introduction

After fighting for 3 weeks trying to setup a NFS/Kerberos configuration with an ActiveDirectory, and Googling thousands of mailing lists and tutorials, here is my succesfull story.
Hope it may help others…

Configuration

The KDC is a Windows AD. The NFS server and clients are under Linux.

Ensure that packagekit is installed (it should be in a default Gnome installation) and that the rpcsec_gss_krb5 kernel module is loaded (lsmod | grep rpcsec_gss_krb5 should return something).

step 1: linux configuration

I have tried to use the realm command to join my domain from both the client and NFS server.

    root@z-stretchl:~# realm join -U administrateur

The command was successfull and the machine appeared on my AD but I could not retrieve my users with getent. I tried another approch.

configure the hosts file (client and server)

It is important that the first line contains the IP addresses and fqdn’s of the machines. Moreover the machines fqdn must be registered in the DNS.

192.168.128.34  dublin.iut.local dublin
127.0.0.1       localhost.localdomain localhost
192.168.105.225 z-stretchl.iut.local z-stretchl
127.0.0.1       localhost.localdomain localhost
root@z-stretchl:~# nslookup z-stretchl
Server:         192.168.105.5
Address:        192.168.105.5#53

Name:   z-stretchl.iut.local
Address: 192.168.105.225

root@z-stretchl:~# nslookup dublin
Server:         192.168.105.5
Address:        192.168.105.5#53

Name:   dublin.iut.local
Address: 192.168.128.34

configure krb5.conf (client and server)

[libdefaults]                                                       
        default_realm = IUT.LOCAL
        kdc_timesync = 1            
        ccache_type = 4         
        forwardable = true            
        proxiable = true                                                            
[realms]                              
    IUT.LOCAL = {
        kdc = coruscant                                                           
    }
[domain_realm]
    .iut.local = IUT.LOCAL
    iut.local = IUT.LOCAL

Do NOT put allow_weak_crypto = true in the libdefaults section. This is not needed anymore.

configure sssd.conf (client and server)

[sssd]
domains = iut.local
services = nss, pam
config_file_version = 2

[nss]
filter_groups = root
filter_users = root
default_shell = /bin/bash

[pam]
reconnection_retries = 3

[domain/iut.local]
krb5_validate = True
krb5_realm = IUT.LOCAL
subdomain_homedir = %o
default_shell = /bin/bash
cache_credentials = True
id_provider = ad
access_provider = ad
chpass_provider = ad
auth_provide = ad
ldap_schema = ad
ad_server = coruscant
ad_hostname = z-stretchl.iut.local
ad_domain = iut.local
ad_gpo_access_control = permissive
use_fully_qualified_names = False
ad_enable_gc = False

unixhomedir

configure idmapd.conf (client and server)

[General]

Verbosity = 0
Pipefs-Directory = /run/rpc_pipefs
Domain = iut.local 

[Mapping]

Nobody-User = nobody
Nobody-Group = nogroup

configure nfs-common (client and server)

...
NEED_STATD=yes
NEED_IDMAPD=yes
NEED_GSSD=yes
...

configure nfs-kernel-server (server)

...
RPCMOUNTDOPTS="--manage-gids"
NEED_SVCGSSD="yes"
...

step 2: AD configuration and keytab generation

This was the longest taks. I have generated thousands of keytab and googled the entire www to find the matching configuration.

general principle

You have to create two AD user per machine (NFS server and clients). The name of these users is not important. The first AD user is host user, the second one a service user. The you must create principals bound to the previous users. A principal is a kerberos element used to authenticate machines, users and services. Finally you have to create keytabs files for the Linux clients.

create AD user per machine

You can do it with the GUI tools or using the dsadd command line tool. Operations must my performed with the administrator account.

dsadd

server:

// host user
dsadd user CN=host-dublin,CN=Users,DC=iut,DC=local -samid host-dublin -pwd 1234
// NFS service user
dsadd user CN=nfs-dublin,CN=Users,DC=iut,DC=local -samid nfs-dublin -pwd 1234

client:

// host user
dsadd user CN=host-z-stretchl,CN=Users,DC=iut,DC=local -samid host-z-stretchl -pwd 5678
// NFS service user
dsadd user CN=nfs-z-stretchl,CN=Users,DC=iut,DC=local -samid nfs-z-stretchl -pwd 5678

create kerberos principals bound to the AD users

What I have understund (but I may be wrong).

You have to create a host principal to authenticate the machine on the AD (for sssd). You have to create a service principal to authenticate the machine on the nfs server. With this principal the machine will be able to mount the krb5 NFS exported paths but this principal is not enought to access the path (ie. read/write).

    root@z-stretchl:~# mount -t nfs4 -o sec=krb5 dublin.iut.local:/home/prof /tmp/test/
    root@z-stretchl:~# touch /tmp/test/toto
    touch: impossible de faire un touch '/tmp/test/toto': Permission non accordée

Ok, the permission denied is expected.

To be able to access the exported path you first have to get a TGT (ticket granting ticket) from the AD with a registered user with the kinit command. This ticket is like an ID card that proves that you are the person your pretend you are.

    root@z-stretchl:~# kinit thbellem
    Password for thbellem@IUT.LOCAL: 

If the authentication is succesfull you can display your TGT with klist.

    root@z-stretchl:~# klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: thbellem@IUT.LOCAL

Valid starting       Expires              Service principal
28/03/2018 13:55:06  28/03/2018 23:55:06  krbtgt/IUT.LOCAL@IUT.LOCAL
        renew until 29/03/2018 13:54:57

The ticket is valid for 10 hours.

With this TGT you will be able to get a service ticket for the NFS server and then access the mounted filesystem (this is automatically done trying to access the mounted filesystem).

root@z-stretchl:~# touch /tmp/test/thbellem/toto
touch: impossible de faire un touch '/tmp/test/thbellem/toto': Permission non accordée

Still permission denied ? Yes even with a TGT the root user is squashed. I have a correct TGT but the path I tried to access is owned by uid/gid of user thbellem and of course NFS does not allow me to access this path.

But if you log with a common user with th login command (that automatically get a TGT from the AD):

root@z-stretchl:~# login thbellem
thbellem@z-stretchl:/$ klist 
Ticket cache: FILE:/tmp/krb5cc_1467053722_69OWsi
Default principal: thbellem@IUT.LOCAL

Valid starting       Expires              Service principal
28/03/2018 14:05:51  29/03/2018 00:05:51  krbtgt/IUT.LOCAL@IUT.LOCAL
        renew until 29/03/2018 14:05:51

thbellem@z-stretchl:/$ touch /tmp/test/thbellem/toto
thbellem@z-stretchl:/$ 

Success ! Of course the remote thbellem directory is owned by the user thbellem.

creating the principal names for the users

server:

setspn -A host/dublin host-dublin
setspn -A host/dublin.iut.local host-dublin
setspn -A host/dublin.iut.local@IUT.LOCAL host-dublin

setspn -A nfs/dublin nfs-dublin
setspn -A nfs/dublin.iut.local nfs-dublin
setspn -A nfs/dublin.iut.local@IUT.LOCAL nfs-dublin

client:

setspn -A host/z-stretchl host-z-stretchl
setspn -A host/z-stretchl.iut.local host-z-stretchl
setspn -A host/z-stretchl.iut.local@IUT.LOCAL host-z-stretchl

setspn -A nfs/z-stretchl nfs-z-stretchl
setspn -A nfs/z-stretchl.iut.local nfs-z-stretchl
setspn -A nfs/z-stretchl.iut.local@IUT.LOCAL nfs-z-stretchl

The host principals are the machines principals used to join the AD to authenticate the users. The nfs principals are the machines principals used to authenticate the machine on the NFS server to mount the exported filesystem.

The 3 principal names:

creating the keytabs

    // server host keytab
    ktpass -princ host/dublin.iut.local@IUT.LOCAL -pass 1234 -mapuser IUT\host-dublin -pType KRB5_NT_PRINCIPAL -out c:\TMP\krb\host-dublin.keytab -crypto rc4-hmac-nt
    // server NFS service keytab
    ktpass -princ nfs/dublin.iut.local@IUT.LOCAL -pass 1234 -mapuser IUT\nfs-dublin -pType KRB5_NT_PRINCIPAL -out c:\TMP\krb\nfs-dublin.keytab -crypto rc4-hmac-nt

    // client host keytab
    ktpass -princ host/z-stretchl.iut.local@IUT.LOCAL -pass 1234 -mapuser IUT\host-z-stretchl -pType KRB5_NT_PRINCIPAL -out c:\TMP\krb\host-z-stretchl.keytab -crypto rc4-hmac-nt
    // client NFS service keytab
    ktpass -princ nfs/z-stretchl.iut.local@IUT.LOCAL -pass 1234 -mapuser IUT\nfs-z-stretchl -pType KRB5_NT_PRINCIPAL -out c:\TMP\krb\nfs-z-stretchl.keytab -crypto rc4-hmac-nt

For the -crypto parameter I have entered the first returned by the klist command.

klistwin

Here are some powershell scripts we use to do the job:

merging the keytab on both the client and server

Use the ktutil command.

    $ ktutil
    $ read_kt /tmp/host-dublin.keytab
    $ read_kt /tmp/nfs-dublin.keytab
    $ write_kt /etc/krb5.keytab
    $ quit

Restart sssd. Clean its cache may help.

Usefull debug commands

 rpcdebug -m nfsd -s all
 rpcdebug -m rpc -s all
 rpc-gssd -vvv -f

Plus: samba and SSSD

To enable SSSD/kerberos authentication with samba add another service AD user and configure the principal names:

    dsadd user CN=cifs-dublin,CN=Users,DC=iut,DC=local -samid cifs-dublin -pwd 1234

    setspn -A cifs/dublin cifs-dublin
    setspn -A cifs/dublin.iut.local cifs-dublin
    setspn -A cifs/dublin.iut.local@IUT.LOCAL cifs-dublin
    setspn -A cifs/dublin@IUT.LOCAL cifs-dublin

and generate an additionnal keytab:

	ktpass -princ cifs/dublin@IUT.LOCAL -pass 1234 -mapuser IUT\cifs-dublin -pType KRB5_NT_PRINCIPAL -out c:\TMP\krb\cifs-dublin.keytab -crypto rc4-hmac-nt

Use ktutil to merge the keytab.

Here is the part of the relevant /etc/smb.conf configuration:

server role = member server
security = ads
workgroup = IUT
realm = iut.local
kerberos method = system keytab