Skip to content

Instantly share code, notes, and snippets.

@lionep
Created June 15, 2024 14:21
Show Gist options
  • Save lionep/4dd6478ddd207b38ee47e48ea6be4813 to your computer and use it in GitHub Desktop.
Save lionep/4dd6478ddd207b38ee47e48ea6be4813 to your computer and use it in GitHub Desktop.
Systemd / udev offline backup script
ACTION=="add", ENV{ID_PART_ENTRY_UUID}=="0b8e6986-ec09-8e44-b31f-38e944220a66", TAG+="systemd", ENV{SYSTEMD_WANTS}="offline-backup-connected.service"

Purpose

Script to copy a backup to external usb harddrive for a 3-2-1+ backup strategy.
The USB disk being disconnected most of the time make it secure for remote attacks.

Tested on debian 12

udev rules is located at /usr/lib/udev/rules.d/97-offline_backup.rules

0b8e6986-ec09-8e44-b31f-38e944220a66 is the partition ID, it can be get by ls -l /dev/disk/by-uuid/

systemd file is located at /usr/lib/systemd/system/offline-backup-connected.service

shell script is located at /root/scripts/on_usb_connected.sh (chould be owned by root:root and chmod 700)

[Unit]
Description=USB Connected - Offline backup
[Service]
Type=oneshot
ExecStart=/root/scripts/on_usb_connected.sh
User=root
Group=root
[Install]
WantedBy=multi-user.target
#!/bin/bash
DEST=@SLACK_USERNAME
TOKEN=SLACK_TOKEN
VENDOR_ID=aaaa # from lsusb
PRODUCT_ID=aaaa # from lsusb
MOUNT_TARGET=/mnt
PART_UUID=XXXX-XXXXX-XXXX-XXXX # from /usr/bin/lsblk --list --output NAME,FSSIZE,FSTYPE,FSUSED,FSUSE%,FSVER,UUID,GROUP,LABEL,TYPE,VENDOR
sendMessage () {
/usr/bin/curl -H 'Content-Type: application/json' -d '{"text": "'"$1"'", "channel": "'$DEST'"}' -H "Authorization: Bearer $TOKEN" -X POST https://slack.com/api/chat.postMessage -q > /dev/null 2>&1
}
sync () {
/usr/bin/rsync -avP -e 'ssh -i /root/scripts/id_rsa_backup' user@SERVER:/remoteLocation $MOUNT_TARGET/backups/
result=$?
if [[ "$result" != "0" ]]; then
sendMessage "An error occurred while doing rsync..."
else
sleep 5
/usr/bin/umount $MOUNT_TARGET
sendMessage "Done. USB Can be disconnected."
fi
}
# sendMessage "Test 1"
res=$(/usr/bin/lsusb -d $VENDOR_ID:$PRODUCT_ID)
found=$?
if [[ "$found" != "0" ]]; then
/usr/bin/echo "USB Device not detected"
exit -1
else
/usr/bin/echo "USB Device detected"
fi
DEVICES=$(/usr/bin/lsblk --list --output NAME,FSSIZE,FSTYPE,FSUSED,FSUSE%,FSVER,UUID,GROUP,LABEL,TYPE,VENDOR | grep $PART_UUID)
MATCHING_PART=$(/usr/bin/echo "$DEVICES" | cut -d\ -f1)
if [[ "$MATCHING_PART" == "" ]]; then
/usr/bin/echo "Part not found"
exit -1
fi
if /usr/bin/mountpoint -q "$MOUNT_TARGET"; then
/usr/bin/echo "Already mounted"
else
/usr/bin/echo "Mounting..."
/usr/bin/mount -o rw,noatime,compress=no /dev/$MATCHING_PART $MOUNT_TARGET
fi
/usr/bin/echo "File system mounted !"
DEVICES=$(/usr/bin/lsblk --list --output UUID,FSSIZE,FSTYPE,FSUSED,FSUSE% | grep $PART_UUID)
USED=$(/usr/bin/echo $DEVICES | cut -d\ -f4)
TOTAL=$(/usr/bin/echo $DEVICES | cut -d\ -f2)
USED_PERCENT=$(/usr/bin/echo $DEVICES | cut -d\ -f5)
/usr/bin/echo "Usage : $USED / $TOTAL ($USED_PERCENT)"
/usr/bin/echo "Starting sync"
sendMessage "File system mounted \nUsage : $USED / $TOTAL ($USED_PERCENT) \nStarting offline copy..."
sync
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment