PVE mit ZFS und native encryption
Proxmox Virtual Environment hat meinen alten XEN Server abgelöst. Die Festplatten werden wieder verschlüsselt, damit beim Wechsel diese nicht mehr gelöscht werden müssen.
Installation von PVE mit ZFS
Die Installation erfolgte mittels ISO Datei auf einem USB-Stick. Als Filesystem wählte ich ZFS mit RAID 1 auf zwei SSD mit Standard Parametern.
Lokale Anpassungen
Deaktiviere Subscription Warnung
Deaktivierung der nervigen Warnung über eine fehlende Subscription: Über /etc/rc.local starte ich ein kleines script remove-proxmox-subscription-notice.sh
encrypted ZFS pool anlegen
Ich habe ein Verzeichnis '/etc/cryptkey' angelegt, dass alle zur Verschlüsselung notwendigen Dateien aufnimmt:
- keymanager_zfs.sh - Key Management Tool
- keyscript.sh - Startscript (Bootprozess)
- key_zfs.conf - Konfigurationsdetails
- root - Zertifikat (ZFS KEY)
root# ls -l /etc/cryptkey -rwxr-x--x 1 root root 9542 Dec 19 22:40 keymanager_zfs.sh -rwxr-x--x 1 root root 680 Dec 19 20:49 keyscript_zfs.sh -r-------- 1 root root 859 Dec 19 21:46 key_zfs.conf -r-------- 1 root root 130 Dec 19 20:49 root
Das Key Management Tool habe ich in einem Forum gefunden: keymanagement.sh
./keymanager_zfs.sh zfscreate -v rpool/encrypted_data
Unlock encrypted ZFS Pool
Files
/root
remove-proxmox-subscription-notice.sh
Das Script remove-proxmox-subscription-notice.sh sdeaktiviert die Subscription Warnung im Webinterface. Ich starte es über /etc/rc.local.
#!/bin/sh sed -Ezi.bak "s/(Ext.Msg.show\(\{\s+title: gettext\('No valid sub)/void\(\{ \/\/\1/g" /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js && systemctl restart pveproxy.service
/etc/rc.local
Deaktiviere Subscription Warnung, aktiviere den encrypted ZFS Pool.
#!/bin/sh -e # local init script # load ZFS encryption key on boot from USB Stick if [ -r /etc/cryptkey/key_zfs.conf ]; then /etc/cryptkey/keyscript_zfs.sh fi /root/remove-proxmox-subscription-notice.sh # evtl. Sleepmodus für HDD Festplatten aktivieren #[ -e /dev/sda ] && hdparm -Y -S 242 /dev/sda || true #[ -e /dev/sdb ] && hdparm -Y -S 242 /dev/sdb || true mount -a exit 0
/etc/cryptkey
keymanager_zfs.sh
Das Key Management Tool habe ich in einem Forum gefunden: keymanager.sh
#!/bin/bash # zfs multiple passwords # found at: https://forums.gentoo.org/viewtopic-t-1122263-start-0.html # # keymanager.sh case $1 in "makekey") #default values keysize=64 keyname=$USER [ ! -z $SUDOUSER ] && keyname=$SUDOUSER store=. cnt=1 ls=1 for a in "$@" do let cnt+=1 case $a in -k | --keysize) keysize=${!cnt} ls=1 ;; -s | --keystore) store=${!cnt} ls=1 ;; -n | --keyname) keyname=${!cnt} ls=1 ;; -p | --password) pass=${!cnt} ls=1 ;; -*) echo $1: unknown argument $a exit 255 ;; *) # if we get here twice in a row, something is wrong [ $ls = 0 ] && echo $1: unknown argument $a && exit 254 ls=0 ;; esac done mkdir -p $store key=`openssl rand -base64 $keysize |tr -d '\n='` [ $? != 0 ] && echo "Keygeneration failed" && exit 3 key="KEY${key:0:$keysize}" [ -e ${store}/${keyname} ] && echo Key exists. I will not overwrite ${store}/${keyname} && exit 252 if [ -z $pass ] ; then openssl enc -aes-256-cbc -a -pbkdf2 -iter 1000000 <<< ${key} > ${store}/${keyname} else openssl enc -aes-256-cbc -a -pbkdf2 -iter 1000000 -pass pass:${pass} <<< ${key} > ${store}/${keyname} fi [ $? != 0 ] && echo "Encryption failed" && rm ${store}/${keyname} && exit 4 chmod 600 ${store}/${keyname} ;; "zfscreate") #default values keyname=$USER [ ! -z $SUDOUSER ] && keyname=$SUDOUSER store=. opt="" cnt=1 ls=1 for a in "$@" do let cnt+=1 case $a in -s | --keystore) store=${!cnt} ls=1 ;; -n | --keyname) keyname=${!cnt} ls=1 ;; -p | --password) pass=${!cnt} ls=1 ;; -v | --volname) vol=${!cnt} ls=1 ;; -o) opt="$opt -o ${!cnt}" ls=1 ;; -*) echo $1: unknown argument $a exit 255 ;; *) # if we get here twice in a row, something is wrong [ $ls = 0 ] && echo $1: unknown argument $a && exit 254 ls=0 ;; esac done [ -z $vol ] && echo $1 needs volumeName. Use -v volumename [ ! -r ${store}/${keyname} ] && echo Key not accessible ${store}/${keyname} && exit 123 if [ -z $pass ] ; then key=`openssl enc -aes-256-cbc -a -pbkdf2 -iter 1000000 -d < ${store}/${keyname}` else key=`openssl enc -aes-256-cbc -a -pbkdf2 -iter 1000000 -d -pass pass:${pass} < ${store}/${keyname}` fi [ "KEY" != ${key:0:3} ] && echo Key decrypt failed && exit 10 defopt="" [[ "$opt" != *"encryption="* ]] && defopt="$defopt -o encryption=on" [[ "$opt" != *"keyformat="* ]] && defopt="$defopt -o keyformat=passphrase" zfs create $defopt $opt $vol <<< $key ;; "zfsload") #default values keyname=$USER [ ! -z $SUDOUSER ] && keyname=$SUDOUSER store=. opt="" cnt=1 ls=1 for a in "$@" do let cnt+=1 case $a in -s | --keystore) store=${!cnt} ls=1 ;; -n | --keyname) keyname=${!cnt} ls=1 ;; -p | --password) pass=${!cnt} ls=1 ;; -v | --volname) vol=${!cnt} ls=1 ;; -*) echo $1: unknown argument $a exit 255 ;; *) # if we get here twice in a row, something is wrong [ $ls = 0 ] && echo $1: unknown argument $a && exit 254 ls=0 ;; esac done [ -z $vol ] && echo $1 needs volumeName. Use -v volumename zfs get keystatus |grep $vol |grep " available" && echo Key already loaded, nothing to do && exit 0 [ ! -r ${store}/${keyname} ] && echo Key not accessible ${store}/${keyname} && exit 123 if [ -z $pass ] ; then key=`openssl enc -aes-256-cbc -a -pbkdf2 -iter 1000000 -d < ${store}/${keyname}` else key=`openssl enc -aes-256-cbc -a -pbkdf2 -iter 1000000 -d -pass pass:${pass} < ${store}/${keyname}` fi [ "KEY" != "${key:0:3}" ] && echo Key decrypt failed && exit 10 zfs load-key $vol <<< $key ;; "useradd") #default values keyname=$USER [ ! -z $SUDOUSER ] && keyname=$SUDOUSER newkeyname=$USER [ ! -z $SUDOUSER ] && newkeyname=$SUDOUSER store=. opt="" cnt=1 ls=1 for a in "$@" do let cnt+=1 case $a in -s | --keystore) store=${!cnt} ls=1 ;; -n | --keyname) keyname=${!cnt} ls=1 ;; -p | --password) pass=${!cnt} ls=1 ;; -m | --newkeyname) newkeyname=${!cnt} ls=1 ;; -q | --newpass) newpass=${!cnt} ls=1 ;; -*) echo $1: unknown argument $a exit 255 ;; *) # if we get here twice in a row, something is wrong [ $ls = 0 ] && echo $1: unknown argument $a && exit 254 ls=0 ;; esac done [ ! -r ${store}/${keyname} ] && echo Key not accessible ${store}/${keyname} && exit 123 if [ -z $pass ] ; then echo Decrypting key key=`openssl enc -aes-256-cbc -a -pbkdf2 -iter 1000000 -d < ${store}/${keyname}` else key=`openssl enc -aes-256-cbc -a -pbkdf2 -iter 1000000 -d -pass pass:${pass} < ${store}/${keyname}` fi [ "KEY" != ${key:0:3} ] && echo Key decrypt failed && exit 10 [ -e ${store}/${newkeyname} ] && echo New key exists. I will not overwrite ${store}/${newkeyname} && exit 252 if [ -z $newpass ] ; then echo Encrypting key openssl enc -aes-256-cbc -a -pbkdf2 -iter 1000000 <<< ${key} > ${store}/${newkeyname} else openssl enc -aes-256-cbc -a -pbkdf2 -iter 1000000 -pass pass:${newpass} <<< ${key} > ${store}/${newkeyname} fi chmod 600 ${store}/${newkeyname} ;; *) iam=`basename $0` echo Usage: echo "$iam makekey [-k keySize] [-s keystoreFolder] [-n keyname] [-p password]" echo " Generates at random string (base_64 characters) of length keySize " echo " encrypts it by password, and stores the encrypted string in" echo " folder keystoreFolder." echo " If password is not given, it will be requested from stdin." echo " If no keyname is given, the current username will be used as keyname." echo " If no keystoreFolder is given, the current folder will be used." echo " If no keysize is given, default 64 will be used" echo echo "$iam zfscreate [-s keystoreFolder] [-n keyname] [-p password] -v volumename [-o zfsoption [-o ....]]" echo " Creates a zfs volume named volumename encrypted with key" echo " previously generated by makekey." echo " Default zfsoption are -o encryption=on -o keyformat=passphrase" echo " Additional zfsoptions may be specified." echo " Password is used to decrypt key. If password is not given, it " echo " will be requested from stdin." echo " If no keyname is given, the current username will be used as keyname." echo " If no keystoreFolder is given, the current folder will be used." echo echo "$iam zfsload [-s keystoreFolder] [-n keyname] [-p password] -v volumename" echo " Decrypts key previously generated by makekey and executes zfs load-key" echo " Password is used to decrypt key. If password is not given, it " echo " will be requested from stdin." echo " If no keyname is given, the current username will be used as keyname." echo " If no keystoreFolder is given, the current folder will be used." echo echo "$iam useradd [-s keystoreFolder] [-n keyname] [-p password] [-m newkeyname] [-q newpass] " echo " Makes a key previously generated by makekey available to anotheruser." echo " That is, decrypts the key saved under keyname using password, then" echo " saves it under newkeyname encryoted by using newpass" echo " Password is used to decrypt key. If password is not given, it " echo " will be requested from stdin." echo " Newpassw is used to encrypt key. If newpass is not given, it " echo " will be requested from stdin." echo " If no keyname is given, the current username will be used as keyname." echo " If no newkeyname is given, the current username will be used as keyname." echo " If no keystoreFolder is given, the current folder will be used." ;; esac