After backing up (step 1) and unmounting (between 2 and 3), run fsck
to ensure that the filesystem is healthy:
e2fsck -f /dev/mapper/ExistingExt4
Other than that, the steps are OK.
Purpose of the cryptsetup resize
command
what should I choose for $SECTORS? Is this step even necessary?
This step is necessary, otherwise the partition would still show up at the old side. This is confirmed with Nautilus, even after resizing with resize2fs
, the LUKS partition showed up as the old size. After running cryptsetup resize
, the correct number is shown. This step is not necessary. It only affects the current size status as shown in the file browser. After changing the size and closing/opening the partition again, the number is restored. So, when closing the LUKS partition as shown later will make this obsolete.
$SECTORS
can be determined by looking at the output of cryptsetup status ExistingExt4
:
/dev/mapper/ExistingExt4 is active.
type: LUKS1
cipher: aes-cbc-essiv:sha256
keysize: 256 bits
device: /dev/sda2
sector size: 512
offset: 2056 sectors
size: 156049348 sectors
mode: read/write
(As of cryptsetup 2.0.0 (December 2017), the sector size may be larger than 512 bytes: see the cryptsetup(8)
manpage and the --sector-size
option.)
Thus, to subtract 15 GiB, use a sector size of 156049348 - 15 * 1024 * 1024 * 2 = 124592068
:
cryptsetup resize ExistingExt4 -b 124592068
Resizing the partition with parted
As for resizing the partition, parted
works fine with GPT partitions. The resize
command does not work however, as a workaround (or solution), remove the partition information and create a new partition as inspired by http://ubuntuforums.org/showthread.php?p=8721017#post8721017:
# cryptsetup luksClose ExistingExt4
# parted /dev/sda2
GNU Parted 2.3
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) unit s
(parted) p
Model: ATA INTEL SSDSA2CW08 (scsi)
Disk /dev/sda: 156301488s
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Number Start End Size File system Name Flags
1 34s 2082s 2049s Boot bios_grub
3 2083s 250034s 247952s ext2 RootBoot
2 250035s 156301438s 156051404s Everything
As 15 GiB has to be shaved off, the new end becomes 156301438 - 15 * 1024 * 1024 * 2 = 124844158
. Since I want to change partition 2, I first have to remove it and then recreate it with the label "Everything" (this could be changed if you like). Note: this disk has a GPT layout. For MBR, you should replace Everything
by primary
or extended
(untested, resizing a partition on MBR has not been tested and is not recommended because it is untested).
WARNING: the following commands has destroyed data. Do not copy it without understanding what is happening. The sector dimensions must be changed, otherwise you WILL destroy your partition(s). I am in no way responsible for your stupidness, BACKUP BACKUP BACKUP your data to a second storage medium before risking your data.
(parted) rm 2
(parted) mkpart Everything 250035s 124844158s
Warning: The resulting partition is not properly aligned for best performance.
Ignore/Cancel? ignore
(parted) p
Model: ATA INTEL SSDSA2CW08 (scsi)
Disk /dev/sda: 156301488s
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Number Start End Size File system Name Flags
1 34s 2082s 2049s Boot bios_grub
3 2083s 250034s 247952s ext2 RootBoot
2 250035s 124844158s 124594124s Everything
(parted) quit
In the above parted
example, my sectors are not aligned which is a mistake from an earlier installation, do not pay too much attention to it.
That is it! You can use cryptsetup status
and file -Ls /dev/...
to verify that everything is OK and then reboot.
The LUKS format has multiple key slots, each one may contain the encrypted master key that is used for data encryption. This master key is encrypted using another key which is derived from your passphrase.
Using plain hash_function(passphrase)
to generate a key would be dumb as hashes such as sha1 can be calculated fast (SHA-1 is an example of a MAC algorithm, for authentication of a message, not to be used as plain for a password).
For data encryption based on a passphrase, you want the function to be slow to thwart brute-force attacks. For this purpose, PBKDF2 (password-based key derivation function) is used (see the excellent answers on this Sec.SE question for motivations and other examples).
derivedKey = PBKDF2(hash_function, passphrase, salt, iterations, derivedKeyLen)
The hash_function for my installation is sha1 as is shown in cryptsetup --help
:
Default compiled-in key and passphrase parameters:
Maximum keyfile size: 8192kB, Maximum interactive passphrase length 512 (characters)
Default PBKDF2 iteration time for LUKS: 1000 (ms)
Default compiled-in device cipher parameters:
loop-AES: aes, Key 256 bits
plain: aes-cbc-essiv:sha256, Key: 256 bits, Password hashing: ripemd160
LUKS1: aes-xts-plain64, Key: 256 bits, LUKS header hashing: sha1, RNG: /dev/urandom
The derived key length depends on the cipher used for data encryption. The number of iterations depends on your processor speed.
These details can be found in the manual page of cryptsetup (pbkdf2 should ring a bell). For other security details, see the FAQ of cryptsetup.
Best Answer
It's about online resize.
For example if you use LVM, create a LV of 1G size, and put LUKS on that, it's like this:
So the LUKS device is about the same size as the VG-test device (1G minus 2MiB used by the LUKS header).
Now what happens when you make the LV larger?
The LV is 2G large now, but the LUKS device is still stuck at 1G, as that was the size it was originally opened with.
Once you
luksClose
andluksOpen
, it would also be 2G — because LUKS does not store a size, it defaults to the device size at the time you open it. So close and open (or simply rebooting) would update the crypt mapping to the new device size. However, since you can only close a container after umounting/stopping everything inside of it, this is basically an offline resize.But maybe you have a mounted filesystem on the LUKS, it's in use, and you don't want to umount it for the resize, and that's where
cryptsetup resize
comes in as an online resize operation.cryptsetup resize
updates the active crypt mapping to the new device size, no umount required, and then you can follow it up withresize2fs
or whatever to also grow the mounted filesystem itself online.If you don't mind rebooting or remounting, you'll never need
cryptsetup resize
as it happens automatically offline. But if you want to do it online, that's the only way.When shrinking (
cryptsetup resize --size x
), the resize is temporary. LUKS does not store device size, so next time you luksOpen, it will simply use the device size again. So shrinking sticks only if the backing device was also shrunk accordingly.For a successful shrink you have to work backwards... growing is grow partition first, then LUKS, then filesystem... shrinking is shrink filesystem first, and partition last.
If the resize doesn't work, it's most likely due to the backing device not being resized, for example the kernel may refuse changes to the partition table while the drive is in use. Check with blockdev that all device layers have the sizes you expect them to have.