NFS fürs Heimnetz einrichten

NFS fürs Heimnetz einrichten

Da die Datenübertragungsrate bei Samba doch etwas arg bescheiden ist, habe ich mir einmal NFS als Alternative angesehen. Um ein Mindestmaß an Sicherheit zu haben, soll NFSv4 in Verbindung mit Kerberos zum Einsatz kommen.

Server

Als Server steht mein NAS, bestehend aus einem ODROID-HC4 mit Debian Bullseye, zur Verfügung. Hier installieren wir zunächst die Pakete nfs, nfs-kernel-server, nfs-utils sowie krb5-kdc und krb5-admin-server.

NFSv4 only

Es soll ausschließlich NFSv4 verwendet werden. Dazu passen wir einige Einstellungen in /etc/default/nfs-common an:

NEED_STATD="no"
NEED_IDMAPD="yes"

Außerdem ändern wir folgendes in /etc/default/nfs-kernel-server:

RPCNFSDOPTS="-N 2 -N 3"
RPCMOUNTDOPTS="--manage-gids -N 2 -N 3"

Und da rcpbind bei NFSv4 nicht notwendig ist, maskieren wir diesen Dienst:

sudo systemctl mask rpcbind.service
sudo systemctl mask rpcbind.socket

Nun legen wir die zu exportierenden Verzeichnisse in /etc/exports fest. Diese sollten alle unterhalb eines Einstiegspunktes, etwa /srv/nfs, liegen.

/srv/nfs          *(rw,async,fsid=0,no_subtree_check,sec=krb5i:krb5)
/srv/nfs/media    *(rw,async,no_subtree_check,sec=krb5i:krb5)
/srv/nfs/familie  *(rw,async,no_subtree_check,sec=krb5i:krb5)

Die Benutzer sollten alle auf dem Server einen lokalen Account, entsprechend ihrem Benutzernamen auf ihren Clients, haben. Anmelden müssen sie sich darüber jedoch nicht können. Zugriffsberechtigungen werden wie üblich mittels ACLs auf Dateisystemebene festgelegt.

Kerberos

Nun ist es Zeit, Kerberos auf dem Server einzurichten. Da in meinem Heimnetz eine Fritz!Box das Sagen hat, verwende ich als REALM »FRITZ.BOX«.

Als Erstes passen wir die Datei /etc/krb5.conf unseren Gegebenheite an. Im Wesentlichen ersetzen wir den REALM durch unseren und geben den Kerberos-Server (unser NAS) an:

[libdefaults]
	default_realm = FRITZ.BOX
	forwardable = true

[realms]
# use "kdc = ..." if realm admins haven't put SRV records into DNS
	FRITZ.BOX = {
		admin_server = droidnas.fritz.box
		kdc = droidnas.fritz.box
		default_principal_flags = +preauth
	}

[domain_realm]
	fritz.box = FRITZ.BOX
	.fritz.box = FRITZ.BOX

[logging]
#	kdc = CONSOLE

Diese Datei verwenden wir 1:1 auch auf den Clients.

Jetzt können wir die Kerberos-Datenbank einrichten:

sudo kdb5_util -r FRITZ.BOX create -s
Loading random data
Initializing database '/var/lib/krb5kdc/principal' for realm 'FRITZ.BOX',
master key name 'K/M@FRITZ.BOX'
You will be prompted for the database Master Password.
It is important that you NOT FORGET this password.
Enter KDC database master key: 
Re-enter KDC database master key to verify: 

Den Database Master Key sichern wir natürlich in einem Passwortsafe. Ebenso erstellen wir einen Kerberos-Admin, dessen Passwort ebenfalls gut zu sichern ist:

sudo kadmin.local
Authenticating as principal root/admin@FRITZ.BOX with password.
kadmin.local:  addprinc root/admin
No policy specified for root/admin@FRITZ.BOX; defaulting to no policy
Enter password for principal "root/admin@FRITZ.BOX": 
Re-enter password for principal "root/admin@FRITZ.BOX": 
Principal "root/admin@FRITZ.BOX" created.

Nicht vergessen dürfen wir, Kerberos zu sagen, dass dieser User auch Adminrechte hat. Das geschieht in der Datei /etc/krb5kdc/kadm5.acl. Hier fügen wir folgende Zeile ein:

*/admin@FRITZ.BOX *

Für den Server selbst erstellen wir nun noch einen Host- sowie einen Dienst-Schlüssel für NFS und fügen diese mittels ktadd der Datei /etc/krb5.keytab hinzu:

kadmin.local:  addprinc -randkey host/droidnas.fritz.box
No policy specified for host/droidnas.fritz.box@FRITZ.BOX; defaulting to no policy
Principal "host/droidnas.fritz.box@FRITZ.BOX" created.
kadmin.local:  addprinc -randkey nfs/droidnas.fritz.box
No policy specified for nfs/droidnas.fritz.box@FRITZ.BOX; defaulting to no policy
Principal "nfs/droidnas.fritz.box@FRITZ.BOX" created.
admin.local:  ktadd host/droidnas.fritz.box
Entry for principal host/droidnas.fritz.box with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.
Entry for principal host/droidnas.fritz.box with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.
kadmin.local:  ktadd nfs/droidnas.fritz.box
Entry for principal nfs/droidnas.fritz.box with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.
Entry for principal nfs/droidnas.fritz.box with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.

Auch ein (also jeder) Client benötigt einen Dienste-Principal. Diese(n) können wir nun auch gleich erstellen:

kadmin.local:  addprinc -randkey nfs/myclient1.fritz.box
No policy specified for nfs/myclient1.fritz.box@FRITZ.BOX; defaulting to no policy
Principal "nfs/myclient1.fritz.box@FRITZ.BOX" created.

Dieser Schlüssel wird aber nicht auf dem Server exportiert, sondern erst später auf dem entsprechenden Client.

Damit später die Benutzerauthentifizierung und somit der Dateizugriff funktioniert, muss nun für jeden Benutzer ein Kerberos-Account erstellt werden:

kadmin.local:  addprinc bob
No policy specified for bob@FRITZ.BOX; defaulting to no policy
Enter password for principal "bob@FRITZ.BOX": 
Re-enter password for principal "bob@FRITZ.BOX": 
Principal "bob@FRITZ.BOX" created.

Damit das Mapping der Benutzernamen funktioniert (bei NFSv4 spielt die UID keine Rolle mehr), sollte man Sicherstellen dass in /etc/idmapd.conf die eigene Domain (in meinem Fall fritz.box) eingestellt ist.

Nun ist es Zeit, die NFS- und Kerberos-Dienste auf dem Server neu zu starten. Man könnte sogar an einen Reboot denken, da es doch einige Dienste und Abhängigkeiten sind.

Client(s)

Auf dem Client (bei mir ein Arch Linux) stellen wir sicher, dass die Pakete krb5 und nfs-utils installiert sind, aktivieren den Dienst nfs-client.target und übernehmen die Dateien /etc/krb5.conf sowie /etc/idmapd.conf vom Server.

Nun starten wir auf dem Client kadmin und exportieren den Kerberos-Schlüssel für NFS:

sudo kadmin -p root/admin
Authentifizierung als Principal root/admin mit Passwort
Passwort für root/admin@FRITZ.BOX: 
kadmin:  ktadd nfs/myclient.fritz.box
[…]

Ich mounte die NFS-Shares gerne unter /media, damit GNOME-Files (also Nautilus) gleich einen entsprechenden Eintrag anzeigt. Der Eintrag in /etc/fstab sieht also so beispielsweise so aus:

droidnas.fritz.box:/media   /media/media    nfs4   rw,sec=krb5i,soft,async,user,noauto   0 0

Auch hier habe ich festgestellt, dass der eine oder andere Dienst neu gestartet werden muss, damit die Änderungen greifen. Insbesondere wenn man noch etwas am Herumprobieren ist, artet es gerne in ein wildes Neustarten der Dienste aus.

GNOME Online Konten

Ein Problem gibt es noch: Die einzelnden Benuter können nur auf das gemountete NFS-Share zugreifen, wenn sie ein Kerberos-Ticket bekommen haben. Dies kann man durch Eingabe von kinit auf der Konsole erhalten. Da das aber nicht sehr benutzerfreundlich (und auch nicht wirklich tauglich für alle Familienmitglieder) ist, erstellt man am Besten in GNOME über Einstellungen -> Online Konten einen Kerberos-Eintrag. Fortan erhält man das Ticket dann automatisch über GNOME.

(Quellen: Debian: NFSServerSetup, Debian: NFSv4 (nfs4) + Kerberos in Debian, Arch Wiki: Kerberos)