2020-08-27 11:18:39 -04:00
<!--
2020-10-02 09:42:15 -04:00
Title: How to backup and encrypt data using rsync and VeraCrypt on macOS
Description: Learn how to backup and encrypt data using rsync and VeraCrypt on macOS.
2020-08-27 11:18:39 -04:00
Author: Sun Knudsen < https: / / github . com / sunknudsen >
2020-09-10 15:26:57 -04:00
Contributors: Sun Knudsen < https: / / github . com / sunknudsen > , Alex Anderson < https: / / github . com / Serpent27 >
2020-09-10 17:27:18 +00:00
Reviewers: Alex Anderson < https: / / github . com / Serpent27 >
2020-08-27 11:18:39 -04:00
Publication date: 2020-08-26T14:07:36.767Z
2020-11-10 07:13:35 -05:00
Listed: true
2020-08-27 11:18:39 -04:00
-->
2020-10-02 09:42:15 -04:00
# How to backup and encrypt data using rsync and VeraCrypt on macOS
2020-08-27 11:18:39 -04:00
2020-10-02 09:42:15 -04:00
[](https://www.youtube.com/watch?v=1cz_ViFB6eE "How to backup and encrypt data using rsync and VeraCrypt on macOS - YouTube")
2020-08-28 09:09:44 -04:00
2020-09-10 15:27:28 -04:00
> Heads-up: when using storage devices with wear-leveling (most flash storage devices), it is not possible to securely change password once it has been set (see [Wear-Leveling](https://www.veracrypt.fr/en/Wear-Leveling.html)).
2020-09-10 10:13:53 -04:00
2020-08-27 11:18:39 -04:00
## Requirements
- Computer running macOS Mojave or Catalina
2020-09-10 10:13:53 -04:00
- USB flash drive or SD card formatted using FAT (4GiB file size limit) or exFAT filesystem (see [Journaling File Systems ](https://www.veracrypt.fr/en/Journaling%20File%20Systems.html ))
2020-08-27 11:18:39 -04:00
## Caveats
- When copy/pasting commands that start with `$` , strip out `$` as this character is not part of the command
- When copy/pasting commands that start with `cat << "EOF"` , select all lines at once (from `cat << "EOF"` to `EOF` inclusively) as they are part of the same (single) command
## Setup guide
2020-12-03 06:29:52 -05:00
### Step 1: install [Homebrew](https://brew.sh/)
2020-09-10 10:13:53 -04:00
```shell
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
```
2020-12-03 06:29:52 -05:00
### Step 2: disable Homebrew analytics
2020-08-27 11:18:39 -04:00
2020-09-10 10:13:53 -04:00
```shell
brew analytics off
```
2020-12-03 06:29:52 -05:00
### Step 3: install [FUSE for macOS](https://osxfuse.github.io/) and [GnuPG](https://gnupg.org/)
2020-12-03 16:09:33 -05:00
> Heads-up: if `brew install --cask osxfuse` fails, try `brew cask install osxfuse` (see [issue](https://github.com/Homebrew/brew/issues/9382)).
2020-09-10 10:13:53 -04:00
```shell
2020-12-03 06:29:52 -05:00
brew install --cask osxfuse
2020-09-10 10:13:53 -04:00
brew install gnupg
```
2020-08-27 11:18:39 -04:00
2020-12-03 06:29:52 -05:00
### Step 4: import VeraCrypt’ s public key
2020-08-27 11:18:39 -04:00
```console
$ gpg --keyserver hkps://keys.openpgp.org --recv-keys 0x821ACD02680D16DE
gpg: key 0x821ACD02680D16DE: public key "VeraCrypt Team (2018 - Supersedes Key ID=0x54DDD393) < veracrypt @idrix .fr > " imported
gpg: Total number processed: 1
gpg: imported: 1
```
2020-12-03 06:29:52 -05:00
### Step 5: download [VeraCrypt](https://www.veracrypt.fr/en/Home.html)
2020-08-27 11:18:39 -04:00
2020-11-10 07:13:35 -05:00
Go to [https://www.veracrypt.fr/en/Downloads.html ](https://www.veracrypt.fr/en/Downloads.html ) and download latest release and its associated PGP signature to `~/Downloads` folder.
2020-08-27 11:18:39 -04:00
2020-12-03 06:29:52 -05:00
### Step 6: verify VeraCrypt release signature using GnuPG
2020-08-27 11:18:39 -04:00
Replace `VeraCrypt_1.24-Update7` with current release.
```console
$ gpg --verify ~/Downloads/VeraCrypt_1.24-Update7.dmg.sig
gpg: assuming signed data in '/Users/sunknudsen/Downloads/VeraCrypt_1.24-Update7.dmg'
gpg: Signature made Sat 8 Aug 14:20:27 2020 EDT
gpg: using RSA key 5069A233D55A0EEB174A5FC3821ACD02680D16DE
gpg: Good signature from "VeraCrypt Team (2018 - Supersedes Key ID=0x54DDD393) < veracrypt @idrix .fr > " [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner.
Primary key fingerprint: 5069 A233 D55A 0EEB 174A 5FC3 821A CD02 680D 16DE
```
Good signature
👍
2020-12-03 06:29:52 -05:00
### Step 7: install VeraCrypt
2020-08-27 11:18:39 -04:00
2020-12-03 06:29:52 -05:00
### Step 8: create and test VeraCrypt symlink
2020-08-27 11:18:39 -04:00
```console
$ ln -s /Applications/VeraCrypt.app/Contents/MacOS/VeraCrypt /usr/local/bin/veracrypt
$ veracrypt --text --version
VeraCrypt 1.24-Update7
```
VeraCrypt 1.24-Update7
👍
2020-12-03 06:29:52 -05:00
### Step 9: set temporary environment variable
2020-08-27 11:18:39 -04:00
```shell
2020-12-03 17:09:03 -05:00
BACKUP_VOLUME_PATH="/Volumes/Samsung BAR/backup"
2020-08-27 11:18:39 -04:00
```
2020-12-03 06:29:52 -05:00
### Step 10: create encrypted volume
2020-08-27 11:18:39 -04:00
2020-09-10 15:27:28 -04:00
> Heads-up: volume size cannot be increased later.
2020-08-27 11:18:39 -04:00
2020-09-10 15:27:28 -04:00
> Heads-up: Mac OS Extended filesystem required on macOS.
2020-08-27 11:18:39 -04:00
```console
$ veracrypt --text --create "$BACKUP_VOLUME_PATH"
Volume type:
1) Normal
2) Hidden
Select [1]:
Enter volume size (sizeK/size[M]/sizeG): 1G
Encryption Algorithm:
1) AES
2) Serpent
3) Twofish
4) Camellia
5) Kuznyechik
6) AES(Twofish)
7) AES(Twofish(Serpent))
8) Camellia(Kuznyechik)
9) Camellia(Serpent)
10) Kuznyechik(AES)
11) Kuznyechik(Serpent(Camellia))
12) Kuznyechik(Twofish)
13) Serpent(AES)
14) Serpent(Twofish(AES))
15) Twofish(Serpent)
2020-09-10 10:13:53 -04:00
Select [7]:
2020-08-27 11:18:39 -04:00
Hash algorithm:
1) SHA-512
2) Whirlpool
3) SHA-256
4) Streebog
Select [1]:
Filesystem:
1) None
2) FAT
3) Mac OS Extended
4) exFAT
5) APFS
Select [3]:
Enter password:
Re-enter password:
Enter PIM:
Enter keyfile path [none]:
Please type at least 320 randomly chosen characters and then press Enter:
2020-09-10 10:13:53 -04:00
Done: 100.000% Speed: 24 MiB/s Left: 0 s
2020-08-27 11:18:39 -04:00
The VeraCrypt volume has been successfully created.
```
2020-12-03 06:29:52 -05:00
### Step 11 (optional): mount, rename and dismount encrypted volume
2020-08-27 11:18:39 -04:00
2020-10-10 10:43:57 -04:00
By default, VeraCrypt encrypted volumes with Mac OS Extended filesystem are named “untitled”.
2020-08-27 11:18:39 -04:00
#### Mount encrypted volume
```console
$ veracrypt --text --mount --pim 0 --keyfiles "" --protect-hidden no "$BACKUP_VOLUME_PATH" /Volumes/Backup
2020-12-03 06:29:52 -05:00
Enter password for /Volumes/Samsung BAR/backup:
2020-08-27 11:18:39 -04:00
```
#### Rename encrypted volume
```console
$ diskutil rename "untitled" "Backup"
Volume on disk3 renamed to Backup
```
#### Dismount encrypted volume
```shell
veracrypt --text --dismount "$BACKUP_VOLUME_PATH"
```
2020-12-03 06:29:52 -05:00
### Step 12: create `/usr/local/bin/backup.sh` script
2020-08-27 11:18:39 -04:00
```shell
2020-09-03 16:53:44 -04:00
cat < < EOF > /usr/local/bin/backup.sh
2020-08-27 11:18:39 -04:00
#! /bin/sh
2020-09-10 10:13:53 -04:00
set -e
2020-11-07 05:44:56 -05:00
function dismount()
2020-09-10 10:13:53 -04:00
{
2020-11-07 05:44:56 -05:00
if [ -d "\$mount_point" ]; then
veracrypt --text --dismount "\$mount_point"
2020-09-10 10:13:53 -04:00
fi
}
2020-11-07 05:44:56 -05:00
trap dismount ERR INT
2020-08-27 11:18:39 -04:00
2020-11-07 05:44:56 -05:00
volume_path="$BACKUP_VOLUME_PATH"
mount_point="/Volumes/Backup"
2020-08-27 11:18:39 -04:00
2020-11-19 09:25:00 -05:00
veracrypt --text --mount --pim "0" --keyfiles "" --protect-hidden "no" "\$volume_path" "\$mount_point"
2020-11-07 05:44:56 -05:00
mkdir -p "\$mount_point/Versioning"
2020-09-10 10:13:53 -04:00
2020-09-26 07:20:10 -04:00
files=(
2020-11-12 11:42:14 -05:00
"/Users/$USER/.gnupg"
"/Users/$USER/.ssh"
"/Users/$USER/Library/Keychains"
2020-08-27 11:18:39 -04:00
)
for file in "\${files[@]}"; do
2020-11-07 05:44:56 -05:00
rsync -axRS --delete --backup --backup-dir "\$mount_point/Versioning" --suffix="\$(date +".%F-%H%M%S")" "\$file" "\$mount_point"
2020-08-27 11:18:39 -04:00
done
2020-11-07 05:44:56 -05:00
if [ "\$(find "\$mount_point/Versioning" -type f -ctime +90)" != "" ]; then
2020-09-10 10:13:53 -04:00
printf "Do you wish to prune versions older than 90 days (y or n)? "
read -r answer
if [ "\$answer" = "y" ]; then
2020-11-07 05:44:56 -05:00
find "\$mount_point/Versioning" -type f -ctime +90 -delete
find "\$mount_point/Versioning" -type d -empty -delete
2020-09-10 10:13:53 -04:00
fi
fi
2020-09-03 16:53:44 -04:00
open /Volumes/Backup
2020-09-10 10:13:53 -04:00
printf "Inspect backup and press enter"
2020-08-27 11:18:39 -04:00
read -r answer
2020-11-07 05:44:56 -05:00
dismount
2020-08-27 11:18:39 -04:00
2020-09-10 10:13:53 -04:00
printf "Generate hash (y or n)? "
read -r answer
if [ "\$answer" = "y" ]; then
2020-11-07 05:44:56 -05:00
openssl dgst -sha512 "\$volume_path"
2020-09-10 10:13:53 -04:00
fi
printf "%s\n" "Done"
2020-08-27 11:18:39 -04:00
EOF
2020-09-03 16:53:44 -04:00
chmod +x /usr/local/bin/backup.sh
2020-08-27 11:18:39 -04:00
```
2020-12-03 06:29:52 -05:00
### Step 13: edit `/usr/local/bin/backup.sh` script
2020-08-27 11:18:39 -04:00
```shell
2020-09-03 16:53:44 -04:00
vi /usr/local/bin/backup.sh
2020-08-27 11:18:39 -04:00
```
2020-08-28 09:09:44 -04:00
Press < kbd > i< / kbd > to enter insert mode, edit backup script, press < kbd > esc< / kbd > to exit insert mode and press < kbd > shift+z+z< / kbd > to save and exit.
2020-08-27 11:18:39 -04:00
2020-12-03 06:29:52 -05:00
### Step 14: create `/usr/local/bin/check.sh` script
2020-09-10 10:13:53 -04:00
```shell
cat < < EOF > /usr/local/bin/check.sh
#! /bin/sh
set -e
red=$'\e[1;31m'
nc=$'\e[0m'
printf "Backup hash: "
read -r previous
current=\$(openssl dgst -sha512 "$BACKUP_VOLUME_PATH")
if [ "\$current" != "\$previous" ]; then
printf "\${red}%s\${nc}\n" "Integrity check failed"
exit 1
fi
printf "%s\n" "OK"
EOF
chmod +x /usr/local/bin/check.sh
```
2020-12-03 06:29:52 -05:00
### Step 15: create `/usr/local/bin/restore.sh` script
2020-09-26 07:20:10 -04:00
```shell
cat < < EOF > /usr/local/bin/restore.sh
#! /bin/sh
set -e
2020-11-07 05:44:56 -05:00
function dismount()
2020-09-26 07:20:10 -04:00
{
2020-11-07 05:44:56 -05:00
if [ -d "\$mount_point" ]; then
veracrypt --text --dismount "\$mount_point"
2020-09-26 07:20:10 -04:00
fi
}
2020-11-07 05:44:56 -05:00
trap dismount ERR INT
2020-09-26 07:20:10 -04:00
2020-11-07 05:44:56 -05:00
volume_path="$BACKUP_VOLUME_PATH"
mount_point="/Volumes/Backup"
2020-09-26 07:20:10 -04:00
2020-11-19 09:25:00 -05:00
veracrypt --text --mount --mount-options "readonly" --pim "0" --keyfiles "" --protect-hidden "no" "$volume_path" "$mount_point"
2020-11-07 05:44:56 -05:00
open "\$mount_point"
2020-09-26 07:20:10 -04:00
printf "Restore data and press enter"
read -r answer
2020-11-07 05:44:56 -05:00
dismount
2020-09-26 07:20:10 -04:00
printf "%s\n" "Done"
EOF
chmod +x /usr/local/bin/restore.sh
```
2020-12-03 06:29:52 -05:00
👍
---
2020-08-27 11:18:39 -04:00
## Usage guide
2020-09-10 10:13:53 -04:00
### Backup
2020-09-10 19:22:38 +00:00
> Heads-up: store hash in safe place such as password manager (not on same device as backup).
2020-08-27 11:18:39 -04:00
```console
2020-09-03 16:53:44 -04:00
$ backup.sh
2020-12-03 06:29:52 -05:00
Enter password for /Volumes/Samsung BAR/backup:
2020-08-27 11:18:39 -04:00
Inspect backup and press enter
2020-09-10 10:13:53 -04:00
Generate hash (y or n)? y
2020-12-03 06:29:52 -05:00
SHA512(/Volumes/Samsung BAR/backup)= 281a3b0afec6708eff9566effdfa67de357933527688dfa2dfabae5dda5b7681f0fb84f6cfec6c3f7ac20246517f18f40babbd4f337b254a55de30ff67d6dd2e
2020-08-27 11:18:39 -04:00
Done
```
Done
👍
2020-09-10 10:13:53 -04:00
2020-09-26 07:20:10 -04:00
### Check
2020-09-10 10:13:53 -04:00
```console
$ check.sh
2020-12-03 06:29:52 -05:00
Backup hash: SHA512(/Volumes/Samsung BAR/backup)= 281a3b0afec6708eff9566effdfa67de357933527688dfa2dfabae5dda5b7681f0fb84f6cfec6c3f7ac20246517f18f40babbd4f337b254a55de30ff67d6dd2e
2020-09-10 10:13:53 -04:00
OK
```
OK
👍
2020-09-26 07:20:10 -04:00
### Restore
```console
$ restore.sh
2020-12-03 06:29:52 -05:00
Enter password for /Volumes/Samsung BAR/backup:
2020-09-26 07:20:10 -04:00
Restore data and press enter
Done
```
Done
👍