Proxmox Part 1 - Encrypted Installation
Encrypted Proxmox installation on top of clean Debian 12
Motivation
This article will closely follow the official Proxmox tutorial on installing Proxmox on a fresh Debian 12 installation.
Installing Debian
- Download the Debian installer ISO image and flash it onto a USB thumb drive.
- Boot your system from the USB drive and begin the installation process.
- When the “Installation Menu” appears, interrupt the process.
By default, the Debian installer attempts to use IP autoconfiguration and DHCP to obtain an IP address. We need to force it to use manual configuration instead.
- Press
e
to enter edit mode. - Add
netcfg/disable_autoconfig=true
to the linux boot command line. - Press
F10
to continue booting.
Follow the installation process, choosing your preferred settings until you reach the Network Configuration step. Here, configure your network interface with a static IP address, netmask, gateway, and DNS server address. I use Cloudflare DNS 1.1.1.1
on my installations for improved performance.
Proceed with the installation until you reach the Partition Disks section. Select the Manual partitioning method.
Delete all existing partitions on the disk intended for Proxmox installation. If you encounter errors related to existing LVM configurations, navigate to Configure the Logical Volume Manager and delete the volumes and groups.
Create the following partitions:
- EFI Partition: 512 MB, Use as: EFI System Partition.
- Boot Partition: 2 GB, Use as: ext4, Mount point:
/boot
and Mount options:noatime
- Encrypted Volume: 480 GB, Use as: physical volume for encryption, Erase data: no (this disk has never had anything sensitive on it)
Enter the “Configure encrypted volumes” section.
- Check “Yes” to write changes to disk.
- Choose “Create encrypted volumes.”
- Select the crypto device.
- On next screen, select “Finish.”
- Enter and confirm a strong encryption password.
Once the encrypted volume appears in the “Partition Disks” view, modify it:
- Use as: ext4
- Mount point:
/
- Mount options:
noatime
Finally:
- “Finish partitioning and write changes to disk.”
- Choose “no” when asked about configuring swap.
- Choose “yes” to write the changes to the disk.
For Software selection choose SSH server
and standard system utilities
.
Once installation is complete, reboot the system and remove installation media.
Configuring SSH for first connection
It’s more convenient to continue the installation from a remote machine, and SSH is the perfect tool for this. However, SSH employs a TOFU (Trust on First Use) authentication scheme, requiring us to verify the connection when connecting to an unknown endpoint for the first time. Furthermore, the default OpenSSH server configuration relies on password authentication which is vulnerable to man-in-the-middle attacks.
While it’s unlikely my network has any malicious actors waiting to exploit my devices, I try to prioritize security best practices whenever possible.
Log in as root on the Debian machine we just installed:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# Prepare the USB drive: (Skip steps 2 and 3 if you're not using the Debian installer USB)
# 1. Identify the USB drive with two partitions (/dev/sdb in my case)
lsblk
# 2. Create a new partition on the USB
fdisk /dev/sdb
n (new partition)
p (primary)
3 (next available partition number)
Press Enter to accept the default first sector.
Press Enter to use all remaining free space.
w (write changes and exit)
# 3. Format the new partition
mkfs.ext4 /dev/sdb3
# 4. Create a mount point and mount the partition
mkdir -p /mnt/usb
mount /dev/sdb3 /mnt/usb
# 5. Navigate to the mounted drive
cd /mnt/usb
# 6. Create an empty file for encrypted container (512 MB)
dd if=/dev/urandom of=filevault.img bs=1M count=512
# 7. Create LUKS volume within the empty file
cryptsetup --verify-passphrase luksFormat filevault.img
# 8. Open the LUKS volume and confirm it is visible in the system
cryptsetup open --type luks filevault.img keyvault
ls /dev/mapper
# 9. Create filesystem labeled as keyvault
mkfs.ext4 -L keyvault /dev/mapper/keyvault
# 10. Create mount point for the keyvault, mount it and navigate to the mounted folder
mkdir -p /media/keyvault
mount /dev/mapper/keyvault /media/keyvault
cd /media/keyvault
# 11. Retrieve and save the host key fingerprint
ssh-keygen -l -f /etc/ssh/ssh_host_ed25519_key >> host_fingerprint.txt
# 12. Generate SSH keys (Use a strong password)
ssh-keygen -t ed25519 -f vault_key
# 13. Create the SSH configuration folder for the non-admin user
mkdir /home/tanezky/.ssh
# 14. Copy the public key to the user's authorized_keys file
cat vault_key.pub >> /home/tanezky/.ssh/authorized_keys
# 15. Give the user permissions to .ssh folder and files
chown -R tanezky:tanezky /home/tanezky/.ssh/
# 16. Finally, exit the folder and unmount drive.
cd /
umount /media/keyvault
cryptsetup close keyvault
umount /mnt/usb
First SSH Connection
Connect the USB drive to your PC and move filevault.img
on your hard drive.
On my Gnome Desktop I can mount the filevault via double clicking the file. After entering the password it is mounted.
How-to in shell:
1
2
3
4
5
6
7
8
# 1. Open the LUKS container
sudo cryptsetup open --type luks filevault.img keyvault
# 2. If not existing, create location for the mount point
sudo mkdir -p /media/keyvault
# 3. Mount
sudo mount /dev/mapper/keyvault /media/keyvault
Finally, connect to the device with SSH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 1. Navigate to the mounted location or open a new terminal in that folder
cd /media/keyvault
# 2. List files, there should be vault_key and vault-fingerprint.txt
ls
lost+found vault-fingerprint.txt vault_key vault_key.pub
# 3. Print contents of vault-fingerprint.txt
cat vault-fingerprint.txt
256 SHA256:h+YtATVdtGddY5c3hCM9Negu+rS/pKrpliXI/Lg7s2U root@aurum-vault (ED25519)
# 4. Create SSH connection using vault_key
ssh -i vault_key tanezky@10.42.42.150
The authenticity of host '10.42.42.150 (10.42.42.150)' can't be established.'
ED25519 key fingerprint is SHA256:h+YtATVdtGddY5c3hCM9Negu+rS/pKrpliXI/Lg7s2U.
This key is not known by any other names.
# 5. Copy paste the SHA256 fingerprint from step 3
Are you sure you want to continue connecting (yes/no/[fingerprint])? SHA256:h+YtATVdtGddY5c3hCM9Negu+rS/pKrpliXI/Lg7s2U
Warning: Permanently added '10.42.42.150' (ED25519) to the list of known hosts.
# 6. Enter password for the vault_key
Enter passphrase for key 'vault_key':
# 7. Login complete
Linux aurum-vault 6.1.0-23-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.99-1 (2024-07-15) x86_64
The programs included with the Debian GNU/Linux system are free software;
...
Make SSH easier
Typing the full ssh command with the key file every time can get tedious. To streamline this, it’s a good idea to create a configuration file that simplifies future connections.
1
2
3
4
5
6
7
8
9
10
11
12
13
# Edit the local SSH config file on your PC
~/.ssh/config
# Add following content with your details
Host vault
HostName 10.42.42.150
User tanezky
IdentityFile /media/keyvault/vault_key
LogLevel INFO
Compression yes
# Making connection is now much more straightforward
ssh vault
Installing Proxmox
Ensure /etc/hosts
does not have 127.0.1.1
in it and the hostname is allocated with IP address
1
2
3
4
5
6
7
8
9
10
11
12
# Become root, enter root password which was given during debian installation
su -
# Check /etc/hosts to be similar as below, edit if necessary
cat /etc/hosts
127.0.0.1 localhost
10.42.42.150 aurum-vault.proxmox.com aurum-vault
# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
Repository
Add the Proxmox VE repository to apt sources
1
echo "deb [arch=amd64] http://download.proxmox.com/debian/pve bookworm pve-no-subscription" > /etc/apt/sources.list.d/pve-install-repo.list
Add Proxmox VE repository key
1
2
3
4
5
6
7
wget https://enterprise.proxmox.com/debian/proxmox-release-bookworm.gpg -O /etc/apt/trusted.gpg.d/proxmox-release-bookworm.gpg
# Verify checksum of the repository key
echo "7da6fe34168adc6e479327ba517796d4702fa2f8b4f0a9833f5ea6e6b48f6507a6da403a274fe201595edc86a84463d50383d07f64bdde2e3658108db7d6dc87 /etc/apt/trusted.gpg.d/proxmox-release-bookworm.gpg" | sha512sum -c
# Should output:
/etc/apt/trusted.gpg.d/proxmox-release-bookworm.gpg: OK
Sources and Packages
Update sources, run full-upgrade, install Proxmox VE kernel and reboot
1
apt update && apt full-upgrade -y && apt install -y proxmox-default-kernel && systemctl reboot
After reboot install Proxmox VE packages
1
apt install -y proxmox-ve postfix open-iscsi chrony
For Postfix Configuration I chose No configuration since I don’t have a mail server.
Cleanup
Remove Debian kernel, unnecessary packages, update grub and remove subscription repository
1
2
3
4
5
6
7
8
# Remove kernel and unnecessary packages
apt remove -y linux-image-amd64 'linux-image-6.1*' os-prober
# Update grub and check its config
update-grub
# Remove pve-enterprise.list (don't remove unless you have subscription)
rm /etc/apt/sources.list.d/pve-enterprise.list
Finalising Setup
Last thing on the list is to add network bridge, for time being I’m going to use default configuration.
More information on Proxmox Network configuration on their wiki page.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# Change /etc/network/interfaces from this:
....
source /etc/network/interfaces.d/*
auto lo
iface lo inet loopback
auto enp2s0
iface enp2s0 inet static
address 10.42.42.150/24
gateway 10.42.42.1
dns-nameservers 1.1.1.1
# dns-* options are implemented by the resolvconf package, if installed
iface enp1s0 inet manual
# To look something like this:
...
source /etc/network/interfaces.d/*
auto lo
iface lo inet loopback
iface enp2s0 inet manual
auto vmbr0
iface vmbr0 inet static
address 10.42.42.150/24
gateway 10.42.42.1
bridge-ports enp2s0
bridge-stp off
bridge-fd 0
# dns-* options are implemented by the resolvconf package, if installed
iface enp1s0 inet manual
# Reboot the system after the bridge configuration is created
systemctl reboot
Admin Web-interface
Installation is complete, it’s time to start using the new setup.
Go to admin web-interface https://10.42.42.150:8006
Use your root
credentials and Realm: Linux PAM standard authentication