Skip to main content

Server Backup to Local Archive

Backups are important for obvious reasons. Many approaches exist to back up local data and the very same tools can be used to back up remote machines utilizing reverse ssh tunnels. Here, I am describing my personal backup process.

Goal

I want to have a local backup of my server. Even if all information on the remote machine is lost, I want to keep its configuration and relevant information locally available. The backup process shall depend on as less requirements as possible to be applicable in most constellations.

Requirements

The described process relies on ssh and borg being available on both the remote and local machine.

Additionally, the process relies on GatewayPorts being enabled for ssh. The relevant configuration can be found in /etc/ssh/sshd_config on ArchLinux and is enabled by default.

You will need to connect from the remote machine back to the local machine via ssh. If not already done, you might want to generate ssh keys on the remote machine and copy them over to the local machine using ssh-copy-id. That way you can avoid using your local user password for the session.

As alternatives to borg other backup tools like rsync can be used. Even if your particular tool does not support ssh per default, one might be able to use sshfs for backups.

Steps

  1. Create the local archive for the backups once.

  2. Start local ssh service if it is not already running.

  3. Connect to the server via ssh enabling reverse tunnel.

  4. Backup the remote machine to local archive using the ssh tunnel.

  5. Optionally, verify the presence of the newly created backup.

Example

0. Create Local Archive

Navigate to a cozy spot in your file system and create the local borg archive dedicated to store backups of your remote machine.

$ borg init --encryption=repokey-blake2 archive_server

You will be prompted for an encryption password. Omit the corresponding option if you would like to have an unencrypted archive.

1. Start ssh Service

Start the local sshd daemon if it is not already running. On ArchLinux this is done by issuing the following on the local machine.

# systemctl start sshd

In this example we are assuming that sshd is configured to use the default port 22 for the ssh service.

2. Connect to Remote Machine

Now, you want to connect to the remote machine creating the reverse tunnel by utilizing option -R. As parameter, you provide the port on the remote side, the fact that the connection is to be forwarded to localhost and the default port 22 of local sshd. The rest consists of the remote user and the machine you would like to connect to, as usual.

$ ssh -R 2000:localhost:22 user_remote@server

This gives you a ssh session and also creates the ssh tunnel along with it.

Note that in this example we are using port 2000 on the remote side. You can choose anything above the reserved 1024 port numbers, as long as there are no conflicts with other services.

You can verify the connection by connecting back from your remote machine to the local machine. On the remote machine, issue

$ ssh user_local@localhost -p 2000

If everything works as intended, you should get a shell on the local machine.

3. Backup Remote Machine

With the ssh tunnel being open, you can now back up your remote machine as if it was the other way around. Make sure to use the specified port of the reverse tunnel.

The following bash script template should give some inspiration regarding the options for borg.

REMOTE='ssh://user_local@localhost:2000'
ARCHIVE="${REMOTE}//mnt/archive_server"

borg create --stats                       \
            --progress                    \
            --compression zstd,11         \
            "${ARCHIVE}"::{now:%Y-%m-%d}  \
            /                             \
            --exclude /sys                \
            --exclude /proc               \
            []

With --stats we are requesting statistics regarding archive utilization after the backup is completed, --process gives some basic information during the backup process and --compression determines the algorithm used for compression along with the compression level.

The archive consists of its location and a name for the new backup, which we choose to be the date in this example. Then, we provide the root path to back up. Additional paths for exclusion are supplied using --exclude.

You might want to include the server logs in your backup. Those might be valuable for failure diagnostics. You might also want to exclude the package cache to limit the size of the archive. Additionally, you might want to add a borg purge step for thinning out your backups over time.

Consult the documentation for borg regarding more options.

4. Verify Local Backup

With the backup process finished, you can verify the presence of the newly created backup in the borg archive. In order to do that, list the available backups in the archive.

$ borg list archive_server

You will be prompted for the archive password every time you want to access it, if provided at initialization. The output for the first backup should be something like the following.

2019-10-06    Sun, 2019-10-06 11:46:08 []

The actual contents can be listed via

$ borg list archive_server::2019-10-06

Congratulations! The backup process is set up.

Conclusion

The described backup process is independent of the infrastructure and other services surrounding the remote machine. Especially it does not rely on dedicated backup servers.

Furthermore, the process does not require more free space on the remote machine than is necessary for borg. You do not need to preserve space for compressed data, effectively rendering it unusable for regular usage.

Most importantly, you can place your server backups along with all the other backups on an external drive, locally available at any time.

Have fun with it.