TrueNAS mit vollverschlüsseltem ZFS RAID-Z1 als Gast in qemu auf einem debian host

reinhard@finalmedia.de Sun 07 Nov 2021 07:10:40 PM CET

Installation in QEMU

TrueNAS Minimale Anforderungen sind:

TrueNAS braucht kein Hardware RAID. Es nutzt das geniale ZFS.

Wir betreiben hier in der Demo die VM mit 2GB RAM. Das tut. Der Installer warnt dich aber, dass du in der Low-Memory-Mode arbeitest.

In realen Szenarien und Produktivbetrieb solltest du pro 1 TB Plattenplatz auch Bedarf an 1 GB RAM rechnen. Wenn du also einen 200TB Filer betreiben willst, dann solltest du mindestens 256 GB RAM einplanen, um auch noch genügend RAM für andere Dienste zu haben, denn TrueNAS bietet dir ja auch die Möglichkeit Virtuelle Maschinen zu betreiben - mittels bhyve.

Los gehts...


#!/bin/sh
# reinhard@finalmedia.de
# Sun 07 Nov 2021 07:25:21 PM CET


# variablen definition

isofile="TrueNAS-12.0-U6.iso"

# iso herunterladen, wenn nicht vorhanden
test ! -f "$isofile" && wget -c https://download.freenas.org/12.0/STABLE/U6/x64/TrueNAS-12.0-U6.iso

keyfile="demo.truenas.luks.key"

imagefile_prefix="demo.truenas.luks.disk"
imagefile_suffix=".img"

imagefile00="demo.truenas.luks.disk00.img"
imagefile01="demo.truenas.luks.disk01.img"
imagefile02="demo.truenas.luks.disk02.img"

imagefile03="demo.truenas.luks.disk03.img"
imagefile04="demo.truenas.luks.disk04.img"
imagefile05="demo.truenas.luks.disk05.img"
imagefile06="demo.truenas.luks.disk06.img"

imagefile07="demo.truenas.luks.disk07.img"
imagefile08="demo.truenas.luks.disk08.img"
imagefile09="demo.truenas.luks.disk09.img"
imagefile10="demo.truenas.luks.disk10.img"

# groesse jeder der insgesamt 11 virtuellen Festplatten. Das hier ist eine Demo.
# Daher machen wir sehr kleine Platten. In Real World ist das natürlich größer.
imagesize="8G"

# wenn noch nicht existent, dann
# keyfile erstellen, wir verzichten dabei bei dem 32-stelligen Kennwort auf
# potentiell verwechselbare Zeichen wie Eins, Null, Oh, kleines L, großes I etc.
test ! -f "$keyfile" && umask 077 && tr -dc "0-9a-zA-Z" < /dev/urandom | tr -d "01IloO" | head -c 32 > "$keyfile"


# LUKS disk images erstellen
# macht jetzt hier scheinbar keinen sinn, weil sie ja alle drei am gleichen platz liegen
# und auch das keyfile direkt daneben. Das ist jetzt nur symbolisch!
# Man verteilt diese image-files dann später auch
# auf separate filer und mountpoints, oder arbeitet direkt mit qemu-nbd auf drei
# separaten hosts direkt übers netzwerk. (anderes howto).
# Nur das winzige keyfile legt man zusammen mit diesem
# script auf den vmhost, der dieses script startet und damit die vm betreibt.

for d in 00 01 02 03 04 05 06 07 08 09 10
do
imagefilename="${imagefile_prefix}${d}${imagefile_suffix}"
test ! -f "$imagefilename" && qemu-img create -f luks \
--object secret,id=sec0,file="$keyfile" \
-o key-secret=sec0 "$imagefilename" "$imagesize"
done

# qemu starten und dabei in den freebsd installer booten
qemu-system-x86_64 -enable-kvm \
-boot menu=on,reboot-timeout=4 -cpu host -smp cores=2 -m 2048 \
-object secret,id=sec00,file="$keyfile" \
-object secret,id=sec01,file="$keyfile" \
-object secret,id=sec02,file="$keyfile" \
-object secret,id=sec03,file="$keyfile" \
-object secret,id=sec04,file="$keyfile" \
-object secret,id=sec05,file="$keyfile" \
-object secret,id=sec06,file="$keyfile" \
-object secret,id=sec07,file="$keyfile" \
-object secret,id=sec08,file="$keyfile" \
-object secret,id=sec09,file="$keyfile" \
-object secret,id=sec10,file="$keyfile" \
-device ahci,id=ahci \
-device ahci,id=storage0 \
-device ahci,id=storage1 \
-drive if=none,id=drive0,driver=luks,key-secret=sec00,file="$imagefile00" \
-device ide-drive,bus=ahci.0,drive=drive0 \
-drive if=none,id=drive1,driver=luks,key-secret=sec01,file="$imagefile01" \
-device ide-drive,bus=ahci.1,drive=drive1 \
-drive if=none,id=drive2,driver=luks,key-secret=sec02,file="$imagefile02" \
-device ide-drive,bus=ahci.2,drive=drive2 \
-drive if=none,id=storagedrive0,driver=luks,key-secret=sec03,file="$imagefile03" \
-device ide-drive,bus=storage0.0,drive=storagedrive0 \
-drive if=none,id=storagedrive1,driver=luks,key-secret=sec04,file="$imagefile04" \
-device ide-drive,bus=storage0.1,drive=storagedrive1 \
-drive if=none,id=storagedrive2,driver=luks,key-secret=sec05,file="$imagefile05" \
-device ide-drive,bus=storage0.2,drive=storagedrive2 \
-drive if=none,id=storagedrive3,driver=luks,key-secret=sec06,file="$imagefile06" \
-device ide-drive,bus=storage0.3,drive=storagedrive3 \
-drive if=none,id=storagedrive4,driver=luks,key-secret=sec07,file="$imagefile07" \
-device ide-drive,bus=storage1.0,drive=storagedrive4 \
-drive if=none,id=storagedrive5,driver=luks,key-secret=sec08,file="$imagefile08" \
-device ide-drive,bus=storage1.1,drive=storagedrive5 \
-drive if=none,id=storagedrive6,driver=luks,key-secret=sec09,file="$imagefile09" \
-device ide-drive,bus=storage1.2,drive=storagedrive6 \
-drive if=none,id=storagedrive7,driver=luks,key-secret=sec10,file="$imagefile10" \
-device ide-drive,bus=storage1.3,drive=storagedrive7 \
-vga qxl --sandbox on -usb -k de -monitor /dev/null \
-netdev user,restrict=off,id=net0,hostfwd='tcp:127.0.0.1:3322-:22',hostfwd='tcp:127.0.0.1:8080-:80',hostfwd='tcp:127.0.0.1:4443-:443',hostfwd='tcp:127.0.0.1:1445-:445' \
-device e1000,netdev=net0 \
-vnc 127.0.0.1::5901 \
-rtc base=localtime,clock=host \
-cdrom "$isofile"

Dann nun xvncviewer verwenden, um zur Session zu verbinden.


apt-get update
apt-get install xtightvncviewer

xvncviewer 127.0.0.1::5901

QEMU bootet nun in den TrueNAS Installer.

Hier Schritt für Schritt die Dialoge des Installers:

So. Die Installation ist abgeschlossen. Nun die ISO aushängen und in das System booten. Dir wird dann auch am Ende des Bootprozess angezeigt auf welcher IP du die WebGUI erreichst. Wir haben uns das ja geforwardet. Du öffenst also nun in deinem Webbrowser einfach:


http://127.0.0.1:8080

oder


https://127.0.0.1:4443

Da noch ein selfsigned Cert hinterlegt ist, musst du die Ausnahme akzeptieren, wenn du via https verbindest.

Du kanst auch via ssh arbeiten mittels


ssh -p 3332 root@127.0.0.1

Setze nun bitte zuerst die Systemzeit und Locale korrekt, sonst wird 2FA scheitern.

Den Webdienst neustarten, damit aktiv

Nun die 2-Faktor-Authentifikation aktivieren. Du kannst auch ein Fenster von 2 oder 3 setzen, wenn die Zeit auch diesem System nicht 100% zuverlässig ist. Ein Fenster steht für das angegebene Intervall von 30 Sekunden. der TOTP ändert sich alle 30 Sekunden. Mit Fenster von 3 erlaubst du also, dass auch 2 vorherige/nachfolgende TOTP Codes noch als akzeptiert werden würden.

Wenn du dich nun ausloggst und neu einloggst, wirst du in der Login-Maske ein drittes Feld finden, in dem du den aktuellen TOTP 2FA Code eingeben musst

Nachtrag

Um mit einem apache2 tls und websocket proxy das http frontend zu forwarden, und via https erreichbar zu machen (z.B. lets encrypt), kannst Du die nachfolgende apache2 vhost Konfigurationr verwenden.

(Oder natürlich im TrueNAS selbst https und dortiges zertifikat nutzen und den ganzen port via tcp forwarden und remote binden)

Allerdings ist auf die nachfolgend beschriebene Weise auch ein forward zu einem remote host apache pathproxy mit dortigem https bequem möglich:


a2enmod ssl
a2enmod proxy_http
a2enmod proxy_html
a2enmod proxy_wstunnel
a2enmod sed

Um dann z.B. in dem Unterverzeichnis truenas die vm erreichbar zu halten



 <VirtualHost *:443>

	Servername demohost.finalmedia.de

	SSLEngine on
	SSLStrictSNIVHostCheck off
	SSLHonorCipherOrder on
	SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384  EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+AESGCM EECDH EDH+AESGCM EDH+aRSA HIGH !MEDIUM !LOW !aNULL !eNULL !LOW !RC4 !MD5 !EXP !PSK !SRP !DSS"
	SSLCompression Off
	SSLProtocol -All +TLSv1.2 +TLSv1.3

	SSLCertificateFile ....
	SSLCertificateKeyFile ...
	SSLCertificateChainFile ....
	SSLCACertificateFile .... ca.cer

	# truenas proxy
        ProxyRequests on
        ProxyPreserveHost Off
        <Location "/truenas/">
        UseCanonicalName On
        ProxyPass http://127.0.0.1:8080/
        ProxyPassReverse http://127.0.0.1:8080/
        ProxyPassReverseCookiePath "/" "/truenas/"
        ProxyHTMLExtended On
        ProxyHTMLEnable On
        SetOutputFilter INFLATE;proxy-html;DEFLATE
        ProxyHTMLURLMap "/ui/" "/truenas/ui/"
        AddOutputFilter Sed js
        OutputSed "s|/websocket|/truenas/websocket|g"
        </Location>
        <Location "/truenas/websocket">
        ProxyPass "ws://127.0.0.1:8080/websocket"
        ProxyPassReverse "ws://127.0.0.1:8080/websocket"
        </Location>

</VirtualHost>