v4
This commit is contained in:
parent
ed2afd876c
commit
4e3fa8285b
44
README.md
44
README.md
|
@ -1,10 +1,52 @@
|
||||||
# ckupeye
|
# ckupeye
|
||||||
|
|
||||||
Small bash script for entire server backups.
|
Small bash script for entire filesystem backups.
|
||||||
|
|
||||||
It backups filesystems, sure, but also creates workable version of
|
It backups filesystems, sure, but also creates workable version of
|
||||||
PostgreSQL / MariaDB backups, Pacman / Apt software list, ACL.
|
PostgreSQL / MariaDB backups, Pacman / Apt software list, ACL.
|
||||||
|
|
||||||
It then uses [BorgBackup](https://www.borgbackup.org/) to create, compress, encrypt and send the backups.
|
It then uses [BorgBackup](https://www.borgbackup.org/) to create, compress, encrypt and send the backups.
|
||||||
|
You'd probably want to be familiar with the latter if you want to understand this script fully.
|
||||||
|
|
||||||
|
**DISCLAIMER:** This program is just a publication of my personal script.
|
||||||
|
It haven't been tested outside of my (very) specific use case.
|
||||||
|
You'd probably better use it as a reference rather than as is.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Basically it's just the `ckupeye` script.
|
||||||
|
Have some example installation instructions, for the client.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://git.frogeye.fr/geoffrey/ckupeye.git /opt/ckupeye
|
||||||
|
ln -s /opt/ckupeye/ckupeye /usr/local/bin/ckupeye
|
||||||
|
mkdir /etc/ckupeye
|
||||||
|
mkdir /var/lib/ckupeye
|
||||||
|
cp /opt/ckupeye/config.sample.sh /etc/ckupeye/config.sh
|
||||||
|
ssh-keygen -t ed25519 -C ckupeye@$(cat /etc/hostname) -f /etc/ckupeye/id_ed25519
|
||||||
|
$EDITOR /etc/ckupeye/config.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
And to run it, just `ckupeye`.
|
||||||
|
|
||||||
|
Or, if you don't want to pollute your '/' namespace,
|
||||||
|
provide an argument to the configuration file, as so:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
/path/to/ckupeye /path/to/config.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
For the server, I would recommend having an account for backups (or one account per backup for extra security),
|
||||||
|
and use a [ssh forced command](https://borgbackup.readthedocs.io/en/stable/usage/serve.html#examples).
|
||||||
|
Add something like the following to the user's `~/.ssh/authorized_keys`:
|
||||||
|
|
||||||
|
```
|
||||||
|
restrict,command="borg serve --restrict-to-repository=/var/lib/borg/clientname --append-only --storage-quota=150G" ssh-ed25519 ... ckupeye@clientname
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
At minimum you will need to set `BORG_REPO` and a `BORG_PASSPHRASE` in the config file.
|
||||||
|
|
||||||
## Notation
|
## Notation
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ fi
|
||||||
# Default configuration
|
# Default configuration
|
||||||
#
|
#
|
||||||
|
|
||||||
: "${BASE_DIR:="/var/ckupeye"}"
|
: "${BASE_DIR:="/var/lib/ckupeye"}"
|
||||||
|
|
||||||
# Directories to backup
|
# Directories to backup
|
||||||
[ -z ${BACKUP_FILES+x} ] && BACKUP_FILES=("/") # What to include in the backup
|
[ -z ${BACKUP_FILES+x} ] && BACKUP_FILES=("/") # What to include in the backup
|
||||||
|
@ -76,7 +76,7 @@ fi
|
||||||
: "${EXPORT_MARIADB_CREDENTIALS:="$BASE_DIR/mariadb.cnf"}"
|
: "${EXPORT_MARIADB_CREDENTIALS:="$BASE_DIR/mariadb.cnf"}"
|
||||||
|
|
||||||
# Pruning the backup
|
# Pruning the backup
|
||||||
: "${PRUNE:="true"}"
|
: "${PRUNE:="false"}"
|
||||||
: "${PRUNE_OPTIONS:="--keep-hourly 24 --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --keep-yearly 10"}"
|
: "${PRUNE_OPTIONS:="--keep-hourly 24 --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --keep-yearly 10"}"
|
||||||
|
|
||||||
# Borg specific
|
# Borg specific
|
||||||
|
@ -88,15 +88,18 @@ fi
|
||||||
: "${BORG_ENCRYPTION:="repokey-blake2"}" # Passed `borg init`
|
: "${BORG_ENCRYPTION:="repokey-blake2"}" # Passed `borg init`
|
||||||
|
|
||||||
# Answer borg questions
|
# Answer borg questions
|
||||||
: "${BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK:=no}"
|
: "${BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK:="no"}"
|
||||||
: "${BORG_RELOCATED_REPO_ACCESS_IS_OK:=no}"
|
: "${BORG_RELOCATED_REPO_ACCESS_IS_OK:="no"}"
|
||||||
: "${BORG_CHECK_I_KNOW_WHAT_I_AM_DOING:=NO}"
|
: "${BORG_CHECK_I_KNOW_WHAT_I_AM_DOING:="NO"}"
|
||||||
: "${BORG_DELETE_I_KNOW_WHAT_I_AM_DOING:=NO}"
|
: "${BORG_DELETE_I_KNOW_WHAT_I_AM_DOING:="NO"}"
|
||||||
: "${BORG_RECREATE_I_KNOW_WHAT_I_AM_DOING:=NO}"
|
: "${BORG_RECREATE_I_KNOW_WHAT_I_AM_DOING:="NO"}"
|
||||||
|
|
||||||
# Ckupeye specific
|
# Ckupeye specific
|
||||||
: "${CLIENT_RUNFILE:="$BASE_DIR/ckupeye.pid"}"
|
: "${CLIENT_RUNFILE:="$BASE_DIR/ckupeye.pid"}"
|
||||||
|
|
||||||
|
# Vim macro to copy the above defaults to the config file (minus the arrays):
|
||||||
|
# :%s/: "\${\(\w\+\):=\(.\+\)}"/\1=\2
|
||||||
|
|
||||||
# Export borg environment variables
|
# Export borg environment variables
|
||||||
export BORG_REPO
|
export BORG_REPO
|
||||||
export BORG_PASSPHRASE
|
export BORG_PASSPHRASE
|
||||||
|
@ -129,7 +132,7 @@ echo $$ > $CLIENT_RUNFILE
|
||||||
|
|
||||||
if [ ! -z "$BORG_SSH_IDENTITY_FILE" ]
|
if [ ! -z "$BORG_SSH_IDENTITY_FILE" ]
|
||||||
then
|
then
|
||||||
export BORG_RSH="ssh -oBatchMode=yes -i $BORG_SSH_IDENTITY_FILE $BORG_RSH_EXTRA"
|
export BORG_RSH="ssh -oIdentitiesOnly=yes -oBatchMode=yes -i $BORG_SSH_IDENTITY_FILE $BORG_RSH_EXTRA"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "→ Opening repository"
|
echo "→ Opening repository"
|
||||||
|
@ -164,24 +167,25 @@ then
|
||||||
etckeeper commit "$EXPORT_ETCKEEPER_MESSAGE" &> /dev/null &
|
etckeeper commit "$EXPORT_ETCKEEPER_MESSAGE" &> /dev/null &
|
||||||
fi
|
fi
|
||||||
|
|
||||||
export EXPORT_FILEs=""
|
|
||||||
function _feedExport() { # export_file
|
function _feedExport() { # export_file
|
||||||
touch "$1"
|
touch "$1"
|
||||||
chmod 700 "$1"
|
chmod 700 "$1"
|
||||||
cat - > "$1"
|
cat - > "$1"
|
||||||
export EXPORT_FILES="$1 $EXPORT_FILES"
|
|
||||||
}
|
}
|
||||||
|
EXPORT_FILEs=""
|
||||||
|
|
||||||
if $EXPORT_ACL
|
if $EXPORT_ACL
|
||||||
then
|
then
|
||||||
echo → Exporting ACL
|
echo → Exporting ACL
|
||||||
sudo getfacl -R "$EXPORT_ACL_DESTINATION[@]" 2> /dev/null | _feedExport "$EXPORT_ACL_FILE"
|
sudo getfacl -R "$EXPORT_ACL_DESTINATION[@]" 2> /dev/null | _feedExport "$EXPORT_ACL_FILE"
|
||||||
|
EXPORT_FILES="$EXPORT_ACL_FILE $EXPORT_FILES"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if $EXPORT_POSTGRESQL
|
if $EXPORT_POSTGRESQL
|
||||||
then
|
then
|
||||||
echo → Exporting PostgreSQL
|
echo → Exporting PostgreSQL
|
||||||
pg_dumpall $EXPORT_POSTGRESQL_OPTIONS | _feedExport "$EXPORT_POSTGRESQL_FILE"
|
pg_dumpall $EXPORT_POSTGRESQL_OPTIONS | _feedExport "$EXPORT_POSTGRESQL_FILE"
|
||||||
|
EXPORT_FILES="$EXPORT_POSTGRESQL_FILE $EXPORT_FILES"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if $EXPORT_MARIADB
|
if $EXPORT_MARIADB
|
||||||
|
@ -192,28 +196,31 @@ then
|
||||||
EXPORT_MARIADB_OPTIONS="--defaults-extra-file=$EXPORT_MARIADB_CREDENTIALS $EXPORT_MARIADB_OPTIONS"
|
EXPORT_MARIADB_OPTIONS="--defaults-extra-file=$EXPORT_MARIADB_CREDENTIALS $EXPORT_MARIADB_OPTIONS"
|
||||||
fi
|
fi
|
||||||
mysqldump $EXPORT_MARIADB_OPTIONS | _feedExport "$EXPORT_MARIADB_FILE"
|
mysqldump $EXPORT_MARIADB_OPTIONS | _feedExport "$EXPORT_MARIADB_FILE"
|
||||||
|
EXPORT_FILES="$EXPORT_MARIADB_FILE $EXPORT_FILES"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if $EXPORT_PACMAN
|
if $EXPORT_PACMAN
|
||||||
then
|
then
|
||||||
echo → Exporting Pacman package list
|
echo → Exporting Pacman package list
|
||||||
pacman -Qeq | _feedExport "$EXPORT_PACMAN_FILE"
|
pacman -Qeq | _feedExport "$EXPORT_PACMAN_FILE"
|
||||||
|
EXPORT_FILES="$EXPORT_PACMAN_FILE $EXPORT_FILES"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if $EXPORT_APT
|
if $EXPORT_APT
|
||||||
then
|
then
|
||||||
echo → Exporting Apt package list
|
echo → Exporting Apt package list
|
||||||
apt list --installed 2> /dev/null | _feedExport "$EXPORT_APT_FILE"
|
apt list --installed 2> /dev/null | _feedExport "$EXPORT_APT_FILE"
|
||||||
|
EXPORT_FILES="$EXPORT_APT_FILE $EXPORT_FILES"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "→ Transfering files"
|
echo "→ Transfering files"
|
||||||
|
|
||||||
for exclude in "${BACKUP_EXCLUDES[@]}"
|
for exclude in "${BACKUP_EXCLUDES[@]}"
|
||||||
do
|
do
|
||||||
BACKUP_OPTIONS="$BORG_CREATE_OPTIONS --exclude=$exclude"
|
BACKUP_OPTIONS="$BACKUP_OPTIONS --exclude=$exclude"
|
||||||
done
|
done
|
||||||
|
|
||||||
$BORG_EXECUTABLE $BORG_OPTIONS create --stats $BACKUP_OPTIONS "${BORG_REPO}::${BACKUP_TAG}" ${BACKUP_FILES[@]} 2>&1
|
$BORG_EXECUTABLE $BORG_OPTIONS create --stats $BACKUP_OPTIONS "${BORG_REPO}::${BACKUP_TAG}" ${BACKUP_FILES[@]} $EXPORT_FILES 2>&1
|
||||||
|
|
||||||
echo "→ Remove temporary files"
|
echo "→ Remove temporary files"
|
||||||
rm -f $EXPORT_FILES
|
rm -f $EXPORT_FILES
|
59
config.sample.sh
Normal file
59
config.sample.sh
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
BASE_DIR="/var/lib/ckupeye"
|
||||||
|
BORG_REPO="ssh://user@server:port/~/client"
|
||||||
|
BORG_PASSPHRASE=""
|
||||||
|
|
||||||
|
# Directories to backup
|
||||||
|
BACKUP_FILES=("/") # What to include in the backup
|
||||||
|
BACKUP_EXCLUDES=("/var/cache" "**.lock" "**/.cache/") # What to exclue from the backup
|
||||||
|
BACKUP_TAG="$(date -Isec)" # “Name” of the backup
|
||||||
|
BACKUP_OPTIONS="--one-file-system --compression auto,zstd" # Configuration of the backup
|
||||||
|
|
||||||
|
# Default folder where the database / package managers / ACL exported data will be stored.
|
||||||
|
EXPORT_DIR="$BASE_DIR"
|
||||||
|
|
||||||
|
# Things to export the data of
|
||||||
|
EXPORT_MARIADB="false"
|
||||||
|
EXPORT_POSTGRESQL="false"
|
||||||
|
EXPORT_APT="false"
|
||||||
|
EXPORT_PACMAN="false"
|
||||||
|
EXPORT_ACL="false"
|
||||||
|
EXPORT_ETCKEEPER="false"
|
||||||
|
|
||||||
|
# Where to put the exported data
|
||||||
|
EXPORT_MARIADB_FILE="$EXPORT_DIR/mariadb.sql"
|
||||||
|
EXPORT_POSTGRESQL_FILE="$EXPORT_DIR/postgresql.sql"
|
||||||
|
EXPORT_APT_FILE="$EXPORT_DIR/apt.list"
|
||||||
|
EXPORT_PACMAN_FILE="$EXPORT_DIR/pacman.list"
|
||||||
|
EXPORT_ACL_FILE="$EXPORT_DIR/acl.list"
|
||||||
|
|
||||||
|
# Options for exporting data
|
||||||
|
EXPORT_ACL_DIRECTORIES=("${BACKUP_FILES[@]}")
|
||||||
|
EXPORT_ETCKEEPER_MESSAGE="ckupeye backup for $(date -Isec)"
|
||||||
|
EXPORT_POSTGRESQL_OPTIONS=""
|
||||||
|
EXPORT_MARIADB_OPTIONS="--all-databases --flush-privileges"
|
||||||
|
EXPORT_MARIADB_CREDENTIALS="$BASE_DIR/mariadb.cnf"
|
||||||
|
|
||||||
|
# Pruning the backup
|
||||||
|
PRUNE="false"
|
||||||
|
PRUNE_OPTIONS="--keep-hourly 24 --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --keep-yearly 10"
|
||||||
|
|
||||||
|
# Borg specific
|
||||||
|
BORG_BASE_DIR="$BASE_DIR"
|
||||||
|
BORG_EXECUTABLE="$(command -v borg)" # Path to BorgBackup executable
|
||||||
|
BORG_SSH_IDENTITY_FILE="/etc/ckupeye/id_ed25519" # Identity file to use to connect to remote repo (will overwrite $BORG_RSH)
|
||||||
|
BORG_RSH_EXTRA="" # Options to add to $BORG_RSH (even after overriden by BORG_SSH_IDENTITY_FILE)
|
||||||
|
BORG_OPTIONS="" # Additional options to pass to BorgBackup
|
||||||
|
BORG_ENCRYPTION="repokey-blake2" # Passed `borg init`
|
||||||
|
|
||||||
|
# Answer borg questions
|
||||||
|
BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK="no"
|
||||||
|
BORG_RELOCATED_REPO_ACCESS_IS_OK="no"
|
||||||
|
BORG_CHECK_I_KNOW_WHAT_I_AM_DOING="NO"
|
||||||
|
BORG_DELETE_I_KNOW_WHAT_I_AM_DOING="NO"
|
||||||
|
BORG_RECREATE_I_KNOW_WHAT_I_AM_DOING="NO"
|
||||||
|
|
||||||
|
# Ckupeye specific
|
||||||
|
CLIENT_RUNFILE="$BASE_DIR/ckupeye.pid"
|
||||||
|
|
Loading…
Reference in a new issue