This repository was archived by the owner on Mar 24, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathbackup.sh
More file actions
261 lines (221 loc) · 8.15 KB
/
backup.sh
File metadata and controls
261 lines (221 loc) · 8.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
#!/usr/bin/env bash
# BorgGuard Backup Script
# Created by: KeepItTechie
# YouTube Channel: https://youtube.com/@KeepItTechie
# Blog: https://docs.keepittechie.com/
# Purpose:
# This script automates the process of creating and managing encrypted backups using BorgBackup.
# BorgGuard simplifies the setup and execution of secure backups by handling tasks such as:
# - Creating and storing secure passwords for encryption.
# - Initializing new Borg repositories.
# - Automating the backup process with detailed progress and status messages.
# - Providing both manual and automatic password generation options.
# - Ensuring strong password policies are enforced for security.
# - Verifying passwords to ensure they match the stored hash before performing operations.
# - Storing and retrieving password hashes securely.
# This script was created to make it easier for Linux users to secure their data with encrypted backups.
# By reducing the manual configuration required, BorgGuard provides a quick and efficient way to safeguard
# important data.
# Please review the script before running it on your system to ensure it meets your requirements and to
# understand the changes it will make. Customize the backup directory and other settings as needed to
# suit your environment.
# Full details and instructions can be found on my GitHub repository:
# https://github.com/keepittechie/borgguard
_____ _____ _
| __ | ___ ___ ___ | __ | ___ ___ | |_ _ _ ___
| __ -|| . || _|| . || __ -|| .'|| _|| '_|| | || . |
|_____||___||_| |_ ||_____||__,||___||_,_||___|| _|
|___| |_|
CONFIG_FILE="borgguard.conf"
# Load configuration file
load_config() {
if [ ! -f "$CONFIG_FILE" ]; then
echo "Error: Configuration file $CONFIG_FILE not found!"
exit 1
fi
source "$CONFIG_FILE"
}
# Dependencies check
check_dependencies() {
for dep in borg pwgen python3; do
if ! command -v $dep &> /dev/null; then
echo "Error: $dep is not installed. Please install it and try again."
exit 1
fi
done
}
# Logging function
log() {
local msg="$1"
echo "$(date +'%Y-%m-%d %H:%M:%S') - $msg" | tee -a /var/log/borgguard.log
}
# Store password securely
store_password() {
local passwd="$1"
local passwd_location="$HOME/passwd_bytes.borg"
python3 << ENDOFpy
import os, hashlib
passwd = "$passwd"
salt = os.urandom(32)
password_hash = hashlib.pbkdf2_hmac("sha256", passwd.encode("utf-8"), salt, 100000)
storage = salt + password_hash
with open('$passwd_location', 'bw') as f:
f.write(storage)
ENDOFpy
}
# Read password with asterisks
passd_with_asterisk() {
stty -echo
local CHAR PASSWORD
while IFS= read -p "" -r -s -n 1 CHAR; do
if [[ $CHAR == $'\0' ]]; then
break
elif [[ $CHAR == $'\177' ]]; then
if [ ${#PASSWORD} -gt 0 ]; then
PASSWORD="${PASSWORD%?}"
printf '\b \b'
fi
else
PASSWORD+="$CHAR"
printf '*'
fi
done
stty echo
printf '\n'
eval "$1='$PASSWORD'"
}
# Check password length and special character
check_passwd_len_char() {
local password="$1"
local special_char_check=$(printf %s "$password" | tr -d "[:alnum:]")
local length_check=${#password}
if [ "$length_check" -lt 6 ] || [ -z "$special_char_check" ]; then
echo -e "\033[5;31;40m\nPassword is not strong enough\033[0m"
echo "Your password needs to be at least 6 characters long and contain at least one special character."
return 1
else
return 0
fi
}
# Automatically set password
auto_setting_passwd() {
local npasswd=$(pwgen -ysBv 15 1)
echo "$npasswd" > ./config.borg
export BORG_PASSPHRASE="$npasswd"
}
# Manually set password
man_setting_passwd() {
local passwd password
for i in {1..4}; do
echo -n "Enter a password: "
passd_with_asterisk password
passwd="$password"
if check_passwd_len_char "$passwd"; then
echo -n "Verify your password: "
passd_with_asterisk password
if [ "$passwd" == "$password" ]; then
export BORG_PASSPHRASE="$passwd"
store_password "$passwd"
return 0
else
echo -e "\033[5;31;40m\nPasswords didn't match\033[0m\nTry Again"
fi
fi
done
echo -e "\033[5;31;40m\nMaximum attempts reached. Exiting.\033[0m"
exit 1
}
# Check password against stored hash
check_passwd() {
local passwd="$1"
local passwd_location="$HOME/passwd_bytes.borg"
python3 << ENDOFpy
import os, hashlib
with open('$passwd_location', 'br') as f:
storage_input = f.read()
salt_stored = storage_input[:32]
passwd_stored = storage_input[32:]
check_password = "$passwd"
encoded_check_password = hashlib.pbkdf2_hmac("sha256", check_password.encode(), salt_stored, 100000)
print(encoded_check_password == passwd_stored)
ENDOFpy
}
# Get password information
getting_passwd_info() {
read -p "To create a backup a password will be created to secure the backup\nEnter 'a' to automatically create a password or 'm' to manually create a password (default: manual): " passwd_option
passwd_option=${passwd_option:-m}
case $passwd_option in
[mM]*) man_setting_passwd ;;
[aA]*) auto_setting_passwd ;;
*) echo -e "\033[5;31;40m\nInvalid option\033[0m" ;;
esac
}
# Detect password option
detect_passwd_option() {
while true; do
read -p "Enter 'a' for automatic password or 'm' for manual password: " passwd_option
case $passwd_option in
[mM]*) while true; do
echo -n "Verify your password: "
passd_with_asterisk password
if [ "$(check_passwd "$password")" == "True" ]; then
eval "$2='$REPOSITORY_PATH'"
eval "$1='$password'"
return 0
else
echo -e "\033[5;31;40m\nPassword is not accurate\033[0m\nTry Again"
fi
done ;;
[aA]*) local password=$(sed '1q;d' ./config.borg)
eval "$2='$REPOSITORY_PATH'"
eval "$1='$password'"
return 0 ;;
*) echo -e "\033[5;31;40m\nInvalid option\033[0m" ;;
esac
done
}
# Initialize repository
init_repo() {
borg init --encryption="$ENCRYPTION_TYPE" "$1"
}
# Backup procedure with rotation
backup_procedure() {
detect_passwd_option passwd dest
read -p "Enter the directory you want to backup [default: $BACKUP_DIRECTORY]: " bkupdir
bkupdir=${bkupdir:-$BACKUP_DIRECTORY}
local backup_day=$(date '+%A the %d.%b.%Y')
local host_name=$(hostname -s)
local borg_bckupname="$host_name-$(date +%Y%m%d)-$(date +%H:%M:%S)"
log "Initializing Backup $borg_bckupname. Backing up $bkupdir to $dest on $backup_day."
export BORG_PASSPHRASE="$passwd"
borg create -v --stats "$dest::$borg_bckupname" "$bkupdir"
# Implement backup rotation: keep last 7 daily, 4 weekly, and 6 monthly archives
borg prune -v --list "$dest" --keep-daily="$KEEP_DAILY" --keep-weekly="$KEEP_WEEKLY" --keep-monthly="$KEEP_MONTHLY"
log "Backup Completed on $backup_day."
}
# Main function
main() {
load_config
check_dependencies
while true; do
read -p "Is this a new backup repository? (y/n): " newrepo
case $newrepo in
[yY]*) read -p "Enter path to new repository [default: $REPOSITORY_PATH]: " ndest
ndest=${ndest:-$REPOSITORY_PATH}
echo "$ndest" > ./config.borg
getting_passwd_info
init_repo "$ndest"
backup_procedure
break ;;
[nN]*) if [ ! -f ./config.borg ]; then
echo "Config file not found!"
exit 1
else
backup_procedure
break
fi ;;
*) echo -e "\033[5;31;40m\nInvalid option\033[0m" ;;
esac
done
}
main