Compare commits

..

2 commits

Author SHA1 Message Date
nold 0dc25d5428 Git key import again 2020-03-26 18:16:56 +01:00
Pietro 0108fcf653
Split run.sh and add git retrival
This patch modularize run.sh, adding two new helper scripts and
make it possible to specify a git repository for ssh keys via a
new env variable `BORG_SSHKEYS_REPO`.

the modularization add two new files :
- `env.sh` : define a few envriroment variables
- `create-client-dirs.sh`  : update and create user directories and
  re-create authorized_keys

We also add a new script `update-ssh-keys.sh` to be called regurlarly
in a cron job to check if the git repository is up-to-date and
eventually adding/removing users.
2020-03-24 14:03:24 +01:00
11 changed files with 148 additions and 101 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
/backup /backup
/sshkeys /sshkeys
.env

View file

@ -1,39 +0,0 @@
steps:
build:
image: woodpeckerci/plugin-docker-buildx
settings:
dry-run: true
repo: git.merp.digital/${CI_REPO_OWNER}/borgserver
platforms: linux/386,linux/amd64,linux/arm/v7,linux/arm64/v8
registry: git.merp.digital
when:
- event: push
branch:
exclude: [develop, master]
publish-nightly:
image: woodpeckerci/plugin-docker-buildx
settings:
repo: git.merp.digital/${CI_REPO_OWNER}/borgserver
platforms: linux/386,linux/amd64,linux/arm/v7,linux/arm64/v8
registry: git.merp.digital
tags: develop-${CI_COMMIT_SHA}
username: ${CI_REPO_OWNER}
password:
from_secret: cb_token
when:
- event: push
branch: develop
publish-release:
image: woodpeckerci/plugin-docker-buildx
settings:
repo: git.merp.digital/${CI_REPO_OWNER}/borgserver
platforms: linux/386,linux/amd64,linux/arm/v7,linux/arm64/v8
registry: git.merp.digital
tags: ${CI_COMMIT_TAG}
username: ${CI_REPO_OWNER}
password:
from_secret: cb_token
when:
- event: tag

View file

@ -2,7 +2,7 @@
# Dockerfile to build borgbackup server images # Dockerfile to build borgbackup server images
# Based on Debian # Based on Debian
############################################################ ############################################################
FROM debian:12.4-slim FROM debian:buster-slim
# Volume for SSH-Keys # Volume for SSH-Keys
VOLUME /sshkeys VOLUME /sshkeys
@ -24,6 +24,9 @@ RUN apt-get update && apt-get -y --no-install-recommends install \
COPY ./data/run.sh /run.sh COPY ./data/run.sh /run.sh
COPY ./data/sshd_config /etc/ssh/sshd_config COPY ./data/sshd_config /etc/ssh/sshd_config
COPY ./data/update-ssh-keys.sh /usr/local/bin/
COPY ./data/create-client-dirs.sh /usr/local/bin/
COPY ./data/env.sh /usr/local/bin/env.sh
ENTRYPOINT /run.sh ENTRYPOINT /run.sh

9
Dockerfile.pullgit Normal file
View file

@ -0,0 +1,9 @@
############################################################
# Dockerfile to build borgbackup server images with git-pull support!
# Based on Debian
############################################################
FROM borgserver:latest
RUN apt-get update && apt-get -y --no-install-recommends install \
git ca-certificates && apt-get clean && \
rm -rf /var/lib/apt/lists/* /var/tmp/* /tmp/*

View file

@ -29,7 +29,7 @@ docker run -td \
-p 2222:22 \ -p 2222:22 \
--volume ./borg/sshkeys:/sshkeys \ --volume ./borg/sshkeys:/sshkeys \
--volume ./borg/backup:/backup \ --volume ./borg/backup:/backup \
git.merp.digital/eranmorkon/borgserver:1.0.0 nold360/borgserver:latest
``` ```
@ -45,7 +45,7 @@ See the the documentation for all available arguments: [borgbackup.readthedocs.i
##### Example ##### Example
``` ```
docker run --rm -e BORG_SERVE_ARGS="--progress --debug" (...) git.merp.digital/eranmorkon/borgserver docker run --rm -e BORG_SERVE_ARGS="--progress --debug" (...) nold360/borgserver
``` ```
#### BORG_APPEND_ONLY #### BORG_APPEND_ONLY
@ -62,7 +62,7 @@ To declare a client as admin, set this variable to the name of the client/sshkey
##### Example ##### Example
``` ```
docker run --rm -e BORG_APPEND_ONLY="yes" -e BORG_ADMIN="nolds_notebook" (...) git.merp.digital/eranmorkon/borgserver 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: To prune repos from another client, you have to add the path to the repository in the clients directory:
@ -112,7 +112,23 @@ In this directory will borg write all the client data to. It's best to start wit
## Example Setup ## Example Setup
### docker-compose.yml ### docker-compose.yml
Here is a quick example, how to run borgserver using docker-compose: [docker-compose.yml](https://github.com/Nold360/docker-borgserver/blob/master/docker-compose.yml) Here is a quick example, how to run borgserver using docker-compose:
```
services:
borgserver:
image: nold360/borgserver
volumes:
- /backup:/backup
- ./sshkeys:/sshkeys
ports:
- "2222:22"
environment:
BORG_SERVE_ARGS: ""
BORG_APPEND_ONLY: "no"
BORG_ADMIN: ""
PUID: 1000
PGID: 1000
```
### ~/.ssh/config for clients ### ~/.ssh/config for clients
With this configuration (on your borg client) you can easily connect to your borgserver. With this configuration (on your borg client) you can easily connect to your borgserver.

55
data/create-client-dirs.sh Executable file
View file

@ -0,0 +1,55 @@
#!/bin/bash
# This script generates the authorized_keys file from SSH_KEY_DIR
# authorized_keys will only get overridden after syntax check
set -e
source env.sh
TMPFILE=$(mktemp)
echo "######################################################"
echo "* Regenerate borgserver authorized_keys *"
echo "######################################################"
# Add every key to borg-users authorized_keys
for keyfile in $(find "${SSH_KEY_DIR}/clients" ! -regex '.*/\..*' -a -type f); do
client_name=$(basename ${keyfile})
# Only import valid keyfiles, skip other files
if ! ssh-keygen -lf $keyfile >/dev/null ; then
echo " Warning: Skipping invalid ssh-key file '$keyfile'"
continue
fi
if [ ! -d "${BORG_DATA_DIR}/${client_name}" ]; then
echo " ** Adding client ${client_name} with repo path ${BORG_DATA_DIR}/${client_name}"
mkdir "${BORG_DATA_DIR}/${client_name}"
else
echo "Directory ${BORG_DATA_DIR}/${client_name} exists: Nothing to do"
fi
# 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}\")\" " >> ${TMPFILE}
cat ${keyfile} >> ${TMPFILE}
done
# Due to `set -e` the script will end here on failure anyways
echo " * Validating structure of generated ${AUTHORIZED_KEYS_PATH}..."
ssh-keygen -lf ${TMPFILE} >/dev/null
mv ${TMPFILE} ${AUTHORIZED_KEYS_PATH}
echo " ** Success"
chown -R borg:borg ${BORG_DATA_DIR}
chown borg:borg ${AUTHORIZED_KEYS_PATH}
chmod 600 ${AUTHORIZED_KEYS_PATH}
exit 0

23
data/env.sh Executable file
View file

@ -0,0 +1,23 @@
# Default values for environment
PATH=$PATH:/usr/local/bin
PUID=${PUID:-1000}
PGID=${PGID:-1000}
# Append only mode?
BORG_APPEND_ONLY=${BORG_APPEND_ONLY:=no}
# Volume for backup repositories
BORG_DATA_DIR=${BORG_DATA_DIR:-/backup}
# Branch of KEY_GIT_URL
KEY_GIT_BRANCH=${KEY_GIT_BRANCH:-master}
# This will contain the host and client keys
SSH_KEY_DIR=${SSH_KEY_DIR:-/sshkeys}
### CAUTION
# This is more of a template then something you need to change, it should stay static
BORG_CMD='cd ${BORG_DATA_DIR}/${client_name}; borg serve --restrict-to-path ${BORG_DATA_DIR}/${client_name} ${BORG_SERVE_ARGS}'
# Path to authorized_keys file
AUTHORIZED_KEYS_PATH=${AUTHORIZED_KEYS_PATH:-/home/borg/.ssh/authorized_keys}

View file

@ -1,36 +1,30 @@
#!/bin/bash #!/bin/bash
# Start Script for docker-borgserver # Start Script for docker-borgserver
set -e
PUID=${PUID:-1000} source env.sh
PGID=${PGID:-1000}
usermod -o -u "$PUID" borg &>/dev/null usermod -o -u "$PUID" borg &>/dev/null
groupmod -o -g "$PGID" borg &>/dev/null groupmod -o -g "$PGID" borg &>/dev/null
BORG_DATA_DIR=/backup
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}'
AUTHORIZED_KEYS_PATH=/home/borg/.ssh/authorized_keys
# Append only mode?
BORG_APPEND_ONLY=${BORG_APPEND_ONLY:=no}
source /etc/os-release
echo "########################################################" echo "########################################################"
echo -n " * Docker BorgServer powered by " echo -n " * Docker BorgServer powered by "
borg -V borg -V
echo " * Based on ${PRETTY_NAME}"
echo "########################################################" echo "########################################################"
echo " * User id: $(id -u borg)" echo " * User id: $(id -u borg)"
echo " * Group id: $(id -g borg)" echo " * Group id: $(id -g borg)"
if [ -z "${KEY_GIT_URL}" ] ; then
echo "* Pulling keys from ${KEY_GIT_URL}"
fi
echo "########################################################" echo "########################################################"
# Precheck if BORG_ADMIN is set # Precheck if BORG_ADMIN is set
if [ "${BORG_APPEND_ONLY}" == "yes" ] && [ -z "${BORG_ADMIN}" ] ; then if [ "${BORG_APPEND_ONLY}" == "yes" ] && [ -z "${BORG_ADMIN}" ] ; then
echo "WARNING: BORG_APPEND_ONLY is active, but no BORG_ADMIN was specified!" echo "WARNING: BORG_APPEND_ONLY is active, but no BORG_ADMIN was specified!"
fi fi
# Init the ssh keys directory from a remote git repository
update-ssh-keys.sh
# Precheck directories & client ssh-keys # Precheck directories & client ssh-keys
for dir in BORG_DATA_DIR SSH_KEY_DIR ; do for dir in BORG_DATA_DIR SSH_KEY_DIR ; do
dirpath=$(eval echo '$'${dir}) dirpath=$(eval echo '$'${dir})
@ -56,42 +50,8 @@ for keytype in ed25519 rsa ; do
fi fi
done done
echo "########################################################"
echo " * Starting SSH-Key import..."
# Add every key to borg-users authorized_keys # Add every key to borg-users authorized_keys
rm ${AUTHORIZED_KEYS_PATH} &>/dev/null create-client-dirs.sh
for keyfile in $(find "${SSH_KEY_DIR}/clients" ! -regex '.*/\..*' -a -type f); do
client_name=$(basename ${keyfile})
mkdir ${BORG_DATA_DIR}/${client_name} 2>/dev/null
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 "restrict,command=\"$(eval echo -n \"${borg_cmd}\")\" " >> ${AUTHORIZED_KEYS_PATH}
cat ${keyfile} >> ${AUTHORIZED_KEYS_PATH}
echo >> ${AUTHORIZED_KEYS_PATH}
done
chmod 0600 "${AUTHORIZED_KEYS_PATH}"
echo " * Validating structure of generated ${AUTHORIZED_KEYS_PATH}..."
ERROR=$(ssh-keygen -lf ${AUTHORIZED_KEYS_PATH} 2>&1 >/dev/null)
if [ $? -ne 0 ]; then
echo "ERROR: ${ERROR}"
exit 1
fi
chown -R borg:borg ${BORG_DATA_DIR}
chown borg:borg ${AUTHORIZED_KEYS_PATH}
chmod 600 ${AUTHORIZED_KEYS_PATH}
echo "########################################################" echo "########################################################"
echo " * Init done! Starting SSH-Daemon..." echo " * Init done! Starting SSH-Daemon..."

View file

@ -25,6 +25,3 @@ PermitTTY no
PrintMotd no PrintMotd no
PermitTunnel no PermitTunnel no
Subsystem sftp /bin/false Subsystem sftp /bin/false
ClientAliveInterval 10
ClientAliveCountMax 30

20
data/update-ssh-keys.sh Executable file
View file

@ -0,0 +1,20 @@
#!/bin/bash
# This script updates the authorized_keys file
# Will clone/pull ssh-pubkeys from GIT_KEY_URL if set
set -e
source env.sh
if [ -d "${SSH_KEY_DIR}/clients/.git" ] ; then
git -C "${SSH_KEY_DIR}/clients" fetch
if ! git -C "${SSH_KEY_DIR}/clients" diff --quiet remotes/origin/HEAD; then
echo "Pull from git repository"
git -C "${SSH_KEY_DIR}/clients" pull
create-client-dirs.sh
else
echo "$0: Nothing to do"
fi
elif [ ! -z "${KEY_GIT_URL}" ] ; then
git clone --depth=1 -b ${KEY_GIT_BRANCH} ${KEY_GIT_URL} ${SSH_KEY_DIR}/clients
fi
exit 0

View file

@ -1,21 +1,23 @@
version: '3' version: '3'
services: services:
borgserver: borgserver:
image: git.merp.digital/eranmorkon/borgserver #image: nold360/borgserver
#build: . build:
context: .
dockerfile: Dockerfile.pullgit
volumes: volumes:
- ./backup:/backup - ./backup:/backup
- ./sshkeys:/sshkeys - ./sshkeys:/sshkeys
ports: ports:
- "2222:22" - "2222:22"
env_file: .env
environment: environment:
# Additional Arguments, see https://borgbackup.readthedocs.io/en/stable/usage/serve.html
BORG_SERVE_ARGS: "" BORG_SERVE_ARGS: ""
# If set to "yes", only the BORG_ADMIN # If set to "yes", only the BORG_ADMIN
# can delete/prune the other clients archives/repos # can delete/prune the all clients archives/repos
BORG_APPEND_ONLY: "no" BORG_APPEND_ONLY: "no"
# Filename of Admins SSH-Key; has full access to all repos # Hostname of Admin's SSH-Key
BORG_ADMIN: "" BORG_ADMIN: ""
restart: unless-stopped restart: unless-stopped