Virtualisierter Server - NFS-Server im Proxmox-LXC - durch Kerberos und FreeIPA abgesichert
In diesem Beitrag beschreibe ich, wie unter Proxmox ein NFS-Server in einem LXC-basierten Container aufgesetzt werden kann. NFS soll dabei durch Kerberos auf Grundlage von FreeIPA abgesichert werden.
Weitere Beiträge in der Reihe:
- VMs automatisch für Puppet vorbereiten
- Apt-Update automatisch verwalten mit apt-dater
- Umzug von Proxmox und VMs auf SSD
- RAID-Controller Marvell 88SE9230 unter Debian live verwalten
- automatische DNS-Einträge für IPv6-Adressen mit wechselndem Präfix
- Puppet-Module: Apache-VHosts mit SSL und Kerberos aus FreeIPA sichern
- Kerberos-basiertes Single-Sign-On (SSO) für SSH und Firefox
- Authentifizierung gegen FreeIPA für Proxmox, pfsense, Puppet und Postfix
- Domäne mit FreeIPA
- Puppet strukturieren mit Profilen, Environments, r10k und git
- Mail-Relay für die VMs mit Postfix und Sendgrid
- SSL überall mit Let’s Encrypt, verteilt durch Puppet
- Puppet Server aufsetzen
- pfsense-Firewall zur Einteilung des Netzwerks mit ipv4 und ipv6
- IPv6-Vorüberlegungen
- Hardware-Setup und Proxmox
Voraussetzungen
Zielsetzungen im Detail
Ziel wird sein, via NFS Shares bereitzustellen, die anhand von FreeIPA und mit Hilfe von Kerberos zugriffsbeschränkt sind. Das ist leider nicht ganz so einfach wie einen TCP-Dienst bereitzustellen, den man dann einfach mit Hilfe eines Clients irgendwo einbindet. Man muss mehrere Rahmenbedingungen herstellen, die passen.
Die Einrichtung von Samba als Alternative, sofern sie auf die User aus der zentralen Verwaltung bei FreeIPA zugreifen soll, ist dabei nicht viel einfacher. Mitunter muss man auch hier dann Kerberos verwenden oder das LDAP-Schema im Hintergrund modifizieren, damit Samba hier ordentlich funktioniert. Die Entscheidung fällt also zu Gunsten von NFS. NFS ist sehr Linux-spezifisch. Wer Windows-Clients bedienen möchte, sollte sich dennoch die Verwendung von Samba überlegen.
Diese Anleitung bezieht sich ausdrücklich auf die Einrichtung auf Grundlage von LXC. NFS findet hauptsächlich im Kernel statt und LXC-basierte Container verwenden den Kernel des Host-Systems, dadurch ist die Trennung zwischen virtualisierter Umgebung und Host-System hier nicht so groß wie bei getrennten Systemen. Ist diese notwendig und sind erhöhte Sicherheitsanforderungen zu beachten, bietet das Anlegen einer virtuellen Maschine an dieser Stelle eine deutlichere Trennung.
Vorbereitungen im Proxmox
Nachdem NFS ohnehin für gewöhnlich vom Kernel bedient wird und die Container den Kernel des Host-Systems verwenden, könnte auch direkt das Host-System die NFS-Shares bereitstellen. Ich möchte das Host-System allerdings unabhängig von den dort laufenden Containern halten. Das schließt zum einen die Verwaltung des Host-Systems mit Puppet, zum anderen auch die Integration in die Rechteverwaltung mit FreeIPA und Kerberos aus. Nachdem ich aber beides für die Datenfreigabe nutzen möchte, bleibt keine andere Lösung als eben einen weiteren Container für Dateifreigaben zu nutzen.
Container-Erstellung
Während es sehr sinnvoll ist, Linux-Container unprivilegiert zu starten und dadurch etwas mehr Sicherheit zu gewinnen, ist das allerdings beim Aufsetzen von NFS nicht so leicht möglich. Ich habe mich also dafür entschieden, einen minimalen Container aufzusetzen, auf dem außer NFS nichts passiert.
Dieser Container muss also privilegiert sein. Ansonsten können die Einstellungen beim Erstellen des Containers nach Belieben getroffen werden.
Nach Aufsetzend es Containers sollte dieser noch nicht gestartet werden, damit noch sein AppArmor-Profil festgelegt werden kann.
Apparmor
Die Abgrenzung der Container zum Host-System wird bei Proxmox mit Hilfe von AppArmor durchgesetzt. Dort werden verschiedene sicherheitsrelevante Rechte beschränkt. Dazu gehört auch die Einschränkung von mounts. Für NFS werden einige Mounts gebraucht, also müssen die wieder freigegeben werden.
Bei der Recherche im Internet zum Thema NFS im Container unter Proxmox
wird oft geraten, man solle den ganzen Container auf unconfined
stellen. Dadurch ist dann allerdings so gut wie kein Schutz mehr
vorhanden, der das Host-System vom Gast abtrennen würde. Insbesondere
weil für NFS ein privilligierter Contianer gebraucht wird, entspricht
UID 0
im Container der UID 0
auf dem Host! Bricht man also mit Hilfe der Root-Rechte aus dem
Container aus, hat man sie auch auf dem Host! Ein paar
Sicherheitsmaßnahmen sollte man also durchaus gültig lassen.
Im Proxmox-Forum gibt es ein AppArmor-Profil, was die notwendigen
Mounts
ermöglicht.
Die folgende Datei sollte also unter
/etc/apparmor.d/lxc/lxc-default-with-nfsd
angelegt
werden:
# Do not load this file. Rather, load /etc/apparmor.d/lxc-containers, which
# will source all profiles under /etc/apparmor.d/lxc
profile lxc-container-default-with-nfsd flags=(attach_disconnected,mediate_deleted) {
#include <abstractions/lxc/container-base>
# the container may never be allowed to mount devpts. If it does, it
# will remount the host's devpts. We could allow it to do it with
# the newinstance option (but, right now, we don't).
deny mount fstype=devpts,
mount fstype=nfsd,
mount fstype=rpc_pipefs,
mount fstype=cgroup -> /sys/fs/cgroup/**,
}
Nachdem die Datei angelegt wurde, muss das Profil noch eingelesen werden:
apparmor_parser -r /etc/apparmor.d/lxc-containers
Das Profil muss im Anschluss dem neu erstellten Container zugewiesen
werden. Dazu muss seine Konfigurationsdatei bearbeitet werden, die unter
/etc/pve/lxc/1337.conf
(1337
durch die Container-ID ersetzen):
lxc.apparmor.profile = lxc-container-default-with-nfsd
Container starten und konfigurieren
Nun kann der Container gestartet werden. Das reguläre Setup kann stattfinden. Dabei sind ein paar Dinge sehr wichtig für den Betrieb als NFS-Server:
- Der Host braucht einen FQDN, beim Aufruf von
hostname -f
sollte der vollständige Hostname inklusive Domain zurückgegeben werden. Mit relativ modernen Distributionen reicht dafürhostnamectl set-hostname $hostname.$domain
- Der Host sollte ebenfalls Mitglied bei FreeIPA sein. Das macht es sehr viel einfacher, die notwendigen Kerberos-Credentials zwischen den Systemen auszutauschen.
Im FreeIPA
Auch auf der Seite von FreeIPA müssen Dinge vorbereitet werden:
Service für NFS anlegen
Damit NFS mit Kerberos geschützt werden kann, wird ein
Kerberos-Prinzipal gebraucht, bei FreeIPA passiert das über das Anlegen
von Services. Um einen Service anzulegen kann man entweder auf der
FreeIPA-Weboberfläche unter Identity, Services einen anlegen
(Service nfs
, als Host Name der FQDN des
NFS-Servers) oder auf der Shell eines bereits bei FreeIPA beigetretenen
Hosts (mit installierten FreeIPA-Admintools):
kinit admin
ipa service-add nfs/hostnamedesnfsservers.domain.tld
Reverse-DNS - Einträge
Der FQDN der DNS-Einträge muss auch umgekehrt auflösen, für Kerberos
und NFS ist DNS sehr wichtig. *Das gilt auch für alle Clients! Sollte
sich aus der Infrastruktur keine bessere Methode ergeben, für alle
beteiligten IP-Adressen gültige RDNS-Einträge anzulegen, kann das
immerhin in den DNS-Servern von FreeIPA passieren. Dazu muss dann die
notwendige DNS-Zone angelegt werden, für das Netzwerk in dem die
IP-Adresse liegt, beispielsweise 192.168.0.0/24
.
Das kann wieder über die Weboberfläche von FreeIPA stattfinden oder auch
wieder über die Shell eines bereits bei FreeIPA beigetretenen Hosts (mit
installierten FreeIPA-Admintools):
kinit admin
ipa dnszone-add --name-from-ip=192.168.0.0/24
Der neuen Zone kann man dann wie exemplarisch folgt neue RDNS-Einträge hinzufügen:
kinit admin
ipa dnsrecord-add --ptr-hostname=bla.example.com. 0.168.192.in-addr.arpa 23
Am Beispiel von 192.168.0.23
:
--ptr-hostname
: Der FQDN, abgeschlossen mit einem.
- der Punkt ist nicht optional, der signalisiert nämlich das Ende des DNS-Records, ansonsten wird noch die (meist falsche) Domain angehängt.0.168.192.in-addr.arpa
: Hier werden die Oktette der IP-Adresse umgekehrt aufgereiht und die Sonder-Domainin-addr.arpa
angehängt. Das letzte Oktett der IP-Adresse ist nicht mit anzugeben. Stattdessen wird die letzte Zahl durch Leerzeichen abgetrennt einfach dazugeschrieben.
Der Befehl legt in der Zone 0.168.192.in-addr.arpa
den Eintrag 23
an, der auf
bla.example.com.
zeigt.
Im Container
Keytab aktualisieren
Damit der NFS-Server die Krypto-Teile von Kerberos nutzen kann, wird auf dem Host das Kerberos-Prinzipal gebraucht. Wenn der Host Mitglied bei FreeIPA ist, kann dieses Prinzipal einfach heruntergeladen werden:
ipa-getkeytab -p nfs/hostnamedesnfsservers.domain.tld -k /etc/krb5.keytab
Damit wird das Prinzipal im systemweiten Kerberos-Keytab gespeichert und kann verwendet werden.
NFS-Tools installieren
Damit NFS gesteuert und aktiviert werden kann, werden Programme benötigt:
- Ubuntu:
sudo apt install nfs-kernel-server
- CentOS:
dnf install nfs-utils
Shares anlegen
NFS-Shares werden in der /etc/exports
angelegt. Am
deutlichsten wird die Syntax an einem Beispiel:
/nas 192.168.0.0/24(rw,sec=krb5i,async,insecure)
/nas
: Pfad zur Freigabe192.168.0.0/24
: Netzwerk, für das die Freigabe verfügbar sein sollrw
: Lesen und Schreibensec=krb5i
: Kerberos-Authentifizierung verwenden und die RPC-Pakete verifiziereninsecure
: Erlaubt, dass Pakete auch von Ports>1024
kommen
Um die neuen Shares zu aktivieren und die
/etc/exports
neu einzulesen, gibt man ein:
exportfs -rav
Auf dem Client
Der Client sollte selbst Mitglied im FreeIPA sein damit die Autentifizierung funktioniert. Um ein Share einzuhängen genúgt für gewöhnlich:
sudo mount -t nfs hostnamedesnfsservers.domain.tld:/nas /mnt/nas -o sec=krb5i