Eric’s Substack

Share this post

Automatically Revert ESXi VM Snapshot on a Schedule

blog.ecapuano.com

Discover more from Eric’s Substack

I write about all things information security, security operations, digital forensics & incident response, and some miscellaneous in between.
Over 4,000 subscribers
Continue reading
Sign in
General Technology

Automatically Revert ESXi VM Snapshot on a Schedule

Eric Capuano
Feb 8, 2023
Share this post

Automatically Revert ESXi VM Snapshot on a Schedule

blog.ecapuano.com
Share

Why is this useful?

Let’s say you have a VM that you use for unsavory things like malware analysis and you would like to automatically revert it on a scheduled basis. There are many ways to go about this manually, but for my particular use-case, I wanted it done automatically everyday at 3AM.

While this can be accomplished a few different ways such as non-persistent disks, I found the snapshot revert method ideal for me because the machine stays up and on at all times except the brief moment the snapshot is being restored.

Great, just tell me how to do it!

In my example, I am using standalone ESXi 6.7 (no vCenter). There is a VM running that has a single snapshot called “Clean”. Of course, one could use the ESXi WebUI to revert the snapshot at will, but in order to get it to revert automatically on a schedule, I scripted up the following tasks in ESXi CLI and created a cronjob.

  1. Snapshot your VM in the WebUI

  2. SSH to the ESXi server and run the following commands:

    1. Get your target VM ID with this command:

      1. vim-cmd vmsvc/getallvms

    2. Learn the snapshot ID of your VM with this command:

      1. vim-cmd vmsvc/get.snapshotinfo [VM_id]

    3. Create a cronjob that reverts this VM everyday at 3AM (customize as neccesary)

      1. Backup existing crontab

        1. cp /var/spool/cron/crontabs/root /var/spool/cron/crontabs/root.old

      2. Edit running crontab

        1. vi /var/spool/cron/crontabs/root

      3. Add the new job on the last line, this job runs everyday at 3AM. The 0 at the end is to ensure the VM stays powered on after the snapshot is restored.

        1. * 3 * * * /bin/vim-cmd vmsvc/snapshot.revert [VM_id] [snapshot_id] 0

      4. Restart cron service (yes, this is a odd way of doing it, but ESXi is weird like that)

        1. PID=$(cat /var/run/crond.pid)

          echo "Old cron PID was $PID"

          kill $PID

          /usr/lib/vmware/busybox/bin/busybox crond
          PID=$(cat /var/run/crond.pid)

          echo "NEW cron PID is $PID"

      5. And you’re set! Your VM will now revert to the snapshot everyday at 3AM.

Ok so now your VM will revert to this snapshot everyday at 3AM, but what happens if you create a new snapshot and want the cron to use the new snapshot ID? Luckily, I crafted a little script that will ensure that your latest snapshot ID is always used by the cron.

NOTE: This script only works if there is ONE snapshot for the VM. Multiple snapshots will break it.

The script:

#/bin/bash
# NOTE: This script only works if there is ONE snapshot for the VM.
# Multiple snapshots will break it.

# BE SURE TO CHANGE VM_id TO YOUR VM's ID!
VM_id=33

# get snapshot ID for VM
SNAPSHOTID=$(vim-cmd vmsvc/get.snapshotinfo $VM_id | grep id | egrep -o '[0-9]+')

# edit cron to reflect new snapshot id

sed -ri "s/$VM_id [0-9]+ 0/$VM_id $SNAPSHOTID 0/" /var/spool/cron/crontabs/root

# restart crond
PID=$(cat /var/run/crond.pid)
echo "Old cron PID was $PID"
kill $PID
/usr/lib/vmware/busybox/bin/busybox crond
PID=$(cat /var/run/crond.pid)
echo "NEW cron PID is $PID"
echo "New crontab contents:"
cat /var/spool/cron/crontabs/root

Now that we have a script that can automatically update the crontab when a new snapshot ID exists, we can use another cronjob to make sure this happens before the snapshot revert happens.

  1. Edit running crontab

    1. vi /var/spool/cron/crontabs/root

  2. Add the new job on the last line, you want this job to run before the revert job runs. This job runs everyday at 2AM.

    1. * 2 * * * /path_to_above_script.sh

  3. Restart cron service

    1. PID=$(cat /var/run/crond.pid)

      echo "Old cron PID was $PID"

      kill $PID

      /usr/lib/vmware/busybox/bin/busybox crond
      PID=$(cat /var/run/crond.pid)

      echo "NEW cron PID is $PID"

  4. And you’re set! Your VM will now revert to the snapshot everyday at 3AM, even if you delete and recreate a new snapshot!

Thanks for reading Eric’s Substack! Subscribe for free to receive new posts and support my work.

Share this post

Automatically Revert ESXi VM Snapshot on a Schedule

blog.ecapuano.com
Share
Comments
Top
New
Community

No posts

Ready for more?

© 2023 Eric Capuano
Privacy ∙ Terms ∙ Collection notice
Start WritingGet the app
Substack is the home for great writing