This is the configuration I have used to set up home PCs to be resistant to the kinds of bugs and malware and spyware that seem to get installed over time on a windows PC. This is in combination with using limited accounts for everyone who uses the PC.
The quick overview is:
- Partition hard disk into 3 partitions:
- 1st: Windows C: drive (this is the smallest and is the partition to be "frozen")
- 2nd: Windows D: drive (an NTFS partition that can be used to store persistent data and shared with Linux)
- 3rd (and maybe 4th and 5th): Ubuntu installation that may include multiple partitions for linux swap, etc. This is where snapshots of C: drive are stored (though the 2nd partition could be used as well)
- Install Operating Systems: First windows (setting up C: and D: partitions), then ubuntu, choosing the "install alongside windows" option.
- Create the first snapshot of C: drive
- Create scripts and grub configuration so that windows is the default operating system and each reboot uses an imaging tool to restore the snapshot of the C: drive.
I used rufus for creating a windows installer usb from a CD for computer with no CD drive.
- Delete all partitions
- Create c: NTFS partition with 30G
- Create d: NTFS partition with 50G
- Leave the rest alone for ubuntu
- Install windows on C:
- Use ubuntu usb or cd to install to remaining partition. Choose to install alongside windows. Accept all the defaults
Here is a step by step guide to setting up snapshots. It makes some assumptions about which partition windows is on and which version of ubuntu is used. Everything here should work if windows C: drive corresponds to /dev/sda1 in linux and if ubuntu is version 14.04. If that is the case, you can avoid all the following steps by just downloading and running the following script in ubuntu: https://gist.githubusercontent.com/saltlakeryan/ecd4cea06573681044d5/raw/setup-snapstates.sh
- Customize grub boot options:
- set windows as default boot option
- create new menu option called "Restore Windows"
- edit kernel flags to end with "xcmd=restore 1" (the xcmd=restore is arbitrary flag to use in restore script later, the "1" is single user mode)
- Accomplish the above by editing /etc/grub.d/40_custom as follows. The assumptions made are that the windows menu entry that was created during ubuntu install is called "Microsoft Windows XP Professional (on /dev/sda1)" and that linux was installed on /dev/sda5. Also, vmlinuz-3.13.0-32-generic and initrd.img-3.13.0-32 are OS specific. If using a different version of ubuntu, those file names may need to be updated :
#!/bin/sh
exec tail -n +3 $0
# This file provides an easy way to add custom menu entries. Simply type the
# menu entries you want to add after this comment. Be careful not to change
# the 'exec tail' line above.
menuentry 'Restore Windows' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'win-restore' {
load_video
gfxmode $linux_gfx_mode
insmod gzio
insmod part_msdos
insmod ext2
set root='hd0,msdos5'
linux /boot/vmlinuz-3.13.0-32-generic root=/dev/sda5 ro xcmd=restore 1
initrd /boot/initrd.img-3.13.0-32-generic
}
if [ -z "${need_restore}" ]; then
set need_restore="yes"
save_env need_restore
set default="Microsoft Windows XP Professional (on /dev/sda1)"
else
set need_restore=
save_env need_restore
set default="Restore Windows"
fi
-
run: sudo update-grub
-
Install partclone to create initial backup
sudo su
apt-get install partclone
- Use backup script to create initial backup. Replace /root/backup-windows.sh with the following:
#!/bin/bash
set -e
mkdir -p /var/backups
BACKUPDATE=`date +%Y-%m-%d_%H_%M_%S`
BACKUPNAME="sda1_$BACKUPDATE.partclone.img.gz"
partclone.ntfs -c -d -F -L /var/log/partclone.log -s /dev/sda1 | gzip -c --fast > /var/backups/$BACKUPNAME
rm -f /var/backups/windows-pristine.img.gz
ln -s /var/backups/$BACKUPNAME /var/backups/windows-pristine.img.gz
- Run the backup script
sudo /root/backup-windows.sh
I found that occassionally the "recordfail" grub environment would cause the default boot menu item to change. If this happens, you can fix it with the following:
Change /etc/grub.d/00_header: from 'if [ "${recordfail}" = 1 ] ; then' to 'if [ 0 -eq 1 ] ; then'
then run 'sudo update-grub' in order to keep that if clause from ever executing.
Append to /root/.bashrc the following:
cat /proc/cmdline | grep 'xcmd=restore'
if [ $? -eq 0 ]
then
echo "restore mode"
~/restore-windows.sh
fi
Replace /root/restore-windows.sh with the following (make sure file is executable by root afterwards -- eg. sudo chmod 755 /root/restore-windows.sh):
#!/bin/bash
main() {
display_warning
read -p "Do you want to restore windows to original backup? Type 'yes' if so. " yesno
case $yesno in
yes ) restore;;
* ) echo "Not restoring";;
esac
}
restore() {
echo "Restoring with command (in 5 seconds):"
echo "cat /var/backups/windows-pristine.img.gz | gzip -d -c | partclone.restore -F -L /var/log/partclone-restore.log -O /dev/sda1"
sleep 5
cat /var/backups/windows-pristine.img.gz | gzip -d -c | partclone.restore -F -L /var/log/partclone-restore.log -O /dev/sda1
}
display_warning() {
clear
cat <<EOF
***************************************
* WARNING: *
* About to restore windows to backed *
* image. You may lose data. *
* *
* Press CTRL + C to stop *
***************************************
EOF
}
main
reboot
If you want to go crazy and restore on every reboot, you can modify the grub config so that the grub environment contains a variable that toggles between true and false every boot. Then you use that variable to decide to either boot into windows or boot into the "Restore Windows" boot option we created. Here are the steps you would take to create this setup:
Edit /boot/grub/grub.cfg
- before load_env is called, set the toggling parameter to a default value. Example:
...
set need_restore="yes"
if [ -s $prefix/grubenv ]; then
set have_grubenv=true
load_env
fi
...
- after all other logic for setting the default menu item (look for "set default=..."), add if statement to use the toggling parameter to boot into the restore mode every other boot. Example:
...
if [ -z "${need_restore}" ]; then
set need_restore="yes"
save_env need_restore
else
set need_restore=
save_env need_restore
set default="Restore Windows"
fi
...
Inevitably, you'll want to update the windows image. In that case, just make your updates, reboot into plain ubuntu and run the backup script again (/root/backup-windows.sh). Of course, you could make another boot menu item that does this for you.
These posts were useful in figuring this out:
http://askubuntu.com/questions/317352/the-grub-can-be-scheduled-this-means-changing-default-entry-auto-login-at/323516#323516
http://unix.stackexchange.com/questions/70620/use-boot-parameter-to-perform-certain-actions-after-boot