backup-server 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949
  1. #!/bin/bash
  2. #/###################################################################\
  3. #| Make backup of: |
  4. #| -Web Pages (/var/www) |
  5. #| -SQL Databases (MySQL or MariaDB) |
  6. #| -HTTP Server Configuration (nginx) |
  7. #| -Let's Encrypt Certificates |
  8. #| -Home Directory (/home) |
  9. #| -GOGS Git Repository |
  10. #| -Mail Mailboxes (/var/mail) |
  11. #| -PostFix MTA Configuration (SMTP mail server) |
  12. #| -Dovecot MDA Configuration (POP3/IMAP server) |
  13. #| -OpenDKIM Configuration (Anti email Spoofing) |
  14. #| -SPF Configuration (Anti email Spoofing) |
  15. #| -OpenDMARC Configuration (Anti email Spoofing) |
  16. #| -Amavis Configuration (Antivirus) |
  17. #| -SPAM Assassin (AntiSPAM) |
  18. #| Compressed with: |
  19. #| -Gzip |
  20. #| -Bzip2 |
  21. #| -XZ |
  22. #| and encrypted (or not). |
  23. #| |
  24. #| USAGE: backup-server [options] -z|-j|-J backupdir |
  25. #| HELP: backup-server -h |
  26. #| |
  27. #| Guzmán Castanedo (guzman@castanedo.es) |
  28. #| Version 2.2 (May 2018) |
  29. #| Licence: GPL v3.0 -> https://www.gnu.org/licenses/gpl-3.0.en.html |
  30. #\###################################################################/
  31. function usage {
  32. printf "%s Version 2.2\n" $(basename $0)
  33. printf "Usage: %s [options]... -z|-j|-J [backupdir]\n" $(basename $0)
  34. printf "Make a encrypted backup of a server compressed with: \n"
  35. printf "\t·Gzip (tar.gz or tar.gz.gpg)\n"
  36. printf "\t·Bzip2 (tar.bz2 or tar.gz.gpg)\n"
  37. printf "\t·XZ (tar.xz or tar.xz.gpg)\n"
  38. printf "\n"
  39. printf "Backup Directory:\n"
  40. printf "\tbackupdir: argument to set to directory to save the backup\n"
  41. printf "\t\tDefault: %s\n" $backupDir
  42. printf "Backup Options:\n"
  43. printf "\t-p, --prefix name: prefix for the name of the backup\n"
  44. printf "\t\tDefault: backup-'hostname'(%s)\n" $backupPrefix
  45. printf "\t--postfix name: postfix for the name of the backup.\n"
  46. printf "\t\tTo unset default postfix: --postfix \"\"\n"
  47. printf "\t\tDefault: prefix-yyyy-mm-dd(date)-XXXXXX(random)\n"
  48. printf "\t--no-remove: no remove old files\n"
  49. printf "\t\tDefault: false\n"
  50. printf "\t--remove-days number: set number of days to considere a backup old\n"
  51. printf "\t\tDefault: %s\n" $deleteDays
  52. printf "\t-u, --user uid: name of the user owner of the backup\n"
  53. printf "\t\tDefault: %s\n" $user
  54. printf "\t-g, --group gid: name of the group owner of the backup\n"
  55. printf "\t\tDefault: %s\n" $group
  56. printf "\t--permision-mask number: octal mask to set accesss permision of the backup\n"
  57. printf "\t\tDefault: %s\n" $permisionMask
  58. printf "\t-e, --exclude file1[,file2,[file3,[...]]]: files to be excluded of backup\n"
  59. printf "\t\tSeparate files with commas \",\"\n"
  60. printf "\t\tDefault: %s\n" $exclude
  61. printf "\n"
  62. printf "Compression Options:\n"
  63. printf "\t-z, --gzip: compress using gzip (tar.gz or tar.gz.gpg)\n"
  64. printf "\t-j, --bzip2: compress using bzip2 (tar.bz2 or tar.bz2.gpg)\n"
  65. printf "\t-J, --xz: compress using xz (tar.xz or tar.xz.gpg)\n"
  66. printf "\n"
  67. printf "Encryption Options:\n"
  68. printf "\t-k, --key-id ID: set gpg2 public key-id used for encryption\n"
  69. printf "\t\tUse with Gzip, Bzip2 or XZ compression\n"
  70. printf "\t\tDefault: %s\n" $keyID
  71. printf "\t--no-encryption: disable the encryption of the backup\n"
  72. printf "\t\tDefault: %s\n" $noEncryption
  73. printf "\n"
  74. printf "Web Options:\n"
  75. printf "\t--web-dir dir: set web pages directory to backup\n"
  76. printf "\t\tDefault: %s\n" $webDir
  77. printf "\t--no-web: disable backup of web pages\n"
  78. printf "\t\tDefault: %s\n" $noWeb
  79. printf "\n"
  80. printf "SQL Options:\n"
  81. printf "\t--no-sql: disable MySQL/MariaDB backup\n"
  82. printf "\t\tDefault: %s\n" $noSql
  83. printf "\t--sql-user username: set MySQL/MariaDB username\n"
  84. printf "\t\tDefault: %s\n" $mysqluser
  85. printf "\t--sql-password password: set MySQL/MariaDB password (INSECURE)\n"
  86. printf "\t\tDefault: %s\n" $mysqlpass
  87. printf "\n"
  88. printf "Nginx Options:\n"
  89. printf "\t--nginx-dir dir: set nginx configuration directory to backup\n"
  90. printf "\t\tDefault: %s\n" $nginxDir
  91. printf "\t--no-nginx: disable Nginx backup\n"
  92. printf "\t\tDefault: %s\n" $noNginx
  93. printf "\n"
  94. printf "Let's Encrypt Options:\n"
  95. printf "\t--letsencrypt-dir dir: set Let's Encrypt configuration directory to backup\n"
  96. printf "\t\tDefault: %s\n" $letsencryptDir
  97. printf "\t--no-letsencrypt: disable Let's Encrypt backup\n"
  98. printf "\t\tDefault: %s\n" $noLetsencrypt
  99. printf "\n"
  100. printf "Mail Options:\n"
  101. printf "\t--mail-dir dir: set Mailboxes directory to backup\n"
  102. printf "\t\tDefault: %s\n" $mailDir
  103. printf "\t--no-mail: disable mailboxes backup\n"
  104. printf "\t\tDefault: %s\n" $noMail
  105. printf "\n"
  106. printf "Home Options:\n"
  107. printf "\t--home-dir dir: set home directories to backup\n"
  108. printf "\t\tDefault: %s\n" $homeDir
  109. printf "\t--no-home: disable home directory backup\n"
  110. printf "\t\tDefault: %s\n" $noHome
  111. printf "\n"
  112. printf "GOGS Options:\n"
  113. printf "\t--gogs-dir dir: set GOGS Git Repository to backup\n"
  114. printf "\t\tDefault: %s\n" $gogsDir
  115. printf "\t--no-gogs: disable gogs backup\n"
  116. printf "\t\tDefault: %s\n" $noGogs
  117. printf "\n"
  118. printf "Postfix Options:\n"
  119. printf "\t--postfix-dir dir: set Postfix configuration directory to backup\n"
  120. printf "\t\tDefault: %s\n" $postfixDir
  121. printf "\t--no-postfix: disable Postfix backup\n"
  122. printf "\t\tDefault: %s\n" $noPostfix
  123. printf "\n"
  124. printf "Dovecot Options:\n"
  125. printf "\t--dovecot-dir dir: set Dovecot configuration directory to backup\n"
  126. printf "\t\tDefault: %s\n" $dovecotDir
  127. printf "\t--no-dovecot: disable Dovecot backup\n"
  128. printf "\t\tDefault: %s\n" $noDovecot
  129. printf "\n"
  130. printf "OpenDKIM Options:\n"
  131. printf "\t--opendkim-conf file: set OpenDKIM configuration file to backup\n"
  132. printf "\t\tDefault: %s\n" $openDKIMConf
  133. printf "\t--opendkim-default file: set OpenDKIM socket configuration file to backup\n"
  134. printf "\t\tDefault: %s\n" $openDKIMDefault
  135. printf "\t--opendkim-keys dir: set OpenDKIM keys dir to backup\n"
  136. printf "\t\tDefault: %s\n" $openDKIMKeys
  137. printf "\t--no-opendkim: disable OpenDKIM backup\n"
  138. printf "\t\tDefault: %s\n" $noOpenDKIM
  139. printf "\n"
  140. printf "SPF Options:\n"
  141. printf "\t--spf-dir dir: set SPF configuration directory to backup\n"
  142. printf "\t\tDefault: %s\n" $spfDir
  143. printf "\t--no-spf: disable SPF backup\n"
  144. printf "\t\tDefault: %s\n" $noSPF
  145. printf "\n"
  146. printf "OpenDMARC Options:\n"
  147. printf "\t--opendmarc-conf file: set OpenDMARC configuration file to backup\n"
  148. printf "\t\tDefault: %s\n" $openDMARCConf
  149. printf "\t--opendmarc-default file: set OpenDMARC socket configuration file to backup\n"
  150. printf "\t\tDefault: %s\n" $openDMARCDefault
  151. printf "\t--no-opendmarc: disable OpenDMARC backup\n"
  152. printf "\t\tDefault: %s\n" $noOpenDMARC
  153. printf "\n"
  154. printf "Amavis Options:\n"
  155. printf "\t--amavis-dir dir: set Amavis configuration directory to backup\n"
  156. printf "\t\tDefault: %s\n" $amavisDir
  157. printf "\t--no-amavis: disable Amavis backup\n"
  158. printf "\t\tDefault: %s\n" $noAmavis
  159. printf "\n"
  160. printf "SPAM Assassin Options:\n"
  161. printf "\t--spamassassin-dir dir: set SPAM Assassin configuration directory to backup\n"
  162. printf "\t\tDefault: %s\n" $spamAssassinDir
  163. printf "\t--no-spamassassin: disable SPAM Assassin backup\n"
  164. printf "\t\tDefault: %s\n" $noSpamAssassin
  165. printf "\n"
  166. printf "Other Options:\n"
  167. printf "\t--no-sha512: not calculate SHA512 hash (to check integrity)\n"
  168. printf "\t-h, --help: shows this message and exit\n"
  169. printf "\n"
  170. printf "Examples:\n"
  171. printf "\t·%s --xz -k ABCDEFG -p backup-example.com --no-sql /var/backup\n" $(basename $0)
  172. printf "\t\tMake a backup in \"/var/backup\" compressed with XZ and encrypted with GPG2\n"
  173. printf "\t\tPublic Key (\"backup-example.com-2018-03-19-a1b2c3.tar.xz.gpg\")\n"
  174. printf "\t\tDisable SQL backup\n"
  175. printf "\t·%s -j -k ABCDEFG --sql-user root --sql-password toor /var/www/backup\n" $(basename $0)
  176. printf "\t\tMake a backup in \"/var/www/backup\" compressed with BZip2 and encrypted\n"
  177. printf "\t\t(\"backup-%s-2018-03-19-abcdef.tar.bz2.gpg\")\n" $(hostname)
  178. printf "\t·%s -z --no-encryption --no-sql /var/backup\n" $(basename $0)
  179. printf "\t\tMake a backup in \"/var/backup\" compressed with GZip and not encrypted\n"
  180. printf "\t\t(\"backup-%s-2018-03-19-qwerty.tar.gz\")\n" $(hostname)
  181. }
  182. function makeTar {
  183. #Destination file
  184. printf "Backup File:\t%s\n" $(realpath $backupOutput)
  185. #Copy webpages code (except backup and main/public)
  186. if [ $noWeb = false ];then
  187. printf "Adding:\t%s\n" $webDir
  188. tar -rf $tempOutput $exclude $webDir > /dev/null 2>&1
  189. if [ $? != 0 ]; then
  190. printf "WARNING:\tError copying web pages (Continue).\n"
  191. fi
  192. fi
  193. #Copy MySQL databases (mysqldump)
  194. if [ $noSql = false ]; then
  195. list=$(mysql -u $mysqluser -p$mysqlpass -e "show DATABASES;" 2> /dev/null)
  196. mkdir /tmp/mysql
  197. #Parse databases expect information_schema & performance_schema
  198. for database in $list; do
  199. valid=true
  200. for excep in Database information_schema performance_schema; do
  201. if [ $database = $excep ]; then
  202. valid=false
  203. break
  204. fi
  205. done
  206. if [ $valid = true ]; then
  207. printf "Adding MySQL database:\t%s\n" $database.sql
  208. mysqldump -u $mysqluser -p$mysqlpass $database > /tmp/mysql/$database.sql 2> /dev/null
  209. if [ $? != 0 ];then
  210. printf "WARNING:\tError extracting database (%s) (Continue).\n" $database
  211. continue
  212. fi
  213. tar -rf $tempOutput -C /tmp mysql/$database.sql > /dev/null 2>&1
  214. if [ $? != 0 ];then
  215. printf "WARNING:\tError adding to tar (%s) (Continue)\n"
  216. fi
  217. rm /tmp/mysql/$database.sql
  218. fi
  219. done
  220. rm -R /tmp/mysql
  221. fi
  222. #Copy nginx configuration (sites-available)
  223. if [ $noNginx = false ];then
  224. printf "Adding:\t%s\n" $nginxDir
  225. tar -rf $tempOutput $exclude $nginxDir > /dev/null 2>&1
  226. if [ $? != 0 ];then
  227. printf "WARNING:\tError copying nginx configuration (Continue)\n"
  228. fi
  229. fi
  230. #Copy Email (this could be heavy in the future)
  231. if [ $noMail = false ];then
  232. printf "Adding:\t%s\n" $mailDir
  233. tar -rf $tempOutput $exclude $mailDir > /dev/null 2>&1
  234. if [ $? != 0 ];then
  235. printf "WARNING:\tError copying mailboxes (Continue)\n"
  236. fi
  237. fi
  238. #Copy Certificates (LetsEncrypt)
  239. if [ $noLetsencrypt = false ];then
  240. printf "Adding:\t%s\n" $letsencryptDir
  241. tar -rf $tempOutput $exclude $letsencryptDir > /dev/null 2>&1
  242. if [ $? != 0 ];then
  243. printf "WARNING:\tError copying Let's Encrypt certificates (Continue)\n"
  244. fi
  245. fi
  246. #Copy /home
  247. if [ $noHome = false ];then
  248. printf "Adding:\t%s\n" $homeDir
  249. tar -rf $tempOutput $exclude $homeDir > /dev/null 2>&1
  250. if [ $? != 0 ];then
  251. printf "WARNING:\tError copying home dir (Continue)\n"
  252. fi
  253. fi
  254. #Copy GOGS
  255. if [ $noGogs = false ];then
  256. printf "Adding:\t%s\n" $gogsDir
  257. tar -rf $tempOutput $exclude $gogsDir > /dev/null 2>&1
  258. if [ $? != 0 ];then
  259. printf "WARNING:\tError copying GOGS Repository (Continue)\n"
  260. fi
  261. fi
  262. #Copy Postfix
  263. if [ $noPostfix = false ] && [ -d $postfixDir ];then
  264. printf "Adding:\t%s\n" $postfixDir
  265. tar -rf $tempOutput $exclude $postfixDir > /dev/null 2>&1
  266. if [ $? != 0 ];then
  267. printf "WARNING:\tError copying Postfix configuration (Continue)\n"
  268. fi
  269. fi
  270. #Copy Dovecot
  271. if [ $noDovecot = false ];then
  272. printf "Adding:\t%s\n" $dovecotDir
  273. tar -rf $tempOutput $exclude $dovecotDir > /dev/null 2>&1
  274. if [ $? != 0 ];then
  275. printf "WARNING:\tError copying Dovecot configuration (Continue)\n"
  276. fi
  277. fi
  278. #Copy OpenDKIM
  279. if [ $noOpenDKIM = false ];then
  280. if [ -f $openDKIMConf ];then
  281. printf "Adding:\t%s\n" $openDKIMConf
  282. tar -rf $tempOutput $exclude $openDKIMConf > /dev/null 2>&1
  283. if [ $? != 0 ];then
  284. printf "WARNING:\tError copying OpenDKIM configuration (Continue)\n"
  285. fi
  286. fi
  287. if [ -f $openDKIMDefault ];then
  288. printf "Adding:\t%s\n" $openDKIMDefault
  289. tar -rf $tempOutput $exclude $openDKIMDefault > /dev/null 2>&1
  290. if [ $? != 0 ];then
  291. printf "WARNING:\tError copying OpenDKIM sockets configuration (Continue)\n"
  292. fi
  293. fi
  294. if [ -d $openDKIMKeys ];then
  295. printf "Adding:\t%s\n" $openDKIMKeys
  296. tar -rf $tempOutput $exclude $openDKIMKeys > /dev/null 2>&1
  297. if [ $? != 0 ];then
  298. printf "WARNING:\tError copying OpenDKIM keys (Continue)\n"
  299. fi
  300. fi
  301. fi
  302. #Copy SPF
  303. if [ $noSPF = false ];then
  304. printf "Adding:\t%s\n" $spfDir
  305. tar -rf $tempOutput $exclude $spfDir > /dev/null 2>&1
  306. if [ $? != 0 ];then
  307. printf "WARNING:\tError copying SPF configuration (Continue)\n"
  308. fi
  309. fi
  310. #Copy OpenDMARC
  311. if [ $noOpenDMARC = false ];then
  312. if [ -f $openDMARCConf ];then
  313. printf "Adding:\t%s\n" $openDMARCConf
  314. tar -rf $tempOutput $exclude $openDMARCConf > /dev/null 2>&1
  315. if [ $? != 0 ];then
  316. printf "WARNING:\tError copying OpenDMARC configuration (Continue)\n"
  317. fi
  318. fi
  319. if [ -f $openDMARCDefault ];then
  320. printf "Adding:\t%s\n" $openDMARCDefault
  321. tar -rf $tempOutput $exclude $openDMARCDefault > /dev/null 2>&1
  322. if [ $? != 0 ];then
  323. printf "WARNING:\tError copying OpenDMARC sockets configuration (Continue)\n"
  324. fi
  325. fi
  326. fi
  327. #Copy Amavis
  328. if [ $noAmavis = false ];then
  329. printf "Adding:\t%s\n" $amavisDir
  330. tar -rf $tempOutput $exclude $amavisDir > /dev/null 2>&1
  331. if [ $? != 0 ];then
  332. printf "WARNING:\tError copying Amavis configuration (Continue)\n"
  333. fi
  334. fi
  335. #Copy SPAMAssassin
  336. if [ $noSpamAssassin = false ];then
  337. printf "Adding:\t%s\n" $spamAssassinDir
  338. tar -rf $tempOutput $exclude $spamAssassinDir > /dev/null 2>&1
  339. if [ $? != 0 ];then
  340. printf "WARNING:\tError copying SPAM Assasin configuration (Continue)\n"
  341. fi
  342. fi
  343. }
  344. function gzUnencrypted {
  345. printf "Compressing (GZIP)..."
  346. gzip -9 --stdout $tempOutput > $backupOutput
  347. if [ $? != 0 ]; then
  348. printf "\nERROR:\tImpossible to compress (%s)\n" $backupOutput$ext
  349. exit 1
  350. fi
  351. rm $tempOutput
  352. printf " done\n"
  353. }
  354. function gzEncrypted {
  355. printf "Compressing (GZIP) and encrypting..."
  356. gzip -9 --stdout $tempOutput | gpg2 --no-batch --output $backupOutput --encrypt -r $keyID -
  357. if [ $? != 0 ]; then
  358. printf "\nERROR:\tImpossible to compress (%s)\n" $backupOutput$ext
  359. exit 1
  360. fi
  361. rm $tempOutput
  362. printf " done\n"
  363. }
  364. function bz2Unencrypted {
  365. printf "Compressing (BZIP2)..."
  366. bzip2 -9 --stdout $tempOutput > $backupOutput
  367. if [ $? != 0 ]; then
  368. printf "\nERROR:\tImpossible to compress (%s)\n" $backupOutput$ext
  369. exit 1
  370. fi
  371. rm $tempOutput
  372. printf " done\n"
  373. }
  374. function bz2Encrypted {
  375. printf "Compressing (BZIP2) and encrypting..."
  376. bzip2 -9 --stdout $tempOutput | gpg2 --no-batch --output $backupOutput --encrypt -r $keyID -
  377. if [ $? != 0 ]; then
  378. printf "\nERROR:\tImpossible to compress (%s)\n" $backupOutput$ext
  379. exit 1
  380. fi
  381. rm $tempOutput
  382. printf " done\n"
  383. }
  384. function xzUnencrypted {
  385. printf "Compressing (XZ)..."
  386. xz -9 --stdout $tempOutput > $backupOutput
  387. if [ $? != 0 ]; then
  388. printf "\nERROR:\tImpossible to compress (%s)\n" $backupOutput$ext
  389. exit 1
  390. fi
  391. rm $tempOutput
  392. printf " done\n"
  393. }
  394. function xzEncrypted {
  395. printf "Compressing (XZ) and encrypting..."
  396. xz -9 --stdout $tempOutput | gpg2 --no-batch --output $backupOutput --encrypt -r $keyID -
  397. if [ $? != 0 ]; then
  398. printf "\nERROR:\tImpossible to compress (%s)\n" $backupOutput$ext
  399. exit 1
  400. fi
  401. rm $tempOutput
  402. printf " done\n"
  403. }
  404. function makeSHA512 {
  405. if [ ! -x $(which sha512sum) ]; then
  406. printf "WARNING:\tsha512sum not installed\n"
  407. sha512=false
  408. fi
  409. if [ $sha512 = true ]; then
  410. printf "Calculating checksum (SHA512)..."
  411. cd $backupDir > /dev/null 2>&1
  412. sha512sum -b $(basename $backupOutput) > $backupOutput.sha512
  413. #Permissions
  414. chown $user:$group $backupOutput.sha512
  415. chmod $permisionMask $backupOutput.sha512
  416. cd - > /dev/null 2>&1
  417. printf " done\n"
  418. fi
  419. }
  420. function checkRoutes {
  421. if [ ! -d $backupDir ];then
  422. printf "ERROR:\tBackup directory don't exist\n"
  423. usage
  424. exit 1
  425. fi
  426. if [ $noWeb = false ] && [ ! -d $webDir ];then
  427. printf "WARNING:\t%s don't exist (no backup)\n" $webDir
  428. noWeb=true
  429. fi
  430. if [ $noNginx = false ] && [ ! -d $nginxDir ];then
  431. printf "WARNING:\t%s don't exist (no backup)\n" $nginxDir
  432. noNginx=true
  433. fi
  434. if [ $noLetsencrypt = false ] && [ ! -d $letsencryptDir ];then
  435. printf "WARNING:\t%s don't exist (no backup)\n" $letsencryptDir
  436. noLetsencrypt=true
  437. fi
  438. if [ $noMail = false ] && [ ! -d $mailDir ];then
  439. printf "WARNING:\t%s don't exist (no backup)\n" $mailDir
  440. noMail=true
  441. fi
  442. if [ $noHome = false ] && [ ! -d $homeDir ];then
  443. printf "WARNING:\t%s don't exist (no backup)\n" $homeDir
  444. noHome=true
  445. fi
  446. if [ $noGogs = false ] && [ ! -d $gogsDir ];then
  447. printf "WARNING:\t%s don't exist (no backup)\n" $gogsDir
  448. noGogs=true
  449. fi
  450. if [ $noPostfix = false ] && [ ! -d $postfixDir ];then
  451. printf "WARNING:\t%s don't exist (no backup)\n" $postfixDir
  452. noPostfix=true
  453. fi
  454. if [ $noDovecot = false ] && [ ! -d $dovecotDir ];then
  455. printf "WARNING:\t%s don't exist (no backup)\n" $dovecotDir
  456. noDovecot=true
  457. fi
  458. # No noOpenDKIM=true, to make a parcial copy
  459. if [ $noOpenDKIM = false ] && [ ! -f $openDKIMConf ];then
  460. printf "WARNING:\t%s don't exist (no backup)\n" $openDKIMConf
  461. fi
  462. if [ $noOpenDKIM = false ] && [ ! -f $openDKIMDefault ];then
  463. printf "WARNING:\t%s don't exist (no backup)\n" $openDKIMDefault
  464. fi
  465. if [ $noOpenDKIM = false ] && [ ! -d $openDKIMKeys ];then
  466. printf "WARNING:\t%s don't exist (no backup)\n" $openDKIMKeys
  467. fi
  468. if [ $noSPF = false ] && [ ! -d $spfDir ];then
  469. printf "WARNING:\t%s don't exist (no backup)\n" $spfDir
  470. noSPF=true
  471. fi
  472. # No noOpenDMARC=true, to make a parcial copy
  473. if [ $noOpenDMARC = false ] && [ ! -f $openDMARCConf ];then
  474. printf "WARNING:\t%s don't exist (no backup)\n" $openDMARCConf
  475. fi
  476. if [ $noOpenDMARC = false ] && [ ! -f $openDMARCDefault ];then
  477. printf "WARNING:\t%s don't exist (no backup)\n" $openDMARCDefault
  478. fi
  479. if [ $noAmavis = false ] && [ ! -d $amavisDir ];then
  480. printf "WARNING:\t%s don't exist (no backup)\n" $amavisDir
  481. noAmavis=true
  482. fi
  483. if [ $noSpamAssassin = false ] && [ ! -d $spamAssassinDir ];then
  484. printf "WARNING:\t%s don't exist (no backup)\n" $spamAssassinDir
  485. noSpamAssassin=true
  486. fi
  487. }
  488. function checkMethod {
  489. if [ $gzipOn = false ] && [ $bzip2On = false ] && [ $xzOn = false ];then
  490. printf "ERROR:\tCompressing method not set\n"
  491. exit 1
  492. fi
  493. if [ $noEncryption = false ];then
  494. if [ $gzipOn = true ] || [ $bzip2On = true ] || [ $xzOn = true ];then
  495. if [ ! -x $(which gpg2) ];then
  496. printf "WARNING:\tGPG2 Not Installed: continue without encryption (type \"%s -h\" for help)\n" $(basename $0)
  497. noEncryption=true
  498. else
  499. if [ ! -z $keyID ];then
  500. ext=$ext.gpg
  501. gpg2 --list-keys $keyID > /dev/null 2>&1
  502. if [ $? != 0 ];then
  503. printf "ERROR:\tKeyID %s don't exist in keyring (\"gpg2 --list-keys\" to see all keys)\n" $keyID
  504. exit 1
  505. fi
  506. else
  507. printf "WARNING:\tKeyID (-k keyID) not set: continue without encryption (type \"%s -h\" for help)\n" $(basename $0)
  508. noEncryption=true
  509. fi
  510. fi
  511. fi
  512. fi
  513. }
  514. function checkSqlAuth {
  515. if [ $noSql = false ];then
  516. if [ ! -x "$(which mysql)" ] || [ ! -x "$(which mysqldump)" ];then
  517. printf "WARNING:\tmysql or/and mysqldump Not installed\n"
  518. noSql=true
  519. fi
  520. if [ -z $mysqluser ] || [ -z $mysqlpass ]; then
  521. printf "WARNING:\tSQL User/Password not set: continue without SQL backup (type \"%s -h\" for help)\n" $(basename $0)
  522. noSql=true
  523. fi
  524. fi
  525. }
  526. #Check root
  527. startTime=$(date +"%s")
  528. if [ $(id -u) -ne 0 ]; then
  529. printf "ERROR:\tNeed to be root :O\n"
  530. exit 1
  531. fi
  532. #Default Data
  533. mysqluser="root"
  534. mysqlpass=""
  535. keyID=""
  536. backupDir=/var/backup
  537. backupPrefix="backup-"$(hostname)
  538. backupPostfix=-$(date +"%Y-%m-%d")-$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 6 | head -n 1)
  539. deleteDays="15"
  540. user="www-data"
  541. group="www-data"
  542. exclude=""
  543. #Default Routes
  544. webDir="/var/www"
  545. nginxDir="/etc/nginx"
  546. mailDir="/var/mail"
  547. letsencryptDir="/etc/letsencrypt"
  548. homeDir="/home"
  549. gogsDir="/opt/gogs"
  550. postfixDir="/etc/postfix"
  551. dovecotDir="/etc/dovecot"
  552. openDKIMConf="/etc/opendkim.conf"
  553. openDKIMDefault="/etc/default/opendkim"
  554. openDKIMKeys="/etc/dkimkeys"
  555. spfDir="/etc/postfix-policyd-spf-python"
  556. openDMARCConf="/etc/opendmarc.conf"
  557. openDMARCDefault="/etc/default/opendmarc"
  558. amavisDir="/etc/amavis"
  559. spamAssassinDir="/etc/spamassassin"
  560. #Control Variables
  561. noEncryption=false
  562. gzipOn=false
  563. bzip2On=false
  564. xzOn=false
  565. ext=""
  566. permisionMask=640
  567. removeOld=true
  568. noWeb=false
  569. noSql=false
  570. noNginx=false
  571. noMail=false
  572. noLetsencrypt=false
  573. noHome=false
  574. noGogs=false
  575. noPostfix=false
  576. noDovecot=false
  577. noOpenDKIM=false
  578. noSPF=false
  579. noOpenDMARC=false
  580. noAmavis=false
  581. noSpamAssassin=false
  582. sha512=true
  583. #Parse args
  584. TEMP=$(getopt -q -o zjJp:u:g:e:k:h --longoptions gzip,bzip2,xz,prefix:,postfix:,no-remove,remove-days:,user:,group:,permision-mask:,exclude:,key-id:,no-encryption,web-dir:,no-web,no-sql,sql-user:,sql-password:,nginx-dir:,no-nginx,letsencrypt-dir:,no-letsencrypt,mail-dir:,no-mail,home-dir:,no-home,gogs-dir:,no-gogs,postfix-dir:,no-postfix,dovecot-dir:,no-dovecot,opendkim-conf:,opendkim-default:,opendkim-keys:,no-opendkim,spf-dir:,no-spf,opendmarc-conf:,opendmarc-default:,no-opendmarc,amavis-dir:,no-amavis,spamassassin-dir:,no-spamassassin,no-sha512,help --name $(basename $0) -- $@)
  585. eval set -- $TEMP
  586. unset TEMP
  587. while true; do
  588. case $1 in
  589. -z|--gzip)
  590. gzipOn=true
  591. ext=".tar.gz"
  592. if [ $bzip2On = true ] || [ $xzOn = true ];then
  593. printf "ERROR:\tOnly choose one compressing method\n"
  594. exit 1
  595. fi
  596. if [ ! -x $(which gzip) ];then
  597. printf "ERROR:\tGzip Not Installed\n"
  598. exit 1
  599. fi
  600. shift
  601. ;;
  602. -j|--bzip2)
  603. bzip2On=true
  604. ext=".tar.bz2"
  605. if [ $gzipOn = true ] || [ $xzOn = true ];then
  606. printf "ERROR:\tOnly choose one compressing method\n"
  607. exit 1
  608. fi
  609. if [ ! -x $(which bzip2) ];then
  610. printf "ERROR:\tBzip2 Not Installed\n"
  611. exit 1
  612. fi
  613. shift
  614. ;;
  615. -J|--xz)
  616. xzOn=true
  617. ext=".tar.xz"
  618. if [ $gzipOn = true ] || [ $bzip2On = true ];then
  619. printf "ERROR:\tOnly choose one compressing method\n"
  620. exit 1
  621. fi
  622. if [ ! -x $(which xz) ];then
  623. printf "ERROR:\tXZ Not Installed\n"
  624. exit 1
  625. fi
  626. shift
  627. ;;
  628. -p|--prefix)
  629. backupPrefix=$2
  630. shift 2
  631. ;;
  632. --postfix)
  633. backupPostfix=$2
  634. shift 2
  635. ;;
  636. --no-remove)
  637. removeOld=false
  638. shift
  639. ;;
  640. --remove-days)
  641. deleteDays=$2
  642. shift 2
  643. ;;
  644. -u|--user)
  645. grep $2 /etc/passwd > /dev/null 2>&1
  646. if [ $? = 0 ]; then
  647. user=$2
  648. else
  649. printf "ERROR:\tUser %s don't exist\n" $2
  650. exit 1
  651. fi
  652. shift 2
  653. ;;
  654. -g|--group)
  655. grep $2 /etc/group > /dev/null 2>&1
  656. if [ $? = 0 ];then
  657. group=$2
  658. else
  659. printf "ERROR:\tGroup %s don't exist\n" $2
  660. exit 1
  661. fi
  662. shift 2
  663. ;;
  664. --permision-mask)
  665. if [ $2 -eq $2 ] 2> /dev/null;then
  666. permisionMask=$2
  667. else
  668. printf "ERROR:\tPermission has to be a number (%s)\n" $2
  669. exit 1
  670. fi
  671. shift 2
  672. ;;
  673. -e|--exclude)
  674. cont=1
  675. fileCut=$(echo $2 | cut -d "," -f $cont)
  676. fileCut=$(realpath -q -m $fileCut 2>/dev/null)
  677. while [ $fileCut != "" ] > /dev/null 2>&1
  678. do
  679. if [ -d $fileCut ] || [ -f $fileCut ];then
  680. exclude="$exclude --exclude=$fileCut"
  681. else
  682. printf "WARNING:\t%s don't exist\n" $fileCut
  683. fi
  684. cont=$((cont+1))
  685. fileCut=$(echo $2 | cut -d "," -f $cont)
  686. fileCut=$(realpath -q -m $fileCut 2>/dev/null)
  687. done
  688. unset cont fileCut
  689. shift 2
  690. ;;
  691. -k|--key-id)
  692. keyID=$2
  693. shift 2
  694. ;;
  695. --no-encryption)
  696. noEncryption=true
  697. shift
  698. ;;
  699. --web-dir)
  700. webDir=$2
  701. shift 2
  702. ;;
  703. --no-web)
  704. noWeb=true
  705. shift
  706. ;;
  707. --no-sql)
  708. noSql=true
  709. shift
  710. ;;
  711. --sql-user)
  712. mysqluser=$2
  713. shift 2
  714. ;;
  715. --sql-password)
  716. mysqlpass=$2
  717. shift 2
  718. ;;
  719. --nginx-dir)
  720. nginxDir=$2
  721. shift 2
  722. ;;
  723. --no-nginx)
  724. noNginx=true
  725. shift
  726. ;;
  727. --letsencrypt-dir)
  728. letsencryptDir=$2
  729. shift 2
  730. ;;
  731. --no-letsencrypt)
  732. noLetsencrypt=true
  733. shift
  734. ;;
  735. --mail-dir)
  736. mailDir=$2
  737. shift 2
  738. ;;
  739. --no-mail)
  740. noMail=true
  741. shift
  742. ;;
  743. --home-dir)
  744. homeDir=$2
  745. shift 2
  746. ;;
  747. --no-home)
  748. noHome=true
  749. shift
  750. ;;
  751. --gogs-dir)
  752. gogsDir=$2
  753. shift 2
  754. ;;
  755. --no-gogs)
  756. noGogs=true
  757. shift
  758. ;;
  759. --postfix-dir)
  760. postfixDir=$2
  761. shift 2
  762. ;;
  763. --no-postfix)
  764. noPostfix=true
  765. shift
  766. ;;
  767. --dovecot-dir)
  768. dovecotDir=$2
  769. shift 2
  770. ;;
  771. --no-dovecot)
  772. noDovecot=true
  773. shift
  774. ;;
  775. --opendkim-conf)
  776. openDKIMConf=$2
  777. shift 2
  778. ;;
  779. --opendkim-default)
  780. openDKIMDefault=$2
  781. shift 2
  782. ;;
  783. --opendkim-keys)
  784. openDKIMKeys=$2
  785. shift 2
  786. ;;
  787. --no-opendkim)
  788. noOpenDKIM=true
  789. shift
  790. ;;
  791. --spf-dir)
  792. spfDir=$2
  793. shift 2
  794. ;;
  795. --no-spf)
  796. noSPF=true
  797. shift
  798. ;;
  799. --opendmarc-conf)
  800. openDMARCConf=$2
  801. shift 2
  802. ;;
  803. --opendmarc-default)
  804. openDMARCDefault=$2
  805. shift 2
  806. ;;
  807. --no-opendmarc)
  808. noOpenDMARC=true
  809. shift
  810. ;;
  811. --amavis-dir)
  812. amavisDir=$2
  813. shift 2
  814. ;;
  815. --no-amavis)
  816. noAmavis=true
  817. shift
  818. ;;
  819. --spamassassin-dir)
  820. spamAssassinDir=$2
  821. shift 2
  822. ;;
  823. --no-spamassassin)
  824. noSpamAssassin=true
  825. shift
  826. ;;
  827. --no-sha512)
  828. sha512=false
  829. shift
  830. ;;
  831. -h|--help)
  832. usage
  833. exit 0
  834. shift
  835. ;;
  836. --)
  837. #Last One
  838. shift
  839. break
  840. ;;
  841. *)
  842. #Unspected
  843. usage
  844. printf "\nERROR:\tInvalid Option (%s)\n" $1
  845. exit 1
  846. ;;
  847. esac
  848. done
  849. if [ ! $# -eq 1 ];then
  850. printf "ERROR:\tBackup directory not set\n"
  851. usage
  852. exit 1
  853. else
  854. backupDir=$1
  855. backupName=$backupPrefix$backupPostfix
  856. backupOutput=$backupDir/$backupName
  857. tempOutput=/tmp/$backupName.tar
  858. fi
  859. #Check (routes, compression, encryption and SQL auth)
  860. checkRoutes
  861. checkMethod
  862. checkSqlAuth
  863. #make tar file
  864. backupOutput=$backupOutput$ext
  865. if [ ! -x $(which tar) ];then
  866. printf "ERROR:\tTAR Not Installed\n"
  867. exit 1
  868. fi
  869. makeTar
  870. #Compression and encryption
  871. if [ $gzipOn = true ];then
  872. if [ $noEncryption = true ];then
  873. gzUnencrypted
  874. else
  875. gzEncrypted
  876. fi
  877. elif [ $bzip2On = true ];then
  878. if [ $noEncryption = true ];then
  879. bz2Unencrypted
  880. else
  881. bz2Encrypted
  882. fi
  883. else
  884. if [ $noEncryption = true ];then
  885. xzUnencrypted
  886. else
  887. xzEncrypted
  888. fi
  889. fi
  890. #Make SHA512
  891. if [ $sha512 = true ]; then
  892. makeSHA512
  893. fi
  894. #Permissions
  895. chown $user:$group $backupOutput
  896. chmod $permisionMask $backupOutput
  897. #Remove files older than 15 days
  898. if [ $removeOld = true ];then
  899. printf "Deletting old backups (+15 days)..."
  900. find $backupDir -mindepth 1 -maxdepth 1 -mtime +$deleteDays -type f -iname "$backupPrefix*$ext" -delete
  901. if [ $? != 0 ];then
  902. printf "\nWARNING:\tImposible to delete old backups (+%s days)\n" $deleteDays
  903. fi
  904. printf " done\n"
  905. fi
  906. #End
  907. finalTime=$(date +"%s")
  908. printf "\n"
  909. echo "------------------------------------------------"
  910. printf "Backup completed successfully in %s seconds :)\n" $((finalTime-startTime))
  911. echo "------------------------------------------------"