SFTP/SSH backups to a Linux server with added security

This guide is allows new and existing users who desiring two core features:

  • Backups: From clients that backup to a Linux server via SFTP (SSH).
  • Added security: Ensuring that if the client is ever compromised, the hacker cannot compromise the backup.

Currently, Duplicati stores passwords plain text in its client side database. Duplicati must have the passwords plain text, because it must login to the backup server. This design is a security issue and is not easily solved. Future plans hope to use the client side operating system’s keychain features, but that is not currently available.

The core of the security concept is the Linux chattr command. It has options to allow reading, and writing a file one time, while also forbidding overwriting existing data or deleting files. This approach is excellent for Duplicati, as it almost always reads and writes, never appends, and rarely deletes (this latter can be managed with a Duplicati flag.)

What you will need:

Either sudo/root access on the remote server, or the remote server’s admin who can help you configure your backup directory.

Part 1 – Server Side Configuration

For new users, you need a user account on the Linux server. For existing users with backups, if you use this Linux account for anything other than your backup, strongly consider creating a second account for your backups. You have to supply your plaintext password into Duplicati, so if you use one Linux account regularly and store far more than just your backups, then an attacker could obtain your password in the Duplicati database, and access all these other things.

For this account example, I am using an account whose name describes its purpose

sudo adduser duplicati-alice-laptop

Note the password, you will need to put it into Duplicati’s client setup later.

Next, create a directory where the backups should be stored. Often a Linux server’s default home directory for user files isn’t the preferred backup location. (For example, Linux server admins often backup home directories, and making a backup of your Duplicati backup is a rather convoluted idea.) In my case, my backup folder is /backups, and I chose to have directory that match what they’re backing up. I ran the following command:

sudo mkdir /backups/alice-laptop

Now, set ownership of that directory to that user exclusively.

sudo chown -R duplicati-alice-laptop:duplicati-alice-laptop /backups/alice-laptop

Now, change the directory so it supports read/create, but not overwrite/append/delete. This process relies on chattr, which works on existing files, but new files don’t automatically inherit any chattr settings. So the following instructions has two parts: 1) setting the chattr attribute on files (for situations where the directory already has files in it), and 2) ensuring new files and directories get the chattr attribute.

(For users with existing backups) Set chattr on any existing files. This command must be run with the privileged rights (e.g. root or sudo), and cannot work otherwise. (Make sure you put in the *, otherwise, chattr also sets the ‘i’ flag on the directory too, and that prevents creating new files)

sudo chattr +i -R /backups/alice-laptop/*

You will need the incron tool. This tool is obtainable in different ways depending on your Linux distro (such as apt-get install incron). (Notes on incron: This tool allows you to run Linux commands when things change on the system, such as a new file appearing in a directory. Its similarities with cron are that cron triggers commands on a schedule, incron triggers commands on events. The incron tool uses the inotify tool behind the scenes, and changes persist even if the Linux server reboots, whereas the inotify tool does not persist on reboot.)

Start by allowing the root user to use incron

sudo nano /etc/incron.allow

Type “root” without the quotes in here. Ctrl+X to exit and save.

Now find where chattr is located, and note the full path (mine is in /usr/bin/chattr)

which chattr

Now, add an incron entry (Get this exact, it’s picky! See here: Hackery)

sudo incrontab -e

Add this, supplying the full path to chattr:

/backups/alice-laptop IN_CLOSE_WRITE /usr/bin/chattr +i $@/$#

The first part is the directory to watch. The IN_CLOSE_WRITE triggers when a file is created in that directory via an SFTP copy. (It does not work in subdirectories, but fortunately Duplicati doesn’t use subdirectories.) The last part is the command to run, with $@ being the directory, and $# being the new file name. Note that this command will be executed as the root user, not as the user who created the file.

Ctrl+X to exit and save (let it save to whatever path it suggests, it’s fine).

Now test it out! Log in as that duplicati-alice-laptop account (using the password for that account).

su duplicati-alice-laptop

Make a file with data in it.

echo “original data” > /backups/alice-laptop/testfile.txt

Use lsattr to see if it got the ‘i’ attribute.

lsattr /backups/alice-laptop/

You should see a line like: ----i---------e--- /backups/alice-laptop/testfile.txt. If the ‘i’ is missing, something went wrong.

Demonstrate that you can’t append data into it using >>, then view the data

echo “more data” >> /backups/alice-laptop/testfile.txt
cat /backups/alice-laptop/testfile.txt

You should still see “original data”

Demonstrate that you can’t overwrite it using >

echo “overwrite data” > /backups/alice-laptop/testfile.txt
cat /backups/alice-laptop/testfile.txt

You should still see “original data”

Demonstrate that you can’t delete

rm /backups/alice-laptop/testfile.txt
cat /backups/alice-laptop/testfile.txt

Note that not even root can overwrite or delete unless you unset that ‘i’ attribute!

Let’s clean up that testfile.txt. Leave your test user account:

exit

Unset the ‘i’

sudo chattr -i /backups/alice-laptop/testfile.txt
sudo rm /backups/alice-laptop/testfile.txt

Excellent! Your backup directory is now secured!

Part 2 – Client Side Configuration

Fortunately, this part is rather straightforward. The key points here are options to keep all backups, and turn off auto compacting. (Existing users, skip to the appropriate section.)

This uses the GUI instructions.

(For new users)
Click on “+Add Backup”
Click “Next >”
Give your backup a name, and a password for the encryption
Click “Next >”
Storage type, choose SFTP (SSH)
Put in the IP or hostname. The port is usually 22.
For pathname on server, put the appropriate path, such as: /backups/alice-laptop
The username and password are the Linux account credentials you created earlier. (Remember, this password is saved plain text in Duplicati’s database!)
Click “Test Connection”. Accept the new hash fingerprint. Click OK to connection worked.
Choose source files, then click “Next >”
Choose schedule, then click “Next >”

(For new users and users with existing backups )
In Options, choose “Keep All Backups”. You can’t have Duplicati deleting prior backups anymore.
Click on “Advanced Options”, in the drop down in Core Options, choose “no-auto-compact”. Then check the box.
Note, this shouldn’t be needed, but be aware there is also a “keep-versions” option, and values 0 and -1 do the same thing as the “Keep All Backups”

Do a test backup. To confirm, run the command on the server:

lsattr /backups/alice-laptop/

If you see Duplicati files with ----i---------e---, it worked!

Conclusion

Now anybody with non-root access to the server cannot delete any of your backup files. If your server’s Linux account password is ever discovered, your backups are still safe. An attacker could log into your backup account. They could read your data in your files (but most Duplicati users encrypt their files anyway). They cannot overwrite, append extra, or delete your files.

4 Likes

sudo incrontab -e
Add this, supplying the full path to chattr:
/backups/alice-laptop IN_CLOSE_WRITE /usr/bin/chattr +a $@/$#

The example uses the wrong attribute. It adds a instead of i.

Good catch, thanks for sharing. I will edit the original post to help others that may come across it.

1 Like

I propose to slightly restructure the paragraph about the client side configuration. I missed to deactivate automatic compacting and ran into errors because of this misconfiguration (Issue#4724).

(For new users and users with existing backups)
You can’t have Duplicati deleting prior backups anymore.

  • In Options, choose “Keep All Backups”.
  • Click on “Advanced Options”, in the drop down in Core Options, choose “no-auto-compact”. Then check the box.

Note, this shouldn’t be needed, but be aware there is also a “keep-versions” option, and values 0 and -1 do the same thing as the “Keep All Backups”

Technically this applies only to the first bullet, as in original. Backups are represented as dlist files.

Compacting files at the backend and The COMPACT command handle the dblock and dindex files.
As seen on the more technical second link, there are several things that can cause a compact to run.

How the backup process works gets more into dlist and dblock files. A dindex indexes its dblock.

There are other things such as cleaning up after failed uploads that may also attempt file deletions…