Automatically backup your complete Linux system when connecting to a specific wifi network

published:

I have a local server in my office, and use my laptop via wifi. When I arrive at the office and my laptop connects to the wifi, it will stay on for multiple hours, so it is the perfect time to make an automatic backup.

This consists of two scripts: one shell script that runs rsync, and a script for the NetworkManager that starts the first script as soon as I connect to the office wifi network. The first script can also be called directly via the command line, if I want to manually start a backup.

Backup Script

The /home/mh/bin/backup-system.sh file looks like this:

#!/bin/bash

SOURCE_FOLDER="/.snapshots/"
TARGET_FOLDER="server-hostname:/srv/path/to/backups/"

RSYNC_FLAGS="aAXH"
ADDITIONAL_RSYNC_FLAGS="--bwlimit=10000 --delete-after --exclude=/.snapshots --exclude=/dev/* --exclude=/proc/* --exclude=/sys/* --exclude=/tmp/* --exclude=/run/* --exclude=/mnt/* --exclude=/lost+found --exclude=/swap --exclude=/home/*/.thumbnails/* --exclude=/home/*/.cache/*  --exclude=/home/*/.local/share/Trash/*  --exclude=/home/*/.gvfs --exclude=/var/lib/dhcpcd/* --exclude=/var/spool/postfix/dev/*"
# --bwlimit=10000 limits the network (value ist KBps) -- 10000 is 0,08


# make sure we are not running already:
if [[ "`pidof -x $(basename $0) -o %PPID`" ]]; then
	echo "["$(basename $0)"]"
	echo "This script is already running with PID `pidof -x $(basename $0) -o %PPID`"
	exit
fi

# make sure we run as root
if [[ $(id -u) -ne 0 ]] ; then
	echo "Please run as root"
	exit 1
fi

VERBOSE=false
while getopts ":v" opt; do
	case $opt in
		v)
			echo "verbose mode is on"
			VERBOSE=true
			;;
		\?)
			echo "invalid option: -$OPTARG" >&2
			;;
	esac
done


if [ "$VERBOSE" = true ]; then
	echo "starting rsync backup .."
fi


NEWEST_SNAPSHOT=$(ls -td $SOURCE_FOLDER*/ | head -1)

SOURCE_FOLDER=$NEWEST_SNAPSHOT"snapshot/"

if [ "$VERBOSE" = true ]; then
	echo "source folder is "$SOURCE_FOLDER
fi


if [ "$VERBOSE" = true ]; then
	RSYNC_FLAGS+="v"

	echo "using rsync flags -"$RSYNC_FLAGS" "$ADDITIONAL_RSYNC_FLAGS
fi


rsync -$RSYNC_FLAGS $ADDITIONAL_RSYNC_FLAGS "$SOURCE_FOLDER" "$TARGET_FOLDER"

if [ "$VERBOSE" = true ]; then
	echo ".. rsync backup finished"
fi

exit 0

The script can manually be started via sudo backup-system.sh -v - the -v flag runs the script in verbose mode and displays more information, omitting it will only show rsync errors. It needs to be run as sudo, because this will backup the complete root directory and needs corresponding permissions.

Because I use btrfs, and it automatically takes a snapshot every hour, I backup the latest snapshot, and not the live root directory (this helps with vanishing files), but you can update the script to not look for the NEWEST_SNAPSHOT and just use the SOURCE_FOLDER for the rsync source.

NetworkManager autostart script

The NetworkManager has a dispatcher script, that gets called when a wifi network gets connected, and checks the wifis SSID. If it is the correct SSID, it automatically starts the backup-system.sh script.

The script is saved at /etc/NetworkManager/dispatcher.d/50-system-backup and looks like this:

#!/bin/bash

INTERFACE=$1
ACTION=$2

ESSID_OFFICE="The SSID of my office wifi network"

# find SSID of connected wifi:
ESSID=`iwconfig $INTERFACE | grep ESSID | cut -d":" -f2 | sed 's/^[^"]*"\|"[^"]*$//g'`

case "$ACTION" in
	up)
		if [ "$ESSID" = "$ESSID_OFFICE" ]; then
			/home/mh/bin/backup-system.sh
		fi
		;;

	down)
		;;

	pre-up)
		;;

	post-down)
		;;

	*)
		echo $"Usage: $0 {up|down|pre-up|post-down}"
		exit 1
esac

----------
Have a comment? Drop me an email!