DEV Community

PhoenixLandPirate
PhoenixLandPirate

Posted on • Edited on

Backing up securely with Restic

Backing up securely

We all know the saying, you should always back up your stuff, if you don't back it up, there's lots of things that can go wrong, your hard-drive might fail, or might just have some data loss, you might accidently delete the wrong folder, and not realise it until its to late, or maybe you accidently over wrote a newer file, with an older version, maybe someone could have locked you out of your computer, or encrypted your hard-drive, or perhaps you just forget your password.

Todays blog is about Local backup's only, however the tools used in this can be used to back up your things securely online to, the biggest issue with online backups being the cost of service if you have a huge amount of storage to back up.

Install Restic

Restic is the backup software that we're going to use, its Open Source, with strong encryption, versioning, and only transfers what you need to, so you don't use up more space than you need to.

Restic works on Linux, Mac, BSD, and Windows, however if you want to use Restic, you still need to know your way around a shell.

Windows Scoop and PowerShell

To install Restic on Windows, you have to use the Scoop module, and thus you need to be comfortable with PowerShell.

First make sure that the ExecutionPolicy is set to RemoteSigned for the current user, if you don't understand ExecutionPolicy's it just tells PowerShell what level of security, it should be on, for the current user or machine, in this command we're changing the ExecutionPolicy so that it requires that all scripts and configs, that have been gotten remotely (Not on the local machine) must be signed by a trusted publisher, for the Current User, only, this doesn't change the ExecutionPolicy for any other user on the machine.

Set-ExecutionPolicy RemoteSigned -scope CurrentUser

Then we want to use PowerShell to download and install scoop using this command.

Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh')

Then install Restic by using the command

scoop install Restic

you can than use Restic from the PowerShell environment.

Mac

If you use a Mac you can either use homebrew, or MacPorts, since brew is more widely used, it would be of more use in future projects to install homebrew over MacPorts in my opinion, however, you're more than welcome to install software however you like on your own computer.

To Install homebrew use the command

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

Then you can install programs using brew install, to install Restic just use

brew install restic

Now Restic is up and running

Linux and BSD's

Install using your local repositories.

Alternatively

You can download releases from the Restic GitHub release page, and then you can use Restic self-update when there's a newer version.

You can also build Restic from Source.

Local or Online?

Restic supports many different Backup Locations, these include local back ups, online back ups using someone else's cloud infrastructure, or your own remote services.

A local back up is what I'm going to use in this blog, and so for further examples of other services, I suggest looking at the manual or reading someone else's remote back up solution, however, the majority of this blog will be the same regardless, however where you point the commands to and from will be different, there will also be extra account set up to think about that I wont go talk about in this Blog

Local

Local backups are a great option, they're much faster than using the wireless, and wont slowdown any other time sensitive task ran over the network.

Local also means "buy once" it might be a more upfront cost depending on what hard-drive you get, but you only need to pay that once, for online services, you have to pay monthly to keep up and running.

It can be very cheap if you're going to get a spinning disk/s, however the backup will run slowly, this isn't a big problem if you're only backing up a small amount of data, but if you're backing up a lot, then you might want to purchase a more expensive higher speed SSD, however, a slow backup is better than no backup.

You may also want to consider a SSD if you're planning on moving your backup data around, as HDD's are more perceptible to damage from falls, drops, or bangs.

Local also means that your data is there, so if you use an external drive, you can unmount the drive from one computer, and restore the data to a new machine, without using more bandwidth.

However Local means that you can only access the data if you have the storage medium in front of you, if you don't have the storage media, you don't have your data, if you need to get to your data remotely there are ways of doing it, but its a bit more effort, and can open yourself up to security issues, It also means that if you loose your backup device, or if it breaks then you've lost the data on that drive, which might not be to big of a problem if you still have your primary storage device, but if the reason you loose your data is due to a fire, or a electrical surge damages every device hooked into your computer, than you'll loose two drives in one.

Online

Online backups are great as you can use them anywhere, however they can be slow, especially if you live remote, it can be easier to deal with the cost up front if you're subscribing monthly or yearly, however it may cost more in the long run, if you're only backing up a small amount of data then some backup platforms will allow you to use them for free.

However if you're using your own backup machine, say a raspberry pi that you've set up in another location, the price will barely be different from someone who's using a Local copy.

A remote copy that you own will mean you still have to worry about some of the issues that you have to worry about with Local storage, however you don't need to worry about having both storage options breaking at the same time, but you will have to worry about Online issues, such as bandwidth.

With backing up online, a standard backing up procedure you would also have to be concerned with privacy, but due to Restic's encryption, that isn't a issue that we have to worry about.

If you wish to use online services, Restic offers you the following backup options

Provider Init URL scheme Price as of writing
SFTP restic -r sftp:user@host:/srv/restic-repo init Self Rolled
REST Server restic -r rest:http://host:8000/ Self Rolled
Minio Server restic -r s3:http://localhost:9000/restic init Self Rolled
Wasabi restic -r s3:https:/// init $5.99 for 1 TB per month
Backblaze B2 restic -r b2:bucketname:path/to/repo init $0.005 per GB (Aprox $5 for 1 TB)
Amazon S3 restic -r s3:s3.amazonaws.com/bucket_name init $0.024 per GB (Aprox $24 per month for 1 TB)
Microsoft Azure Blob Storage restic -r azure:foo:/ init $0.01 per GB (Aprox $10 per month for 1 TB)
Google Cloud Storage restic -r gs:foo:/ init They have a calculator
rclone services restic -r rclone:foo:bar init Depends what service you're using rclone with

Both

If you can afford the option to do Local and Online, than its best to have one copy in the cloud, and one copy on your desk, it allows you to have the best of both worlds, however the issue majortially, as always will be the cost.

Setting up Local Storage (Linux Only)

I bought a Samsung SSD 860 EVO, with 2TB's of storage as my backup device, it means I don't have to worry about issues with spinning disks or affecting my network speeds, my Pictures directory is 184 GB's so that would take a very long time to upload on my current data speed.

However I do plan to add a online storage backup at some point.

Partitioning the Drive

First step is obvious, you must first plug in the external drive, my external drive connector is USB-C and so I decided to take advantage of the extra speed that USB-C offers over USB type 3, and used a USB-C to USB-C plug.

When I plugged in my SSD it didn't mount, which was quite worrying, however, when I opened KDE Partition Manager, it showed up without a Partition table, this maybe that the Drive didn't come with a partition table on it by default, or more likely, the partition table it came with, just isn't supported on Linux, which one however, we may never know.

So the first thing to do is format the disk, just click on the drive, and then click "New Partition Table" choose GPT, and create the new partition table, however, before we actually create the new partition table, theirs no point in doing that, if we don't add an actual partition, CTRL+N or click "New" will swing open a new popup window in this window, I decided to swap the File system to BTRFS, I didn't enable encryption with LUK's because all the data on the drive will already be encrypted with Restics back up encryption.

I gave it a Label, and then clicked next, typing in my password as it was prompted, and then I mounted the device.

As I'm using KDE Partition manager, I have the problem that I can only write to the device if I'm root, you can check this yourself if you're using Linux and KDE Partition manager, by using ls -l

ls -l /run/media/$USER

This will show you your drives and some information about them, if you see "root root" that means you have to change the owner, but if you see your username instead than that means you'll be okay.

To change the ownership to your current user use chown

sudo chown $USER:$USER /run/media/$USER/backup

Now the device is ready for restic.

Using Restic on a Local drive

First thing to do when starting a new Restic backup is to initiate the repo.

restic init --repo /run/media/$USER/backup

This will then ask you for a new password for the backup, if the data is extremly private, then please do not make a memorable password, but rather use an impossible password, by using a password manager the likes of KeePass or bit-warden, and keep that safe.

Restic will also give you a repository location, mine for example is 2849ef4f60, this is an important number as if you create more repos you'll have to use the repo number to navigate through them.

Now I'm going to back up my Pictures folder, my Pictures folder has all my photos organized into folders, except the Import folder, and some db folder's that I don't need to backup so I create a .exclude.txt file in my Pictures directory, simply saying "import".

restic -r /run/media/$USER/backup backup --tag Photos --verbose=2 ~/Pictures --exclude-file=.exclude.txt

Okay so lets go through this

part of the command What it means
restic this starts restic
-r We are looking for a repository to backup or restore
/run/media/$USER/backup This is the repository that we're backing up or restoring from
backup We're backing up some data
--tag Photos What we're backing up should be tagged, and the tag to this snapshot is Photos
--verbose=2 We are going to display everything we're doing on the commandline
~/Pictures This is the folder we're backing up
--exclude-file=.exclude.txt We aren't backing up anything that this document tells us not to

Then that's it, all I need to do now is choose.

Restic Backup options

Lets look through some options that you can use when backing up your files.

Excluding

Exluding command What you exclude
--exclude=" " This excludes items with that name, or naming scheme
--iexclude=" " Same as exclude, but ignores the case of paths
--exclude-caches Exclude folders containtng a special file
--exclude-file=excludes.txt Excludes items listed in given file
--iexclude-file=excludes.txt same as exclude-file execept ignores the case of paths
--exclude-if-present foo Excludes a folders content if it contains a dffile called foo (optionaly having a given header, no wildcards for hte file name supported)
--exclude-larger-than size Excludes files larger than the given size

Including
--files-from /tmp/files-to-backup /tmp/aditional-file

Reading from stdin

set -o pipefail
mysqldump [...] | restic -r /srv/restic-repo backup --stdin --stdin-filename production.sql

This pipes the sqldump to a Restic backup, the backup then reads it as standard in using --stdin and we then give that stdin a filename using --stdin-filename.

Working with repositories

You can list a repository by using Restic -r /srv/restic-repo snapshots.

This will give you the ID, Date, Host, Tags, and Directory it backed up from, you can filter these by path using --path=, for example,

restic -r /run/media/$USER/backup snapshots --path="/home/$USER/Pictures"

Will just show you snapshots that are backed up from the pictures directory, you can also filter by user by using '--host &USER', not only can you filter using these tags, you can also list them so that they're specifically grouped by hosts, tags, or directory's, by using --group-by

restic -r /run/media/$USER/backup snapshots --group-by paths

This will group things according to the path that that the backup is from.

It is important to check the integrity of a backup, to make sure that a hard-drive hasn't scrambled any data, or that someone with malicious intent hasn't tried to edit, the file, you can do this by using the check command.

restic -r /run/media/$USER/backup check

If your backup hasn't been tempered with or is still working fine, it will tell you there are no errors and you can continue using the backup, otherwise it's best to restore what you can and create a new backup.

The check command also checks such as none referenced packs in the index, it will often give you some recommendations of what to do with the result of the command, in my case Restic suggests that I have files in the repo which are duplicated, that I can get rid of by using the Restic prune command.

This command can be used to save a lot of hard-drive space

$ restic -r /run/media/*/backup prune
enter password for repository:
repository 2849ef4f opened successfully, password is correct
counting files in repo
building new index for repo
[0:05] 100.00% 16742 / 16742 packs
repository contains 16742 packs (73165 blobs) with 80.012 GiB
processed 73165 blobs: 1989 duplicate blobs, 2.430 GiB duplicate
load all snapshots
find data that is still in use for 2 snapshots
[0:00] 100.00% 2 / 2 snapshots
found 71176 of 73165 data blobs still in use, removing 1989 blobs
will remove 0 invalid files
will delete 0 packs and rewrite 1021 packs, this frees 2.430 GiB

Restoring from a snapshot

Whats the point in having a backup if you don't know how to get the data back off the drive?

One way of restoring from a snapshot is by straight up restoring the data.

First step is to identify which backup you want to restore, by listing your repos, and choosing the ID, for me my id for the latest backup of Photos, is 31e587ea, so to restore my latest backup of that path, I would use the command.

$ restic -r /run/media/*/backup restore 31e587ea --target /Pictures

If you don't want top bother with finding out the ID, you can use tell Restic that you want the latest copy of the Pictures file by using the latest and --path tags.

$ restic -r /run/media/*/backup restore latest --target /Pictures --path "/home/Pictures"

However, perhaps I just want to browse the content of a restic folder, without restoring it, perhaps you only want to restore a handful of files, due to corruption, or are using the backup drive as a portable hard drive.

mkdir /mnt/restic
restic -r /run/media/*/backup mount /mnt/restic

This mounts the Restic backup to a mnt directory, so you can easily browse through it using your favourite file manager.

Automating the backups.

You can automate Restic backups using systemd, using the code as a base bellow, and paste it into our favourite text editor of choice, and save the file to ~/.config/systemd/user/restic-backup.service file. you may have to make some of the folders yourself, and you should edit this to reflect your backup system.

[Unit]
Description=Restic backup service
[Service]
Type=oneshot
ExecStart=restic -r $RESTIC_REPOSITORY backup --verbose --tag Photos $RESTIC_PATHS --password-file="$HOME/Documents/Keys/Backup_Codes/resticpassword"
ExecStart=restic -r $RESTIC_REPOSITORY backup --verbose --tag Documents $RESTIC_PATHS_DOCUMENTS --password-file="$HOME/Documents/Keys/Backup_Codes/resticpassword"
ExecStartPost=restic -r $RESTIC_REPOSITORY forget --verbose --group-by "paths" --keep-within 1y0m0d0h --password-file="$HOME/Documents/Keys/Backup_Codes/resticpassword"
EnvironmentFile=$HOME/.config/restic-backup.conf

These reference an Environment file, which will give the service the needed attributes to run the backup

This is waht my restic-backup.conf looks like

RESTIC_PATHS_PICTURES="$USER/Pictures"
RESTIC_PATHS_DOCUMENTS="$USER/Documents"
RESTIC_REPOSITORY="/run/media/*/Backup"

Last but not least is the timer, if you wish to have a weekly timer, just copy and paste this into a new file, and name it "restic-backup.timer", if youd rather your backups happen hourly, just replace weekly with hourly.

[Unit]
Description=Backup with restic weekly
[Timer]
OnCalendar=weekly
Persistent=true
[Install]
WantedBy=timers.target

Then to kick it of just type

systemctl --user enable --now restic-backup.timer

There you have it that's how you make it so restic automatically backs up your data weekly, using systemd, while also removing year old snapshots, however you still need to prune your data now and again, so you can create another automatic systemd process, or prune it yourself, restic is pretty slow when pruning, so you don't want to do it to often, and you want to make sure that you make a log using the check command to make sure that nothing went wrong during pruning.

Perhaps you've left the timer running for a few days, or have had your computer turned off during the scheduled time, and you want to know where the system is with your backup, you can use systemctl to tell you how long it is until the next time the process will run and when it ran last.

systemctl --user list-timers
NEXT LEFT LAST PASSED UNIT ACTIVATES

Mon 2020-12-07 00:00:00 GMT 5 days left Mon 2020-11-30 00:00:57 GMT 1 day 1h ago restic-backup.timer restic-backup.service

Then you can double check that the backup worked and was successful using the restic check command and restic snapshot command, to make sure that the backup happened and was effective, and to make sure nothing broke, in case something like a shutdown during a backup affected the backup.

Top comments (0)