Added new Feature - BORG_APPEND_ONLY & BORG_ADMIN

This commit is contained in:
Gerrit Pannek 2019-04-04 18:19:14 -05:00
parent ae2f6c90ef
commit 1b4ea9e2a0
3 changed files with 81 additions and 50 deletions

View file

@ -4,10 +4,10 @@ For every ssh-key added, a own borg-repository will be created.
**NOTE: I will assume that you know, what a ssh-key is and how to generate & use it. If not, you might want to start here: [Arch Wiki](https://wiki.archlinux.org/index.php/SSH_Keys)**
### Quick Example
## Quick Example
Here is a quick example how to configure & run this image:
#### Create persistent sshkey storage
### Create persistent sshkey storage
```
$ mkdir -p borg/sshkeys/clients
```
@ -17,7 +17,7 @@ Make sure that the permissions are right on the sshkey folder:
$ chown 1000:1000 borg/sshkeys
```
#### (Generate &) Copy every client's ssh publickey into persistent storage
### (Generate &) Copy every client's ssh publickey into persistent storage
*Remember*: Filename = Borg-repository name!
```
$ cp ~/.ssh/my_machine.pub borg/sshkeys/clients/my_machine
@ -26,28 +26,51 @@ Make sure that the permissions are right on the sshkey folder:
The OpenSSH-Deamon will expose on port 22/tcp - so you will most likely want to redirect it to a different port. Like in this example:
```
docker run -td \
-p 2222:22 \
--volume ./borg/sshkeys:/sshkeys \
--volume ./borg/backup:/backup \
nold360/borgserver:latest
-p 2222:22 \
--volume ./borg/sshkeys:/sshkeys \
--volume ./borg/backup:/backup \
nold360/borgserver:latest
```
## Borgserver Configuration
* Place Borg-Clients SSH-PublicKeys in persistent storage
* Client Repositories will be named by the filename found in /sshkeys/clients/
* Client backup-directories will be named by the filename found in /sshkeys/clients/
### Environment Variables
#### BORG_SERVE_ARGS
Use this variable if you want to set special options for the "borg serve"-command, which is used internally.
See the the documentation for all available arguments: [borgbackup.readthedocs.io](https://borgbackup.readthedocs.io/en/1.0.9/usage.html#borg-serve)
See the the documentation for all available arguments: [borgbackup.readthedocs.io](https://borgbackup.readthedocs.io/en/stable/usage.html#borg-serve)
##### Example
```
docker run -e BORG_SERVE_ARGS="--append-only --debug" (...) nold360/borgserver
docker run --rm -e BORG_SERVE_ARGS="--progress --debug" (...) nold360/borgserver
```
#### BORG_APPEND_ONLY
If you want your client to be only able to append & not prune anything from their repo, set this variable to **"yes"**.
#### BORG_ADMIN
When *BORG_APPEND_ONLY* is active, no client is able to prune it's repo.
Since you might want to cleanup the repos at some point, you can declare one client to be the borg "admin".
This client will have **full access to all repos of any client!** So he's able to add/prune/... what ever he wants.
To declare a client as admin, set this variable to the name of the client/sshkey you've added to the /sshkeys/clients directory.
##### Example
```
docker run --rm -e BORG_APPEND_ONLY="yes" -e BORG_ADMIN="nolds_notebook" (...) nold360/borgserver
```
To prune repos from another client, you have to add the path to the repository in the clients directory:
```
borg prune --keep-last 100 --keep-weekly 1 (...) borgserver:/clientA/clientA
```
### Persistent Storages & Client Configuration
We will need two persistent storage directories for our borgserver to be usefull.
@ -90,10 +113,12 @@ services:
ports:
- "2222:22"
environment:
BORG_SERVE_ARGS: "--append-only"
BORG_SERVE_ARGS: ""
BORG_APPEND_ONLY: "no"
BORG_ADMIN: ""
```
### ~/.ssh/config
### ~/.ssh/config for clients
With this configuration (on your borg client) you can easily connect to your borgserver.
```
Host backup

View file

@ -1,65 +1,77 @@
#!/bin/bash
# Init borg-users .ssh/authorized_keys
# Start Script for docker-borgserver
BORG_DATA_DIR=/backup
BORG_CMD='cd ${BORG_DATA_DIR}/${client_name}; borg serve --restrict-to-path ${BORG_DATA_DIR}/${client_name}'
SSH_KEY_DIR=/sshkeys
BORG_CMD='cd ${BORG_DATA_DIR}/${client_name}; borg serve --restrict-to-path ${BORG_DATA_DIR}/${client_name} ${BORG_SERVE_ARGS}'
# Parse environment
if [ ! -z "${BORG_SERVE_ARGS}" ] ; then
BORG_CMD="${BORG_CMD} ${BORG_SERVE_ARGS}"
# Append only mode?
BORG_APPEND_ONLY=${BORG_APPEND_ONLY:=no}
echo "########################################################"
echo -n " * Docker BorgServer powered by "
borg -V
echo "########################################################"
# Precheck if BORG_ADMIN is set
if [ "${BORG_APPEND_ONLY}" == "yes" ] && [ -z "${BORG_ADMIN}" ] ; then
echo "WARNING: BORG_APPEND_ONLY is active, but no BORG_ADMIN was specified!"
fi
# add all sshkeys to borg-user's authorized_keys & create repositories
echo "########################################################"
# Precheck directories & client ssh-keys
for dir in BORG_DATA_DIR SSH_KEY_DIR ; do
dirpath=$(eval echo '$'$dir)
echo " * Testing Volume $dir: $dirpath"
if [ ! -d "$dirpath" ] ; then
echo "ERROR: $dirpath is no directory!"
dirpath=$(eval echo '$'${dir})
echo " * Testing Volume ${dir}: ${dirpath}"
if [ ! -d "${dirpath}" ] ; then
echo "ERROR: ${dirpath} is no directory!"
exit 1
fi
if [ $(find "${SSH_KEY_DIR}/clients" -type f | wc -l) == 0 ] ; then
echo "ERROR: No SSH-Pubkey file found in $SSH_KEY_DIR"
if [ "$(find ${SSH_KEY_DIR}/clients -type f | wc -l)" == "0" ] ; then
echo "ERROR: No SSH-Pubkey file found in ${SSH_KEY_DIR}"
exit 1
fi
done
# (Create &) Copy SSH-Host-Keys to persistent storage
# Create SSH-Host-Keys on persistent storage, if not exist
mkdir -p ${SSH_KEY_DIR}/host 2>/dev/null
echo " * Checking / Preparing SSH Host-Keys..."
if [ ! -f /etc/ssh/ssh_host_rsa_key ] ; then
echo " ** Creating SSH Hostkeys..."
for keytype in ed25519 rsa ; do
ssh-keygen -q -f "/etc/ssh/ssh_host_${keytype}_key" -N '' -t $keytype
done
fi
for keyfile in ssh_host_rsa_key ssh_host_ed25519_key ; do
if [ ! -f "${SSH_KEY_DIR}/host/${keyfile}" ] ; then
cp /etc/ssh/${keyfile} "${SSH_KEY_DIR}/host/${keyfile}"
for keytype in ed25519 rsa ; do
if [ ! -f "${SSH_KEY_DIR}/host/ssh_host_${keytype}_key" ] ; then
echo " ** Creating SSH Hostkey [${keytype}]..."
ssh-keygen -q -f "${SSH_KEY_DIR}/host/ssh_host_${keytype}_key" -N '' -t ${keytype}
fi
done
echo "########################################################"
echo "########################################################"
echo " * Starting SSH-Key import..."
# Add every key to borg-users authorized_keys
rm /home/borg/.ssh/authorized_keys &>/dev/null
for keyfile in $(find "${SSH_KEY_DIR}/clients" -type f); do
client_name=$(basename $keyfile)
echo " ** Adding client ${client_name} with repo path ${BORG_DATA_DIR}/${client_name}"
client_name=$(basename ${keyfile})
mkdir ${BORG_DATA_DIR}/${client_name} 2>/dev/null
echo -n "command=\"$(eval echo -n \"${BORG_CMD}\")\" " >> /home/borg/.ssh/authorized_keys
cat $keyfile >> /home/borg/.ssh/authorized_keys
echo " ** Adding client ${client_name} with repo path ${BORG_DATA_DIR}/${client_name}"
# If client is $BORG_ADMIN unset $client_name, so path restriction equals $BORG_DATA_DIR
# Otherwise add --append-only, if enabled
borg_cmd=${BORG_CMD}
if [ "${client_name}" == "${BORG_ADMIN}" ] ; then
echo " ** Client '${client_name}' is BORG_ADMIN! **"
unset client_name
elif [ "${BORG_APPEND_ONLY}" == "yes" ] ; then
borg_cmd="${BORG_CMD} --append-only"
fi
echo -n "command=\"$(eval echo -n \"${borg_cmd}\")\" " >> /home/borg/.ssh/authorized_keys
cat ${keyfile} >> /home/borg/.ssh/authorized_keys
done
chown -R borg: /backup
chown borg: /home/borg/.ssh/authorized_keys
chmod 600 /home/borg/.ssh/authorized_keys
echo " * Init done!"
echo "########################################################"
echo " * Starting SSH-Daemon"
echo " * Init done! Starting SSH-Daemon..."
/usr/sbin/sshd -D -e

View file

@ -14,12 +14,6 @@ PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
LogLevel INFO
#LogLevel DEBUG
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes128-ctr
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256
KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1
PasswordAuthentication no
ChallengeResponseAuthentication no