WARNING:
- Just because I am mentioning Debian/Ubuntu Linux in my rant, it does not mean the RedHat-derived distros are guilty free. In fact, I am looking at you, Fedora. The reason I am mentioning the Debian-derived distros are because
The principle of my rant still remains, and is really not as security- or privacy-oriented as the other blog posts.
- Kali is built on Debian.
- I usually run an ubuntu derivative desktop Linux in my laptop.
- This post will be a bit more technical than the usual, and will not take the time to explain certain things or this will become a book. There are other shows to watch.
Like many, I have Kali Linux installed in a virtual machine I use for things. Given the requirements in their install page, which said
On the higher end, if you opt to install the default Xfce4 desktop and the kali-linux-default metapackage, you should really aim for at least 2 GB of RAM and 20 GB of disk space.I thought it was fine building a vm following those specs to run Kali. The memory I was not that concerned because adding more to a KVM vm guest is pretty easy (provided you have some to spare). But we are not talking about how to build a Kali vm guest; there are a lot of blogs and websites claiming to provide "everything you need to know about" how to do the deed, where the everything keyword means "we will rush through it but pretend we are experts." Am I being an arrogant bastard? Quite possibly, so let's jump to an example.
The problem
I am kinda of particular about the partition layout I use. In fact, let's take a quick look at my desktop (where I am typing this right now):
Device Start End Sectors Size Type /dev/sda1 2048 2099199 2097152 1G Linux filesystem /dev/sda2 2099200 3147775 1048576 512M EFI System /dev/sda3 3147776 212862975 209715200 100G Linux LVM
Those whith sharp eye noticed I have made the partition for that FAT offspring, EFI, which is way larger than needed. Call me lazy. What you may not be aware is that this is a 1TB (in Subway sandwich math; it really is 931.53 (GiB) if we use powers of 2 just like C'Thulu intended us to do) drive. In other words, I did not create a partition that ranges the entire disk as I found to be the default in most Linux installations, specially desktops. You know, because everyone installs the OS such that to use the entire drive. Who would do anything else?
Next you will notice there are 3 partitions:
- /dev/sda1, which is the /boot
- /dev/sda2, which is the already-mentioned EFI
- /dev/sda3, which is a LVM physical volume for everything else.
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert home desktop -wi-ao---- 30.00g root desktop -wi-ao---- 4.00g swaphole desktop -wi-ao---- 10.00g usr desktop -wi-ao---- 11.00g var desktop -wi-ao---- 6.00g
At this point in time someone on the back of the room will shout "Heresy! Separating partitions in their own filesystems is an outdated concept! You should use a single partition! On the top of that you are not using the entire volume group!" Hey, I said I was an arrogant bastard earlier on. Besides, this is my computer. Fear not, for the next paragraphs will justify the heresy claim even better.
For my kali vm guest, I started with a 20GB virtual disk based on the installation page's notes as mentioned above. At the time I decided to let it set the partition table the way it wanted, and here it is
Device Boot Start End Sectors Size Id Type /dev/vda1 * 2048 39942143 39940096 19G 83 Linux /dev/vda2 39944190 41940991 1996802 975M 5 Extended /dev/vda5 39944192 41940991 1996800 975M 82 Linux swap / Solaris
It created two primary partitions: one for the OS and one that is there just to create an extended partition to put the swap. Riddle me this: why in a 2-partition drive do we need to use the MBT extended partition? Are we close to running out of partitions that we need to reach for that gimmick? Before you answer, remember my 3-partition layout works fine with that style of partition table. Bottom line is the default installation created two partitions to do the job of a single way. Brilliant!
Let's get to where the fun really is: realistically 20GB for Kali is very limiting at best. If you start colleting a few (sizeable) pcaps or grab a binary file or two to inspect (temp files do add up), you may have maxed it out. That happened to me, combined with forgetting to periodically clean the package cache and getting some bits and bobs for metasploit. And all of this happened when I was on the clock.
Brilliant!
If we use the partition layout I like, I would then resize the drive and extend the PV and then the VG. problem solved. Not so here, thanks to that extended partition that is sitting right in the way. The best I could do was to increase the size of the drive as before, then add another partition at its end:
Device Boot Start End Sectors Size Id Type /dev/vda1 * 2048 39942143 39940096 19G 83 Linux /dev/vda2 39944190 41940991 1996802 975M 5 Extended /dev/vda3 41940992 62914559 20973568 10G 83 Linux /dev/vda5 39944192 41940991 1996800 975M 82 Linux swap / Solaris
Since I did not use lvm on this setup, I would have to decide which directory to move to the new partition, which then leads us to the problem the default install wanted to avoid in the first place. And, we now have a drive whose partition table looks convoluted (the adjective I had in my mind was different, but I decided to find a more polite one) and hard to maintain. At this point the only logical thing to do is blow everything up and redo it with a larger disk.
Brilliant!
And this kind of shenaningans are not only limited to the Kali install; installing the OS in my latop has been even more frustrating, but I will save that to another post.
Is there a better way to solve this problem? Well, it requires some heretic maneuvers, which is why I like it.
The solution
By now we should accept we need to move at least one directory tree out of /dev/vda1 I decree it shall be /home, but where should we put it? I will not extend /dev/vda and add another partition there, so what if we create a second virtual drive? Some of the reasons:
- It moves a directory tree that can become quite large out of the root drive.
- Even if you did not use a LVM, which in this case I did not, you can still resize that drive and that partition, without much work.
- If you need to move files between your kali vm guest and the host, you can shoot the vm down and then mount this second disk. This way there is no programs -- malicious or not -- running in the vm gues and you do not need to create a (exploitable) network connection between the host and guest.
- If you decide to blow up you kali install, your work is preserved.
- You can handle /home to somebody else without worrying about compromising your kali passwords.
Enough talk. Here are the steps. I will try to make them as generic as I can but understand most of the time I not only use KVM but also do it from the command line, and on a Linux box. So, if you are doing this from a Mac or a Windows computer, the commands will differ from mine. I am also rushing through the permissions since I assume you know how to set them up so your disk image can be read by your vm. You have been warned.
- Shut the vm guest down. Yes, I know how to add a drive to a running vm -- I do that all the time when I have to do forensics -- but it is much easier and safer if you do not need to upset the virtual machine.
- Create the virtual drive you will use for /home. How big? Up to you. The one I created for my kali vm is 20GB (as close to real disk size units as I can). Remember to put it in a sane location, be it inside the directory where the other vm files are, a place such as /home/user/.local/share/libvirt/images/, or some other secure place. For this example I am using /export/vm.
user@vmhost:~# VMNAME=kalinuts user@vmhost:~# qemu-img create -f qcow2 /export/vm/${VMNAME}.qcow2 20G Formatting '/export/vm/kalinuts.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=21474836480 lazy_refcounts=off refcount_bits=16 user@vmhost:~#
Most people will use qcow2 in KVM because its a sparse disk image (most may not be aware of that) and it is the default (duh!). If you use VirtualBox or VMWare or whatever, chances are the default disk format (vdi) will work fine; check if it can be resized to be sure. If not, find the virtual disk type that can.
Remember we said it is a sparse disk image? Here is proof:
user@vmhost:~# ls -lh /export/vm/kalinuts.qcow2 -rw-r--r-- 1 user user 193K Mar 2 09:51 /export/vm/kalinuts.qcow2 user@vmhost:~#
- Format the drive. Note that I did not say partition it.
user@vmhost:~# mkfs.ext4 /export/vm/kalinuts.qcow2 mke2fs 1.46.2 (28-Feb-2021) Filesystem too small for a journal Discarding device blocks: done Creating filesystem with 192 1k blocks and 24 inodes Allocating group tables: done Writing inode tables: done Writing superblocks and filesystem accounting information: done user@vmhost:~#
- Not needed step: I mounted it just to show I can mount the drive from the vm host side, since this is one of the claims I made ealier on.
root@vmhost:~# mount /export/vm/kalinuts.qcow2 /mnt root@vmhost:~# df -h|grep /mnt /dev/loop0 183K 14K 157K 9% /mnt root@vmhost:~# ls /mnt lost+found root@vmhost:~#
Don't forget to unmount it before going to the next step.
- Now add the drive to your kali/whatever vm. If you have a GUI, click on things. For KVM, there is also a GUI and some command line ways. The bottom line is that you want something like this in your devices session (adjust path and target device names to fit your local setup):
<disk type='file' device='disk'> <driver name='qemu' type='qcow2' iommu='on'/> <source file='/export/vm/kalinuts.qcow2'/> <target dev='vdb' bus='virtio'/> </disk>
When you save the config file, it will autofill the rest of the info such as where in the kali vm pci chain this disk will reside.
- Boot the kali vm and verify it can see the drive. I use dmesg or either fdisk -l or parted -l to see if it was mounted.
- While in the kali vm, become root user so you stop messing with /home
- Mount the new drive somewhere such as /mnt
- Move the contents from /home to /mnt. Remember: if this does not work you still have the files so you can move them back. Also, we are doing all this work to move all the junk in /home off the boot disk.
- Unmont the new drive from /mnt and configure the /etc/fstab so it will mount on /home (bolt line in the /etc/fstab file shown below)
# /etc/fstab: static file system information. # # Use 'blkid' to print the universally unique identifier for a # device; this may be used with UUID= as a more robust way to name devices # that works even if disks are added and removed. See fstab(5). # # systemd generates mount units based on this file, see systemd.mount(5). # Please run 'systemctl daemon-reload' after making changes here. # #
# / was on /dev/vda1 during installation UUID=iisaw-something-under-my-armpit / ext4 errors=remount-ro 0 1 # swap was on /dev/vda5 during installation UUID=do-you-like-vogon-poetry none swap sw 0 0 /dev/sr0 /media/cdrom0 udf,iso9660 user,noauto 0 0 /dev/vdb /home ext4 defaults 0 2 - Reboot it and verify it is using the new drive. If not, correct the issue.
- Get a cold beer.
What about resizing the drive?
- Shut the vm down again.
- Resize the drive, maybe adding another 10G
qemu-img resize /export/vm/kalinuts.qcow2 +10G
- Boot the vm.
- From inside the vm, resize the partition. Since I used ext4, I can do
resize2fs /dev/vdb
- Enjoy the larger /home.
Fun fact: I normally use raw drives, but most of the steps are the same; I just need to have a different <drive></drive> definition.