docker-borgserver/init/entrypoint.sh

108 lines
4 KiB
Bash
Raw Permalink Normal View History

#!/bin/bash
# Init-Start Script for docker-borgserver
# Will pull ssh-keys from git specified via KEY_GIT_URL and KEY_GIT_BRANCH [default: master]
# and merge them into a single [openssh] authorized_keys file.
PUID=${PUID:-1000}
PGID=${PGID:-1000}
usermod -o -u "$PUID" borg &>/dev/null
groupmod -o -g "$PGID" borg &>/dev/null
# FIXME: Is this changeable? guess it should be.. should move it to some kind of
# build-env file
BORG_DATA_DIR=${BORG_DATA_DIR:-/backup}
BORG_CMD='cd ${BORG_DATA_DIR}/${client_name}; borg serve --restrict-to-path ${BORG_DATA_DIR}/${client_name} ${BORG_SERVE_ARGS}'
KEY_GIT_BRANCH=${KEY_GIT_BRANCH:-master}
# This is the path where the final authorized_keys will be written:
AUTHORIZED_KEYS_PATH=${AUTHORIZED_KEYS_PATH:-/home/borg/.ssh/authorized_keys}
# This will only contain host-keys now
SSH_KEY_DIR=${SSH_KEY_DIR:-/sshkeys}
# This is no volume anymore, only temporary during init
GIT_KEY_DIR=/tmp/gitkeys
echo "########################################################"
echo " * Docker BorgServer | Git Init-Container *"
echo " * $(id)"
if [ ! -z "${KEY_GIT_URL}" ] ; then
# FIXME: Should the container die here, in case of error?
# To workaround the limitations of docker-compose we could just loop here like.. forever
# INFO: simle git clone would be enouth, but you can also use a volume for SSH_KEY_DIR if you like
echo " * Cloning '${KEY_GIT_URL}' into '${GIT_KEY_DIR}/clients'"
if [ ! -d "${GIT_KEY_DIR}/clients/.git" ] ; then
git clone -b ${KEY_GIT_BRANCH} --depth=1 "${KEY_GIT_URL}" "${GIT_KEY_DIR}/clients"
else
git -C "${GIT_KEY_DIR}/clients" pull
fi
else
echo " ! FATAL ERROR: KEY_GIT_URL is not set! Can't continue."
exit 1
fi
if [ "$(find ${GIT_KEY_DIR}/clients ! -regex '.*/\..*' -a -type f | wc -l)" == "0" ] ; then
echo " ! FATAL ERROR: No SSH-Pubkey file found in ${GIT_KEY_DIR}. Can't continue."
exit 2
fi
# Create SSH-Host-Keys on persistent storage, if not exist
# This also means that `${SSH_KEY_DIR}` has to be a shared volume
echo " * Checking / Preparing SSH Host-Keys..."
for keytype in ed25519 rsa ; do
if [ ! -f "${SSH_KEY_DIR}/ssh_host_${keytype}_key" ] ; then
echo " ** Creating SSH Hostkey [${keytype}]..."
ssh-keygen -q -f "${SSH_KEY_DIR}/ssh_host_${keytype}_key" -N '' -t ${keytype}
fi
done
echo "########################################################"
echo " * Starting SSH-Key import..."
# Add every key to borg-users authorized_keys
# FIXME: mkdir of filestructure must still be done by server-container
# since we shouldn't have access to the backup-data volume in init
rm -f ${AUTHORIZED_KEYS_PATH} &>/dev/null
for keyfile in $(find "${GIT_KEY_DIR}" ! -regex '.*/\..*' -a -type f); do
client_name=$(basename ${keyfile})
# check if file is a valid openssh public key
if ! ssh-keygen -lf $keyfile &>/dev/null ; then
echo " ! WARNING: '$keyfile' is not a valid [open]ssh-public-key. Will continue anyway."
continue
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}\")\" " >> ${AUTHORIZED_KEYS_PATH}
cat ${keyfile} >> ${AUTHORIZED_KEYS_PATH}
done
# This will also fail if there wasn't a single valid pubkey found
echo " * Validating structure of generated ${AUTHORIZED_KEYS_PATH}..."
if ! ssh-keygen -lf ${AUTHORIZED_KEYS_PATH} >/dev/null ; then
echo " ! FATAL ERROR: ${AUTHORIZED_KEYS_PATH} is no valid authorized_keys file. Can't continue."
exit 3
fi
echo " * Correcting Permissions..."
chown borg:borg ${AUTHORIZED_KEYS_PATH}
chown -R borg:borg ${SSH_KEY_DIR}/*
chown borg:borg ${BORG_DATA_DIR}
chmod 600 ${AUTHORIZED_KEYS_PATH}
echo "########################################################"
echo " * Init done! Ready to fire up your borgserver!"
exit 0