diff --git a/README.md b/README.md index 54627e0..73fc554 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,14 @@ # Bash Scripts collection -TODO: Need install packages for each script +For email notifications: `apt install postfix` + +Configure as internet site and setup this config: + +`postconf -e "inet_interfaces = loopback-only"` + +`systemctl restart postfix` + +`systemctl enable postfix` ## Permanent enviroment variables in ~/.profile diff --git a/backup_gitea.sh b/backup_gitea.sh deleted file mode 100644 index f486139..0000000 --- a/backup_gitea.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash - -PATH=$PATH:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin - -GOTIFY_TOKEN="token" -GOTIFY_MESSAGE="Backup task init: **"`date +"%d/%m/%Y %H:%M:%S"`"** \r" -GITEA_DIR="/path/to/gitea" -BACKUP_FILE="gitea-backup_"`date +\%Y\%m\%d`".zip" -REMOTE_SERVER="remote.example.com" -REMOTE_PATH="/path/to/remote/store/backups/" - -# gitea -su - gitea -s /bin/bash -c "$GITEA_DIR/gitea dump -c $GITEA_DIR/custom/conf/app.ini --file $BACKUP_FILE --tempdir $GITEA_DIR/" -rsync -AaxzPh --remove-source-files "$GITEA_DIR/$BACKUP_FILE" "$REMOTE_SERVER:$REMOTE_PATH" - -GOTIFY_MESSAGE="${GOTIFY_MESSAGE} Backup task end: **"`date +"%d/%m/%Y %H:%M:%S"`"** \r" - -# send gotify notification -sh ./gotifypush.sh "Gitea $(hostname) Backup" "$GOTIFY_MESSAGE" 5 "$GOTIFY_TOKEN" diff --git a/backup_nc.sh b/backup_nc.sh deleted file mode 100644 index 24f80b7..0000000 --- a/backup_nc.sh +++ /dev/null @@ -1,94 +0,0 @@ -#!/bin/bash - -################################################################################### -# Nextcloud Backups as incremental mode, using rdiff-backup -# -# 1. Backup database and send to remote backups server throught rsync using -# ssh public/private key configuration. -# 2. Set X days to preserve db backups -# 3. Backup data folder of nextcloud using rdiff-backup (https://rdiff-backup.net/) -# 4. Set X days to preserve rdiff-backups increments -# 5. Get report statistics of rdiff-backup and send push message throught gotify -# self-hosted server (https://gotify.net/). -# -# Tools needed: mysqldump, gzip. rsync, rdiff-backup, curl -# TODO: save current version 'sudo -u www-data php /var/www/html/nextcloud/occ config:system:get version' -################################################################################### - -PATH=$PATH:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin - -# variables push notifications -readonly GOTIFY_TOKEN="" -readonly GOTIFY_HOST="" -readonly GOTIFY_PRIORITY=5 -# backup db variables -readonly BACKUP_DB_FILE="nextcloud-sqlbkp-"`date +\%Y\%m\%d`".sql" -readonly DB_HOST="" -readonly DB_USER="" -readonly DB_PASS="" -readonly DB_NAME="" -# backup data variables -readonly NEXTCLOUD_DATA="" -readonly NEXTCLOUD_DIR="" -readonly INCLUDE_LIST="include-list" -# remote settings -readonly REMOTE_SERVER="" -# TODO: Use $(hostname) "/path/to/example/"`hostname`"/nextcloud" -readonly REMOTE_PATH="" -readonly REMOTE_NC_DATA_FOLDER="files" -readonly REMOTE_NC_DB_FOLDER="db" -readonly REMOTE_NC_DIR_FOLDER="dir" -readonly BACKUP_PRESERVE_DAYS=60 - -# create include list file and set exclude logs -touch $INCLUDE_LIST -cat > $INCLUDE_LIST < $BACKUP_DB_FILE -gzip $BACKUP_DB_FILE - -# TODO: force create multiple paths (mkdir -p) if not exist with rsync trick -# https://www.schwertly.com/2013/07/forcing-rsync-to-create-a-remote-path-using-rsync-path/ -rsync -AaxzPh --remove-source-files "$BACKUP_DB_FILE.gz" "$REMOTE_SERVER:$REMOTE_PATH/$REMOTE_NC_DB_FOLDER" - -# clear X days old remote db backups -ssh $REMOTE_SERVER 'bash -s' << EOF -find "$REMOTE_PATH/$REMOTE_NC_DB_FOLDER" -maxdepth 1 -mtime +$BACKUP_PRESERVE_DAYS -print -exec "rm" -R {} \; -EOF - -# rdiff-backup all dir of nextcloud -rdiff-backup backup $NEXTCLOUD_DIR "$REMOTE_SERVER::$REMOTE_PATH/$REMOTE_NC_DIR_FOLDER" -# clear X days old increments of backup dir -rdiff-backup remove increments --older-than "${BACKUP_PRESERVE_DAYS}D" "$REMOTE_SERVER::$REMOTE_PATH/$REMOTE_NC_DIR_FOLDER" - -# rdiff-backup all data of nextcloud -OUT=$(rdiff-backup backup --print-statistics --include-globbing-filelist $INCLUDE_LIST $NEXTCLOUD_DATA \ - "$REMOTE_SERVER::$REMOTE_PATH/$REMOTE_NC_DATA_FOLDER") -# set output lines into array and append notification message -readarray -t stats <<<"$OUT" -for val in "${stats[@]}"; do - line=$(echo $val | tr -d '-') - MESSAGE="${MESSAGE} $line \r" -done - -# clear X days old increments of backup data -rdiff-backup remove increments --older-than "${BACKUP_PRESERVE_DAYS}D" \ - "$REMOTE_SERVER::$REMOTE_PATH/$REMOTE_NC_DATA_FOLDER" - -MESSAGE="${MESSAGE} Backup task end: **"`date +"%d/%m/%Y %H:%M:%S"`"** \r" - -rm $INCLUDE_LIST - -# send gotify notification -TITLE="NC $(hostname) Backup" -EXTRAS="{\"client::display\": {\"contentType\": \"text/markdown\"}}" -curl -X POST "$GOTIFY_HOST/message?token=$GOTIFY_TOKEN" -H "accept: application/json" -H "Content-Type: application/json" \ - -d "{ \"message\": \"${MESSAGE}\", \"priority\": ${GOTIFY_PRIORITY}, \"title\": \"${TITLE}\", \"extras\": ${EXTRAS} }" diff --git a/backups/backup-container.sh b/backups/backup-container.sh new file mode 100644 index 0000000..6dbf915 --- /dev/null +++ b/backups/backup-container.sh @@ -0,0 +1,113 @@ +#!/bin/bash + +######################################################### +# # +# Script LXD Backup ct + còpia remota # +# + retenció + email + mida + temps + integritat # +# # +# Requirements # +# - Add cron to lxd group: usermod -aG lxd root # +# and restart crond: systemctl restart crond # +# - Install postfix, set as internet site # +# and set configuration as: # +# postconf -e "inet_interfaces = loopback-only" # +######################################################### + +# Assegurar els paths per al cron +PATH=$PATH:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/var/lib/snapd/snap/bin + +# --- CONFIGURACIÓ --- +CONTAINER="$1" +REMOTE_HOST="estudiset.backups" +REMOTE_DIR="/home/debian/backups/studi7/lxd" +LOCAL_DIR="/var/backups/lxd" +EMAIL="roger@estudiset.cat" +DATE=$(date +"%Y-%m-%d_%H-%M-%S") + +# --- VALIDACIÓ --- +if [ -z "$CONTAINER" ]; then + echo "Ús: $0 " + exit 1 +fi + +if ! lxc info "$CONTAINER" >/dev/null 2>&1; then + MSG="Error: el contenidor '$CONTAINER' no existeix." + echo "$MSG" + echo "$MSG" | mail -s "[Backup LXD] container $CONTAINER - ERROR" "$EMAIL" + exit 1 +fi + +mkdir -p "$LOCAL_DIR" + +# --- TEMPS INICI --- +START_TIME=$(date +%s) + +# --- CREAR BACKUP LOCAL --- +BACKUP_FILE="${LOCAL_DIR}/${CONTAINER}_${DATE}.zstd" + +echo "Creant backup del contenidor '$CONTAINER'..." +if ! lxc export "$CONTAINER" "$BACKUP_FILE"; then + MSG="Error: no s'ha pogut crear el backup del contenidor $CONTAINER." + echo "$MSG" + echo "$MSG" | mail -s "[Backup LXD] container $CONTAINER - ERROR" "$EMAIL" + exit 1 +fi + +# Mida del backup +BACKUP_SIZE=$(du -h "$BACKUP_FILE" | awk '{print $1}') + +# Hash local +LOCAL_HASH=$(sha256sum "$BACKUP_FILE" | awk '{print $1}') + +# --- ENVIAR A SERVIDOR REMOT --- +echo "Enviant backup al servidor remot..." +if ! scp "$BACKUP_FILE" "${REMOTE_HOST}:${REMOTE_DIR}/"; then + MSG="Error: no s'ha pogut copiar el backup al servidor remot." + echo "$MSG" + echo "$MSG" | mail -s "[Backup LXD] container $CONTAINER - ERROR" "$EMAIL" + exit 1 +fi + +# --- VERIFICACIÓ D'INTEGRITAT --- +REMOTE_HASH=$(ssh "${REMOTE_HOST}" "sha256sum ${REMOTE_DIR}/$(basename "$BACKUP_FILE") | awk '{print \$1}'") + +if [ "$LOCAL_HASH" = "$REMOTE_HASH" ]; then + INTEGRITY="OK — la còpia és idèntica" +else + INTEGRITY="ERROR — el hash no coincideix!" +fi + +# --- ELIMINAR BACKUP LOCAL --- +rm -f "$BACKUP_FILE" + +# --- ROTACIÓ DE BACKUPS AL SERVIDOR REMOT --- +ssh "${REMOTE_HOST}" "find ${REMOTE_DIR} -type f -mtime +7 -name '${CONTAINER}_*.zstd' -delete" + +# --- TEMPS FINAL --- +END_TIME=$(date +%s) +TOTAL_TIME=$((END_TIME - START_TIME)) + +H=$((TOTAL_TIME / 3600)) +M=$(((TOTAL_TIME % 3600) / 60)) +S=$((TOTAL_TIME % 60)) + +TIME_FORMAT="${H}h ${M}m ${S}s" + +# --- NOTIFICACIÓ EMAIL --- +SUCCESS_MSG="Backup del contenidor '$CONTAINER' completat correctament. + +Servidor remot: ${REMOTE_HOST} +Ruta: $REMOTE_DIR +Fitxer: $BACKUP_FILE +Mida del backup: ${BACKUP_SIZE} +Temps total del procés: ${TIME_FORMAT} + +Integritat: + - Hash local: ${LOCAL_HASH} + - Hash remot: ${REMOTE_HASH} + - Estat: ${INTEGRITY} +" + +echo "$SUCCESS_MSG" | mail -s "[Backup LXD] contenidor $CONTAINER - OK" "$EMAIL" + +echo "$SUCCESS_MSG" \ No newline at end of file diff --git a/backups/backup_gitea.sh b/backups/backup_gitea.sh new file mode 100644 index 0000000..1196bf5 --- /dev/null +++ b/backups/backup_gitea.sh @@ -0,0 +1,66 @@ +#!/bin/bash + +######################################################### +# # +# Script Backup Gitea + còpia remota + retenció dies # +# + email + mida + temps + integritat # +# # +######################################################### + +# Assegurar els paths per al cron +PATH=$PATH:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin + +# --- CONFIGURACIÓ --- +GITEA_DIR="/opt/gitea" +BACKUP_FILE="gitea-backup_$(date +%Y-%m-%d_%H-%M-%S).tar.gz" +REMOTE_SERVER="estudiset.backups" +REMOTE_PATH="/home/debian/backups/studi7/gitea/" +EMAIL="roger@estudiset.cat" +RETENTION_DAYS=7 + +# Dump gitea +su - gitea -s /bin/bash -c "$GITEA_DIR/gitea dump -c $GITEA_DIR/custom/conf/app.ini --file $GITEA_DIR/$BACKUP_FILE --tempdir $GITEA_DIR/" + +# Mida del backup +BACKUP_SIZE=$(du -h "$GITEA_DIR/$BACKUP_FILE" | awk '{print $1}') + +# Hash local +LOCAL_HASH=$(sha256sum "$GITEA_DIR/$BACKUP_FILE" | awk '{print $1}') + +# --- ENVIAR A SERVIDOR REMOT --- +rsync -AaxzPh --remove-source-files "$GITEA_DIR/$BACKUP_FILE" "$REMOTE_SERVER:$REMOTE_PATH" +if [ $? -ne 0 ]; then + echo "ERROR: No s'ha pogut copiar el backup al servidor remot." | mail -s "[Backup Gitea] ERROR" "$EMAIL" + exit 1 +fi + +# --- HASH REMOT --- +REMOTE_HASH=$(ssh "$REMOTE_SERVER" "sha256sum ${REMOTE_PATH}/${BACKUP_FILE} 2>/dev/null | awk '{print \$1}'") + +if [ "$LOCAL_HASH" = "$REMOTE_HASH" ]; then + INTEGRITY="OK — la còpia és idèntica" +else + INTEGRITY="ERROR — el hash no coincideix!" +fi + +# --- RETENCIÓ DE 7 DIES --- +ssh "$REMOTE_SERVER" "find $REMOTE_PATH -type f -mtime +$RETENTION_DAYS -name 'gitea-backup_*.tar.gz' -delete" + +# --- EMAIL DE RESULTAT --- +MSG="Backup de Gitea completat correctament. + +Servidor remot: $REMOTE_SERVER +Ruta: $REMOTE_PATH +Fitxer: $BACKUP_FILE +Mida: $BACKUP_SIZE + +Integritat: + - Hash local: $LOCAL_HASH + - Hash remot: $REMOTE_HASH + - Estat: $INTEGRITY + +Retenció: S'han eliminat backups de més de 7 dies." + +echo "$MSG" | mail -s "[Backup Gitea] OK" "$EMAIL" + +echo "$MSG" \ No newline at end of file diff --git a/backups/backup_nextcloud.sh b/backups/backup_nextcloud.sh new file mode 100644 index 0000000..a1f8fc6 --- /dev/null +++ b/backups/backup_nextcloud.sh @@ -0,0 +1,115 @@ +#!/bin/bash + +######################################################### +# # +# Script Backup Nextcloud + còpia remota + retenció # +# dies + email + mida + temps + integritat # +# # +######################################################### + +PATH=$PATH:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin + +# --- CONFIGURACIÓ EMAIL --- +EMAIL="roger@estudiset.cat" + +# backup db variables +readonly BACKUP_DB_FILE="nextcloud-sqlbkp-$(date +%Y-%m-%d_%H-%M-%S).sql" +readonly DB_HOST="localhost" +readonly DB_USER="nextcloud" +readonly DB_PASS="3mZlNTeS" +readonly DB_NAME="nextcloud" + +# backup data variables +readonly NEXTCLOUD_DATA="/opt/nextcloud/data" +readonly NEXTCLOUD_DIR="/var/www/html/nextcloud" +readonly INCLUDE_LIST="include-list" + +# remote settings +readonly REMOTE_SERVER="estudiset.backups" +readonly REMOTE_PATH="/home/debian/backups/studi7/nextcloud" +readonly REMOTE_NC_DATA_FOLDER="files" +readonly REMOTE_NC_DB_FOLDER="db" +readonly REMOTE_NC_DIR_FOLDER="dir" +readonly BACKUP_PRESERVE_DAYS=7 + +# init notification message +MESSAGE="Backup Nextcloud iniciat: $(date +"%d/%m/%Y %H:%M:%S")\n\n" + +# create include list file +cat > $INCLUDE_LIST < $BACKUP_DB_FILE +if [ $? -ne 0 ]; then + echo -e "ERROR: Fallada al mysqldump\n" | mail -s "[Backup Nextcloud] ERROR" "$EMAIL" + exit 1 +fi + +gzip "$BACKUP_DB_FILE" + +# --- HASH LOCAL --- +LOCAL_HASH=$(sha256sum "$BACKUP_DB_FILE.gz" | awk '{print $1}') + +# --- ENVIAR A SERVIDOR REMOT --- +rsync -AaxzPh --remove-source-files "$BACKUP_DB_FILE.gz" "$REMOTE_SERVER:$REMOTE_PATH/$REMOTE_NC_DB_FOLDER" +if [ $? -ne 0 ]; then + echo -e "ERROR: Fallada enviant el backup SQL al servidor remot\n" | mail -s "[Backup Nextcloud] ERROR" "$EMAIL" + exit 1 +fi + +# --- HASH REMOT --- +REMOTE_HASH=$(ssh "$REMOTE_SERVER" "sha256sum '$REMOTE_PATH/$REMOTE_NC_DB_FOLDER/$BACKUP_DB_FILE.gz' 2>/dev/null | awk '{print \$1}'") + +# --- COMPARACIÓ --- +if [ "$LOCAL_HASH" = "$REMOTE_HASH" ]; then + DB_INTEGRITY="OK — hash coincident" +else + DB_INTEGRITY="ERROR — hash NO coincideix!" +fi + +MESSAGE+="Backup BD OK\n" +MESSAGE+="Integritat BD:\n" +MESSAGE+=" - Hash local: $LOCAL_HASH\n" +MESSAGE+=" - Hash remot: $REMOTE_HASH\n" +MESSAGE+=" - Estat: $DB_INTEGRITY\n\n" + +# --- NETEJA BACKUPS BD ANTICS --- +ssh $REMOTE_SERVER "find '$REMOTE_PATH/$REMOTE_NC_DB_FOLDER' -maxdepth 1 -mtime +$BACKUP_PRESERVE_DAYS -delete" + +# --- BACKUP DIRECTORI NEXTCLOUD --- +rdiff-backup backup "$NEXTCLOUD_DIR" "$REMOTE_SERVER::$REMOTE_PATH/$REMOTE_NC_DIR_FOLDER" +if [ $? -ne 0 ]; then + echo -e "ERROR: Fallada rdiff-backup del directori Nextcloud\n" | mail -s "[Backup Nextcloud] ERROR" "$EMAIL" + exit 1 +fi + +rdiff-backup remove increments --force --older-than "${BACKUP_PRESERVE_DAYS}D" "$REMOTE_SERVER::$REMOTE_PATH/$REMOTE_NC_DIR_FOLDER" + +MESSAGE+="Backup directori Nextcloud OK\n" + +# --- BACKUP DADES NEXTCLOUD --- +OUT=$(rdiff-backup backup --print-statistics --include-globbing-filelist $INCLUDE_LIST \ + "$NEXTCLOUD_DATA" "$REMOTE_SERVER::$REMOTE_PATH/$REMOTE_NC_DATA_FOLDER") + +if [ $? -ne 0 ]; then + echo -e "ERROR: Fallada rdiff-backup de dades Nextcloud\n" | mail -s "[Backup Nextcloud] ERROR" "$EMAIL" + exit 1 +fi + +MESSAGE+="\nEstadístiques rdiff-backup dades:\n$OUT\n" + +rdiff-backup remove increments --force --older-than "${BACKUP_PRESERVE_DAYS}D" \ + "$REMOTE_SERVER::$REMOTE_PATH/$REMOTE_NC_DATA_FOLDER" + +MESSAGE+="\nBackup finalitzat: $(date +"%d/%m/%Y %H:%M:%S")\n" + +rm $INCLUDE_LIST + +# --- ENVIAR EMAIL --- +echo -e "$MESSAGE" | mail -s "[Backup Nextcloud] OK" "$EMAIL" + +echo -e "$MESSAGE"