[SOLVED] Plama, WiFi, ZFS encryption

Mom0987

New Member
Jul 15, 2023
1
0
1
24
If you use WiFi, want Proxmox as your desktop OS with encrypted ZFS, follow these steps:

00 Prepare these three USB sticks

USB-1 - Proxmox VE 8.0 : proxmox-ve_8.0-2.iso
USB-2 - Debian 12 DVD : debian-12.0.0-amd64-DVD-1.iso
USB-3 - with script1.sh and script2.sh

01 Boot - USB-1 - Proxmox VE 8.0 : proxmox-ve_8.0-2.iso

Select "Install Proxmox"
Choose these "Target harddisk options"
- Filesystem = zfs (RAID0)
- Advanced Options
- compress = zstd
- checksum = sha256

02 Boot the Proxmox VE 8.0 : proxmox-ve_8.0-2.iso USB

1. Choose "Advanced Options" ---> "Console Debug Mode"
2. Enter "exit" at the "Debug mode" command prompt
3. At the "root@proxmox:/#" prompt:
- Insert "USB-3 - with script1.sh and script2.sh"
- "mount /dev/sdb1 /mnt"
- "/mnt/script1.sh"
- "exit"
- Ctrl-Alt-Del

Scrip 1:
Bash:
#!/usr/bin/env bash
#
# Script 1: encrypt the ZFS proxmox installation from 01
#
# PromptExec - function to show you each instruction before exection
# $1 is the comment for the instruction
# $2 is the instuction to be executed
counter=100
PromptExec () {
    counter=$(( ${counter} + 1 ))

    # while loop to show instruction and read choice
    choice="n"
    while ! [[ ${choice} =~ [yY] ]]; do

        # show instruction and read choice
        printf "%d\n%d %s\n%d\n%d ===> %s\n%d\n" "${counter}" "${counter}" "${1}" "${counter}" "${counter}" "${2}" "${counter}"
        read -r -p "${counter} Execute this instruction? (y/n/q) " -n 1 choice ; echo

        # yes execute instruction
        if [[ ${choice} =~ [yY] ]]; then

            # while we want to execute instruction
            check="y"
            while [[ ${check} =~ [yY] ]]; do
                printf "%d\n" "${counter}"
                eval "${2}"

                # check return code
                check=${?}
                if (( ${check} == 0 )); then
                    printf "%d\n%d Returned: \"%d\"\n" "${counter}" "${counter}" "${check}"
                elif (( ${check} > 0 )); then
                    printf "%d\n" "${counter}"
                    read -r -p "${counter} Returned: \"${check}\" Do you want to try that again? (y/n) " -n 1 check ; echo
                fi
            done

        # no or quit
        elif [[ ${choice} =~ [nNqQ] ]]; then

            # check choice
            printf "%d\n" "${counter}"
            read -r -p "${counter} Are you sure? (y/n) " -n 1 check ; echo

            # yes for n or q
            if [[ ${check} =~ [yY] ]]; then

                # quit
                if [[ ${choice} =~ [qQ] ]]; then
                    exit
                fi

                # skip this instruction
                choice="y"
            fi
        fi
    done
}

printf "%d\n%d script 1: instructions 101 to 114 to encrypt the proxmox you installed\n" 100 100
PromptExec 'import installed zpool' \
'zpool import -f rpool'
PromptExec 'take snapshot of unencrypted system' \
'zfs snapshot -r rpool/ROOT@copy'
PromptExec 'save snapshot in copyroot' \
'zfs send -Rv rpool/ROOT@copy | zfs receive -v rpool/copyroot'
PromptExec 'show everything before encryption' \
'zfs list -t all'
PromptExec 'show the encryption settings' \
'zfs get encryption'
PromptExec 'destroy the unencrypted system' \
'zfs destroy -rv rpool/ROOT'
PromptExec 'create a replacement encrypted system' \
'zfs create -v -o encryption=on -o keyformat=passphrase rpool/ROOT'
PromptExec 'copy snapshot to the new encrypted system' \
'zfs send -Rv rpool/copyroot/pve-1@copy | zfs receive -v -o encryption=on rpool/ROOT/pve-1'
PromptExec 'setup encrypted mountpoint' \
'zfs set mountpoint=/ rpool/ROOT/pve-1'
PromptExec 'destroy unencrypted system' \
'zfs destroy -rv rpool/copyroot'
PromptExec 'destroy unencrypted snapshots' \
'zfs destroy -rv rpool/ROOT@copy'
PromptExec 'show everything after encryption' \
'zfs list -t all'
PromptExec 'show the encryption settings' \
'zfs get encryption'
PromptExec 'unmount pool' \
'zpool export rpool'

03 Boot - start the proxmox you installed during job 01

1. Enter the ZFS password when prompted
2. Login as "root" when prompted
3. Use password from Proxmox install
4. At the "root@...:~#" prompt:
- Insert "USB-3 - with script1.sh and script2.sh"
- "mount /dev/sda1 /mnt"
- "cp -van /mnt/script2.sh ~"
- "umount /mnt"
- "~/script2.sh"

Have "USB-2 - Debian 12 DVD : debian-12.0.0-amd64-DVD-1.iso" ready to insert

This script will:
- encrypt the proxmox data
- update proxmox repos - remove enterprise and add no-subscription
- disable ipv6
- create bridge for VM and CT
- configure nftables for NAT
- clean up debian dvd files
- reboot with WiFi, Plasma, and encrypted ZFS

Scrip 2:
Bash:
#!/usr/bin/env bash
#
# Script 2:
# - encrypt the proxmox data
# - update proxmox repos - remove enterprise and add no-subscription
# - disable ipv6
# - create bridge for VM and CT
# - configure nftables for NAT
# - clean up debian dvd files
# - reboot with WiFi, Plasma, and encrypted ZFS
#
# PromptExec - function to show you each instruction before exection
# $1 is the comment for the instruction
# $2 is the instuction to be executed
counter=200
PromptExec () {
    counter=$(( ${counter} + 1 ))

    # while loop to show instruction and read choice
    choice="n"
    while ! [[ ${choice} =~ [yY] ]]; do

        # show instruction and read choice
        printf "%d\n%d %s\n%d\n%d ===> %s\n%d\n" "${counter}" "${counter}" "${1}" "${counter}" "${counter}" "${2}" "${counter}"
        read -r -p "${counter} Execute this instruction? (y/n/q) " -n 1 choice ; echo

        # yes execute instruction
        if [[ ${choice} =~ [yY] ]]; then

            # while we want to execute instruction
            check="y"
            while [[ ${check} =~ [yY] ]]; do
                printf "%d\n" "${counter}"
                eval "${2}"

                # check return code
                check=${?}
                if (( ${check} == 0 )); then
                    printf "%d\n%d Returned: \"%d\"\n" "${counter}" "${counter}" "${check}"
                elif (( ${check} > 0 )); then
                    printf "%d\n" "${counter}"
                    read -r -p "${counter} Returned: \"${check}\" Do you want to try that again? (y/n) " -n 1 check ; echo
                fi
            done

        # no or quit
        elif [[ ${choice} =~ [nNqQ] ]]; then

            # check choice
            printf "%d\n" "${counter}"
            read -r -p "${counter} Are you sure? (y/n) " -n 1 check ; echo

            # yes for n or q
            if [[ ${check} =~ [yY] ]]; then

                # quit
                if [[ ${choice} =~ [qQ] ]]; then
                    exit
                fi

                # skip this instruction
                choice="y"
            fi
        fi
    done
}

printf "%d\n%d script 2: instructions 201 to 249\n" 200 200
printf "%d  you need to have \"USB-2 - Debian 12 DVD : debian-12.0.0-amd64-DVD-1.iso\"\n" 200
printf "%d  - to encrypt the proxmox data\n" 200
printf "%d  - update proxmox repos - remove enterprise and add no-subscription\n" 200
printf "%d  - disable ipv6\n" 200
printf "%d  - create bridge for VM and CT\n" 200
printf "%d  - configure nftables for NAT\n" 200
printf "%d  - clean up debian dvd files\n" 200
printf "%d  - reboot with WiFi, Plasma, and encrypted ZFS\n" 200

PromptExec 'generate a random key for the data' \
'openssl rand -hex -out /root/data-encrypted.key 32'
PromptExec 'make a copy, just in case' \
'cp -van data-encrypted.key .data-encrypted.key'
PromptExec 'show everything before encryption' \
'zfs list -t all'
PromptExec 'show the encryption settings' \
'zfs get encryption'
PromptExec 'destroy the empty data' \
'zfs destroy -rv rpool/data'
PromptExec 'create the encrypted data' \
'zfs create -v -o encryption=on -o keyformat=hex -o keylocation=file:///root/data-encrypted.key rpool/data'
PromptExec 'tell proxmox about the encrypted data' \
'pvesm add zfspool data -pool rpool/data'
PromptExec 'make the zfs-load-key service for mounting rpool/data automatically' \
'echo '\''[Unit]
Description=Load ZFS encryption key
DefaultDependencies=no
After=zfs-import.target
Before=zfs-mount.service

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/sbin/zfs load-key -a
StandardInput=tty-force

[Install]
WantedBy=zfs-mount.service'\'' | tee /etc/systemd/system/zfs-load-key.service'
PromptExec 'enable the zfs-load-key service' \
'systemctl enable zfs-load-key.service'
PromptExec 'reload all the services' \
'systemctl daemon-reload'
PromptExec 'show everything after encryption' \
'zfs list -t all'
PromptExec 'show the encryption settings' \
'zfs get encryption'
PromptExec 'snapshot the encrypted proxmox' \
'zfs snapshot -r rpool/ROOT@encrypted'
PromptExec 'snapshot the empty encrypted data' \
'zfs snapshot -r rpool/data@encrypted'
PromptExec 'get ready to copy debian DVD debs to install' \
'mkdir -vp /usr/local/dvd-debs'
PromptExec 'move to that directory' \
'cd /usr/local/dvd-debs/'
PromptExec 'insert "USB-2 - Debian 12 DVD : debian-12.0.0-amd64-DVD-1.iso" for this mount command' \
'mount /dev/sda1 /mnt/'
PromptExec 'copy all the deb files' \
'find /mnt/ -type f -iname "*\.deb" -exec cp -van {} . \;'
PromptExec 'install the dpkg-dev program to access the debs' \
'dpkg -i libdpkg-perl_1.21.22_all.deb patch_2.7.6-7_amd64.deb make_4.3-4.1_amd64.deb dpkg-dev_1.21.22_all.deb'
PromptExec 'build the packages.gz file' \
'dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz'
PromptExec '"comment out" the deb entries from all the sources.list files' \
'for fn in $(grep -ir ^deb /etc/apt/sources.list* | cut -d: -f1 | sort -u); do
    sed -i '\''s/^deb/#tmp#deb/g'\'' ${fn};
done'
PromptExec 'adjust deb entries in sources.list to include non-free and non-free-firmware' \
'sed -i '\''s/\(.*deb .*\) main .*$/\1 main contrib non-free non-free-firmware/g'\'' /etc/apt/sources.list'
PromptExec 'create a deb entry for the DVD deb files we just added' \
'echo "deb [trusted=yes] file:/usr/local/dvd-debs ./" | tee -a /etc/apt/sources.list'
PromptExec 'read the new apt source list' \
'apt update'
PromptExec 'install plasma desktop and network support for WiFi' \
'apt install -y apt-transport-https bash-completion git iptables task-kde-desktop network-manager plasma-nm vim'
PromptExec 'add bash completion to the default bash profile' \
'echo '\''
if [ -f /etc/bash_completion ]; then
    . /etc/bash_completion;
fi
'\'' >> /etc/bash.bashrc'
PromptExec 'remove comments that were blocking the deb entries' \
'for fn in $(grep -ir ^#tmp#deb /etc/apt/sources.list* | cut -d: -f1 | sort -u); do
    sed -i '\''s/^#tmp#deb/deb/g'\'' ${fn};
done'
PromptExec 'unmount the "USB-2 - Debian 12 DVD : debian-12.0.0-amd64-DVD-1.iso"' \
'umount /mnt'
PromptExec 'choose a username for the user to allow you to login to the plasma desktop' \
'read -r -p "Enter name of Proxmox Desktop user: " pmuname'
PromptExec 'create the user to allow you to login to the plasma desktop' \
'adduser ${pmuname}'
PromptExec 'put ${pmuname} in the sudo group to be a super user' \
'usermod --append --groups sudo ${pmuname}'
PromptExec 'put ${pmuname} in the netdev group to access the network settings' \
'usermod --append --groups netdev ${pmuname}'
PromptExec 'show the ${pmuname} groups' \
'groups ${pmuname}'
PromptExec 'snapshot the system with plasma, WiFi, and ${pmuname}' \
'zfs snapshot -r rpool/ROOT@haveNewUser'
PromptExec 'snapshot the data with plasma, WiFi, and ${pmuname}' \
'zfs snapshot -r rpool/data@haveNewUser'
PromptExec 'comment out the pve-enterprise.list' \
'sed -i '\''s/^\([^#]\)/# \1/g'\'' /etc/apt/sources.list.d/pve-enterprise.list'
PromptExec 'comment out the ceph.list' \
'sed -i '\''s/^\([^#]\)/# \1/g'\'' /etc/apt/sources.list.d/ceph.list'
PromptExec 'create the pve-no-subscription.list' \
'echo '\''deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription'\'' | tee /etc/apt/sources.list.d/pve-no-subscription.list'
PromptExec 'change the grub timeout to 2 seconds' \
'sed -i '\''/GRUB_TIMEOUT/ s/5$/2/'\'' /etc/default/grub'
PromptExec 'disable ipv6 in grub' \
'sed -i '\''/GRUB_CMDLINE_LINUX/ s/"$/ ipv6.disable=1"/'\'' /etc/default/grub'
PromptExec 'disable ipv6 in sysctl' \
'echo '\''net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
'\'' | tee /etc/sysctl.d/disable-ipv6.conf'
PromptExec 'setup the network interfaces' \
'echo '\''
auto lo
iface lo inet loopback

auto vmbr0
iface vmbr0 inet static
    address 10.11.12.1/16
    bridge-ports none
    bridge-stp off
    bridge-fd 0
    bridge-disable-mac-learning 1
'\'' | tee /etc/network/interfaces'
PromptExec 'setup routing.conf' \
'echo '\''net.ipv4.ip_forward=1'\'' | tee /etc/sysctl.d/routing.conf'
PromptExec 'load kernel parameters' \
'sysctl -p --system'
PromptExec 'enable nftables service' \
'systemctl enable nftables.service'
PromptExec 'setup nftables conf' \
'echo '\''#!/usr/sbin/nft -f
flush ruleset
table ip nat {
    chain postrouting {
        type nat hook postrouting priority 0;
        policy accept;
        masquerade
    }
}'\'' | tee /etc/nftables.conf'
PromptExec 'start nftables service' \
'systemctl start nftables.service'
PromptExec 'remove DVD directory from sources list' \
'sed -i '\''s/^.*dvd-debs.*$//g'\'' /etc/apt/sources.list'
PromptExec 'remove DVD deb directory' \
'rm -Rd /usr/local/dvd-debs'
PromptExec 'snapshot with plasma desktop and wifi' \
'zfs snapshot -r rpool/ROOT@plasmaWiFi'
PromptExec 'snapshot with plasma desktop and wifi' \
'zfs snapshot -r rpool/data@plasmaWiFi'
PromptExec 'reboot to proxmox installed with encrypted zfs, plasma desktop, and WiFi' \
'reboot'
 
Last edited:

About

The Proxmox community has been around for many years and offers help and support for Proxmox VE, Proxmox Backup Server, and Proxmox Mail Gateway.
We think our community is one of the best thanks to people like you!

Get your subscription!

The Proxmox team works very hard to make sure you are running the best software and getting stable updates and security enhancements, as well as quick enterprise support. Tens of thousands of happy customers have a Proxmox subscription. Get yours easily in our online shop.

Buy now!