Skip to content

Instantly share code, notes, and snippets.

@only-cliches
Last active June 6, 2024 02:41
Show Gist options
  • Save only-cliches/17f24ae572c8c7a9edc2829b072652cc to your computer and use it in GitHub Desktop.
Save only-cliches/17f24ae572c8c7a9edc2829b072652cc to your computer and use it in GitHub Desktop.
MacOS Automated Time Machine Reconnect
#!/bin/bash
# Place this file in /usr/local/sbin/backup-script.sh
# Add passwords with:
# security add-generic-password -s "password_label" -a "username" -w "your_password_here"
SAMBA_PASS=$(security find-generic-password -s "samba_pass" -a "username" -w)
BACKUP_PASS=$(security find-generic-password -s "backup_pass" -a "username" -w)
# Configuration
SHARE_NAME="//samba_username:$SAMBA_PASS@samba_host.com/path"
MOUNT_POINT="/Users/xxxx/network_backup"
BACKUP_DISK="/Volumes/MacbookProBackup"
SPARSE_IMAGE="/Backups/MacbookProBackup.sparsebundle"
# Function to mount SMB share
mount_smb_share() {
if ! mount | grep -q "$MOUNT_POINT"; then
echo "Mounting SMB share..."
mkdir -p "$MOUNT_POINT"
mount_smbfs "$SHARE_NAME" "$MOUNT_POINT"
else
echo "SMB share is already mounted."
fi
}
# Function to mount backup disk
mount_backup_disk() {
if ! mount | grep -q "$BACKUP_DISK"; then
echo "Mounting backup disk..."
printf '%s\0' $BACKUP_PASS | hdiutil attach "$MOUNT_POINT/$SPARSE_IMAGE" -stdinpass
else
echo "Backup disk is already mounted."
fi
}
# OPTIONAL HTTP CHECK: To use this section set up a simple HTTP server on your local network and put a secret text file on it.
# Then adjust these variables accordingly.
HTTP_ENDPOINT="http:/local.server/secret.txt"
EXPECTED_VALUE="Secret phrase contained in secret.txt"
# Function to check HTTP endpoint
# This fails if we're not on the local network
check_http_endpoint() {
response=$(curl -s "$HTTP_ENDPOINT")
if [ $? -ne 0 ]; then
echo "HTTP request failed. Exiting script."
exit 1
elif [ "$response" != "$EXPECTED_VALUE" ]; then
echo "HTTP response does not match expected value. Exiting script."
exit 1
else
echo "HTTP check passed."
fi
}
check_http_endpoint
# END OPTIONAL HTTP CHECK
# OPTIONAL MAC ADDRESS CHECK: Verify the router on your backup network is currently connected
# Prevents the script from trying to connect to networks when you're not on your backup network
HOME_ROUTER_MAC="00:00:00:00:00:00" # REPLACE THIS VALUE WITH ACTUAL MAC ADDRESS
check_router_mac() {
ROUTER_IP=$(netstat -rn | grep default | awk 'NR==1 {print $2}')
ROUTER_MAC=$(arp -an | grep "($ROUTER_IP)" | awk '{print $4}')
if [ "$ROUTER_MAC" == "$HOME_ROUTER_MAC" ]; then
echo "Router MAC address check passed."
else
echo "Router MAC address check failed. Exiting script."
exit 1
fi
}
check_router_mac
# END OPTIONAL MAC ADDRESS CHECK
# Check and mount SMB share if needed
mount_smb_share
# Check and mount backup disk if needed
mount_backup_disk
echo "Check completed at $(date)"
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.example.backup-script</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/sbin/backup-script.sh</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Minute</key>
<integer>0</integer>
</dict>
<key>StandardOutPath</key>
<string>/tmp/backup-script.log</string>
<key>StandardErrorPath</key>
<string>/tmp/backup-script.error</string>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment