ubuntuusers.de

NFSv4 mit SSH sichern

Hinweis:

Dieses Howto wurde von kB erstellt. Bei Problemen mit der Anleitung melde dies bitte in der dazugehörigen Diskussion und wende dich gegebenenfalls zusätzlich an den/die Verfasser des Howtos.

Dieser Artikel gilt größtenteils unabhängig von der Ubuntu-Version.

Dieser Artikel wurde für die Ubuntu-Version Noble Numbat getestet. Es wird erwartet, dass er wesentlich auch auf nachfolgende Versionen anwendbar ist. Bitte melde abweichendes Verhalten in der Diskussion zu diesem Artikel.

Zum Verständnis dieses Artikels sind folgende Seiten hilfreich:

Dieses Howto beschreibt die Einrichtung von SSH[4]-Tunneln zur Absicherung von NFSv4[1] gegen Abhören. Dies verbessert zusätzlich auch den Zugriffsschutz des NFS-Servers[2], da nun eine Anmeldung erforderlich ist.

Die in diesem Artikel beschriebene Methode kann für kleine Anwendungen (max. ca. 10 beteiligte Rechner) eine Alternative zur Einrichtung und Betrieb eines Kerberos-Servers sein.

Diese Anleitung gilt nur für die Protokollvariante NFSv4, welche den gesamten Verkehr nur über einen einzigen Post 2049/tcp abwickelt. Das Prinzip kann zwar auch auf frühere Versionen von NFS[1] angewendet werden, ist dann aber komplizierter zu konfigurieren, und diese Anleitung geht nicht weiter darauf ein.

Voraussetzungen

  • Der NFS-Server muss bereits funktionsfähig eingerichtet sein. Dieser Artikel geht aus von einem Server gemäß Howto/NFS-Testserver.

  • Auf dem Rechner des NFS-Servers muss auch ein funktionsfähiger SSH-Server[4] erreichbar sein.

  • Man benötigt einen Benutzer, der sich per SSH[4] am Server anmelden darf und dort wie auch auf dem NFS-Client eine Root-Shell[5] starten kann.

Funktionsprinzip

⚓︎ Normalerweise bindet man auf dem NFS-Client[3] CLIENT (eine IP-Adresse) eine Freigabe FREIGABE von einem NFS-Server[2] SERVER (eine IP-Adresse) so auf den Einbindepunkt MP ein:

  • SERVER = 192.0.2.25 (Hier beispielsweise, an eigene Verhältnisse anpassen!)

  • CLIENT = 192.168.178.77 (Hier beispielsweise, an eigene Verhältnisse anpassen!)

sudo mount -v -t nfs SERVER:FREIGABE MP     # direkter Zugriff 

Bei diesem direkten Zugriff sieht der NFS-Server die reguläre IP-Adresse 192.168.178.77 des NFS-Clients und entscheidet anhand dieser gemäß seiner Konfiguration über der Zugriffsversuch.

Das hier dargestellte Verfahren beruht auf der Schaltung eines SSH-Tunnels vom CLIENT zum SERVER, so dass der SERVER im lokalem Adressraum des CLIENTs sichtbar wird:

ssh -4 -NT -L SERVER_fake:2049:CLIENT_fake:2049 SERVER 

Hierbei sind SERVER_fake und CLIENT_fake beides IP-Adressen, die man im Prinzip beliebig wählen kann, jedoch muss SERVER_fake eine Adresse sein, auf der der Client IP-Pakete senden und empfangen kann, und CLIENT_fake muss eine IP-Adresse sein, auf der der Server IP-Pakete senden und empfangen kann. Dieser Artikel verwendet aus dem Block für localhost aus den regulären Adressen abgeleitete Adressen:

  • SERVER_fake = 127.0.2.25 (Aus eigenem Wert für SERVER berechnen.)

  • CLIENT_fake = 127.168.178.77 (Aus eigenem Wert für CLIENT berechnen.)

Nach der Schaltung des Tunnels verwendet man zur Einbindung einen indirekten Zugriff anstelle des oben beschriebenen direkten Zugriffs:

sudo mount -v -t nfs SERVER_fake:FREIGABE MP     # indirekter Zugriff 

Der Zugriff aus den NFS-Server erfolgt nun von der IP-Adresse CLIENT_fake. Damit das funktioniert, muss natürlich der NFS-Server die IP-Adresse CLIENT_fake mit denselben Optionen akzeptieren wie die IP-Adresse CLIENT.

Anleitung

  1. Vom Client aus per SSH auf dem Server anmelden:

    ssh 192.0.2.25 
  2. Auf dem Server eine Root-Shell starten:

    sudo -i 
  3. Bei jeder Freigabe ist der IP-Adressbereich 127/8 gleichberechtigt hinzuzufügen:

    • Aus einer Zeile

      /srv/nfs	192.168.0.0/16(rw,no_subtree_check,insecure) 

      wird daher:

      /srv/nfs	-rw,no_subtree_check,insecure     127.0.0.0/8     192.168.0.0/16 
    • Danach Export-Liste aktualisieren und NFS-Server neu starten:

      exportfs -arv 

      systemctl restart nfs-server.service 
  4. Im Grunde kann man den SSH-Tunnel für jeden Benutzer aufbauen, der auf dem Server bekannt ist. Es ist jedoch zweckmäßig, hierfür einen dedizierten Systembenutzer (hier beispielsweise: ssh-tunnel) einzurichten:

    useradd --gid 65534  --uid 250 --create-home ssh-tunnel 

    Außerdem gibt man dem neuen Benutzer ein Passwort:

    passwd ssh-tunnel 
  5. Man kann nun die Root-Shell verlassen und auch die SSH-Verbindung beenden.

  6. ⚓︎ Auf dem Client richtet man den neuen Benutzer ebenfalls ein und wechselt in seine Identität:

    sudo useradd --gid 65534  --uid 250 --create-home ssh-tunnel 

    sudo -i -u ssh-tunnel 
  7. Auf dem ersten Client erzeugt man für die Anmeldung per SSH ohne Passwort ein Schlüsselpaar:

    ssh-keygen 

    Wichtig ist, diesen Schlüssel nicht durch eine Passphrase abzusichern. Den öffentlichen Teil des Schlüsselpaars transferiert man auf den Server:

    ssh-copy-id 

    Auf allen weiteren Clients kopiert man das vollständige Schlüsselpaar vom ersten Client auf einem sicheren Weg.

  8. Den passwortlosen Zugang per SSH zum Server sollte man testen,

  9. und danach seine Verkleidung als ssh-tunnel beenden:

    exit 
  10. Die vorstehenden Punkte ab Punkt 6 wiederholt man für jeden weiteren Client, der auf den NFS-Server verschlüsselt zugreifen soll.

  11. Optional: Nach ausführlichem Test und Umstellung aller Clients kann man auf dem Server alle Zugriffe für unverschlüsselte Clients entfernen, d.h.

    • aus einer Zeile

      /srv/nfs	-rw,no_subtree_check,insecure     127.0.0.0/8     192.168.0.0/16 

      wird nun:

      /srv/nfs	-rw,no_subtree_check,insecure     127.0.0.0/8 
    • Danach Export-Liste aktualisieren und NFS-Server neu starten!

  12. Optional: Auch das Passwort auf dem Server für den Benutzer ssh-tunnel benötigt man nicht mehr und kann es sperren, beispielsweise:

    sudo usermod -L ssh-tunnel 

Die beiden zuletzt genannten optionalen Aktionen sind optional aus funktionaler Sicht, aber für die Sicherheit durchaus essenziell.

Manueller Zugriff

Eine Einbindung erfordern nun anstatt des einen für direkten Zugriff diese zwei Befehle:

# Allgemeines Schema: sudo -i -u ssh-tunnel -- ssh -4 -f -NT -L SERVER_fake:2049:CLIENT_fake:2049 SERVER
sudo -i -u ssh-tunnel -- ssh -4 -f -NT -L 127.0.2.25:2049:127.168.178.77:2049 192.0.2.25 

und

# Allgemeines Schema: sudo mount -v -t nfs SERVER_fake:FREIGABE MP     # indirekter Zugriff
sudo mount -v -t nfs 127.0.2.25:/ /mnt/tmp 

Den ersten Befehl kann man bereits beim Rechnerstart über eine Unit für Systemd absetzen, wie anschießend gezeigt. Statt des zweiten Befehls kann man natürlich die bekannten anderen Möglichkeiten nutzen, beispielsweise eine entsprechende Zeile in der Datei fstab vorbereiten.

Der oben gezeigte erste Befehl eröffnet einen „ewigen“ Tunnel, der solange offen bleibt, bis man seinen Prozess mit kill beendet. Er eignet sich daher insbesondere für eine Automatik, die beim Systemstart einmalig aktiviert wird. Alternativ kann man den Tunnel auch nur für eine beschränkte Zeit, z.B. eine Minute, öffnen und automatisch schließen, wenn er nicht bzw. nicht mehr benutzt wird:

# Allgemeines Schema: sudo -i -u ssh-tunnel -- ssh -4 -f -T -L SERVER_fake:2049:CLIENT_fake:2049 SERVER sleep DAUER
sudo -i -u ssh-tunnel -- ssh -4 -f -T -L 127.0.2.25:2049:127.168.178.77:2049 192.0.2.25 sleep 60 

Diese Variante eignet sich auch gut für ein Skript, welches die Berechnung der neuen IP-Adressen, Aufbau des Tunnels und den eigentlichen Befehl zur Einbindung kombiniert.

Automatischer Zugriff

Zum automatischen Start des SSH-Tunnels beim Systemstart benötigt man eine Unit für systemd. Dafür legt man auf dem Client mit Root-Rechten[5] im Ordner /etc/systemd/system/ eine Datei nfs-over-ssh.service an und fügt folgenden Text ein:

# /etc/systemd/system/nfs-over-ssh.service
[Unit]
Description =   SSH Tunnel zu NFSv4-Server %i
After =         network.target

[Service]
Type =          exec
Environment =   "SERVER=192.0.2.25"
Environment =   "TUNNEL=127.0.2.25:2049:127.168.178.77:2049"
ExecStart =      sudo -i -u ssh-tunnel -- ssh -4 -f -NT -L $TUNNEL $SERVER

[Install]
WantedBy=multi-user.target

Die Umgebungsvariablen SERVER und TUNNEL sind an die eigenen Verhältnisse anzupassen. Wenn man mit mehreren NFS-Servern kommunizieren will, benötigt man natürlich für jeden einen eigenen Tunnel und eine eigene Unit.

Die Unit aktiviert man für ihren automatischen Start beim Hochlauf des Systems:

sudo systemctl enable nfs-over-ssh.service 

Unabhängig vom Start der Unit zum Aufbau des Tunnels muss man natürlich im System den Befehl oder die Daten zu tatsächlichen Einbindung anpassen; hierzu ist lediglich die IP-Adresse SERVER durch die IP-Adresse SERVER_fake zu ersetzen.

Diese Revision wurde am 29. März 2026 12:25 von kB erstellt.
Die folgenden Schlagworte wurden dem Artikel zugewiesen: Howto