Title: How to self-host a hardened Borg backup server and configure macOS client
Description: Learn how to self-host a hardened Borg backup server and configure macOS client.
Author: Sun Knudsen <https://github.com/sunknudsen>
Contributors: Sun Knudsen <https://github.com/sunknudsen>
Reviewers:
Publication date: 2020-11-10T20:35:16.488Z
Listed: true
-->
# How to self-host a hardened Borg backup server and configure macOS client
## Requirements
- Virtual private server (VPS) or dedicated server running Debian 10 (buster)
- Computer running macOS Mojave or Catalina
## 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
### Step 1: create `server` SSH key pair (on Mac)
When asked for file in which to save key, enter `server`.
When asked for passphrase, use output from `openssl rand -base64 24` (and store passphrase in password manager).
Use `server.pub` public key when setting up server.
```console
$ mkdir -p ~/.ssh
$ cd ~/.ssh
$ ssh-keygen -t rsa -C "server"
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/sunknudsen/.ssh/id_rsa): server
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in server.
Your public key has been saved in server.pub.
The key fingerprint is:
SHA256:rZFDBWi8f6BcRR2gqzIWmWtBiLdk89znOSpZkZGOQH8 server
The key's randomart image is:
+---[RSA 3072]----+
| .. . o.o+o.. |
| ..o * o. . |
|. *.o+E+o. |
| + *.==.o+ |
| . B..=S.. |
| +++.=. |
| *o. =. |
| ooo . . |
| .. |
+----[SHA256]-----+
$ cat server.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCowL4nNnu5Ca3ixlMxD6vVUexhx7M214ElheY/Y3K1mGavd5H6ynhkF71DAgI3YOB3B9KM/IzvV+8ioY+FUVlovBrKwqXzBwb5fnAGPjymjRMY93nYVExICHjI6aQX+9CG1WxRMPhZpDo51sKXORpWQDbMG+CfDa5nmjVjysoCdqwJfd22WEDFIXTiUdVXC5EvJBWiC0MUAphRPmNF/fXyaZPoiL1RmNX7h6JsMQJC/iWHwYgQZhzQCuoAOnvEXKUnu6s7FEUOSbqHCnOuHzxVkDHg1yy667hhyOuwkPdUW276T44GgwicSg/T2IWmwf5cBmDzaSr21kaM00zeg+stqkIwKqdpd0PhV8tjIdKCm3H9GsCRpE0erXLhJVsQTjmmFaodvFyroRHeyH9VBqzYrJXMhG/iXwK8uCeOwGFUosddYw3jJ3sLgsRI34oGKSq9HIRd7P5gdxUZ8cJiZUCpfS4vI4cZDkyR5D8Xvupe/X2pS5Llc8wtiy1K3nxIEQE= server
```
### Step 2: create `borg` SSH key pair (on Mac)
When asked for file in which to save key, enter `borg`.
When asked for passphrase, leave field empty for no passphrase.
```console
$ ssh-keygen -t rsa -C "borg"
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/sunknudsen/.ssh/id_rsa): borg
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in borg.
Your public key has been saved in borg.pub.
The key fingerprint is:
SHA256:ZB293/YueacLtg2a5anHe/PXruP8YwZXwU/caebReSk borg
The key's randomart image is:
+---[RSA 3072]----+
| .. ..*|
| . ..E X*|
| o . .=.=|
| o . .o|
| S . ..|
| ...o|
| .= ooo|
| *oB*+*|
| +o=+X&O|
+----[SHA256]-----+
$ cat borg.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDawvaD0JmNz3XBChQq9OZROa0psAwH0BpHwGZ/4cuDiTnU8gt3gYXDANkS++SKbUNMJCQW3QgVNFhpk2SmWA8lLvlpuD5J3kvHNFNKFv/hBc0XxsVJlpASONeCwilnS5otIqnDT0+KFMOevZUMCumEoBtjQ3IQbGkpWgf3NJ6ysXkt6kLRk7PMls4E733v/T4XUJmeBWT6B0rECqWE3aFzrjjZbfyJho0Pp8VzjT3m4vknNCvvwionjXRti5ObvEo3OZGWQbuhwW63JPS+aldNX9Xo0VC8t2UuSzzy7OeGI+JB76Pw1RYfXaMeflHry3O50kCIWIWHPNblw0sBPBsRs9BDg4R8urwpdVYjyirw9cZHDA8lkPxh0WS3IbA7Q1iRlVrfJkm9r4SqohxwQUeHIT7lpsyDHObUDF3KejRCWtyCqabPJVHqvGIds6rjQQo9lP5JNkeHg+qg8Cw61FihGLrlFStvgx1pMbBo2TvMEsRo65psVYUyi79taqbdlZM= borg
```
### Step 3: generate SSH authorized keys heredoc (on Mac)
#### Set temporary environment variable
`BORG_STORAGE_QUOTA` backup storage quota
```shell
BORG_STORAGE_QUOTA="10G"
```
#### Generate heredoc (the output of following command will be used at [step 21](#step-21-configure-borgs-ssh-authorized-keys))
When asked for password, use output from `openssl rand -base64 24` (and store password in password manager).
```shell
passwd
```
### Step 9: log out
```shell
exit
```
### Step 10: log in as `server-admin`
Replace `185.112.144.30` with IP of server.
```shell
ssh server-admin@185.112.144.30 -i ~/.ssh/server
```
### Step 11: switch to root
When asked, enter root password.
```shell
su -
```
### Step 12: update SSH config to disable root login and password authentication and restart SSH
```shell
sed -i -E 's/(#)?PermitRootLogin (prohibit-password|yes)/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i -E 's/(#)?PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
systemctl restart ssh
```
### Step 13: update APT index and upgrade packages
#### Update APT index
```shell
apt update
```
#### Upgrade packages
```shell
apt upgrade -y
```
### Step 14: install and configure Vim
#### Install Vim
```shell
apt install -y vim
```
#### Configure Vim
```shell
cat << "EOF" > ~/.vimrc
set encoding=UTF-8
set termencoding=UTF-8
set nocompatible
set backspace=indent,eol,start
set autoindent
set tabstop=2
set shiftwidth=2
set expandtab
set smarttab
set ruler
set paste
syntax on
EOF
```
### Step 15: set timezone (the following is for Montreal time)
See [https://en.wikipedia.org/wiki/List_of_tz_database_time_zones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) for available timezones.
```shell
timedatectl set-timezone America/Montreal
```
### Step 16: install iptables-persistent
When asked to save current IPv4 or IPv6 rules, answer `Yes`.
```shell
apt install -y iptables-persistent
```
### Step 17: configure iptables
```shell
iptables -N SSH_BRUTE_FORCE_MITIGATION
iptables -A SSH_BRUTE_FORCE_MITIGATION -m recent --name SSH --set
#### Go to [https://github.com/sunknudsen/borg-backup/releases](https://github.com/sunknudsen/borg-backup/releases) and download latest `.dmg` release ([PGP public key](https://sunknudsen.com/sunknudsen.asc))
#### Double-click `.dmg` release and drag and drop “Borg Backup” to the “Applications” folder
> Heads-up: given “Borg Backup” is developed outside the [Apple Developer Program](https://developer.apple.com/programs/), macOS prevents opening the app without explicit user consent (clicking “Open Anyway” in “System Preferences” / “Privacy & Security”).