Merge pull request #331 from Psycho0verload/s6_clean_secrets

Patch: Separation of secrets and cron
pull/337/head
Grant Bevis 2024-06-25 13:15:27 +01:00 zatwierdzone przez GitHub
commit c8f89acf5e
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: B5690EEEBB952194
12 zmienionych plików z 102 dodań i 80 usunięć

Wyświetl plik

@ -3,7 +3,6 @@ BORG_PASSPHRASE=ReplaceWithYourSecretPassPhrase
VOLUME_SOURCE=/home
VOLUME_TARGET=./data/repository
VOLUME_ETC_BORGMATIC=./data/borgmatic.d
VOLUME_BORGMATIC_STATE=./data/.borgmatic
VOLUME_BORG_CONFIG=./data/.config/borg
VOLUME_SSH=./data/.ssh
VOLUME_BORG_CACHE=./data/.cache/borg

Wyświetl plik

@ -80,16 +80,20 @@ You can set the following environment variables:
You can also provide your own crontab file. If `data/borgmatic.d/crontab.txt` exists, `BACKUP_CRON` will be ignored in preference to it. In here you can add any other tasks you want ran
```
0 1 * * * PATH=$PATH:/usr/bin /usr/bin/borgmatic --stats -v 0 2>&1
0 1 * * * PATH=$PATH:/usr/local/bin /usr/local/bin/borgmatic --stats -v 0 2>&1
```
Beside that, you can also pass any environment variable that is supported by borgmatic. See documentation for [borgmatic](https://torsion.org/borgmatic/) and [Borg](https://borgbackup.readthedocs.io/) and for a list of supported variables.
### Using Secrets (Optional)
You also have the option to use Docker Secrets for more sensitive information. This is not mandatory, but it adds an extra layer of security. **Note that this feature is only applicable to environment variables starting with `BORG`.**
You also have the option of using Docker Secrets for more sensitive information. This is not mandatory, but provides an additional layer of security. **Note that this function is only applicable to environment variables that start with `BORG` or `YOUR`.**
For each environment variable such as `BORG_PASSPHRASE`, you can create a corresponding secret file called `BORG_PASSPHRASE_FILE`. Store the contents of the secret file in this file. The start script automatically searches for corresponding `_FILE` secrets if the environment variables are not set and loads them.
It is important to know that this environment variable is **not** available via `docker compose exec borgmatic sh`. Only for the automated call via the defined cron.
For every environment variable like `BORG_PASSPHRASE`, you can create a corresponding secret file, named as `BORG_PASSPHRASE_FILE`. Place the content of the secret inside this file. The startup script will automatically look for corresponding `_FILE` secrets if the environment variables are not set and load them.
## Using Apprise for Notifications
@ -102,7 +106,7 @@ To enhance your experience with Borgmatic, we'll show you a quick example of how
In an unmodified Borgmatic installation, your `cronjob.txt` might look something like this:
```
0 1 * * * PATH=$PATH:/usr/local/bin /usr/local/bin/borgmatic --stats -v 0 2>&1
0 1 * * * /usr/local/bin/borgmatic --stats -v 0 2>&1
```
To incorporate Apprise notifications, you can modify it like this:
@ -121,11 +125,11 @@ before_backup:
after_backup:
- echo "Backup created."
- apprise -vv -t "✅ SUCCESS" -b "$(cat /tmp/backup_run.log)" "mailtos://smtp.example.com:587?user=info@example.com&pass=YourSecurePassword&from=server@example.com"
- apprise -vv -t "✅ SUCCESS" -b "$(cat /tmp/backup_run.log)" "mailtos://smtp.example.com:587?user=server@example.com&pass=YourSecurePassword&from=server@example.com&to=receiver@example.com"
on_error:
- echo "Error while creating a backup."
- apprise -vv -t "❌ FAILED" -b "$(cat /tmp/backup_run.log)" "mailtos://smtp.example.com:587?user=info@example.com&pass=YourSecurePassword&from=server@example.com"
- apprise -vv -t "❌ FAILED" -b "$(cat /tmp/backup_run.log)" "mailtos://smtp.example.com:587?user=server@example.com&pass=YourSecurePassword&from=server@example.com&to=receiver@example.com"
```
##### Note:
@ -145,7 +149,7 @@ Apprise allows you to notify multiple services at the same time:
```yaml
after_backup:
- echo "Backup created."
- apprise -vv -t "✅ SUCCESS" -b "$(cat /tmp/backup_run.log)" "mailto://smtp.example.com:587?user=info@example.com&pass=YourSecurePassword&from=server@example.com,slack://token@Txxxx/Bxxxx/Cxxxx"
- apprise -vv -t "✅ SUCCESS" -b "$(cat /tmp/backup_run.log)" "mailtos://smtp.example.com:587?user=server@example.com&pass=YourSecurePassword&from=server@example.com&to=receiver@example.com,slack://token@Txxxx/Bxxxx/Cxxxx"
```
### Native Apprise Configuration in Borgmatic 1.8.4+
@ -160,7 +164,7 @@ apprise:
- fail
services:
- url: mailto://smtp.example.com:587?user=info@example.com&pass=YourSecurePassword&from=server@example.com
- url: mailtos://smtp.example.com:587?user=server@example.com&pass=YourSecurePassword&from=server@example.com&to=receiver@example.com
label: mail
- url: slack://token@Txxxx/Bxxxx/Cxxxx
label: slack

Wyświetl plik

@ -1,19 +1,13 @@
version: '3'
services:
borgmatic:
container_name: borg-restore
cap_add:
- SYS_ADMIN
volumes:
- /host/mount/location:/restore
security_opt:
- apparmor:unconfined
- label:disable
devices:
- /dev/fuse:/dev/fuse
command: /bin/sh

Wyświetl plik

@ -1,4 +1,3 @@
version: '3'
services:
borgmatic:
image: ghcr.io/borgmatic-collective/borgmatic
@ -7,7 +6,6 @@ services:
- ${VOLUME_SOURCE}:/mnt/source:ro # backup source
- ${VOLUME_TARGET}:/mnt/borg-repository # backup target
- ${VOLUME_ETC_BORGMATIC}:/etc/borgmatic.d/ # borgmatic config file(s) + crontab.txt
- ${VOLUME_BORGMATIC_STATE}:/root/.borgmatic # borgmatic state files
- ${VOLUME_BORG_CONFIG}:/root/.config/borg # config and keyfiles
- ${VOLUME_SSH}:/root/.ssh # ssh key for remote repositories
- ${VOLUME_BORG_CACHE}:/root/.cache/borg # checksums used for deduplication

Wyświetl plik

Wyświetl plik

@ -0,0 +1 @@
#!/usr/bin/execlineb -P

Wyświetl plik

@ -0,0 +1,71 @@
#!/usr/bin/with-contenv bash
# Function to log debugging information
log_debug_info() {
if [ "${DEBUG_SECRETS}" = "true" ] || [ "${DEBUG_SECRETS}" = "1" ]; then
echo "DEBUG: $1"
fi
}
# Path to the environment file
ENV_FILE="/etc/s6-overlay/env/cron-env"
# Create or clear the environment file
> "$ENV_FILE"
# Array to store debug information
declare -a debug_info
# Loop through all environment variables that start with 'BORG' or 'YOUR'.
for var_name in $(set | grep -E '^BORG|^YOUR' | awk -F= '{print $1}'); do
# Retrieve the current value of each environment variable.
var_value=$(eval echo \$$var_name)
# Check if the variable's name ends with '_FILE'.
if [[ "$var_name" =~ _FILE$ ]]; then
# Strip the '_FILE' suffix to obtain the corresponding variable name.
original_var_name=${var_name%_FILE}
# Retrieve the value of the original environment variable, if it exists.
original_var_value=$(eval echo \$$original_var_name)
# Ensure the *_FILE variable is valid, and the referenced file exists and is not empty.
if [ -n "$var_value" ] && [ -s "$var_value" ]; then
# Notify user if original variable is being overwritten.
if [ -n "$original_var_value" ]; then
debug_info+=("Note: $original_var_name was already set but is being overwritten by $var_name")
fi
# Update the original variable with the content of the file.
var_content=$(cat "$var_value")
export "$original_var_name"="$var_content"
debug_info+=("Setting $original_var_name from the content of $var_value")
# Add the variable to the environment file
echo "export $original_var_name=\"$var_content\"" >> "$ENV_FILE"
# Unset the *_FILE environment variable.
unset "$var_name"
debug_info+=("Unsetting $var_name")
# Add the final value of the original variable
debug_info+=("$original_var_name is now set to: $var_content")
else
# Issue an error if the *_FILE variable is not properly set, or the file does not exist or is empty.
debug_info+=("Error: File $var_value does not exist or is empty.")
fi
else
# Directly add non-_FILE variables to the environment file
echo "export $var_name=\"$var_value\"" >> "$ENV_FILE"
# Add debug info for non-_FILE variables
debug_info+=("Variable $var_name is set to: \"$var_value\"")
fi
done
# Output all debug information at once
if [ "${DEBUG_SECRETS}" = "true" ] || [ "${DEBUG_SECRETS}" = "1" ]; then
echo "Debug Information:"
for info in "${debug_info[@]}"; do
echo "$info"
done
fi

Wyświetl plik

@ -0,0 +1 @@
oneshot

Wyświetl plik

@ -0,0 +1 @@
/etc/s6-overlay/s6-rc.d/secrets/run

Wyświetl plik

@ -1,5 +1,10 @@
#!/command/with-contenv bash
# Load the environment variables from the secrets service
if [ -f /etc/s6-overlay/env/cron-env ]; then
source /etc/s6-overlay/env/cron-env
fi
# Version variables
borgver=$(borg --version)
borgmaticver=$(borgmatic --version)
@ -35,70 +40,18 @@ then
echo "-----------------------------------"
fi
# Enable initial debug logging based on the DEBUG_SECRETS environment variable.
# Logs the initial values of BORG_PASSPHRASE and BORG_PASSPHRASE_FILE.
if [ "${DEBUG_SECRETS}" = "true" ] || [ "${DEBUG_SECRETS}" = "1" ]; then
echo "Before: BORG_PASSPHRASE: ${BORG_PASSPHRASE}"
echo "Before: BORG_PASSPHRASE_FILE: ${BORG_PASSPHRASE_FILE}"
echo "Before: YOUR_PASSPHRASE: ${YOUR_PASSPHRASE}"
echo "Before: YOUR_PASSPHRASE_FILE: ${YOUR_PASSPHRASE_FILE}"
fi
# Loop through all environment variables that start with 'BORG'.
for var_name in $(set | grep -E '^BORG|^YOUR' | awk -F= '{print $1}'); do
# Retrieve the current value of each environment variable.
var_value=$(eval echo \$$var_name)
# Check if the variable's name ends with '_FILE'.
if [[ "$var_name" =~ _FILE$ ]]; then
# Strip the '_FILE' suffix to obtain the corresponding variable name.
original_var_name=${var_name%_FILE}
# Retrieve the value of the original environment variable, if it exists.
original_var_value=$(eval echo \$$original_var_name)
# Ensure the *_FILE variable is valid, and the referenced file exists and is not empty.
if [ -n "$var_value" ] && [ -s "$var_value" ]; then
# Notify user if original variable is being overwritten.
if [ -n "$original_var_value" ]; then
echo "Note: $original_var_name was already set but is being overwritten by $var_name"
fi
# Update the original variable with the content of the file.
export "$original_var_name"=$(cat "$var_value")
echo "Setting $original_var_name from the content of $var_value"
# Unset the *_FILE environment variable.
unset "$var_name"
echo "Unsetting $var_name"
else
# Issue an error if the *_FILE variable is not properly set, or the file does not exist or is empty.
echo "Error: File $var_value does not exist or is empty."
fi
fi
done
# Enable final debug logging based on the DEBUG_SECRETS environment variable.
# Logs the final values of BORG_PASSPHRASE and BORG_PASSPHRASE_FILE.
if [ "${DEBUG_SECRETS}" = "true" ] || [ "${DEBUG_SECRETS}" = "1" ]; then
echo "Before: BORG_PASSPHRASE: ${BORG_PASSPHRASE}"
echo "Before: BORG_PASSPHRASE_FILE: ${BORG_PASSPHRASE_FILE}"
echo "Before: YOUR_PASSPHRASE: ${YOUR_PASSPHRASE}"
echo "Before: YOUR_PASSPHRASE_FILE: ${YOUR_PASSPHRASE_FILE}"
fi
# Disable cron if it's set to disabled.
if [[ "$CRON" = "false" ]]; then
if [[ "$BACKUP_CRON" = "false" ]]; then
echo "Disabling cron, removing configuration"
# crontab -r # quite destructive
# echo -n > /etc/crontabs/root # Empty config, doesn't look as nice with "crontab -l"
echo "# Cron disabled" > /etc/crontabs/root
echo "Cron is now disabled"
# Apply default or custom cron if $CRON is unset or set (not null):
elif [[ -v CRON ]]; then
CRON="${CRON:-"0 1 * * *"}"
CRON_COMMAND="${CRON_COMMAND:-"borgmatic --stats -v 0 2>&1"}"
echo "$CRON $CRON_COMMAND" > /etc/crontabs/root
# Apply default or custom cron if $BACKUP_CRON is unset or set (not null):
elif [[ -v BACKUP_CRON ]]; then
BACKUP_CRON="${BACKUP_CRON:-"0 1 * * *"}"
CRON_COMMAND="${CRON_COMMAND:-"/usr/local/bin/borgmatic --stats -v 0 2>&1"}"
echo "$BACKUP_CRON $CRON_COMMAND" > /etc/crontabs/root
echo "Applying custom cron"
# If nothing is set, revert to default behaviour
else