freedombone-backup-local 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. #!/bin/bash
  2. # _____ _ _
  3. # | __|___ ___ ___ _| |___ _____| |_ ___ ___ ___
  4. # | __| _| -_| -_| . | . | | . | . | | -_|
  5. # |__| |_| |___|___|___|___|_|_|_|___|___|_|_|___|
  6. #
  7. # Freedom in the Cloud
  8. #
  9. # Backup to local storage - typically a USB drive
  10. # License
  11. # =======
  12. #
  13. # Copyright (C) 2015-2018 Bob Mottram <bob@freedombone.net>
  14. #
  15. # This program is free software: you can redistribute it and/or modify
  16. # it under the terms of the GNU Affero General Public License as published by
  17. # the Free Software Foundation, either version 3 of the License, or
  18. # (at your option) any later version.
  19. #
  20. # This program is distributed in the hope that it will be useful,
  21. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23. # GNU Affero General Public License for more details.
  24. #
  25. # You should have received a copy of the GNU Affero General Public License
  26. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  27. PROJECT_NAME='freedombone'
  28. COMPLETION_FILE=$HOME/${PROJECT_NAME}-completed.txt
  29. CONFIGURATION_FILE=$HOME/${PROJECT_NAME}.cfg
  30. MONGODB_APPS_FILE=$HOME/.mongodbapps
  31. BACKUP_EXTRA_DIRECTORIES=/root/backup-extra-dirs.csv
  32. ENABLE_BACKUP_VERIFICATION="no"
  33. export TEXTDOMAIN=${PROJECT_NAME}-backup-local
  34. export TEXTDOMAINDIR="/usr/share/locale"
  35. PROJECT_INSTALL_DIR=/usr/local/bin
  36. if [ -f /usr/bin/${PROJECT_NAME} ]; then
  37. PROJECT_INSTALL_DIR=/usr/bin
  38. fi
  39. function please_wait {
  40. local str width height length
  41. width=$(tput cols)
  42. height=$(tput lines)
  43. str="Standby to backup to USB"
  44. length=${#str}
  45. clear
  46. tput cup $((height / 2)) $(((width / 2) - (length / 2)))
  47. echo "$str"
  48. tput cup $((height * 3 / 5)) $(((width / 2)))
  49. echo -n ''
  50. }
  51. please_wait
  52. source "$PROJECT_INSTALL_DIR/${PROJECT_NAME}-vars"
  53. # include utils which allow function_check and drive mount
  54. UTILS_FILES="/usr/share/${PROJECT_NAME}/utils/${PROJECT_NAME}-utils-*"
  55. for f in $UTILS_FILES
  56. do
  57. source "$f"
  58. done
  59. clear
  60. USB_DRIVE=/dev/sdb1
  61. USB_MOUNT=/mnt/usb
  62. read_config_param USB_DRIVE
  63. ADMIN_USERNAME=
  64. ADMIN_NAME=
  65. # The name of a currently suspended site
  66. # Sites are suspended so that verification should work
  67. SUSPENDED_SITE=
  68. DATABASE_PASSWORD=$("${PROJECT_NAME}-pass" -u root -a mariadb)
  69. function make_backup_directory {
  70. # make a backup directory on the drive
  71. if [ ! -d $USB_MOUNT/backup ]; then
  72. mkdir $USB_MOUNT/backup
  73. fi
  74. if [ ! -d $USB_MOUNT/backup ]; then
  75. echo $"There was a problem making the directory $USB_MOUNT/backup."
  76. umount $USB_MOUNT
  77. rm -rf $USB_MOUNT
  78. exit 3
  79. fi
  80. }
  81. function check_storage_space_remaining {
  82. # Check space remaining on the usb drive
  83. used_percent=$(df -k $USB_MOUNT | tail -n 1 | awk -F ' ' '{print $5}' | awk -F '%' '{print $1}')
  84. if [ "$used_percent" -gt 95 ]; then
  85. echo $"Less than 5% of space remaining on backup drive"
  86. umount $USB_MOUNT
  87. rm -rf $USB_MOUNT
  88. exit 4
  89. fi
  90. }
  91. function backup_users {
  92. # Backup user files
  93. for d in /home/*/ ; do
  94. USERNAME=$(echo "$d" | awk -F '/' '{print $3}')
  95. if [[ $(is_valid_user "$USERNAME") == "1" ]]; then
  96. # Backup any gpg keys
  97. if [ -d "/home/$USERNAME/.gnupg" ]; then
  98. echo $"Backing up gpg keys for $USERNAME"
  99. backup_directory_to_usb "/home/$USERNAME/.gnupg" "gnupg/$USERNAME"
  100. fi
  101. # Backup any personal settings
  102. if [ -d "/home/$USERNAME/personal" ]; then
  103. echo $"Backing up personal settings for $USERNAME"
  104. backup_directory_to_usb "/home/$USERNAME/personal" "personal/$USERNAME"
  105. fi
  106. # Backup ssh keys
  107. if [ -d "/home/$USERNAME/.ssh" ]; then
  108. echo $"Backing up ssh keys for $USERNAME"
  109. backup_directory_to_usb "/home/$USERNAME/.ssh" "ssh/$USERNAME"
  110. fi
  111. # Backup fin database if it exists
  112. if [ -d "/home/$USERNAME/.fin" ]; then
  113. echo $"Backing up fin files for $USERNAME"
  114. backup_directory_to_usb "/home/$USERNAME/.fin" "fin/$USERNAME"
  115. fi
  116. # Backup emacs
  117. if [ -d "/home/$USERNAME/.emacs.d" ]; then
  118. echo $"Backing up Emacs config for $USERNAME"
  119. if [ -f "/home/$USERNAME/.emacs" ]; then
  120. cp "/home/$USERNAME/.emacs" "/home/$USERNAME/.emacs.d/dotemacs"
  121. fi
  122. backup_directory_to_usb "/home/$USERNAME/.emacs.d" "config/$USERNAME"
  123. fi
  124. # Backup user configs
  125. if [ -d "/home/$USERNAME/.config" ]; then
  126. echo $"Backing up config files for $USERNAME"
  127. backup_directory_to_usb "/home/$USERNAME/.config" "config/$USERNAME"
  128. fi
  129. # Backup monkeysphere
  130. if [ -d "/home/$USERNAME/.monkeysphere" ]; then
  131. echo $"Backing up monkeysphere files for $USERNAME"
  132. backup_directory_to_usb "/home/$USERNAME/.monkeysphere" "monkeysphere/$USERNAME"
  133. fi
  134. # Backup user local
  135. if [ -d "/home/$USERNAME/.local" ]; then
  136. echo $"Backing up local files for $USERNAME"
  137. backup_directory_to_usb "/home/$USERNAME/.local" "local/$USERNAME"
  138. fi
  139. # Backup mutt
  140. if [ -f "/home/$USERNAME/.muttrc" ]; then
  141. echo $"Backing up Mutt settings for $USERNAME"
  142. if [ ! -d "/home/$USERNAME/tempbackup" ]; then
  143. mkdir -p "/home/$USERNAME/tempbackup"
  144. fi
  145. cp "/home/$USERNAME/.muttrc" "/home/$USERNAME/tempbackup"
  146. if [ -f /etc/Muttrc ]; then
  147. cp /etc/Muttrc "/home/$USERNAME/tempbackup"
  148. fi
  149. backup_directory_to_usb "/home/$USERNAME/tempbackup" "mutt/$USERNAME"
  150. fi
  151. if [ -d "/home/$USERNAME/.mutt" ]; then
  152. echo $"Backing up Mutt configurations for $USERNAME"
  153. backup_directory_to_usb "/home/$USERNAME/.mutt" "mutt/${USERNAME}configs"
  154. fi
  155. # Backup email
  156. if [ -d "/home/$USERNAME/Maildir" ]; then
  157. echo $"Stopping mail server"
  158. systemctl stop exim4
  159. echo $"Creating an email archive for $USERNAME"
  160. if [ ! -d "/root/tempbackupemail/$USERNAME" ]; then
  161. mkdir -p "/root/tempbackupemail/$USERNAME"
  162. fi
  163. tar -czvf "/root/tempbackupemail/$USERNAME/maildir.tar.gz" "/home/$USERNAME/Maildir"
  164. echo $"Restarting mail server"
  165. systemctl start exim4
  166. echo $"Backing up emails for $USERNAME"
  167. backup_directory_to_usb "/root/tempbackupemail/$USERNAME" "mail/$USERNAME"
  168. fi
  169. # Backup spamassassin
  170. if [ -d "/home/$USERNAME/.spamassassin" ]; then
  171. echo $"Backing up spamassassin settings for $USERNAME"
  172. backup_directory_to_usb "/home/$USERNAME/.spamassassin" "spamassassin/$USERNAME"
  173. fi
  174. # Backup procmail
  175. if [ -f "/home/$USERNAME/.procmailrc" ]; then
  176. echo $"Backing up procmail settings for $USERNAME"
  177. if [ ! -d "/home/$USERNAME/tempbackup" ]; then
  178. mkdir -p "/home/$USERNAME/tempbackup"
  179. fi
  180. cp "/home/$USERNAME/.procmailrc" "/home/$USERNAME/tempbackup"
  181. backup_directory_to_usb "/home/$USERNAME/tempbackup" "procmail/$USERNAME"
  182. fi
  183. gpg_agent_enable "$USERNAME"
  184. fi
  185. done
  186. }
  187. function backup_directories {
  188. # directories to be backed up (source,dest)
  189. backup_dirs=(
  190. "/etc/letsencrypt, letsencrypt"
  191. "/etc/ssl, ssl"
  192. "/var/spool/mlmmj, mailinglist"
  193. "/etc/nginx/sites-available, web"
  194. "/var/lib/tor, tor"
  195. "/root/.passwords, passwordstore"
  196. )
  197. # shellcheck disable=SC2068
  198. for dr in ${backup_dirs[@]}
  199. do
  200. # if this directory exists then back it up to the given destination
  201. source_directory=$(echo "$dr" | awk -F ',' '{print $1}' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
  202. if [ -d "$source_directory" ]; then
  203. dest_directory=$(echo "$dr" | awk -F ',' '{print $2}' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
  204. echo $"Backing up $source_directory to $dest_directory"
  205. backup_directory_to_usb "$source_directory" "$dest_directory"
  206. fi
  207. restart_site
  208. done
  209. }
  210. function remove_backup_directory {
  211. if [ "$1" ]; then
  212. if [[ "$1" == "remove" ]]; then
  213. if [ -d $USB_MOUNT/backup ]; then
  214. rm -rf $USB_MOUNT/backup
  215. echo $'Existing backup directory removed'
  216. backup_unmount_drive
  217. exit 0
  218. fi
  219. fi
  220. fi
  221. }
  222. function prepare_directories {
  223. # Some miscellaneous preparation for backing up directories
  224. if [ -d /var/lib/tox-bootstrapd ]; then
  225. cp /etc/tox-bootstrapd.conf /var/lib/tox-bootstrapd
  226. if [ -d /var/lib/tox-bootstrapd/Maildir ]; then
  227. rm -rf /var/lib/tox-bootstrapd/Maildir
  228. fi
  229. fi
  230. }
  231. function backup_blocklist {
  232. if [ ! -f /root/${PROJECT_NAME}-firewall-domains.cfg ]; then
  233. return
  234. fi
  235. echo $"Backing up ${PROJECT_NAME} blocklist"
  236. temp_backup_dir=/root/tempbackupblocklist
  237. if [ ! -d $temp_backup_dir ]; then
  238. mkdir -p $temp_backup_dir
  239. fi
  240. if [ -f "$NODEJS_INSTALLED_APPS_FILE" ]; then
  241. cp -f /root/${PROJECT_NAME}-firewall-domains.cfg $temp_backup_dir
  242. fi
  243. backup_directory_to_usb $temp_backup_dir blocklist
  244. rm -rf $temp_backup_dir
  245. }
  246. function backup_configfiles {
  247. echo $"Backing up ${PROJECT_NAME} configuration files"
  248. temp_backup_dir=/root/tempbackupconfig
  249. if [ ! -d $temp_backup_dir ]; then
  250. mkdir -p $temp_backup_dir
  251. fi
  252. if [ -f "$NODEJS_INSTALLED_APPS_FILE" ]; then
  253. cp -f "$NODEJS_INSTALLED_APPS_FILE" $temp_backup_dir
  254. fi
  255. if [ -f /root/.nostore ]; then
  256. cp -f /root/.nostore $temp_backup_dir
  257. else
  258. if [ -f $temp_backup_dir/.nostore ]; then
  259. rm $temp_backup_dir/.nostore
  260. fi
  261. fi
  262. cp -f "$CONFIGURATION_FILE" $temp_backup_dir
  263. cp -f "$COMPLETION_FILE" $temp_backup_dir
  264. if [ -f $BACKUP_EXTRA_DIRECTORIES ]; then
  265. cp -f $BACKUP_EXTRA_DIRECTORIES $temp_backup_dir
  266. fi
  267. if [ -f "$MONGODB_APPS_FILE" ]; then
  268. cp -f "$MONGODB_APPS_FILE" $temp_backup_dir
  269. fi
  270. # nginx password hashes
  271. if [ -f /etc/nginx/.htpasswd ]; then
  272. cp -f /etc/nginx/.htpasswd $temp_backup_dir/htpasswd
  273. fi
  274. backup_directory_to_usb $temp_backup_dir configfiles
  275. rm -rf $temp_backup_dir
  276. }
  277. function backup_admin_readme {
  278. if [ -f /home/$ADMIN_USERNAME/README ]; then
  279. echo $"Backing up README"
  280. temp_backup_dir=/home/$ADMIN_USERNAME/tempbackup
  281. if [ ! -d $temp_backup_dir ]; then
  282. mkdir -p $temp_backup_dir
  283. fi
  284. cp -f /home/$ADMIN_USERNAME/README $temp_backup_dir
  285. backup_directory_to_usb $temp_backup_dir readme
  286. fi
  287. }
  288. function backup_mariadb {
  289. if [ ${#DATABASE_PASSWORD} -gt 1 ]; then
  290. temp_backup_dir=/root/tempmariadb
  291. if [ ! -d $temp_backup_dir ]; then
  292. mkdir $temp_backup_dir
  293. fi
  294. keep_database_running
  295. mysqldump --lock-tables --password="$DATABASE_PASSWORD" mysql user > $temp_backup_dir/mysql.sql
  296. if [ ! -s $temp_backup_dir/mysql.sql ]; then
  297. echo $"Unable to backup mysql settings"
  298. rm -rf $temp_backup_dir
  299. umount $USB_MOUNT
  300. rm -rf $USB_MOUNT
  301. exit 8
  302. fi
  303. echo "$DATABASE_PASSWORD" > $temp_backup_dir/db
  304. chmod 400 $temp_backup_dir/db
  305. backup_directory_to_usb $temp_backup_dir mariadb
  306. fi
  307. }
  308. function backup_postgresql {
  309. if [ ! -d /etc/postgresql ]; then
  310. return
  311. fi
  312. temp_backup_dir=/root/temppostgresql
  313. if [ ! -d $temp_backup_dir ]; then
  314. mkdir $temp_backup_dir
  315. fi
  316. # shellcheck disable=SC2024
  317. sudo -u postgres pg_dumpall --roles-only > "$temp_backup_dir/postgresql.sql"
  318. if [ ! -s $temp_backup_dir/postgresql.sql ]; then
  319. echo $"Unable to backup postgresql settings"
  320. rm -rf $temp_backup_dir
  321. umount $USB_MOUNT
  322. rm -rf $USB_MOUNT
  323. exit 684365
  324. fi
  325. echo "$DATABASE_PASSWORD" > $temp_backup_dir/db
  326. chmod 400 $temp_backup_dir/db
  327. backup_directory_to_usb $temp_backup_dir postgresql
  328. }
  329. # has the remove option been set ?
  330. remove_option=$2
  331. if [[ $1 == "remove" ]]; then
  332. remove_option=$1
  333. fi
  334. gpg_agent_setup root
  335. backup_mount_drive "$1" "$2"
  336. remove_backup_directory "$remove_option"
  337. make_backup_directory
  338. check_storage_space_remaining
  339. backup_users
  340. prepare_directories
  341. backup_directories
  342. backup_apps local
  343. backup_configfiles
  344. backup_blocklist
  345. backup_admin_readme
  346. backup_mariadb
  347. backup_postgresql
  348. backup_extra_directories local
  349. backup_unmount_drive $USB_DRIVE $USB_MOUNT
  350. echo $"Backup to USB drive is complete. You can now unplug it."
  351. exit 0