Change root password on VM

At some point in time, I found myself in a need of changing KVM virtual machine's root password. When making experiments with a VM it's easy to mess things up (like firewall configuration) so the machine stops responding. In this cases, the only way to recover control over the VM is by connecting to it via VNC. But then, if you didn't setup a password for the user, and this is a pretty common situation with machines accessible only by SSH, you can't do anything even with VNC because you will not be able to log in at the console prompt.

Fortunately, you may setup (change) root's password if you have read/write access to system's drive image. Normally, for KVM, qcow2 format is used, so in this article, I will focus on how to do it using this kind of image file format.

First of all, you should stop the virtual machine.

$ virsh shutdown my-virtual-machine

Find out where is an image file located:

$ virsh dumpxml my-virtual-machine

From the command you will see an output similar to this one:

<!-- output omitted -->
<disk type='file' device='disk'>
  <driver name='qemu' type='qcow2'/>
  <source file='/var/lib/libvirt/images/my-virtual-machine.qcow2'/>
  <backingStore/>
  <target dev='hda' bus='ide'/>
  <alias name='ide0-0-0'/>
  <address type='drive' controller='0' bus='0' target='0' unit='0'/>
</disk>
<!-- output omitted -->

Just remember the file path, in this case, it is /var/lib/libvirt/images/my-virtual-machine.qcow2.

As a next step, you will need to mount this file somewhere, let's use /tmp/my-virtual-machine folder. You will find a full explanation of commands here. For instance, just execute the following commands (you may need to install qemu-nbd, in which case apt-get install qemu-utils):

# modprobe nbd max_part=63
# qemu-nbd -c /dev/nbd0 -P 1 /var/lib/libvirt/images/my-virtual-machine.qcow2
# mount /dev/nbd0 /tmp/my-virtual-machine

So, now you will find the contents of your VM's HDD at /tmp/my-virtual-machine. As you may know, on Linux systems the passwords are stored in /etc/shadow file. More info here. The important thing about this file is that all passwords are hashed and salted. That's why we are going to need openssl as a tool for generating it.

$ openssl passwd -1 -salt 123jkdfj4545090 my-secret-password

You may put whatever you want (ASCII characters only, please) as a salt parameter. This command will produce a string which is a valid password for /etc/shadow file. After this, you will need to go to /tmp/my-virtual-machine/etc/shadow and replace this string for root user between the first and the second colon. For example:

root:$6$eu3lXU8k$I6OhZfLOBYFDu3eiBv4xy4ED7aPvHFCdGCIFhUcMKKAQf7ouQi1XAILjFa9Y0PL5d.KUkpxXzR85FVlm0Mn1/.:16699::::::

As a last step perform an umount on your image file:

# umount /tmp/my-virtual-machine
# qemu-nbd -d /dev/nbd0

Now, you're ready to go, just spin up your VM and you should be good to login via terminal.