Files
test-repo/nfsv4-kerberos-debian.md
2022-08-17 19:12:18 +02:00

10 KiB

NFSv4 with Kerberos on Debian from scratch

This document will (hopefully) allow you to setup a kerberized NFSv4 server on Debian 11/Ubuntu 22.04.

Copyright (C) 2022 Bruno Raoult ("br") Licensed under the GNU Free Documentation License v1.3 or later. Some rights reserved. See COPYING.

You should have received a copy of the GNU Free Documentation License along with this document. If not, see this page.

SPDX-License-Identifier: GFDL-1.3-or-later

Table of Contents

Introduction

If you share some files between your machines, your choice was probably SMB/CIFS, as it is supported on nearly any platform (GNU/Linux, MacOS, Windows, iOS, Android, ...).

However, there are some limitations that you may find unacceptable: the loss of uid/gid/permissions and the lack of symbolic/hard links for SMB.

Another option (at least on GNU/Linux) could be SSHFS: It is simple to use, and requires no special settings but an ssh access to server. It could be the ideal sharing system for many people.

What I dislike here is the need for an ssh access. No, I don't plan to give an ssh access to my servers ;-)

This document is about a third solution : NFSv4 coupled with Kerberos security, on a Debian-based system (Debian, Ubuntu, etc...).

Pre-requisites

  • NTP : All machines (clients and servers) must be time-synchronized, as Kerberos authentication is partly based on tickets timestamps.
  • DNS server (optional) : Kerberos may, in some configurations make use of some DNS records such as SRV or TXT. A lightweight DNS server like dnsmasq is sufficient, and will avoid the administration of a full-fledged server such as bind.

Kerberos (V5)

There are basically two major implementations of Kerberos V5 on GNU/Linux: The original MIT one, and the Heimdal one. There was also a GNU implementation Shishi, but developement looks stalled for 10+ years.

It appears that the MIT implementation may have some export restrictions due to U.S. regulation. Heimdal implementation (explicitely developed outside the USA, in Sweden) does not suffer such limitations. This document will use the "un-regulated" implementation.

Naming

We will use the following conventions :

Name Value Comment
Kerberos realm LAN Always capital
Local DNS name lan Typical hostname: machine.lan
Kerberos KDC 1 kdc1.lan Primary Key Distribution Center
Kerberos KDC 2 kdc2.lan Secondary KDC
Kerberos admin server kadmin.lan Administrative server
Kerberos client 1 kclient1.lan Test client 1
Kerberos client 2 kclient2.lan Test client 2
Kerberos credentials krb5/password Kerberos admin login/password

Packages installation

On server side, install the necessary packages with :

$ sudo apt install krb5-config heimdal-kdc heimdal-servers heimdal-clients heimdal-kcm heimdal-docs

And on client(s), install the following :

$ sudo apt-get install krb5-config heimdal-clients heimdal-docs

Note about documentation: The heimdal-docs package will install GNU info. If you want HTML documentation, you will have to manually build it from source with the following commands :

$ git clone https://github.com/heimdal/heimdal.git
$ cd heimdal
$ autoreconf -f -i
$ sh autogen.sh
$ ./configure
$ make html
$ cd doc/heimdal.html
$ sudo cp -ar heimdal.html /usr/share/doc/heimdal-docs/

Client and server side

The krb5-config package installation will ask you some questions, just fill with the information from Table 1 :

  • Default Kerberos version 5 realm: LAN
  • Kerberos servers for your realm: kdc1.lan and kdc2.lan
  • Administrative server for your Kerberos realm: kadmin.lan

After this initial configuration, /etc/krb5.conf will have been created with some default value, which can look-like :

[libdefaults]
	default_realm = LAN
	kdc_timesync = true
	forwardable = true
	proxiable = true

[realms]
	LAN = {
		kdc = kdc1.lan
		kdc = kdc2.lan
		admin_server = kadmin.lan
	}

[domain_realm]
    lan  = LAN
	.lan = LAN

/etc/krb5.conf - main kerberos configuration

The /etc/krb5.conf can be changed at any time, and we will immediately make some changes with some sane defaults (see krb5.conf(5) for more details) :

[appdefaults]
	# for testing purpose, short lifetime
	ticket_lifetime = 30m
	renew_lifetime = 1h

[libdefaults]
	default_realm = LAN
	kdc_timesync = true
	forwardable = true
	proxiable = true

	#ticket_lifetime = 2 days
	#renew_lifetime = 10 days
	# for testing purpose, short lifetime
	ticket_lifetime = 30m
	renew_lifetime = 1h

	allow_weak_crypto = false

	default_keytab_name = FILE:/var/lib/heimdal-lan.keytab

	# Use DNS SRV records to lookup KDC services location.
	dns_lookup_kdc = false
	# Use DNS TXT records to lookup domain to realm mappings.
	dns_lookup_realm = false

	# required when using basic authentication with Apache2's
	# mod_auth_kerb module (`Request is a replay' errors);
	# `0' for MIT library and `false' for Heimdal library
	kdc_timesync = false

[realms]
	LAN = {
		kdc = kdc1.lan
		kdc = kdc2.lan
		admin_server = kadmin.lan
	}

[domain_realm]
	lan  = LAN
	.lan = LAN

[logging]
	# will default to /var/log/heimdal-kdc.log
	# If you change destination, don't forget /etc/logrotate.d
	kdc = SYSLOG:DEBUG:AUTH
	admin_server = SYSLOG:DEBUG:AUTH
	default = SYSLOG:DEBUG:AUTH

Server only

/etc/heimdal-kdc/kdc.conf - heimdal kdc configuration file

See kdc(8) for configuration details. In this file, we just setup the [kdc] section :

$  grep -vE '(\#|^$)' kdc.conf
[kdc]
	database = {
		dbname    = sqlite:/var/lib/heimdal-kdc/heimdal-lan.sqlite3
		acl_file  = /etc/heimdal-kdc/kadmind.acl
		mkey_file = /var/lib/heimdal-kdc/m-key
	}
	addresses = 0.0.0.0

Master key

Note: A master key is mainly necessary if you store the database in a shared location (think about backups), to make brute-force attacks more difficult. For testing purpose, you may skip this section.

First, we will Usekstash(1) to give a master key to the database (we don't need to remember it). You should use the same mkey-file as the one specified in [kdc] section above.

$ sudo kstash --random-key -k /var/lib/heimdal-kdc/m-key

database initialization

The three kadmin commands below will initialize LAN realm, create a bruno/admin XXX, and list the known YYY :

$ sudo kadmin -l
kadmin> init LAN
Realm max ticket life [unlimited]:
Realm max renewable ticket life [unlimited]:

kadmin> add bruno/admin
Max ticket life [1 day]:
Max renewable life [1 week]:
Principal expiration time [never]:
Password expiration time [never]:
Attributes []:
Policy [default]:
bruno/admin@LAN's Password:
Verify password - bruno/admin@LAN's Password:

kadmin> get -s *
Principal                                        Expiration  PW-exp  PW-change   Max life   Max renew
krbtgt/LAN                                       never       never   2022-08-17  unlimited  unlimited
kadmin/changepw                                  never       never   2022-08-17  5 minutes  5 minutes
kadmin/admin                                     never       never   2022-08-17  1 hour     1 hour
changepw/kerberos                                never       never   2022-08-17  1 hour     1 hour
kadmin/hprop                                     never       never   2022-08-17  1 hour     1 hour
WELLKNOWN/ANONYMOUS                              never       never   2022-08-17  1 hour     1 hour
WELLKNOWN/org.h5l.fast-cookie@WELLKNOWN:ORG.H5L  never       never   2022-08-17  1 hour     1 hour
default                                          never       never   2022-08-17  1 day      1 week
bruno/admin                                      never       never   2022-08-17  1 day      1 week

Then,

Client side

Testing

NFSv4

Server side

Client side

Testing

Sources

Kerberos :