Apple Mac Backup with Rsync and Postfix
Why
Well, I have been happily using BackBlaze to protect all laptops in our family for years. This week, Information Security at my company decided that cloud backup is a risk as I might be sending corporate secrets somewhere and blocked BackBlaze on my corporate laptop. Reasonable. A pain for me, but reasonable. I keep personal files on my corporate laptop (mostly photos) and would like to continue to back those up.
How
Parts List
- A Mac
- Another Computer to Backup To (I use an Ubuntu Laptop)
- rsync (Built into MacOS, but dated)
- homebrew (To update dated MacOS rsync and install sshpass)
- sshpass (To send password to rsync)
- cron (Built into MacOS)
- postfix (Built into MacOS)
Get rsync Updated and Working
When I started testing rsync from my Mac to my Linux server, I was getting some errors. Some posts recommended making sure your major versions of rsync are the same on the source as on the destination. The version of rsync that comes with the Mac is 2.X and the version on my Linux box is 3.x. I updated rsync on my Mac with these commands:
brew install rsync
sudo ln /usr/local/Cellar/rsync/3.2.3/bin/rsync /usr/local/bin/rsync3
Rather than overwriting the built-in rsync, I created a symbolic link named rsync3 in the PATH.
The rsync syntax that worked for me was:
/usr/local/bin/rsync3 -avzhu --delete --stats /Users/faucherd/Downloads/ dennis@192.168.1.51:/media/mybook/Backup/rsync/Dennis/Downloads/
Let's break the rsync command line options down:
- -a (archive mode; equals -rlptgoD (no -H,-A,-X))
- -v (increase verbosity)
- -z (compress file data during the transfer)
- -h (output numbers in a human-readable format)
- -u (--update This forces rsync to skip any files which exist on the destination and have a modified time that is newer than the source file.)
- --delete (delete extraneous files from the receiving side (ones that aren't on the sending side))
- --stats (print a verbose set of statistics on the file transfer)
Use sshpass to Send User Password to rsync
The syntax rsync user@host prompts the user for a paassword. We want this rsync to run regularly and unattended, so we need to pass the password for our Linux user to rsync. The utility sshpass does just that. You install sshpass on MacOS with this command:
brew install hudochenkov/sshpass/sshpass
Now you can pass the password to rsync right on the command line with:
/usr/local/bin/sshpass -p "SuperSecretPassword" /usr/local/bin/rsync3 -avzhu --delete --stats /Users/faucherd/Downloads/ dennis@192.168.1.51:/media/mybook/Backup/rsync/Dennis/Downloads/
Create a Backup Script to Run Regularly
Let's create a shell script that we can run regularly in cron. This is my rsync_all.sh script that backs up my Downloads and my Documents/Personal directories:
#!/bin/bash
# Backup Downloads to MediaLinux
date
/usr/local/bin/sshpass -p "SuperSecretPassword" /usr/local/bin/rsync3 -avzhu --delete --stats /Users/faucherd/Downloads/ dennis@192.168.1.51:/media/mybook/Backup/rsync/Dennis/Downloads/
# Backup Personal to MediaLinux
date
/usr/local/bin/sshpass -p "SuperSecretPassword" /usr/local/bin/rsync3 -avzhu --delete --stats /Users/faucherd/Documents/Personal/ dennis@192.168.1.51:/media/mybook/Backup/rsync/Dennis/Personal/
date
grep "Number of regular files transferred" /Users/faucherd/Documents/Personal/Programming/rsync/rsync_all.log | mail -s "rsync Log" dennis@faucher.net
I added a few date commands in to log start and end time to my log file. The last line emails status of the
backup to me.
Tweak MacOS Postfix to Send Emails Through gMail
The mail command in the shell script uses MacOS Postfix to send the email. You need to tweak MacOS Postfix to define the gMail server and your gMail account. I used the excellent tutorial here.
Schedule Your Backup with Launchd
[I had initially scheduled by rsync job in cron, but cron has been deprecated. I was forced to learn MacOS launchd which is the preferred method]
Running scripts from launchd can cause issues if Terminal does not have default write access to the directories you need. Turning your shell script into an app with Mac Automator overcomes this issue.
Create an App with Automator
Launch Automator and choose Application
Search for shell script and drag that into the pane on the right
Create a new .plist file for launchd in ~/Library/LaunchAgents. Here is my working .plist that runs my app every hour (3600 seconds). You should be able to modify this to match your new app.
<?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>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Applications/VMware Fusion.app/Contents/Public:/usr/local/go/bin:/opt/X11/bin:/usr/local/sbin</string>
</dict>
<key>Label</key>
<string>FaucherRsync</string>
<key>ProcessType</key>
<string>Interactive</string>
<key>ProgramArguments</key>
<array>
<string>/Applications/FaucherRsync.app/Contents/MacOS/Application Stub</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StartInterval</key>
<integer>3600</integer>
</dict>
</plist>
Load your new plist:
launchctl load ~/Library/LaunchAgents/FaucherRsync.plist
Start your new plist:
launchctl start ~/Library/LaunchAgents/FaucherRsync.plist
Check to see if you have any errors. Anything non-zero is an error:
launchctl list|grep Faucher
- 0 FaucherRsync
Thank You
Thank you for taking the time to read this post. I hope you found it educational as well as helpful. I welcome any feedback.
Comments