[[Vorlage(Howto, kB ) ]] ## [[Vorlage(getestet, noble ) ]] [[Vorlage(getestet-general-ab, 'Noble Numbat' ) ]] {{{#!vorlage Wissen [:NFS:] [:NFS-Server:] [:NFS-Client:] [:SSH:] [:mit Root-Rechten arbeiten:Root-Rechte] }}} [[Inhaltsverzeichnis()]] 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 [#Links 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 = [[Anker( direkter-Zugriff ) ]] 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!) {{{#!vorlage Befehl 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: {{{#!vorlage Befehl 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 [#direkter-Zugriff oben] beschriebenen direkten Zugriffs: {{{#!vorlage Befehl 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: [[Vorlage( Befehl, "ssh 192.0.2.25" ) ]] 1. Auf dem Server eine Root-Shell starten: [[Vorlage( Befehl, "sudo -i" ) ]] 1. 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: [[Vorlage( Befehl, "exportfs -arv" ) ]] [[Vorlage( Befehl, "systemctl restart nfs-server.service" ) ]] 1. 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: [[Vorlage( Befehl, "useradd --gid 65534 --uid 250 --create-home ssh-tunnel" ) ]] Außerdem gibt man dem neuen Benutzer ein Passwort: [[Vorlage( Befehl, "passwd ssh-tunnel" ) ]] 1. Man kann nun die Root-Shell verlassen und auch die SSH-Verbindung beenden. 1. [[Anker( Punkt-6 ) ]] Auf dem Client richtet man den neuen Benutzer ebenfalls ein und wechselt in seine Identität: [[Vorlage( Befehl, "sudo useradd --gid 65534 --uid 250 --create-home ssh-tunnel" ) ]] [[Vorlage( Befehl, "sudo -i -u ssh-tunnel" ) ]] 1. Auf dem ersten Client erzeugt man für die Anmeldung per SSH ohne Passwort ein Schlüsselpaar: [[Vorlage( Befehl, ssh-keygen ) ]] Wichtig ist, diesen Schlüssel __nicht__ durch eine Passphrase abzusichern. Den öffentlichen Teil des Schlüsselpaars transferiert man auf den Server: [[Vorlage( Befehl, ssh-copy-id ) ]] Auf allen weiteren Clients kopiert man das vollständige Schlüsselpaar vom ersten Client auf einem sicheren Weg. 1. Den passwortlosen Zugang per SSH zum Server sollte man testen, 1. und danach seine Verkleidung als `ssh-tunnel` beenden: [[Vorlage( Befehl, exit ) ]] 1. Die vorstehenden Punkte ab [#Punkt-6 Punkt 6] wiederholt man für jeden weiteren Client, der auf den NFS-Server verschlüsselt zugreifen soll. 1. 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! 1. Optional: Auch das Passwort auf dem Server für den Benutzer `ssh-tunnel` benötigt man nicht mehr und kann es sperren, beispielsweise: [[Vorlage( Befehl, "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 [#direkter-Zugriff direkten Zugriff] diese zwei Befehle: {{{#!vorlage Befehl # 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 {{{#!vorlage Befehl # 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 [#Automatischer-Zugriff 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: {{{#!vorlage Befehl # 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: {{{#!vorlage Befehl 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. = Links = * [:Kerberos/NFS mit Kerberos sichern:] #tag: Howto