Compare commits

...

661 commits

Author SHA1 Message Date
Jérémy Lecour 859bb800d4 Merge pull request 'fix-tempfiles' (#72) from fix-tempfiles into master
All checks were successful
gitea/evobackup/pipeline/head This commit looks good
Reviewed-on: #72
2024-03-22 11:27:34 +01:00
Brice Waegeneire 21533c6fb9 client: Write temporary files in /tmp
All checks were successful
gitea/evobackup/pipeline/head This commit looks good
By default "mktemp" creates a temporary file in the current working directory,
which in the context of Debian's cron is /. To avoid littering /, we add the
option "--tmpdir" that use $TMPDIR or /tmp instead.
2024-03-22 10:05:10 +01:00
Brice Waegeneire 9510546d48 client: Correctly clean up temporary files
The function "build_rsync_main_cmd" is called in a subshell, so it can't
effectively modify it's parent variable "temp_files". To correctly cleanup
those temporary files, we do it when this specific function exits.
2024-03-22 09:56:03 +01:00
Mathieu Trossevin f1d4e6ed9d
fix(includes): Avoid breaking is_btrfs if path doesn't exists
Some checks failed
gitea/evobackup/pipeline/head There was a failure building this commit
This should return with a err code of 1, not result in the entire
command breaking
2024-02-06 15:03:21 +01:00
Jérémy Lecour 491c839014
Add note for includes/excludes brace expansion
All checks were successful
gitea/evobackup/pipeline/head This commit looks good
2023-12-28 15:29:39 +01:00
William Hirigoyen 4298da250b Add WARNING and CRITICAL values to default conf
All checks were successful
gitea/evobackup/pipeline/head This commit looks good
2023-12-19 10:26:30 +01:00
William Hirigoyen d359883700 server: fix install.md paths
All checks were successful
gitea/evobackup/pipeline/head This commit looks good
2023-12-19 09:45:25 +01:00
Bruno TATU 4cd1554780 Correction url dans README.md
All checks were successful
gitea/evobackup/pipeline/head This commit looks good
2023-10-27 11:30:53 +02:00
William Hirigoyen 981f5118ce Ajout exclusion /var/lib/amavis/virusmails
All checks were successful
gitea/evobackup/pipeline/head This commit looks good
2023-06-15 11:18:49 +02:00
Jérémy Lecour 5dac827bb5 invert dry-run logic
All checks were successful
gitea/evobackup/pipeline/head This commit looks good
2023-05-03 22:08:17 +02:00
William Hirigoyen 4807dfbc99 Fix missing dump.rdb in Redis dump compression, which caused compression fail.
All checks were successful
gitea/evobackup/pipeline/head This commit looks good
2023-04-19 17:46:34 +02:00
William Hirigoyen fd9bb57f8b #71538 : fix Redis dump list in case directory is a symlink
All checks were successful
gitea/evobackup/pipeline/head This commit looks good
2023-04-17 17:13:23 +02:00
Alexis Ben Miloud--Josselin d62455cd1a Compress Redis dump
All checks were successful
gitea/evobackup/pipeline/head This commit looks good
2023-04-04 15:05:30 +02:00
Bruno Tatu 72f5900cf3 On backup les données dans les bases
All checks were successful
gitea/evobackup/pipeline/head This commit looks good
2023-03-30 16:37:36 +02:00
Jérémy Lecour 05a62e17b5 client: Release 22.12
All checks were successful
gitea/evobackup/pipeline/head This commit looks good
2022-12-27 13:37:48 +01:00
Jérémy Lecour 8babc64e0d client: log line with more details
All checks were successful
gitea/evobackup/pipeline/head This commit looks good
2022-12-27 13:36:24 +01:00
Jérémy Lecour aa7366ce2e client: separate Rsync for the canary file if the main Rsync has finished without errors
All checks were successful
gitea/evobackup/pipeline/head This commit looks good
2022-12-27 11:56:07 +01:00
Jérémy Lecour ef744f77cf client: No more fallback if dump-server-state is missing
All checks were successful
gitea/evobackup/pipeline/head This commit looks good
2022-12-27 11:11:02 +01:00
Jérémy Lecour 80426c9ba9 whitespaces 2022-12-27 11:09:37 +01:00
Jérémy Lecour b34ee2c3dc client: use long options for readability 2022-12-27 11:09:11 +01:00
Jérémy Lecour 94b470770f client: use sub shells instead of moving around
All checks were successful
gitea/evobackup/pipeline/head This commit looks good
2022-12-27 10:46:53 +01:00
Jérémy Lecour ed0645c9d2 remodel how we build the rsync command (#63)
All checks were successful
gitea/evobackup/pipeline/head This commit looks good
* use a log file for rsync
* build the command argument by argument, without backslashes
* move excludes into a file

Co-authored-by: Jeremy Lecour <jlecour@evolix.fr>
Reviewed-on: #63
2022-12-27 10:43:39 +01:00
Jérémy Lecour 140a498e28 client: Only one loop for all redis instances
All checks were successful
gitea/evobackup/pipeline/head This commit looks good
2022-12-27 10:38:55 +01:00
David Prevot bdd3ef7350 CI: Push *.buildinfo too
All checks were successful
gitea/evobackup/pipeline/head This commit looks good
2022-12-22 11:39:42 +01:00
Alexis Ben Miloud--Josselin 6e0ab85c6b client: ignore errors when listing instances
All checks were successful
gitea/evobackup/pipeline/head This commit looks good
2022-12-13 09:53:10 +01:00
David Prevot ff681275e3 CI: Don’t use Drone CI anymore
All checks were successful
gitea/evobackup/pipeline/head This commit looks good
2022-12-12 17:27:36 +01:00
David Prevot 1a892ba002 CI: Actually limit upload to .deb and .changes
All checks were successful
continuous-integration/drone/push Build is passing
gitea/evobackup/pipeline/head This commit looks good
2022-12-12 17:13:28 +01:00
Alexis Ben Miloud--Josselin e3a969f3e2 client: replace rm ** by find -delete
All checks were successful
continuous-integration/drone/push Build is passing
gitea/evobackup/pipeline/head This commit looks good
** has no particular meaning in bash unless shopt globstar is
set (it isn't by default).
2022-12-12 16:06:58 +01:00
David Prevot ca4fe4ffb5 CI: Limit upload to .deb and .changes
All checks were successful
continuous-integration/drone/push Build is passing
gitea/evobackup/pipeline/head This commit looks good
2022-12-12 11:42:19 +01:00
David Prevot 2338c92fe3 CI: Upload to pub2
All checks were successful
continuous-integration/drone/push Build is passing
gitea/evobackup/pipeline/head This commit looks good
2022-12-12 10:56:13 +01:00
David Prevot d2a76dce9c CI: use build-area instead of outside of scope subdirectory 2022-12-12 10:26:06 +01:00
David Prevot 4476802182 Use sbuild during CI
All checks were successful
continuous-integration/drone/push Build is passing
gitea/evobackup/pipeline/head This commit looks good
2022-12-09 13:42:44 +01:00
Mathieu Trossevin 1e35aaa4db
Corrige messages d'erreurs intempestif
All checks were successful
continuous-integration/drone/push Build is passing
gitea/evobackup/pipeline/head This commit looks good
2022-12-08 14:09:37 +01:00
Jérémy Lecour 7b10b56e35 add gobal .gitignore
All checks were successful
continuous-integration/drone/push Build is passing
gitea/evobackup/pipeline/head This commit looks good
continuous-integration/drone/tag Build is passing
gitea/evobackup/pipeline/tag This commit looks good
2022-11-28 15:27:26 +01:00
Jérémy Lecour c8cfbe18aa server: release 22.11
All checks were successful
continuous-integration/drone/push Build is passing
gitea/evobackup/pipeline/head This commit looks good
continuous-integration/drone/tag Build is passing
2022-11-28 15:06:53 +01:00
Jérémy Lecour 777b469485 bkctld check-canary: add tests 2022-11-28 15:06:53 +01:00
Jérémy Lecour d3c75ab94e bkctld-stats: filter active jails and columnize the output 2022-11-28 15:06:53 +01:00
Jérémy Lecour 860b982556 better error message 2022-11-28 15:06:53 +01:00
Jérémy Lecour 8ee2aa3b51 bkctld-check-canary: new subcommand to check canary files and content 2022-11-28 15:06:53 +01:00
Alexis Ben Miloud--Josselin 2b83cd71bc postgresql: change wd before dump
All checks were successful
continuous-integration/drone/push Build is passing
gitea/evobackup/pipeline/head This commit looks good
2022-11-14 11:29:43 +01:00
Jérémy Lecour 88a7907fd3 typo
All checks were successful
continuous-integration/drone/push Build is passing
gitea/evobackup/pipeline/head This commit looks good
continuous-integration/drone/tag Build is passing
2022-10-28 15:48:59 +02:00
Jérémy Lecour 18e0563377 quotes
All checks were successful
continuous-integration/drone/push Build is passing
gitea/evobackup/pipeline/head This commit looks good
2022-10-28 14:02:26 +02:00
Jérémy Lecour e921c92cae More explicit warning for rsync comments/spaces 2022-10-27 18:48:35 +02:00
William Hirigoyen aff5dbba95 Add --no-header option for status command.
All checks were successful
continuous-integration/drone/push Build is passing
gitea/evobackup/pipeline/head This commit looks good
2022-10-27 17:10:14 +02:00
Jérémy Lecour f683691853 client: tolerate absence of mtr or traceroute
All checks were successful
continuous-integration/drone/push Build is passing
gitea/evobackup/pipeline/head This commit looks good
2022-10-13 09:09:01 +02:00
Eric Morino c769a6e823 Update link to the installation documentation
All checks were successful
continuous-integration/drone/push Build is passing
gitea/evobackup/pipeline/head This commit looks good
2022-09-05 14:42:06 +02:00
William Hirigoyen 5739b8afe2 Revert "Fix variable reading in case VAR is specified multiple times in file."
All checks were successful
continuous-integration/drone/push Build is passing
gitea/evobackup/pipeline/head This commit looks good
This reverts commit 89580f2929.
2022-08-26 18:05:14 +02:00
William Hirigoyen 89580f2929 Fix variable reading in case VAR is specified multiple times in file.
All checks were successful
continuous-integration/drone/push Build is passing
gitea/evobackup/pipeline/head This commit looks good
2022-08-26 10:58:48 +02:00
Alexis Ben Miloud--Josselin c80881debf Exclure datadir MongoDB
All checks were successful
continuous-integration/drone/push Build is passing
gitea/evobackup/pipeline/head This commit looks good
2022-08-24 14:40:30 +02:00
Jérémy Lecour e7b7f50d9d server: release 22.07
Some checks are pending
continuous-integration/drone/push Build is passing
gitea.evolix.org/evobackup/pipeline/head Build started...
gitea/evobackup/pipeline/head This commit looks good
gitea/evobackup/pipeline/tag This commit looks good
continuous-integration/drone/tag Build is passing
2022-07-20 14:31:22 +02:00
Jérémy Lecour a3ca2f0f68 check-setup: check minifirewall version only if minifirewall is present
All checks were successful
continuous-integration/drone/push Build is passing
2022-07-20 14:24:12 +02:00
Jérémy Lecour 1891c98f57 check-setup: use findmnt with mountpoint instead of target 2022-07-20 14:23:13 +02:00
Jérémy Lecour aef2637c1e check-setup: get minifirewall version from internal variable
All checks were successful
continuous-integration/drone/push Build is passing
there is no other backward compatible way :
* really old version don't have a know version
* some versions used to display the version on each command, but it is removed.
* the VERSION variable seems to be the most forward-compatible way
2022-07-20 13:43:33 +02:00
David Prevot f0581fee47 CI: Drop .git directory that was not present during first build
All checks were successful
continuous-integration/drone/push Build is passing
gitea.evolix.org on plain agent00/evobackup/pipeline/head This commit looks good
2022-07-11 14:40:38 +02:00
David Prevot ba4629bee7 server/README.md: tfix
All checks were successful
continuous-integration/drone/push Build is passing
gitea.evolix.org on plain agent00/evobackup/pipeline/head This commit looks good
2022-06-30 16:13:29 +02:00
David Prevot 7901fd1950 Jenkins CI: Improve clean up
All checks were successful
continuous-integration/drone/push Build is passing
2022-06-29 14:43:42 +02:00
David Prevot bdb84e809f CI: Don’t rely on /tmp
/tmp is mounted noexec, so can’t be used to run scripts.
2022-06-29 14:03:24 +02:00
David Prevot 3150d48ba5 server: release 22.06
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
gitea.evolix.org on plain agent00/evobackup/pipeline/head This commit looks good
2022-06-28 16:30:15 +02:00
David Prevot 6c6b64ed34 Update client changelog 2022-06-28 16:26:32 +02:00
David Prevot 604317d4a7 client: tfix (comment) 2022-06-28 16:16:04 +02:00
David Prevot 92ae8a1c7a Jenkins CI: Unconditional clean up 2022-06-28 16:03:14 +02:00
David Prevot 14ca808658 Jenkins CI: Provide .Jenkinsfile as .drone.yml
All checks were successful
continuous-integration/drone/push Build is passing
TODO: upload package when it works.
2022-06-28 15:35:17 +02:00
David Prevot 0bea9f24ab CI: Build Bullseye package under Bullseye 2022-06-28 15:34:11 +02:00
David Prevot f13c6404fd Drone CI: fetch tags 2022-06-28 15:32:29 +02:00
David Prevot e14ab10562 Drone CI: don’t sign packages (yet?) 2022-06-28 15:31:28 +02:00
Brice Waegeneire 1bc62d81cd client: fix pt-show-grants error path
All checks were successful
continuous-integration/drone/push Build is passing
2022-06-20 17:52:26 +02:00
Jérémy Lecour ec638ecb3b move from sh to bash
All checks were successful
continuous-integration/drone/push Build is passing
2022-06-15 14:19:50 +02:00
Jérémy Dubois 0d48a8eec3 update-evobackup-canary : do not use GNU date, for it to be compatible with OpenBSD
All checks were successful
continuous-integration/drone/push Build is passing
2022-06-09 16:16:47 +02:00
Alexis Ben Miloud--Josselin 328763380f [elasticsearch] Écrire la sortie de curl dans log normal
All checks were successful
continuous-integration/drone/push Build is passing
2022-06-07 10:38:04 +02:00
Mathieu Trossevin 36f3cccc92
Ajoute support pour findmnt de Debian 8
All checks were successful
continuous-integration/drone/push Build is passing
2022-06-06 15:21:16 +02:00
Jérémy Lecour 417876cbba zzz_evobackup: replace rsync option --verbose by --itemize-changes
All checks were successful
continuous-integration/drone/push Build is passing
2022-06-02 15:53:00 +02:00
Jérémy Lecour 6c2ba1bc79 zzz_evobackup: do not use rsync compression
All checks were successful
continuous-integration/drone/push Build is passing
2022-06-02 14:56:57 +02:00
Jérémy Lecour 400be16e8a Ajout de liens vers les docs de la partie "client"
All checks were successful
continuous-integration/drone/push Build is passing
2022-06-01 10:14:48 +02:00
Jérémy Lecour 7faedbeab1 remove RSYNC_LOGFILE
All checks were successful
continuous-integration/drone/push Build is passing
2022-06-01 09:48:17 +02:00
Jérémy Lecour 86c01a1075 WIP: extract code into functions 2022-06-01 09:48:17 +02:00
Jérémy Dubois c621324845 Use --dump-dir instead of --backup-dir for OpenBSD too
All checks were successful
continuous-integration/drone/push Build is passing
2022-05-18 09:51:34 +02:00
Jérémy Lecour 89b0636cf6 bkctld-init: create "incs/\<jail\>" directory for jails
All checks were successful
continuous-integration/drone/push Build is passing
2022-05-05 11:43:02 +02:00
Jérémy Lecour f9a295daae fix broken test 2022-05-05 11:39:32 +02:00
Jérémy Lecour ed183fb854 Add canary to zzz_evobackup 2022-05-05 11:24:45 +02:00
David Prevot 12e8d79d1c Include CI upstream
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
The current build is limited to the debian branch (so it’s a no-op),
but CI should be extended to more than building packages. Furthermore,
providing files outside debian/ on a debian branch is going to confuse
gbp otherwise.
2022-05-03 14:54:24 +02:00
Jérémy Lecour ff02816538 Add AGPL License to client script 2022-05-02 10:27:07 +02:00
Jérémy Lecour d2daef52d9 read_variable + read_numerical_variable: keep the last found value only 2022-05-02 10:21:22 +02:00
Jérémy Lecour 9745d78a16 Fix shell syntax error when ${btrfs_bin} variable is empty 2022-04-28 14:51:15 +02:00
Jérémy Lecour 4d9d846703 fix quote 2022-04-28 14:51:15 +02:00
Jérémy Lecour 3f248cdbaa server: release 22.04 2022-04-28 14:51:15 +02:00
Ludovic Poujol c01e6d11cd Use --dump-dir instead of --backup-dir to supress dump-server-state warning 2022-04-20 09:51:44 +02:00
Jérémy Dubois 1efca713c0 zzz_evobackup: Make start_time and stop_time compatible with OpenBSD 2022-04-13 17:08:38 +02:00
Jérémy Lecour 5cbc2cbf42 Split client and server parts 2022-04-03 11:28:59 +02:00
Jérémy Lecour 3b0e6934d9 bkctld-check-setup: compatibility with minifirewall 22.03+ 2022-03-30 15:07:45 +02:00
Jérémy Lecour 9c3813716e update CHANGELOG with forgotten change 2022-03-27 10:42:21 +02:00
Jérémy Lecour 0587b5043f dump-server-state: use --all option to be forward compatible and always dump everything 2022-03-27 10:42:01 +02:00
Jérémy Lecour 114c65684c rename backup-server-state to dump-server-state 2022-03-27 10:14:39 +02:00
Jérémy Lecour 960dd97d68 Tell sed to follow symlinks 2022-03-27 10:14:07 +02:00
Jérémy Dubois 959077327a fix backup-server-state option for OpenBSD 2022-03-25 18:02:18 +01:00
Jérémy Lecour a658e2aa7f use new firewall file path 2022-03-18 15:23:33 +01:00
Jérémy Lecour 8330918aad TODO: deal with empty lines 2022-03-18 15:11:04 +01:00
William Hirigoyen (Evolix) 595be40c38 Fix init btrfs check location, fix error msg spelling brtfs -> btrfs 2022-03-09 16:16:37 +01:00
Eric Morino 7f0bb53cd2 Add Mysql dump all variables on zzz_evobackup 2022-03-02 10:56:44 +01:00
William Hirigoyen (Evolix) efd8d980c2 Fix insecable space 2022-02-22 15:30:32 +01:00
William Hirigoyen (Evolix) 43826224e3 Fix insecable space 2022-02-22 14:56:34 +01:00
Jérémy Lecour 0a3d7996a7 fix nettoyage de dumps PG 2022-02-03 16:05:34 +01:00
Jérémy Lecour dc70f9937c fix backup-server-state option 2022-01-31 09:38:10 +01:00
Jérémy Lecour 8020a357a6 use force mode for backup-server-state 2022-01-28 16:29:48 +01:00
Jérémy Lecour 8b72415669 variable plus explicite 2022-01-27 13:57:56 +01:00
Jérémy Lecour 0705625dbd fix date syntax 2022-01-27 13:55:14 +01:00
Jérémy Lecour 15c9682be1 zzz_evobackup: use "backup-server-state script if available 2022-01-27 12:08:00 +01:00
Jérémy Lecour fa8d8cfd84 zzz_evobackup: log version 2022-01-27 12:06:39 +01:00
Jérémy Lecour aba4a9f992 amélioration du log d'erreurs SSH 2022-01-26 12:00:07 +01:00
Jérémy Lecour 82e111adc8 Reorganize logging 2022-01-26 11:46:41 +01:00
William Hirigoyen (Evolix) 06f6c54d8c Update changelog 2022-01-26 09:18:30 +01:00
Jérémy Lecour 45f057bce8 /var/log is no longer excluded 2022-01-25 19:01:54 +01:00
Jérémy Lecour 3042b72a78 evobackup: store log file in /var/log/evobackup/ 2022-01-25 17:22:18 +01:00
William Hirigoyen (Evolix) e6d8f73b42 Add exclusions LXC tmp zzz_evobackup 2021-12-24 11:36:55 +01:00
William Hirigoyen (Evolix) b9bd67488b Reduce IP column width to avoid empty ligne return 2021-12-24 10:04:27 +01:00
William Hirigoyen (Evolix) f8db747970 Header in uppercase, enlarge column RETENTION 2021-12-03 15:36:54 +01:00
William Hirigoyen (Evolix) 0b777b4a3f Add a header for bktcld status output. 2021-12-03 15:17:00 +01:00
Brice Waegeneire 4f9b56d7a4 Add bullseye to to the test suite 2021-11-17 16:15:17 +01:00
William Hirigoyen (Evolix) bca2d1147e Fix apt source.list 2021-11-17 15:55:03 +01:00
William Hirigoyen (Evolix) 0aa233d939 Exclude /var/tmp from backups in zzz_evobackup 2021-11-17 15:34:39 +01:00
William Hirigoyen (Evolix) edcec2d619 Add location of build files in docs/debian.md. 2021-11-16 17:45:37 +01:00
William Hirigoyen (Evolix) 58ebf9d2ef Add time unit for retention policy status display (bkctld status). 2021-11-10 15:24:56 +01:00
Jérémy Lecour 4195c3bea5 Release 2.12.0 2021-11-02 17:30:29 +01:00
William Hirigoyen (Evolix) ed1d2bf660 Moving from package btrfs-tools (transitionnal) to btrfs-progs (retro-compatible) to allow Vagrant tests in Bullseye. 2021-11-02 17:24:50 +01:00
William Hirigoyen (Evolix) 4e7d5506de Add btrfs command check (for future btrfs-progs switch from Depends to Recommends in .deb) 2021-11-02 16:38:58 +01:00
Jérémy Lecour 3be8b638fe Pseudo-code for btrfs check 2021-11-02 15:23:21 +01:00
Jérémy Lecour da6e59a37b Add bullseye to test suite 2021-11-02 15:22:08 +01:00
Ludovic Poujol 0565ad831a Mise à jour de 'zzz_evobackup'
Change order of sql dumps commands
2021-08-17 13:44:30 +02:00
Jérémy Lecour d6dd91eb1f Release 2.11.1 2021-06-30 18:13:34 +02:00
Jérémy Lecour a2c6d073a7 bkctld-rename: abort operation if incs exist with the new name 2021-06-30 18:12:36 +02:00
Jérémy Lecour 09f1789a53 Release 2.11.0 2021-06-30 15:20:43 +02:00
Jérémy Lecour 1960e9097a bkctld-archive/remove: confirmation defaults to 'No' 2021-06-30 14:58:39 +02:00
Jérémy Lecour 7c6fefd00b bkctld-remove: remove config directory 2021-06-30 14:57:42 +02:00
Jérémy Lecour b8f0a377d9 force flag must be exported 2021-06-30 14:56:09 +02:00
Jérémy Lecour ec4502ef9b Release 2.10.0 2021-06-29 17:25:35 +02:00
Jérémy Lecour 9e1d8636ff update copyright 2021-06-29 17:25:35 +02:00
Jérémy Lecour d8e1ce9fb1 bkctld-remove: force mode bypass inexisting jail 2021-06-29 17:25:35 +02:00
Jérémy Lecour c38ec89010 Add tests for bkctld-archive 2021-06-29 17:25:35 +02:00
Jérémy Lecour b1b4d8b19f No date/process in stdout/stderr
Don't treat stdout/stderr as a logging facility
2021-06-29 17:25:35 +02:00
Jérémy Lecour 49fff6e85d bkctld-rename: reset firewall rules and fix logic error 2021-06-29 17:25:35 +02:00
Jérémy Lecour 134faf3e47 bkctld-archive: archive a jail 2021-06-29 17:25:35 +02:00
Jérémy Lecour d467690ff5 Reset firewall for new jail name 2021-06-29 17:25:35 +02:00
Jérémy Lecour a50991226c bkctld-rename: rename a jail and all its incs and configuration… 2021-06-29 17:25:35 +02:00
Eric Morino 31fb33adc4 Add compressed PostgreSQL dump for each databases 2021-06-22 15:36:12 +02:00
Jérémy Lecour 0090595d40 zzz_evobackup: commands to purge previous dumps 2021-06-09 17:16:26 +02:00
Jérémy Dubois 582e8e0c9c Use of fstat instead of netstat on OpenBSD
Allow to know which PID is listening to a port
2021-05-25 20:55:00 +02:00
Jérémy Lecour afb7427e40 exclusion de 'lxc/*/rootfs/var/lib/php/sessions' 2021-05-06 10:23:50 +02:00
Jérémy Lecour fe0f655f07 Release 2.9.0 2021-02-22 12:14:19 +01:00
Jérémy Lecour 937e75daa7 Rename incs_policy template 2021-02-22 10:15:53 +01:00
Jérémy Lecour 82dbb29511 bkctld-upgrade-config: install check_policy template if missing 2021-02-22 09:37:15 +01:00
Jérémy Lecour 21f4544016 Install default check_policy file on init 2021-02-22 09:36:53 +01:00
Jérémy Lecour eecd105d33 improve readability 2021-02-08 17:20:56 +01:00
Jérémy Lecour f84e9ec02d fix infinite loop 2021-02-08 17:20:20 +01:00
Jérémy Lecour 34de467b00 Merge branch 'fixes-43' 2021-02-08 14:18:36 +01:00
Brice Waegeneire 3215ab2fa3 bkctld-check-incs: Correct shellchek warnings
- SC2013: To read lines rather than words, pipe/redirect to a 'while
  read' loop.
- SC2086: Double quote to prevent globbing and word splitting.
2021-02-08 14:17:28 +01:00
Brice Waegeneire c27cb81b57 bkctld-check-incs: Protect jail_config_epoch
Test if `incs_policy_file` exists before using it. Fixes #43.
2021-02-08 14:17:22 +01:00
Jérémy Lecour a41eb2a218 test: bkctld check-incs shouldn't fail without incs_policy file
Currently it does, because we "stat" a blank file (issue #43).
2021-02-08 14:16:08 +01:00
Jérémy Lecour b7cddcac27 tests: clean jail configuration after each test 2021-02-08 14:13:10 +01:00
Jérémy Lecour 68a7da6b88 evobackup: log/pid files named after program's name 2021-02-08 11:32:12 +01:00
Jérémy Dubois 53a1309d69 zzz_evobackup: exclude OpenBSD mails folder 2021-01-07 09:47:27 +01:00
Tristan PILAT da8451e649 zzz_evobackup: add 2 slapcat examples for separate config/data backups 2020-12-04 10:47:44 +01:00
Jérémy Lecour d991fff710 Release 2.8.0 2020-11-28 10:47:40 +01:00
Jérémy Lecour 1a52f012a6 bkctld: new inc-lock and inc-unlock command 2020-11-28 10:46:57 +01:00
Jérémy Lecour fd6c5e4a12 Release 2.7.1 2020-11-28 08:43:16 +01:00
Jérémy Lecour 3aef89053b bkctld-upgrade-config is executable 2020-11-27 10:04:09 +01:00
Jérémy Dubois 34c06bfc9a zzz_evobackup: exclude munin tmp files for OpenBSD 2020-11-16 11:22:18 +01:00
Jérémy Lecour 01a19ad2da Release 2.7.0 2020-11-13 15:49:43 +01:00
Jérémy Lecour a7dc09bb46 New test : All incs are removed by 'rm' with empty inc policy 2020-11-13 15:47:06 +01:00
Jérémy Lecour 76a298c042 bkctld-rm: delete empty jails in incs directory 2020-11-13 15:33:18 +01:00
Jérémy Lecour f9018738b9 tests: use FORCE flag to remove jail in tests 2020-11-13 15:32:19 +01:00
Jérémy Lecour 3c5a646ae3 bkctld-rm: list jails from incs directory
We list jails in "incs" directory, not in "jails" directory so we can 
clean old incs after a jail is archived
2020-11-12 18:35:41 +01:00
Jérémy Lecour bf56c16ed2 bkctld-remove: confirmation before removal of jails if not in force mode 2020-10-11 15:19:00 +02:00
Jérémy Lecour 2ccd8c1b8d add a [-f|--force] option to remove confirmation on some commands 2020-10-11 14:57:47 +02:00
Jérémy Lecour 9eae80c002 globally disable shecllcheck SC2034 in lib/includes
Many variables defined in this file are not used here.
2020-10-11 14:56:22 +02:00
Jérémy Lecour 05c3715c6a Better help message composition and formating 2020-10-11 14:53:26 +02:00
Jérémy Lecour 2ad1032f9d Release 2.6.0 2020-10-07 20:51:29 +02:00
Jérémy Lecour c1fbe6394f Add "version" and extract "help" options 2020-10-07 20:50:17 +02:00
Jérémy Lecour 6fe81c7077 Release 2.5.1 2020-10-07 18:35:00 +02:00
Jérémy Lecour cf95909f0b bkctld: Replace xargs with a simple loop 2020-10-05 11:36:02 +02:00
Jérémy Lecour 88899fb0fe fix bad destination directory for mysql backups 2020-09-25 15:53:13 +02:00
Jérémy Lecour 08d113d2ce Release 2.5.0 2020-09-25 14:13:20 +02:00
Jérémy Lecour 2057a6fd80 Restore compatibility with Debian <10
ssh-keygen has "-f prefix_path" in openssh-server version 7.9+
2020-09-25 14:12:12 +02:00
Jérémy Lecour 9f5a4066ee zzz_evobackup: exclude LXC rootfs 2020-09-15 14:08:20 +02:00
Jérémy Lecour af68d9951b zzz_evobackup: reorder rsync excludes 2020-09-15 10:14:04 +02:00
Jérémy Lecour 69146f1f9f remove /srv from default directory list 2020-09-01 18:41:16 +02:00
Jérémy Lecour 1b9c56dbfd Release 2.4.1 2020-08-28 10:23:10 +02:00
Jérémy Lecour 7d1964370d jails and incs lists are sorted alphanumerically 2020-08-28 10:21:13 +02:00
Jérémy Lecour 39901967a7 bkctld-check-setup: forgot to increment the summary 2020-08-20 14:50:09 +02:00
Jérémy Lecour e5d40f8fe4 Release 2.4.0 2020-08-19 14:08:01 +02:00
Jérémy Lecour 08a2e067c2 bkctld-check-setup: remove "set -x" 2020-08-19 14:01:57 +02:00
Jérémy Lecour bc6a571595 whitespaces for readability 2020-08-19 13:58:23 +02:00
Jérémy Lecour ea9aac50a3 explicit path refix for ssh-keygen 2020-08-19 13:58:03 +02:00
Jérémy Lecour 1063dfe74d bkctld: don't replace SSH host keys when creating/updating a jail 2020-08-19 13:57:18 +02:00
Jérémy Lecour c141986a6d create new ssh keys for new jails instead of copying those from the host
It increases the security by having different keys between jails.
It reduces the risk of changing the keys of jails after creationtheir 
creation.
2020-08-07 14:24:20 +02:00
Jérémy Lecour 1f29162da4 evobackup script timeout defaults to 90 seconds 2020-07-22 23:00:27 +02:00
Jérémy Lecour 3a6e21dce8 use ${LOCAL_BACKUP_DIR}/mysql/ instead of /home/mysqldump/ 2020-07-16 22:20:05 +02:00
Jérémy Lecour 251d0c14d6 zzz_evobackup: add template for multiple redis instances 2020-07-16 22:16:34 +02:00
Jérémy Lecour 0ad1e8d342 Split check into check-jails and check-setup
bkctld-check-setup checks if the partition is mounted and writable, if 
firewall is configured and if all jails are started
2020-07-10 14:34:06 +02:00
Jérémy Lecour d07b493131 bkctld-update: start jail after upgrade if it was started before 2020-07-09 17:14:49 +02:00
Bruno TATU 049bdb9216 add --relative to rsync from zzz_evobackup 2020-06-09 10:59:23 +02:00
Jérémy Lecour 505e0f7f53 New command bkctld upgrade-config
It moves the legacy config file "/etc/evobackup/<jail>" to the new 
config structure "/etc/evobackup/<jail>.d/incs_policy"
2020-05-28 11:11:59 +02:00
Jérémy Lecour 67bbb5c100 Release 2.3.3 2020-05-28 10:24:47 +02:00
Jérémy Lecour 505bdb9117 On sync, add trailing slash to rsync command 2020-05-28 10:22:34 +02:00
Jérémy Lecour 80fb38d534 Release 2.3.2 2020-05-03 11:13:55 +02:00
Jérémy Lecour b659e9d8c5 better sync
* add/remove config files to mirror source
* restart minifirewall only if present
* sync state with proper action
2020-05-03 11:03:04 +02:00
Jérémy Lecour df180e4d03 Update CHANGELOG 2020-05-01 10:34:35 +02:00
Jérémy Lecour 3ac79da9b2 bkctld-sync: don't sync whole firewall file, just rules for jail 2020-05-01 10:33:06 +02:00
Jérémy Lecour 8311e33c76 join arguments in ssh command 2020-05-01 10:31:46 +02:00
Jérémy Lecour 8ed06511d9 bkctld-sync: don't init jail if it already exists 2020-05-01 10:31:20 +02:00
Jérémy Lecour 9cd94dabc2 An empty lock file shouldn't stop the program 2020-05-01 09:52:06 +02:00
Jérémy Lecour ebfc16f65a grammar 2020-05-01 09:51:47 +02:00
Jérémy Lecour b3529f2131 bkctld-is-on returns code 100 if jail is stopped 2020-05-01 09:51:36 +02:00
Jérémy Lecour 64ec60428d error() function accepts an optional return code 2020-05-01 09:51:09 +02:00
Jérémy Lecour 807dd44408 Display help message if mandatory arguments are missing 2020-04-25 10:30:21 +02:00
Jérémy Lecour 1cbb982d02 extract functions in test helpers 2020-04-25 10:29:00 +02:00
Jérémy Lecour f8395cf445 Release 2.3.1 2020-04-22 08:17:02 +02:00
Patrick Marchand 806714c9b6 Merge pull request 'Fix quoting and escaping shellcheck errors' (#38) from shellcheck-escapes into master
Quieter output from shellcheck, does not break the script or introduce functional changes.
2020-04-21 15:05:09 +02:00
Jérémy Lecour fa109e216b Give the pid of the new process 2020-04-21 09:03:18 +02:00
Jérémy Lecour 4829232a65 quote variable 2020-04-21 09:03:01 +02:00
Jérémy Lecour ea912c40f0 missing whitespace 2020-04-20 23:43:56 +02:00
Jérémy Lecour 5f3cc873a1 fix date format 2020-04-20 23:43:45 +02:00
Jérémy Lecour 11bb59831c bkctld-rm: state the age of the process when killing it 2020-04-20 23:31:39 +02:00
Jérémy Lecour ea140f6137 fix log message wording 2020-04-20 23:30:57 +02:00
Jérémy Lecour 86e88ad2c2 fix log date format
%S = seconds
%s = number of seconds since epoch
2020-04-20 23:30:45 +02:00
Patrick Marchand ec994f7e2c Removed a ignore shellcheck comment in zzz_evobackup and fix warning
Since only one PID can be in the PID file, we will never have more than one, we can thus easily quote the variable and remove the shellcheck ignore.
2020-04-20 12:12:51 -04:00
Jérémy Lecour a937049780 Release 2.3.0 2020-04-20 08:30:00 +02:00
Jérémy Lecour 205e3774a9 rewrite log messages and format 2020-04-20 08:29:21 +02:00
Jérémy Lecour 35d257d9c7 rm/inc : log progress 2020-04-20 00:38:44 +02:00
Jérémy Lecour 18e5173600 remove obsolete test 2020-04-19 11:24:13 +02:00
Jérémy Lecour 0bad1a2cba Release 2.2.2 2020-04-19 10:07:35 +02:00
Jérémy Lecour 1846be4e45 better quotes 2020-04-19 10:05:20 +02:00
Jérémy Lecour 478703d96e No space before colons in log messages 2020-04-19 09:56:52 +02:00
Jérémy Lecour 32f242fe9c Reorganize temp files and lock files
Temp files/dirs all share a common prefix, so we can delete them all 
effectively
Lock file is managed globally for bkctld-rm.
No need for a lock file for bkctld-inc anymore since there is a check on 
the inc directory before starting.
2020-04-19 09:55:43 +02:00
Jérémy Lecour f66d832d3a properly call subcommands 2020-04-19 00:16:30 +02:00
Jérémy Lecour 096fe95b2f bkctld-rm: fix lock file management
logic was badly implemented
2020-04-18 19:11:08 +02:00
Jérémy Lecour 723c8511e1 Don't forget to log the start time! 2020-04-18 19:10:19 +02:00
Jérémy Lecour 7a13a42ad2 Create empty directory in the default tmp directory 2020-04-18 19:09:52 +02:00
Jérémy Lecour 5ae3f04098 exclude build directory in vagrant rsync 2020-04-18 10:40:28 +02:00
Jérémy Lecour 7d9043acc9 Release 2.2.1 2020-04-18 10:34:50 +02:00
Jérémy Lecour f7e8324ba5 Embed check-incs and check-last-incs in bkctld 2020-04-18 10:29:21 +02:00
Jérémy Lecour 0dcd72d3f2 move relative_date() function to includes files 2020-04-18 10:28:44 +02:00
Jérémy Lecour 4c9cbf976e subcommand options are examined in their respective context 2020-04-18 10:28:06 +02:00
Jérémy Lecour 14c4b63e69 error() function is not available at this stage 2020-04-18 10:26:51 +02:00
Jérémy Lecour 2fd063fee4 gitignore build directory 2020-04-18 10:26:08 +02:00
Jérémy Lecour 8e2ed4eae7 Merge pull request 'Code cleanup' (#33) from jlecour-refactoring into master 2020-04-17 15:32:38 +02:00
Patrick Marchand d2b6094f7f Fix quoting and escaping shellcheck errors
shellcheck was still complaining about a few SC1117 and SC2086
warnings. I ignored those that did not seem necessary and fixed the
rest. The less linter noise the better.
2020-04-15 14:46:14 -04:00
Jérémy Lecour 731be98193 Add pt-show-grants to dump MySQL grants 2020-04-15 15:49:41 +02:00
Jérémy Lecour 9057a2780a check-incs : no error if date is in the future 2020-04-12 12:49:46 +02:00
Jérémy Lecour 9c6be0e74c bkctld-rm: fix inc removal
echo-ing the list of incs gives a single line, hard to match with lines 
in the keep file.
We store the incs list in a temp file to help comparing contents.
2020-04-12 11:45:21 +02:00
Jérémy Lecour 7e5aad727f Improve documentation wording 2020-04-12 11:43:41 +02:00
Jérémy Lecour 2d4cae58bc fix typo 2020-04-12 11:43:06 +02:00
Jérémy Lecour 35bed002f0 add shellcheck shell directive to bash_completion 2020-04-11 10:01:46 +02:00
Jérémy Lecour 908e3c8b3a whitespaces 2020-04-11 10:01:00 +02:00
Jérémy Lecour e01a705cff Revamp the README 2020-04-11 09:23:09 +02:00
Jérémy Lecour 8e780eafed Add tests for Buster (ext4/btrfs) 2020-04-11 08:54:01 +02:00
Jérémy Lecour e14ca8dff3 Bad firewall now returns a simple Warning 2020-04-11 08:53:41 +02:00
Jérémy Lecour b1c45b1738 Don't instruct to use a specific branch when installing manually 2020-04-11 08:41:36 +02:00
Jérémy Lecour 3198ba7f37 bkctld-rm: log incs to be deleted 2020-04-11 08:41:04 +02:00
Jérémy Lecour 401c8cd34c Add CHANGELOG file 2020-04-11 08:40:25 +02:00
Jérémy Lecour 51940220dd Instructions to install manually from sources 2020-04-10 08:42:15 +02:00
Jérémy Lecour 11f84a9f7b Emit a warning if no firewall file is configured 2020-04-08 18:35:09 +02:00
Jérémy Lecour bdc6b4fa4d bkctld-check: sourcing issue is just a warning 2020-04-08 18:32:27 +02:00
Jérémy Lecour a0b3c4fd26 bkctld-check: shorter output 2020-04-08 17:54:09 +02:00
Jérémy Lecour c2f39a0218 bkctld-check: don't eval the variables 2020-04-08 17:53:56 +02:00
Jérémy Lecour effecc689d bkctld: auto-detect lib directory 2020-04-08 17:53:28 +02:00
Jérémy Lecour 8099dcbbfe reformat authors list 2020-04-08 17:51:56 +02:00
Jérémy Lecour e1208ed2b8 shellcheck improvements for bats tests 2020-04-08 16:49:27 +02:00
Jérémy Lecour e5997400cd bkctld-check: verify that firewall rules are sourced 2020-04-08 12:26:59 +02:00
Jérémy Lecour 53b8fe8376 extract variable "jail_sshd_config" 2020-04-08 00:32:15 +02:00
Jérémy Lecour 5a90ae8a16 bkctld-ip: fail when trying to add an IP when there is no AllowUsers 2020-04-08 00:31:55 +02:00
Jérémy Lecour 86111acfea tests clarifications 2020-04-05 11:53:44 +02:00
Jérémy Lecour 2ef20df5ca whitespaces 2020-04-05 11:43:52 +02:00
Jérémy Lecour 5937a2d7aa Split tests in a few files and add many tests for incs and checks 2020-04-05 11:42:11 +02:00
Jérémy Lecour d29743357a rename function for ext4 filesystems 2020-04-05 11:41:41 +02:00
Jérémy Lecour 6377ffd09e bkctld-inc: add locks to btrfs actions
It's probably useless since btrfs commands return almost instantly
but it's consistent with ext4 commands.
2020-04-05 11:40:24 +02:00
Jérémy Lecour f6665c646b tests: use test helpers + add many test cases 2020-04-05 01:32:39 +02:00
Jérémy Lecour 41866d8236 Vagrant: reconfigure locales 2020-04-03 10:23:45 +02:00
Jérémy Lecour db70bd21e9 use explicitly relative path 2020-04-03 09:58:10 +02:00
Jérémy Lecour 3f3ffbfffd bkctld-start: extract "mount_jail_fs" function 2020-04-03 09:48:54 +02:00
Jérémy Lecour f8ef5b22cd bkctld-start: better retry logic around fetch SSH PID 2020-04-03 08:31:29 +02:00
Jérémy Lecour 9bbcb852b0 bkctld-start: chroot preparation must stay in the main process 2020-04-03 00:42:08 +02:00
Jérémy Lecour 88dd2e448b bkctld-stop: pkill outside of conditional
it breaks the stop action
2020-04-03 00:37:43 +02:00
Jérémy Lecour c920e91304 improve incs policy parsing 2020-04-02 23:52:27 +02:00
Jérémy Lecour 492433133e fix shellcheck source directive 2020-04-02 23:39:26 +02:00
Jérémy Lecour 09d2014db3 bkctld-stop: use pkill instead of a loop 2020-04-02 23:34:14 +02:00
Jérémy Lecour b141daca29 code clarification 2020-04-02 23:33:54 +02:00
Jérémy Lecour 092b204be2 naming conventions 2020-04-02 23:14:34 +02:00
Jérémy Lecour 7a80b433d6 bkctld-sync: more comment and variables 2020-04-02 18:40:27 +02:00
Jérémy Lecour 1da1c8a7fe extract function for jail config directory 2020-04-02 18:39:15 +02:00
Jérémy Lecour f36771d1f0 bkctld-rm: kill existing processes
Ifa process is still removing incs when a ew one starts, the newest 
kills the other to start again.
2020-04-02 18:30:52 +02:00
Jérémy Lecour 4e6c5cfb20 bkctld-inc : smaller lock file
Only one process can create a specific inc at the same time
2020-04-02 18:29:40 +02:00
Jérémy Lecour 45036bf731 fix incs policy on jail init 2020-04-02 18:28:41 +02:00
Jérémy Lecour 4bf1ccecae Add test for incs_policy config file 2020-04-02 18:28:15 +02:00
Jérémy Lecour 54e66aea84 Raise error if missing arguments in functions 2020-04-02 18:27:54 +02:00
Jérémy Lecour c58878b065 extract functions for config files 2020-04-02 18:26:53 +02:00
Jérémy Lecour 4ef7ab2dde Fix tests 2020-04-02 14:51:09 +02:00
Jérémy Lecour 7a040bac20 better log messages 2020-04-02 14:50:55 +02:00
Jérémy Lecour c7816abd1e bkctld-key: check if the key file is readable 2020-04-02 14:50:21 +02:00
Jérémy Lecour aa8bc9381b bkctld-firewall: removed useless test 2020-04-02 14:43:39 +02:00
Jérémy Lecour 9136d3cff4 replace "! -n" test with "-z" 2020-04-02 14:43:17 +02:00
Jérémy Lecour 1652ebeb67 fix shecllcheck source directives 2020-04-02 13:44:13 +02:00
Jérémy Lecour 5432c2eee8 whitespaces 2020-04-02 13:40:48 +02:00
Jérémy Lecour 4c2480906f adaptation des scripts de test 2020-04-02 13:32:14 +02:00
Jérémy Lecour 779dd9c518 use new conventions 2020-04-02 01:17:11 +02:00
Jérémy Lecour 01cc972d83 rename lib/config to lib/includes 2020-04-02 00:31:57 +02:00
Jérémy Lecour 77d0681d14 refactor init and update subcommands 2020-04-02 00:30:48 +02:00
Jérémy Lecour e9e8a790ba refactor check, inc, rm subcommands
function extractions
variables extractions
comments
2020-04-01 18:44:38 +02:00
Jérémy Lecour e7e3683944 fix shellcheck source directive 2020-04-01 11:23:35 +02:00
Jérémy Lecour 1f59065a17 revert zzz_evobackup commit mistake 2020-04-01 09:24:58 +02:00
Jérémy Lecour 018392e8e3 bkctld-rm: add support for the "new" canonical path for incs policy 2020-04-01 09:13:57 +02:00
Jérémy Lecour a5c0745d09 bkctld-check: use findmnt instead of grep + check "rw" for backup disk 2020-04-01 09:12:40 +02:00
Jérémy Lecour 5cc6d9e28f bkctld-check: simplify overrides
1. add support for the "new" canonical path for jail specific 
configurations

2. use a local value in the loop to prevent changing the global default 
value
2020-04-01 09:11:56 +02:00
Jérémy Lecour 10cc3695a4 Add some shellcheck directives for config source 2020-04-01 07:31:33 +02:00
Jérémy Lecour 9ae2168b1b bkctld-list: note for later, try a simpler command 2020-04-01 07:27:43 +02:00
Jérémy Lecour 6cf49b2a8b bkctld-check: add overrides for "per jail" thresholds
Putting values for CRITICAL/WARNING in <JAIL_DIR>/etc/bkctld-check
overrides the values for this specific jail.
Setting to a value <=0 disables the threshold.
2020-04-01 07:27:17 +02:00
Jérémy Lecour 0b5164b91c Add some shellcheck directives 2020-04-01 07:24:33 +02:00
Jérémy Lecour 14012ca9b0 bkctld-check: fix typos 2020-04-01 07:24:06 +02:00
Jérémy Lecour 1bc5d4ed93 bkctld-check: extract check_jail function 2020-04-01 07:23:23 +02:00
Jérémy Dubois 1fb0af4255 /srv is not on bsd systems 2020-03-25 09:31:44 +01:00
Jérémy Dubois e043118a78 Dump partitions by default on OpenBSD 2020-03-20 11:56:52 +01:00
Jérémy Lecour 81a5883d72 Log SSH errors also to logfile 2020-03-19 07:35:01 +01:00
Jérémy Lecour 34443b18bd Fail on unassigned variables 2020-03-19 07:34:35 +01:00
Victor LABORIE 0a6b5c1b80 Do not run inc / rm in background when not using btrfs 2020-03-09 16:08:17 +01:00
Victor LABORIE ed83404806 Add lock for bkctld inc / rm when not using btrfs (Fix #32) 2020-03-05 14:49:25 +01:00
Jérémy Lecour 6d7072234d improve comments readability 2020-02-14 10:52:54 +01:00
Jérémy Lecour 124af075ae improve partitions dump 2020-02-13 14:34:49 +01:00
Jérémy Lecour 48ca7cc8e4 add a schema-only dump for MySQL databases 2020-02-13 14:34:09 +01:00
Jérémy Lecour 2aeba60095 better install documentation (cron jobs) 2020-02-13 14:27:46 +01:00
Victor LABORIE 24ffa76dfc Do not unnecessary use is-on and reload in ip/port/key (Fix #31) 2020-02-05 14:58:15 +01:00
Victor LABORIE 23c98f64aa Don't force Vagrant::DEFAULT_SERVER_URL (doesn't work with recent Vagrant version) 2020-01-08 14:31:43 +01:00
Jérémy Lecour 86f6089ce6 check-last-incs.sh : new script to quickly check last inc for jails 2019-12-15 18:54:57 +01:00
Jérémy Lecour fe6811bc1e check-incs.sh : whitespaces and braces 2019-12-15 18:52:09 +01:00
Jérémy Lecour 832a219f0b "kill -O" doesn't exist, "kill -0" does! 2019-11-12 14:49:16 +01:00
Jérémy Lecour da40afa99c Add findmnt(8) output in the backup 2019-10-29 17:30:47 +01:00
Jérémy Lecour 4eb5e61ff0 improve iptables backup readability 2019-10-18 11:53:29 +02:00
Jérémy Lecour 055ee8dd90 kill process if really exists, otherwise remove the pid file 2019-09-26 09:32:51 +02:00
Gregory Colpart 2023724370 Add dump iptables / pf 2019-09-25 15:11:05 +02:00
Jérémy Lecour e83f94eaad make SSH_CONNECT_TIMEOUT configurable from outside 2019-09-23 18:06:27 +02:00
Jérémy Lecour ddba0942e3 Add variable to toggle the servers fallback 2019-09-23 18:06:00 +02:00
Gregory Colpart 6b26d7fc53 add command to dump Unix rights 2019-09-16 14:15:50 +02:00
Tristan Pilat 27b346a20d Merge branch 'pgrep' of evolix/evobackup into master
@jlecour being okay with this, I merge
2019-09-05 17:48:07 +02:00
Tristan PILAT 7eecbe3745 Replace ps for pgrep to list evobackup child procs
The command being used to identify evobackup child processes isn't
supported on OpenBSD. The pgrep command is supported on both Linux and
OpenBSD.
2019-09-05 11:41:56 +02:00
Jérémy Lecour 04296895da exclude drbd disks from list 2019-09-05 11:15:25 +02:00
Jérémy Lecour e2156ad41a Fix zzz_evobackup for fdisk command 2019-09-04 13:16:09 +02:00
Jérémy Lecour 35f3434237 Use lsblk to find actual disks 2019-09-03 10:26:38 +02:00
Jérémy Lecour d7b221796e 30 secondes suffisent par défaut 2019-08-23 14:26:48 +02:00
Jérémy Lecour 55e9c0dd63 Tasks switch are configurable from envirnoment variables too. 2019-08-23 12:05:22 +02:00
Jérémy Lecour 24481ca37e Same timeout for Rsync than SSH 2019-08-23 12:04:57 +02:00
Jérémy Lecour 242153b472 Make local and sync tasks skipable. 2019-08-22 14:50:20 +02:00
Jérémy Lecour 6ede66fa5c Use printf instead of echo where relevant 2019-08-22 13:26:18 +02:00
Jérémy Lecour c2cbcb23b4 Print SSH connection errors only if no server is available. 2019-08-22 13:25:45 +02:00
Jérémy Lecour 075f35e1a0 Merge branch 'variable-for-log-and-pidfile' of evolix/evobackup into master 2019-08-22 10:38:23 +02:00
Benoît S c3e9614dbb Adding LOGFILE variable
This is way better than hardcoding log file path.
2019-07-10 14:30:18 +02:00
Jérémy Lecour aa97d3ea88 fix partitions list
No need to look for all partitions, only disks are needed.
2019-06-24 16:36:36 +02:00
Jérémy Lecour d0afc0089c zzz_evobackup: better disks detection 2019-06-11 11:26:31 +02:00
Victor LABORIE 3d3e235ecc Make partitions dump by default on Linux 2019-06-05 11:49:18 +02:00
Jérémy Lecour e174f24b16 Merge branch 'ssh-timeout' of evolix/evobackup into master 2019-06-03 15:32:23 +02:00
Jérémy Lecour 607333d120 Merge branch 'log-server-name' of evolix/evobackup into master 2019-06-03 15:31:55 +02:00
Jérémy Lecour f9c9ab6113 zzz_evobackup: add rsync server in logfile 2019-06-03 15:28:35 +02:00
Jérémy Lecour a4ae0b84ed zzz_evobackup : SSH timeout at 60 seconds by default 2019-06-03 15:13:30 +02:00
Jérémy Lecour 25d87b5f86 Merge branch 'netstat-ss' of evolix/evobackup into master 2019-04-25 13:28:38 +02:00
Jérémy Lecour ad82cc7b7a replace netstat by ss on Linux 2019-04-25 13:27:57 +02:00
Jérémy Lecour 7376e52de2 Merge branch 'check-incs' of evolix/evobackup into master 2019-04-25 11:42:59 +02:00
Jérémy Lecour 93f55bfbb8 Merge branch 'cosmetic-changes' of evolix/evobackup into master 2019-04-25 11:39:37 +02:00
Jérémy Lecour ead3cc5678 extract date variable 2019-04-08 11:09:11 +02:00
Jérémy Lecour 02a83c1a76 Remove the leading 0 from the date output 2019-04-08 10:55:41 +02:00
Jérémy Lecour 5719e2b028 Add quotes and braces around variables 2019-04-03 20:57:18 +02:00
Jérémy Lecour 7ddabb23ca Extract a LOCAL_BACKUP_DIR variable 2019-04-03 20:52:36 +02:00
Jérémy Lecour 933b0c6842 Merge branch 'multi-servers-fallback' of evolix/evobackup into master 2019-04-03 11:54:44 +02:00
Jérémy Lecour 305655faa6 revert some quotes and braces 2019-04-01 22:16:13 +02:00
Jérémy Lecour c8e7977b27 revert variable extraction 2019-04-01 14:38:48 +02:00
Jérémy Lecour c82e77f6ee Add documentation comments to test_server and pick_server functions 2019-04-01 14:37:57 +02:00
Jérémy Lecour d741041e4c give SSH more time before failing 2019-04-01 14:23:26 +02:00
Jérémy Lecour ab3ed48f22 don't quote this vaiable ; it's a list ! 2019-03-31 22:09:53 +02:00
Jérémy Lecour abbb20e5d4 shorter lines for section titles 2019-03-31 21:59:59 +02:00
Jérémy Lecour 92d6b8af87 more braces and quotes 2019-03-31 21:58:01 +02:00
Jérémy Lecour dac06e0858 message in english 2019-03-31 21:57:46 +02:00
Jérémy Lecour e852827d9a reorganize sections or the script 2019-03-31 21:53:07 +02:00
Jérémy Lecour 34476ac7c7 whitespaces 2019-03-31 21:32:09 +02:00
Jérémy Lecour 1376771e83 shellcheck fixes 2019-03-31 21:30:07 +02:00
Jérémy Lecour b1f46bc866 Add braces around variables 2019-03-31 21:27:10 +02:00
Jérémy Lecour ab57f64d93 Extract a LOCAL_BACKUP_DIR variable 2019-03-31 21:26:52 +02:00
Jérémy Lecour b5f1e13685 Add logic to have multiple available servers
SERVERS contains 1 or more servers to send backup files to.
Each day a primary backup server is chosen.
If it's not available the script falls back to the next server, and the 
next…
2019-03-31 21:25:33 +02:00
Jérémy Lecour 3300c3df60 Add a check-incs.sh script 2019-03-29 18:20:46 +01:00
Victor Laborie 6f8217001e Merge branch 'add-NODE-in-default-config-file' of evolix/evobackup into master 2019-03-19 18:01:33 +01:00
Benoît S. 07f324bc7c bkctld.conf: Add NODE by default 2019-03-18 16:50:06 +01:00
Victor LABORIE ae883e8ed0 Use mktemp for keepfile and rm it after usage (Fix #9) 2019-02-18 11:32:28 +01:00
Victor Laborie 0044d6ed4b Merge branch 'use-mdoc' of evolix/evobackup into master 2019-01-29 16:53:11 +01:00
Patrick Marchand 77fe70aa70 Fix default bkctld.conf path in docs 2019-01-29 10:48:52 -05:00
Patrick Marchand c23d0d90da Merge branch 'master' into use-mdoc 2019-01-28 17:54:32 -05:00
Benoît S. 3222ee3145 Break line after every contributor name 2019-01-28 17:51:41 -05:00
Benoît S. cdcedbd141 Break line for contributors header infos 2019-01-28 17:51:41 -05:00
Victor LABORIE 835ccc5729 Fix shell error on vagrant provision 2019-01-28 17:51:41 -05:00
Victor LABORIE 29f4fd6e96 Do not create dirs in bkctld script 2019-01-28 17:51:41 -05:00
Victor LABORIE 023fbd18ba Use bkctld-list script for jails listing 2019-01-28 17:51:41 -05:00
Victor LABORIE cba53d8ae7 Transform bkctld SysVinit script into systemd oneshot service 2019-01-28 17:51:41 -05:00
Victor LABORIE f535b77f93 Use lastlog in sshrc 2019-01-28 17:51:41 -05:00
Victor LABORIE 43abccd6a4 Rewrite bats test 2019-01-28 17:51:41 -05:00
Victor LABORIE 09adad03e3 Subcommand list are now dynamic in bash completion 2019-01-28 17:51:41 -05:00
Victor LABORIE 084c7653dd Move logging functions into config 2019-01-28 17:51:41 -05:00
Victor LABORIE 3cb0bea28e Remove check_jail function 2019-01-28 17:51:41 -05:00
Victor LABORIE 79e0d28dcc Move check_jail_on functions into bkctld-is-on script 2019-01-28 17:51:41 -05:00
Victor LABORIE 18b44ce958 Fix help output (command can have dash) 2019-01-28 17:51:41 -05:00
Victor LABORIE c9dcca1a77 Remove get_inc function 2019-01-28 17:51:41 -05:00
Victor LABORIE d47b21343b Fix typo in bkctld-stats 2019-01-28 17:51:41 -05:00
Victor LABORIE ff65126537 Move usage functions into bkctld-help script
* Usage output is now auto-generated
2019-01-28 17:51:41 -05:00
Victor LABORIE 54261e7bcc Move firewall functions into bkctld-firewall script 2019-01-28 17:51:41 -05:00
Victor LABORIE 503ecf23f5 Merge bkctld-params and some functions into bkctld-(ip|port|key) scripts 2019-01-28 17:51:41 -05:00
Victor LABORIE 51f25080d3 Parallelize bkctld <subcommand> all 2019-01-28 17:51:41 -05:00
Victor LABORIE 0ff5d216a9 Fix typo in bkctld-update 2019-01-28 17:51:41 -05:00
Victor LABORIE e788aa152a Drop Debian Jessie support 2019-01-28 17:51:41 -05:00
Victor LABORIE e960946285 Split bkctld into multiples scripts 2019-01-28 17:51:41 -05:00
Patrick Marchand 3af8ac1510 Improved README.md and adjacent files.
* Fixed the english in README.md and docs/debian.md
 * Moved installation instructions from README.md to docs/install.md
 * Reworked the rest of README.md
 * Added a few comments to bkctld.conf
2019-01-28 17:51:41 -05:00
Patrick Marchand 15fa2dab0f Improved documentation for example script
Added the description of variables to change into the zzz_evobackup
script comments and updated the path to the repository.
2019-01-28 17:51:41 -05:00
Victor Laborie f72a0c9213 Merge branch 'break-linnes-header-infos' of evolix/evobackup into master 2019-01-23 10:59:25 +01:00
Benoît S. 2b911cff1d Break line after every contributor name 2019-01-21 14:44:30 +01:00
Benoît S. c25db32a45 Break line for contributors header infos 2019-01-21 14:42:02 +01:00
Victor LABORIE 8eb9c72f4e Fix shell error on vagrant provision 2019-01-16 16:19:09 +01:00
Victor LABORIE d09d0b0572 Do not create dirs in bkctld script 2019-01-08 16:29:03 +01:00
Victor LABORIE 183bc05ec4 Use bkctld-list script for jails listing 2019-01-08 16:23:46 +01:00
Victor LABORIE 8fa127c591 Transform bkctld SysVinit script into systemd oneshot service 2019-01-08 11:26:42 +01:00
Victor LABORIE 16d19b4a28 Use lastlog in sshrc 2019-01-08 11:11:47 +01:00
Victor LABORIE b1905eeffe Rewrite bats test 2019-01-08 11:01:17 +01:00
Victor LABORIE 4db5dcac03 Subcommand list are now dynamic in bash completion 2019-01-07 17:52:19 +01:00
Victor LABORIE cda35bba6e Move logging functions into config 2019-01-07 16:57:12 +01:00
Victor LABORIE 91272f49d5 Remove check_jail function 2019-01-07 16:41:29 +01:00
Victor LABORIE d9f8ae7036 Move check_jail_on functions into bkctld-is-on script 2019-01-07 16:34:44 +01:00
Victor LABORIE 5856cb2011 Fix help output (command can have dash) 2019-01-07 16:33:08 +01:00
Victor LABORIE 41b3536bcf Remove get_inc function 2019-01-07 16:12:51 +01:00
Victor LABORIE a028d3abee Fix typo in bkctld-stats 2019-01-07 16:11:57 +01:00
Victor LABORIE 0272c43751 Move usage functions into bkctld-help script
* Usage output is now auto-generated
2019-01-07 14:47:07 +01:00
Victor LABORIE d0165a9e3c Move firewall functions into bkctld-firewall script 2019-01-04 16:55:56 +01:00
Victor LABORIE 1522d2f6cd Merge bkctld-params and some functions into bkctld-(ip|port|key) scripts 2019-01-04 16:39:35 +01:00
Victor LABORIE 6caa9078e6 Parallelize bkctld <subcommand> all 2019-01-04 16:03:33 +01:00
Victor LABORIE 16014f3c4f Fix typo in bkctld-update 2019-01-04 15:55:34 +01:00
Victor LABORIE 6255cb23f2 Drop Debian Jessie support 2019-01-04 13:53:56 +01:00
Victor LABORIE e062a05a4b Split bkctld into multiples scripts 2019-01-04 13:52:15 +01:00
Victor Laborie 2b586b0257 Merge branch 'split-docs' of evolix/evobackup into master 2019-01-03 16:56:03 +01:00
Victor Laborie 137a87e4cb Merge branch 'improve-readme' of evolix/evobackup into master 2019-01-03 09:41:16 +01:00
Victor Laborie 1f329dd2e2 Merge branch 'example-comment-cleanup' of evolix/evobackup into master 2019-01-03 09:39:31 +01:00
Patrick Marchand eda30a013c Switch documentation to mdoc(7)
Markdown is not a suitable language for technical documentation.
2019-01-02 13:45:21 -05:00
Patrick Marchand 15819ca867 Split docs/usage.md into 3 files.
One for incremental configuration, one for bkctld.conf, and one for usage.
2019-01-02 13:40:33 -05:00
Patrick Marchand 48fb7324d8 Improved README.md and adjacent files.
* Fixed the english in README.md and docs/debian.md
 * Moved installation instructions from README.md to docs/install.md
 * Reworked the rest of README.md
 * Added a few comments to bkctld.conf
2019-01-02 12:20:41 -05:00
Patrick Marchand 720c479e73 Improved documentation for example script
Added the description of variables to change into the zzz_evobackup
script comments and updated the path to the repository.
2019-01-02 12:13:38 -05:00
Victor LABORIE ee34be5fec btrfs is now in /bin 2018-12-04 16:11:00 +01:00
Victor LABORIE f1be9e7132 Check if disk is mounted in bkctld check 2018-11-29 17:04:40 +01:00
Alexis Ben Miloud--Josselin eb85dc6175 Add clusterized elasticsearch snapshots 2018-11-21 14:32:38 +01:00
Gregory Colpart 81e79b1aaa add packages available for restauration 2018-08-25 00:02:00 +02:00
Gregory Colpart 83155a8de4 unlimited width for ps command 2018-08-25 00:00:31 +02:00
Gregory Colpart cb186dc775 Force chmod 700 for all mkdir 2018-08-20 23:12:36 +02:00
Benoît S. f369615a2f Exclude the sys database from mysql dump 2018-08-14 14:46:03 +02:00
Jérémy Dubois 664a424aee Send traceroute stderr to stdout
OpenBSD sends its first line of information into stderr
2018-07-25 19:05:26 +02:00
Jérémy Dubois d69a015025 Revert "/srv is not on BSD systems"
This reverts commit 853f6dff21.
Paths in systems variable are always backed up, that is not the case of /srv.
We have to manually remove /srv when we do not want it.
2018-07-16 16:04:43 +02:00
Jérémy Dubois 853f6dff21 /srv is not on BSD systems 2018-07-16 11:54:11 +02:00
Jérémy Dubois 391ef207f7 Add PATH, which is needed for BSD systems 2018-07-16 11:53:23 +02:00
Victor LABORIE 958eeb8776 Use absolute PATH for btrfs command
* Because command -v fail in some cases
2018-07-04 14:48:36 +02:00
Victor LABORIE 1b3b68ba16 Fix last update date of stats index file 2018-06-13 18:21:31 +02:00
Victor LABORIE a835491703 Add incs info to stats 2018-06-13 18:01:43 +02:00
Victor LABORIE f780d4d94a Add stats subcommands 2018-06-13 15:22:21 +02:00
Victor LABORIE ce674490f7 Add bats test for generate jails with different times 2018-05-30 18:33:36 +02:00
Victor LABORIE b1400c83b6 Better bkctld check output 2018-05-30 18:30:15 +02:00
Victor LABORIE dcba6d5634 Merge check_nrpe into bkctld check subcommand 2018-05-30 16:39:26 +02:00
Victor LABORIE f6aca343fb Add doc for Debian packaging 2018-05-30 15:22:17 +02:00
Victor LABORIE 1bc4530430 Convert bkctld man page in a markdown file 2018-05-30 15:21:54 +02:00
Benoît S. 86711f2234 Merge branch 'update_es_backup' 2018-04-05 16:26:22 +02:00
Benoît S. bc1012b091 Modification commentaire 2018-04-05 16:24:18 +02:00
Alexis Ben Miloud--Josselin 7a9e4c6168 Simplify and store deletion logs in /tmp 2018-04-05 16:02:07 +02:00
Victor LABORIE d27bbbc0f5 Rewrite bats tests 2018-03-28 15:11:49 +02:00
Victor LABORIE 2893953ec0 Reload when update params 2018-03-28 14:09:22 +02:00
Victor LABORIE 685b70b632 Fix reload 2018-03-27 18:35:06 +02:00
Victor LABORIE 3c12286704 Double quote all vars and add brackets 2018-03-27 18:22:31 +02:00
Victor LABORIE fa27759cad Force variables definition and add a set -u 2018-03-27 17:11:25 +02:00
Victor LABORIE d565374c5d Retab 2018-03-27 16:39:03 +02:00
Victor LABORIE 0927e79954 Use cat instead of echo for usage function 2018-03-27 16:31:50 +02:00
Victor LABORIE 8680b742dd Refactoring of logging and notification
* Use logger command, no longer write directly to logfile
* Loglevel can be set in bkctld.conf
* Remove mail notification, cronjob do it when stdout/stderr
2018-03-27 16:14:39 +02:00
Alexis Ben Miloud--Josselin 6548c5a1d8 Remove old logs 2018-03-21 18:06:00 +01:00
Alexis Ben Miloud--Josselin f449ea9b9f Removed useless (old) comment 2018-03-21 18:00:25 +01:00
Victor LABORIE d430740383 Add bats test for NRPE check 2018-03-15 12:41:54 +01:00
Victor LABORIE bde8072941 Refactoring VagrantFile and add test section to README
* nodes are set in an array
* add ext4 nodes in addition to btrfs nodes
* run bats test from nodes
2018-03-15 11:56:20 +01:00
Alexis Ben Miloud--Josselin 135c1df22a Remove unneeded lines 2018-03-14 14:49:25 +01:00
Alexis Ben Miloud--Josselin afc33a4002 Update elasticsearch snapshot 2018-03-09 10:39:59 +01:00
Victor LABORIE 8bfa8e18dd Add basics tests with bats 2018-03-05 16:16:18 +01:00
Victor LABORIE 506b1e94f9 Use run command for bats test 2018-03-05 15:43:36 +01:00
Victor LABORIE 72993de1c2 Use bats for unit test with Vagrant 2018-03-05 15:29:08 +01:00
Victor LABORIE e32c8c31ac Add a Vagrantfile for test with Vagrant 2018-03-05 14:15:23 +01:00
Benoît S. b30e0ef775 Remove mongodump backup dir before dumping
This is mandatory, elsewhere you'll retain old DBs/collections dumped.
2018-02-13 11:57:29 +01:00
Gregory Colpart 0b9049b568 Improve mysqldump in zzz_evobackup (thanks Bruno for the idea) 2018-02-08 01:44:14 +01:00
Victor LABORIE 3b40cb19d9 Fix bkctld logging on non interactive usage 2017-12-04 11:49:45 +01:00
Victor LABORIE 1b2491e201 Fix docs and README for zzz_evobackup 2017-12-04 10:56:45 +01:00
Daniel Jakots 5819a00ada zzz_evobackup is not part of the documentation... 2017-11-13 16:28:34 -05:00
Jérémy Lecour f7b8e96547 zzz_evobackup: fix arithmetics
09 % 2 is invalid
2017-10-09 11:34:18 +02:00
Gregory Colpart 7c04155fe8 add exclude for default php sessions path for Debian 9 2017-09-29 09:51:17 +02:00
Daniel Jakots d31bec4eb7 there's no /boot on OpenBSD 2017-09-07 11:05:34 -04:00
Daniel Jakots 5c8e46491a group things that need to be changed 2017-09-07 11:05:05 -04:00
Benoît S. ade9cd0e7c When doing cd -, redirect stdout
Because, `cd -` will displays on stdout the path... And we want only errors in
the cron output.
2017-09-07 10:01:27 +02:00
Victor LABORIE 7b9f834e4a Fix bashims amd deprecated backquote in sample script 2017-09-01 14:16:50 +02:00
Victor LABORIE dbea4d46b1 Use touch instead of lastlog in sshrc
Because lastlog -S doesn't work on Debian Jessie
lastlog: invalid option -- 'S'
2017-08-30 17:24:45 +02:00
Victor LABORIE fc7229fe9f Clean jail before creating it 2017-08-30 17:24:45 +02:00
Victor LABORIE 9606b23d97 Update lastlog even on non interactive ssh (eg. with rsync) 2017-08-30 17:24:45 +02:00
Victor LABORIE 985c72194a Fix /var/run to /run symlink 2017-08-30 17:24:45 +02:00
Benoît S. 2f8b655fa6 Use -e instead of -f when checking for Keyfile
Why? Because we can use FD in place of regular files. Like this:
root@backup:~# bkctld key test <(echo "ssh-rsa AA...")
Update test : key = /dev/fd/63
2017-08-30 17:23:45 +02:00
Victor Laborie ea5362ca2a Add mount check when starting jail 2017-08-17 14:55:09 -04:00
Victor Laborie 3bd4294cfb Fix jail cleaning when not running 2017-08-17 14:53:40 -04:00
Victor Laborie 44620c363a Detect btrfs command path instead of harcoding it 2017-08-17 10:35:08 -04:00
Victor Laborie 00e1569fd6 Move /var/run to /run 2017-08-17 10:35:08 -04:00
Victor Laborie f911adfe88 Fix host_key usage in sshd_config tpl 2017-08-17 10:35:08 -04:00
Daniel Jakots a16cd4be55 fix file name 2017-08-05 17:33:00 -04:00
Victor Laborie 26098f1020 Fix right on check_nrpe 2017-08-05 16:05:31 -04:00
Victor Laborie 5d462bf72a Add explicit LICENCE file 2017-08-05 15:49:27 -04:00
Victor LABORIE 2ec3f27938 Add nrpe check 2017-08-01 21:01:55 +02:00
Victor LABORIE 2688ac99bc Set UseDNS to no in default jail's sshd_config 2017-08-01 16:38:38 +02:00
Victor LABORIE f2146a56e5 Simplier, lighter and more secure jail 2017-07-21 16:46:37 +02:00
Victor LABORIE 4b86284ca0 Don't copy dsa host key but copy ecdsa and ed25519 if present 2017-07-21 16:46:36 +02:00
Victor LABORIE 4cbe721eb6 Use sh instead of bash for root in jail 2017-07-21 16:46:36 +02:00
Victor LABORIE f8b5269ca3 Allow only SSH key in default sshd_config 2017-07-21 16:46:36 +02:00
Victor LABORIE 8f2c869dfa Fix sshd logging 2017-07-21 16:46:36 +02:00
Victor LABORIE 431a245d65 Bump version to 1.4 2017-07-21 16:46:36 +02:00
Victor LABORIE 8ac454dae0 Fix shellcheck warnings 2017-07-19 14:08:48 +02:00
Victor LABORIE b8e4c3f11b Posix compatibility
* Don't use brace expansion
* Don't use process substitution
* Don't use source keyword
* Don't use $RANDOM var
2017-07-19 13:40:16 +02:00
Victor LABORIE 03ce05b2a9 Cleaning, thanks to shellcheck 2017-07-18 16:02:43 +02:00
Victor LABORIE a4e3b72373 Bump version to 1.3 2017-07-17 11:36:11 +02:00
Victor LABORIE e82340943b Fix if [[ -> if [ 2017-07-13 16:41:38 +02:00
Victor LABORIE beecd93c2b Fix btrfs support/detection 2017-07-13 16:41:32 +02:00
Gregory Colpart 641d400afa Improve packages list backup 2017-07-12 01:19:22 +02:00
Victor LABORIE 1a777afb5f Add chroot dependency to README 2017-05-17 16:46:54 +02:00
Victor LABORIE cc4bee52bd Btrfs snapshot (incs) are now readonly 2017-05-17 16:46:54 +02:00
Daniel Jakots b7fedb5609 Use English for var names 2017-05-15 13:20:44 -04:00
Benoît S. d461e44609 Another method with gzip directly piped for pg_dumpall. 2017-04-04 09:47:47 +02:00
Victor LABORIE e5ac7e6e73 Delete firewall rules on bkctld remove 2017-03-31 14:54:18 +02:00
Victor LABORIE d8b6fe9d87 Dump all disk (include vd[a-z]) on Linux (work for mbr and gpt disk) 2017-03-27 11:36:53 +02:00
Victor LABORIE 8c4be9fc0d Update man page 2017-03-24 12:20:51 +01:00
Victor LABORIE e815d61867 Use lazy umount (wait for sshd stop) 2017-03-24 12:19:19 +01:00
Daniel Jakots 661e69ed4b autodetect the system we run on 2017-03-23 13:57:50 -04:00
Victor LABORIE 207386de28 Fix schema on README 2017-03-17 11:07:56 +01:00
Victor LABORIE 7493327b1b Don't automatically purge incs with bkctld remove (cp version) 2017-03-15 11:15:55 +01:00
Victor LABORIE da72a2e71b Add uname in client sample script (Fix #1953) 2017-02-17 13:19:53 +01:00
Victor LABORIE 031723d26a Add local dir for surcharge default templates files 2017-02-17 13:19:53 +01:00
Victor LABORIE f945ad2b2c Fix repository url in README 2017-02-10 11:31:08 +01:00
Victor LABORIE d35c37dd6e Print all IP on bkctld status (Fix #2135) 2017-02-09 15:24:55 +01:00
Benoît S. 49c811432e Removed username. 2017-02-09 09:48:38 +01:00
Benoît S. a03dc4e378 Check exit code of mongodump. 2017-02-07 15:26:22 +01:00
Benoît S. 4268c8f0ed mongodump with --quiet. Not std{err,out} redirection! 2017-02-07 10:19:53 +01:00
Victor LABORIE b7db022bed Add bash completion 2017-02-02 18:23:28 +01:00
Victor LABORIE 3ad28029a3 Fix bkctld sync 2017-02-02 10:43:48 +01:00
Victor LABORIE 43137dadb2 Make minifirewall silent 2017-02-01 16:31:12 +01:00
Victor LABORIE 2a6b998d9e Use absolute path for btrfs command (fix cron use) 2017-01-27 11:33:58 +01:00
Victor LABORIE ee3ab76877 Extract debian dir from ustream repo 2017-01-19 15:02:11 +01:00
Victor LABORIE 0296fab941 Fix mail notification constant name 2017-01-18 10:33:02 +01:00
Victor LABORIE 60ccaaa2e2 Add licence and author/contributor infos 2017-01-17 16:50:39 +01:00
Victor LABORIE 5ca8bb99dc Add comment default value in conf file 2017-01-17 16:10:16 +01:00
Tristan PILAT 7f017b6cf5 First proofread 2017-01-16 18:52:24 +01:00
Victor LABORIE 2fa0842224 Rewrite Readme and man page 2017-01-16 17:23:40 +01:00
Victor LABORIE e7d3d7cdca Kill old rm only if always run 2017-01-12 12:27:58 +01:00
Victor LABORIE 61481e81fb Fix bkctld restart all 2017-01-12 11:32:02 +01:00
Victor LABORIE a1942c486f Fix inc and rm logging 2017-01-12 11:26:58 +01:00
Victor LABORIE 9faa3b3c34 Fix default constants 2017-01-12 11:14:39 +01:00
Victor LABORIE a0051afa41 Fix inc PATH for cp and inc log 2017-01-12 11:09:27 +01:00
Victor LABORIE ebedc7b06c Better file hierarchy 2017-01-12 10:25:41 +01:00
Victor LABORIE 4c4e845dd8 Initial version of Debian package 2017-01-11 18:47:10 +01:00
Victor LABORIE f5116b8c9d Fix sync subcommand 2017-01-11 12:12:02 +01:00
Victor LABORIE 0ca32f1579 Auto restart minifirewall if present 2017-01-11 11:28:28 +01:00
Victor LABORIE 0498a2fc32 Fix print of status of all jail 2017-01-10 18:16:15 +01:00
Victor LABORIE c9f0a0aeb4 Fix default value 2017-01-10 16:28:20 +01:00
Victor LABORIE 30b69affa8 Send mail with rm recap 2017-01-10 16:22:15 +01:00
Victor LABORIE ebec139084 Send mail with inc recap 2017-01-10 16:11:43 +01:00
Victor LABORIE b36d6f90e2 Kill previous bkctld rm if always run 2017-01-10 15:26:58 +01:00
Victor LABORIE b2222b0d47 Add default value for constant defined in /etc/default/evobackup 2017-01-10 14:56:17 +01:00
Victor LABORIE e58b2c3f65 More verbose log 2017-01-10 14:35:04 +01:00
Victor LABORIE 2f289a4bcd Refactoring 2017-01-10 12:12:33 +01:00
Victor LABORIE ea869a9c8e Add log function for logging
(utilisez "git push" pour publier vos commits locaux)
2017-01-09 18:35:07 +01:00
Victor LABORIE f6e404bc1f Fix bkctld rm 2017-01-09 16:54:54 +01:00
Victor LABORIE 4adcd90e9a Refactoring 2017-01-09 14:26:52 +01:00
Victor LABORIE d876e17624 Rename bkctl to bkctld 2017-01-09 14:16:03 +01:00
Victor LABORIE ce46f760a7 Add remove subcommand 2017-01-09 14:05:22 +01:00
Victor LABORIE 7816bd37ff Merge btrfs support 2017-01-09 13:55:35 +01:00
Victor LABORIE d28a138265 Extract update from init command
Check sshd return code on start
Refactoring
2016-12-22 17:16:03 +01:00
Victor LABORIE d809f01606 Support for sync jail on other node 2016-12-20 14:37:59 +01:00
Victor LABORIE 65d2b291cc Support for set firewall rules 2016-12-20 13:56:09 +01:00
Victor LABORIE 283d1b3c6c Set IP support for bkctl 2016-12-20 13:38:26 +01:00
Victor LABORIE d663f4591d Refactoring 2016-12-20 11:59:18 +01:00
Victor LABORIE 9f10f9bc52 Populate dev rather than mount it 2016-12-19 21:31:17 +01:00
Victor LABORIE 6a3fd23d91 bkctl script for managing evobackup 2016-12-19 17:03:49 +01:00
Victor LABORIE 6a4af139ba Add RabbitMQ example. 2016-11-09 12:10:10 +01:00
Benoît S. 29cd250c73 Updated mongodb example. 2016-08-18 18:01:07 +02:00
Benoît S. ce3d199065 Added jail_init.sh.
A script that can be used when you have two servers in nodes.
2016-06-03 14:31:09 +02:00
Gregory Colpart 11e73103d0 new default routes (more stable) 2016-05-10 00:34:27 +02:00
Benoît S. a2bdfc106b Exclude /var/lib/munin/*tmp* in place of /var/lib/munin/*.tmp
Better match for files like:
  file has vanished: "/var/lib/munin/graphs.tmp.3006"
2016-04-21 11:59:51 +02:00
Gregory Colpart 8aab335168 Add command to backup megacli config (RAID hw config) 2015-11-25 17:16:46 +01:00
Gregory Colpart ee57c20134 retab 2015-11-24 19:52:05 +01:00
Gregory Colpart e924394230 force umask 2015-11-24 19:50:51 +01:00
Gregory Colpart cc72f8eaa2 typo 2015-11-24 19:50:51 +01:00
Tristan PILAT cbe6af8ce7 Making zzz_evobackup more BSD compatible 2015-11-12 17:54:58 +01:00
Benoît S. 23c53cfca2 Added synchronize /etc/evobackup for multi nodes. 2015-09-07 09:40:46 +02:00
Benoît S. ee4d9ea72d Updated french documentation. 2015-09-03 10:23:10 +02:00
Benoît S. 831806fe68 Delete TOC and fixing some notes. 2015-08-28 19:10:48 +02:00
Benoît S. e6bd94031e Updated French README. 2015-08-28 19:01:06 +02:00
Gregory Colpart ecd3190fdd Fix #1533 : revert chroot-dir -> chroot-name change
I want chroot-ssh.sh stay evo-independant, then we can't "detect" chroot dir.
2015-08-14 18:44:55 +02:00
Gregory Colpart 1b02ba0a70 - use only english in comments
- improve comments
2015-08-12 13:18:47 +02:00
Benoît S. 0fcc2478c4 Some ameliorations esp. for shared libraries and chroot path.
* Replaced backtick by $().
* Some "Beautification".
* Better finding of shared libraries.
* $chrootdir used when giving name to the chroot with -n.
* Jessie tested OK.
2015-07-02 16:25:04 +02:00
Benoît S. aaa0910e9b chmod +x for executables. 2015-07-02 15:21:29 +02:00
Benoît S. 62d397386d Add --exclude "/var/lib/clamav/*.tmp" 2015-02-06 11:39:27 +01:00
Gregory Colpart e84cc25c5c Set LANG=C 2015-02-03 01:06:09 +01:00
Benoît S. bd48826956 Exclude /home/mysqltmp 2015-01-16 11:38:48 +01:00
Benoît S. 0a3ab673cc Added --hex-blob to mysqldump. 2014-12-30 10:08:08 +01:00
Gregory Colpart 33ab2d2f74 Improve exceptions 2014-12-29 18:25:45 +01:00
Gregory Colpart 4dafd8bc62 add exception by default 2014-12-22 18:35:35 +01:00
Benoît S. 3eef93bb10 Added insserv evobackup in README. 2014-10-07 15:46:41 +02:00
Gregory Colpart 4fa9c89dae Add infos for MS Window$ clients 2014-07-15 22:13:50 +02:00
Gregory Colpart b69ad78f18 update doc 2014-06-25 02:22:26 +02:00
Gregory Colpart 6e1499f31d Create empty authorized_keys 2014-06-25 02:08:05 +02:00
Gregory Colpart e5641d6b23 Remove deprecated jail-evobackup-add.sh 2014-06-25 02:07:42 +02:00
Gregory Colpart 44599590ae Errors with new init script 2014-06-19 04:55:27 +02:00
Gregory Colpart a27c2e79c2 Merge improvements from Benoit (part 2) 2014-06-19 02:43:36 +02:00
Gregory Colpart b7a5efa462 support symlink without modification 2014-06-17 19:17:31 +02:00
Gregory Colpart 80fc96a17f Merge improvements from Benoit (part 1) 2014-05-28 16:48:25 +02:00
Benoît S. d494400364 Added mount /dev/pts in README. 2014-01-30 11:08:38 +01:00
Benoît S. 839dbdc98a Added compatibility for Wheezy when creating chroot. 2014-01-30 10:50:40 +01:00
Benoît S. 6eea9aa47e Exclude database performance_schema for MySQL dumps. 2014-01-10 14:29:05 +01:00
Benoît S. 75f256b8e7 Added --events for mysqldump. 2014-01-10 11:07:05 +01:00
Benoît S. b48b2a58fa Comment of ElasticSearch dump.
No need to be activated by default...
2014-01-09 17:00:51 +01:00
Benoît S. 3ca2623d70 Added a way of backuping ElasticSearch 2013-11-15 12:16:50 +01:00
Benoît S. 174c46aea8 Adding a loop when dumping routes. 2013-09-03 15:01:55 +02:00
Benoît S. 92f6db4439 Fix a bug in the way of killing evobackup.
The process is launched by "run-parts /etc/cron.daily". When you kill the
process, run-parts is not informed and the process go in Z state (and rsync
continue to work!). When another run-parts is launched the part wich kill a
process if already launched fail.

This fix this particular bug.
2013-08-05 17:46:18 +02:00
Gregory Colpart 88fb702b46 Add netstat dump 2013-06-30 13:18:54 +02:00
Romain Dessort 6bf536dc1e Remove exit 0 if evobackup already running. 2013-05-03 15:41:54 +02:00
Romain Dessort 329617461e Merge branch 'master' of ssh://git.evolix.org/git/evolinux/evobackup 2013-05-03 15:27:45 +02:00
Romain Dessort 4fe816827f Kill evobackup process if it was already running, instead of simply send
an email.
2013-05-03 15:25:50 +02:00
Gregory Colpart 516eece91c Merge branch 'master' of ssh://git.evolix.org/git/evolinux/evobackup 2013-04-12 18:05:03 +02:00
Gregory Colpart 606ff2923b Add --partial option to rsync ! 2013-04-12 18:04:32 +02:00
Gregory Colpart 1a54bb92e3 Error on mysqldump option 2013-01-28 00:18:11 +01:00
Gregory Colpart 1f910818ca Update infos about versions of Debian 2013-01-27 20:15:23 +01:00
Romain Dessort fc39d0c186 Fix argument order in mysqldump commandline
--defaults-extra-file must be the first option.
2012-11-05 11:47:14 +01:00
Gregory Colpart 7453e90313 Merge branch 'master' of ssh://git.evolix.org/git/evolinux/evobackup 2012-10-27 18:27:49 +02:00
Gregory Colpart f66d088636 backup Redis 2012-10-27 18:27:18 +02:00
Benoît S. 1c3390b398 Adding --force parameter to mysqldump commands. This permit to continue even if mysqldump fail (i.e corrupt table). 2012-07-30 14:55:09 +02:00
Benoît S. 1f60b99e33 Add a new way of backuping MySQL databases. Each databases go in a separate .sql.gz file. 2012-07-30 14:52:10 +02:00
Arnaud Tomeï c382eda4f0 Correction du README pour remplacer sh par bash :( 2012-03-19 14:31:35 +01:00
Romain Dessort 1384458ad4 Save list of installed packages. 2012-03-14 17:52:41 +01:00
Romain Dessort f0192548b7 Fix a bug in the slapcat command line. 2012-02-27 15:12:27 +01:00
Romain Dessort 6a9614750d chroot-ssh.sh is not sh-compatible :-(. 2012-01-10 17:39:03 +01:00
Romain Dessort 7c208d7bff Add a proces snapshot to zzz_evobackup. 2011-12-30 14:13:51 +01:00
Romain Dessort 7ba57a1cd2 Merge branch 'master' of ssh://billux@git.evolix.org/git/evolinux/evobackup 2011-10-06 10:36:22 +02:00
Romain Dessort 2f15f29d9a Fix a mistake in the README file about incremental backups. 2011-10-06 10:33:52 +02:00
Romain Dessort 7c7de1b6f1 Fix a bug when redirecting stderr in mongodump command. 2011-09-08 13:37:31 +02:00
atomei 9272184e41 Remove vmlinuz, since it does no longer exist 2011-08-22 17:23:24 +02:00
Romain Dessort 19b668006f Merge branch 'master' of ssh://billux@git.evolix.org/git/evolinux/evobackup 2011-08-17 11:04:39 +02:00
Romain Dessort d9303b062f Add an example to dump Mongo databases 2011-08-17 11:02:39 +02:00
atomei 08bb28ba85 Correction d'un bug sous Squeeze et ajout d'une dépendance: makedev. 2011-07-15 18:29:15 +02:00
Gregory Colpart 31e69c380c Separation between creating inc copy and purge inc copies 2011-07-14 18:17:39 +02:00
Romain Dessort 28f179c60a Exclude /var/lib/postgresql 2011-07-01 17:28:43 +02:00
Romain Dessort 0fe492a484 Fix a bug while getting mysql instance's port
Tabulations characters wasn't handled correctly, and $instance variable
didn't contain correct port value.
2011-06-11 09:50:19 +02:00
Romain Dessort 9d322b4e2a Check if evobackup already running before launch it 2011-05-24 11:24:28 +02:00
Romain Dessort 824fff557e Ignore certain slapcat warnings (unclean shutdown...) 2011-05-24 11:17:49 +02:00
Romain Dessort 2e1f3e90c7 Fix bug when creating jails (wrong path for authorized_keys file) 2011-05-03 17:54:13 +02:00
Romain Dessort df2c1945d6 Fix a bug on first installation
Create /etc/evobackup/ directory if not present (first installation)
2011-05-03 17:41:24 +02:00
Romain Dessort f6ed17e75a New startup script
Evobackup has now his own startup script (/etc/init.d/evobackup). The
jail-evobackup-add.sh can add new jails in the startup script (no manual
edit needed).
2011-03-15 17:02:38 +01:00
Romain Dessort fb62ae9572 Add a new script to automatically create a new jail
Not completely finished yet.
2011-03-04 17:16:20 +01:00
Gregory Colpart 73df2f04f9 Add --force option to rsync, to enable deleting non-empty dirs 2010-12-09 23:20:22 +01:00
Gregory Colpart 422069e40c Improve a way of mysqldump 2010-11-30 20:27:05 +01:00
Gregory Colpart 1d96b82b43 Delete so stupid space 2010-10-26 01:18:17 +02:00
Gregory Colpart b99d62ac97 Add /var/lib/metche in --exclude list 2010-09-30 20:55:14 +02:00
Gregory Colpart 70c07af8af Add some informations (thanks to testers/reporters) 2010-09-22 00:54:07 +02:00
69 changed files with 6513 additions and 545 deletions

33
.Jenkinsfile Normal file
View file

@ -0,0 +1,33 @@
pipeline {
agent { label 'sbuild' }
stages {
stage('Build Debian package') {
when {
branch 'debian'
}
steps {
script {
sh 'gbp buildpackage'
}
archiveArtifacts allowEmptyArchive: true, artifacts: 'build-area/*.gz,build-area/*.bz2,build-area/*.xz,build-area/*.deb,build-area/*.dsc,build-area/*.changes,build-area/*.buildinfo,build-area/*.build,build-area/lintian.txt'
}
}
stage('Upload Debian package') {
when {
branch 'debian'
}
steps {
script {
sh 'rsync -avP build-area/bkctld*.deb build-area/bkctld*.changes build-area/bkctld*.buildinfo pub.evolix.org:/srv/upload/'
}
}
}
}
post {
// Clean after build
always {
cleanWs()
}
}
}

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
*.swp
.vagrant

View file

@ -1,10 +0,0 @@
PLAN DES SAUVEGARDES
====================
PORT JAIL ETAT
-------------------------------------------------------
2222 Serveur 1 (IP) 1
2223 Serveur 2 (IP) 1
2224 Serveur 3 (IP) 0
etc....
.......

202
README
View file

@ -1,202 +0,0 @@
EvoBackup
=========
EvoBackup est un ensemble de scripts permettant de mettre en place
un service de backups gérant les sauvegardes de plusieurs machines.
Le principe est d'installer des prisons/chroot contenant un service
SSH écoutant sur un port différent dans chaque prison. Chaque serveur
peut ainsi envoyer ses données quotidiennement en "root" via rsync
dans sa propre prison. Les prisons sont ensuite copiées en dehors des
prisons (donc inacccessible par les serveurs) de façon incrémentale
grâce à des "hard links". On peut ainsi conserver des dizaines de
sauvegardes de chaque serveur de façon sécurisé et avec peu de place.
**************************
Serveur 1 ------SSH/rsync -------> * tcp/2222 Serveur *
* de *
Serveur 2 ------SSH/rsync -------> * tcp/2223 Sauvegardes *
**************************
Cette technique de sauvegarde s'appuient sur des technologies
standards. Elle est utilisée depuis plusieurs années par Evolix
pour sauvegarder chaque jour des centaines de serveurs représentant
plusieurs To de données incrémentales.
Serveur de sauvegardes
----------------------
Le serveur de sauvegardes doit être sous Debian Lenny.
(testé sous Etch et Lenny, les instructions sont pour Lenny).
Avec les logiciels suivants :
- OpenSSH
- Rsync (le daemon rsync n'est pas nécessaire)
- Commande "mail" (ou un équivalent) capable d'envoyer
des messages à l'extérieur.
Un volume d'une taille importante doit être monté sur /backup
Pour des raisons de sécurité on pourra chiffre ce volume.
On créera ensuite les répertoires suivants :
- /backup/jails : pour les prisons
- /backup/incs : pour les copies incrémentales des prisons
- /etc/evobackup : config des fréquences des copies incrémentales
Pour la mise en place des backups incrémentaux sur le serveur :
- Mettre en place le script evobackup-inc.sh dans /usr/share/scripts
- Activer le crontab suivant (ajuster éventuellement les heures) :
30 10 * * * /usr/share/scripts/evobackup-inc.sh
Si le noyau du serveur est patché avec GRSEC, on évitera pas mal
de warnings en positionnant les paramètres Sysctl suivants :
# sysctl kernel.grsecurity.chroot_deny_chmod=0
# sysctl kernel.grsecurity.chroot_deny_mknod=0
Serveurs à sauvegarder
----------------------
On peut sauvegarder différents systèmes : Linux, BSD, Windows, MacOSX.
L'un des seuls prérequis est d'avoir rsync.
Installation d'une sauvegarde
-----------------------------
Côté serveur de sauvegardes
~~~~~~~~~~~~~~~~~~~~~~~~~~~
1) On récupère les sources via http://git.evolix.org/git/evolinux/evobackup.git
- Exporter la variable $JAIL avec le nom d'hôte saisit dans la grille :
# export JAIL=<nom d'hote>
- Se placer dans le bon répertoire puis exécuter :
# sh chroot-ssh.sh /backup/jails/$JAIL
Note : Ignorer une éventuelle erreur avec ld-linux-x86-64.so.2 (32bits) ou ld-linux.so.2 (64bits)
- Editer le fichier /backup/jails/$JAIL/etc/ssh/sshd_config
et remplacer le port SSH utilisé par le prochain disponible
(ou garder celui assigné si c'est la première prison).
Ajouter également la restriction d'IP si possible via "AllowUsers" :
AllowUsers root@IP root@::ffff:IP
- Ajouter la clé publique du client à sauvegarder dans
/backup/jails/$JAIL/root/.ssh/authorized_keys
- Puis corrigez les droits SSH :
# chmod -R 600 /backup/jails/$JAIL/root/.ssh/
# chown -R root:root /backup/jails/$JAIL/root/.ssh/
2) Gestion du lancement des prisons en modifiant le fichier
de démarrage /etc/init.d/ssh (on remplacera $JAIL par sa
vraie valeur).
- Ajouter à start) :
mount -t proc proc-chroot /backup/jails/$JAIL/proc/
mount -t devpts devpts-chroot /backup/jails/$JAIL/dev/pts/
chroot /backup/jails/$JAIL /usr/sbin/sshd > /dev/null
- Ajouter à stop) :
umount /backup/jails/$JAIL/proc/
umount /backup/jails/$JAIL/dev/pts/
kill -9 `chroot /backup/jails/$JAIL cat /var/run/sshd.pid`
- Ajouter à reload|force-reload) :
kill -HUP `chroot /backup/jails/$JAIL cat /var/run/sshd.pid`
- Ajouter à restart) :
kill -9 `chroot /backup/jails/$JAIL cat /var/run/sshd.pid`
chroot /backup/jails/$JAIL /usr/sbin/sshd > /dev/null
3) On lance la prison :
# mount -t proc proc-chroot /backup/jails/$JAIL/proc/
# mount -t devpts devpts-chroot /backup/jails/$JAIL/dev/pts/
# chroot /backup/jails/$JAIL /usr/sbin/sshd > /dev/null
Pour vérifier que tout est OK :
# /etc/init.d/ssh reload
4) Gestion des sauvegardes incrémentales
Pour activer les gestions des copies incrémentales,
créer le fichier /etc/evobackup/$JAIL contenant par
exemple :
+%Y-%m-%d.-0day
+%Y-%m-%d.-1day
+%Y-%m-%d.-2day
+%Y-%m-%d.-3day
+%Y-%m-01.-0month
+%Y-%m-01.-1month
Quelques explications sur cette syntaxe particulière.
Par exemple, la ligne ci-dessous signifie "garder la sauvegarde du
jour actuel" (à toujours mettre sur la première ligne a priori) :
+%Y-%m-%d.-0day
La ligne ci-dessous signifie "garder la sauvegarde d'hier" :
+%Y-%m-%d.-1day
La ligne ci-dessous signifie "garder la sauvegarde du 1er jour du
mois courant" :
+%Y-%m-01.-0month
Toujours le même principe, on peut garder celle du 1er jours du
mois dernier :
+%Y-%m-01.-1month
Et bien sûr, on peut garder aussi le 15e jour (pour avoir une sauvegarde
toutes les 15 jours, le 1er janvier de chaque année, etc.)
Côté serveur à sauvegarder
~~~~~~~~~~~~~~~~~~~~~~~~~~
1) Générez une clé SSH pour l'utilisateur "root" :
# ssh-keygen
(Ne pas la protéger par une passphrase, sauf si un humain
va l'entrer manuellement à chaque sauvegarde effectuée)
(La clé générée doit être de type RSA et non DSA !!)
2) Envoyez "/root/.ssh/id_rsa.pub" au responsable du serveur de
sauvegarde, ainsi que l'adresse IP de la machine.
3) Ajoutez à la crontab le fichier "zzz_evobackup"
Pour une sauvegarde quotidienne (conseillé), utilisez le répertoire
"/etc/cron.daily/" (sous Linux) ou "/etc/periodic/daily" (sous FreeBSD).
Il faut éventuellement ajuster le script en supprimant les lignes "--exclude"
si l'on ne souhaite pas exclure les fichiers/répertoires de cette ligne et
ajouter/supprimer les lignes en dessous pour sauvegarder les bons répertoires.
($rep désigne les données systèmes). Vous pouvez donc choisir librement ce
que vous désirez sauvegarder.
4) Une fois que tout en place au niveau du serveur de sauvegardes,
on doit initier la première connexion :
# ssh -p <port> <serveur de sauvegardes>
Mise-à-jour du serveur de sauvegardes
-------------------------------------
En cas d'une mise-à-jour d'un paquet lié à SSH ou rsync côté
serveur de sauvegardes, on mettra à jour ainsi :
# sh chroot-ssh.sh updateall
# /etc/init.d/ssh restart

View file

@ -1,140 +0,0 @@
#!/bin/sh
# Gregory Colpart <reg@evolix.fr>
# chroot script for OpenSSH
# $Id: chroot-ssh.sh,v 1.12 2010-07-02 17:40:29 gcolpart Exp $
# tested on Debian Etch and recently on Lenny
# Exec this script for jail creation:
# ./chroot-ssh.sh /backup/jails/myserver
# Note: etc/{sshd_config,group,passwd} files should be present
# For Etch
# Start: chroot /backup/jails/myserver /usr/sbin/sshd > /dev/null
# Reload: kill -HUP `chroot /backup/jails/myserver cat /var/run/sshd.pid`
# Stop: kill -9 `chroot /backup/jails/myserver cat /var/run/sshd.pid`
# Restart: Stop + Start
# For Lenny
# Start :
# chroot /backup/jails/myserver mount -t proc proc-chroot /proc/
# chroot /backup/jails/myserver mount -t devpts devpts-chroot /dev/pts/
# chroot /backup/jails/myserver /usr/sbin/sshd > /dev/null
# Reload: kill -HUP `chroot /backup/jails/myserver cat /var/run/sshd.pid`
# Stop: kill -9 `chroot /backup/jails/myserver cat /var/run/sshd.pid`
# Restart:
# kill -9 `chroot /backup/jails/myserver cat /var/run/sshd.pid`
# chroot /backup/jails/myserver /usr/sbin/sshd > /dev/null
# After *each* ssh upgrade or libs upgrade:
# sh chroot-ssh.sh updateall
# And restart all sshd daemons
bincopy() {
chrootdir=$1
# TODO : better detection of amd64 arch
cp -f /lib/ld-linux.so.2 $chrootdir/lib/ || cp -f /lib64/ld-linux-x86-64.so.2 $chrootdir/lib64/
cp /lib/libnss* $chrootdir/lib/
for dbin in /bin/bash /bin/cat /bin/chown /bin/mknod /bin/rm /bin/sed /bin/sh /bin/uname /bin/mount /usr/bin/rsync /usr/sbin/sshd /usr/lib/openssh/sftp-server; do
cp -f $dbin $chrootdir/$dbin;
# (comme dans http://www.gcolpart.com/hacks/chroot-bind.sh)
for lib in `ldd $dbin | cut -d">" -f2 | cut -d"(" -f1`; do
cp -p $lib $chrootdir/$lib
done
done
}
# synopsis
if [ $# -ne 1 ]; then
echo "Vous devez indiquer un repertoire."
echo "Exemple : chroot-ssh.sh /backup/jails/myserver"
exit 0
fi
# are u root?
if [ `whoami` != "root" ]; then
echo "Vous devez executer le script en étant root."
exit 0
fi
if [ -e $1 ]; then
echo "Le repertoire $1 existe deja..."
fi
if [ "$1" = "updateall" ]; then
for i in `ls -1 /backup/jails/*/lib/libnss_compat.so.2`; do
chrootdir=`echo $i | cut -d"/" -f1,2,3,4`
echo -n "MaJ $chrootdir ..."
bincopy $chrootdir
echo "...OK"
done
else
# where is jail
chrootdir=$1
mkdir -p $chrootdir
chown root:root $chrootdir
# create jail
echo -n "1 - Creation de la prison..."
mkdir -p $chrootdir/{bin,dev,etc/ssh,lib,lib64}
mkdir -p $chrootdir/lib/tls/i686/cmov/
mkdir -p $chrootdir/proc
mkdir -p $chrootdir/root/.ssh
mkdir -p $chrootdir/usr/lib/i686/cmov/
mkdir -p $chrootdir/lib/i686/cmov/
mkdir -p $chrootdir/usr/{bin,lib,sbin}
mkdir -p $chrootdir/usr/lib/openssh
mkdir -p $chrootdir/var/log/
mkdir -p $chrootdir/var/run/sshd
touch $chrootdir/var/log/{authlog,lastlog,messages,syslog}
touch $chrootdir/etc/fstab
echo "...OK"
echo -n "2 - Copie des donnees..."
cp /proc/devices $chrootdir/proc
cp /etc/ssh/{ssh_host_rsa_key,ssh_host_dsa_key} $chrootdir/etc/ssh/
cp etc/sshd_config $chrootdir/etc/ssh/
cp etc/passwd $chrootdir/etc/
cp etc/shadow $chrootdir/etc/
cp etc/group $chrootdir/etc/
echo ".......OK"
echo -n "3 - Copie des binaires..."
bincopy $chrootdir
echo "......OK"
echo -n "4 - Creation des devices..."
cd $chrootdir/dev/
cp /dev/MAKEDEV ./
./MAKEDEV {null,random,urandom,pty}
mkdir pts
#mknod ptmx c 5 2
echo "....OK"
echo -n "5 - Termine."
# end
echo ""
fi

47
client/CHANGELOG.md Normal file
View file

@ -0,0 +1,47 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
### Changed
### Deprecated
### Removed
### Fixed
### Security
## [22.12]
### Changed
* Use --dump-dir instead of --backup-dir to suppress dump-server-state warning
* Do not use rsync compression
* Replace rsync option --verbose by --itemize-changes
* Add canary to zzz_evobackup
* update-evobackup-canary: do not use GNU date, for it to be compatible with OpenBSD
* Add AGPL License and README
* Script now depends on Bash
* tolerate absence of mtr or traceroute
* Only one loop for all Redis instances
* remodel how we build the rsync command
* use sub shells instead of moving around
* Separate Rsync for the canary file if the main Rsync has finished without errors
### Removed
* No more fallback if dump-server-state is missing
### Fixed
* Make start_time and stop_time compatible with OpenBSD
## [22.03]
Split client and server parts of the project

661
client/LICENSE Normal file
View file

@ -0,0 +1,661 @@
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.
A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate. Many developers of free software are heartened and
encouraged by the resulting cooperation. However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.
The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community. It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server. Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.
An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals. This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU Affero General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Remote Network Interaction; Use with the GNU General Public License.
Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software. This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time. Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source. For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code. There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<https://www.gnu.org/licenses/>.

3
client/README.md Normal file
View file

@ -0,0 +1,3 @@
Pour l'installation de `zzz_evobackup`, voir <https://intra.evolix.net/OutilsInternes/EvoBackupClient#installer-et-configurer-le-client-evobackup>
Pour `update-evobackup-canary`, voir <https://intra.evolix.net/OutilsInternes/update-evobackup-canary>

View file

@ -0,0 +1,129 @@
#!/bin/sh
PROGNAME="update-evobackup-canary"
REPOSITORY="https://gitea.evolix.org/evolix/evobackup"
VERSION="22.06"
readonly VERSION
# base functions
show_version() {
cat <<END
${PROGNAME} version ${VERSION}
Copyright 2022 Evolix <info@evolix.fr>,
Jérémy Lecour <jlecour@evolix.fr>,
and others.
${REPOSITORY}
${PROGNAME} comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to redistribute it under certain conditions.
See the GNU General Public License v3.0 for details.
END
}
show_help() {
cat <<END
${PROGNAME} is updating a canary file for evobackup.
Usage: ${PROGNAME} [OPTIONS]
Main options
-w, --who who has updated the file (default: logname())
-f, --file path of the canary file (default: /zzz_evobackup_canary)
-V, --version print version and exit
-h, --help print this message and exit
END
}
main() {
if [ -z "${who:-}" ]; then
who=$(logname)
fi
if [ -z "${canary_file:-}" ]; then
canary_file="/zzz_evobackup_canary"
fi
# This option is supported both on OpenBSD which does not use GNU date and on Debian
date=$(date "+%FT%T%z")
printf "%s %s\n" "${date}" "${who}" >> "${canary_file}"
}
# parse options
# based on https://gist.github.com/deshion/10d3cb5f88a21671e17a
while :; do
case $1 in
-h|-\?|--help)
show_help
exit 0
;;
-V|--version)
show_version
exit 0
;;
-w|--who)
# with value separated by space
if [ -n "$2" ]; then
who=$2
shift
else
printf 'ERROR: "-w|--who" requires a non-empty option argument.\n' >&2
exit 1
fi
;;
--who=?*)
# with value speparated by =
who=${1#*=}
;;
--who=)
# without value
printf 'ERROR: "--who" requires a non-empty option argument.\n' >&2
exit 1
;;
-f|--file)
# with value separated by space
if [ -n "$2" ]; then
canary_file=$2
shift
else
printf 'ERROR: "-f|--file" requires a non-empty option argument.\n' >&2
exit 1
fi
;;
--file=?*)
# with value speparated by =
canary_file=${1#*=}
;;
--file=)
# without value
printf 'ERROR: "--file" requires a non-empty option argument.\n' >&2
exit 1
;;
--)
# End of all options.
shift
break
;;
-?*)
# ignore unknown options
printf 'WARN: Unknown option : %s\n' "$1" >&2
exit 1
;;
*)
# Default case: If no more options then break out of the loop.
break
;;
esac
shift
done
export LC_ALL=C
set -u
main

677
client/zzz_evobackup Executable file
View file

@ -0,0 +1,677 @@
#!/bin/bash
#
# Script Evobackup client
# See https://gitea.evolix.org/evolix/evobackup
#
# Authors: Evolix <info@evolix.fr>,
# Gregory Colpart <reg@evolix.fr>,
# Romain Dessort <rdessort@evolix.fr>,
# Benoit Série <bserie@evolix.fr>,
# Tristan Pilat <tpilat@evolix.fr>,
# Victor Laborie <vlaborie@evolix.fr>,
# Jérémy Lecour <jlecour@evolix.fr>
# and others.
#
# Licence: AGPLv3
#
# /!\ DON'T FORGET TO SET "MAIL" and "SERVERS" VARIABLES
##### Configuration ###################################################
VERSION="22.12"
# email adress for notifications
MAIL=jdoe@example.com
# list of hosts (hostname or IP) and SSH port for Rsync
SERVERS="node0.backup.example.com:2XXX node1.backup.example.com:2XXX"
# explicit PATH
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin
# Should we fallback on other servers when the first one is unreachable?
SERVERS_FALLBACK=${SERVERS_FALLBACK:-1}
# timeout (in seconds) for SSH connections
SSH_CONNECT_TIMEOUT=${SSH_CONNECT_TIMEOUT:-90}
# We use /home/backup : feel free to use your own dir
LOCAL_BACKUP_DIR="/home/backup"
# You can set "linux" or "bsd" manually or let it choose automatically
SYSTEM=$(uname | tr '[:upper:]' '[:lower:]')
# Store pid in a file named after this program's name
PROGNAME=$(basename "$0")
PIDFILE="/var/run/${PROGNAME}.pid"
# Customize the log path if you have multiple scripts and with separate logs
LOGFILE="/var/log/evobackup.log"
# Full Rsync log file, reset each time
RSYNC_LOGFILE="/var/log/${PROGNAME}.rsync.log"
HOSTNAME=$(hostname)
DATE_FORMAT="%Y-%m-%d %H:%M:%S"
# Enable/disable local tasks (default: enabled)
: "${LOCAL_TASKS:=1}"
# Enable/disable sync tasks (default: enabled)
: "${SYNC_TASKS:=1}"
CANARY_FILE="/zzz_evobackup_canary"
# Source paths can be customized
# Empty lines, and lines containing # or ; are ignored
# NOTE: remember to single-quote paths if they contain globs (*)
# and you want to defer expansion
RSYNC_INCLUDES="
/etc
/root
/var
/home
"
# Excluded paths can be customized
# Empty lines, and lines beginning with # or ; are ignored
# NOTE: remember to single-quote paths if they contain globs (*)
# and you want to defer expansion
RSYNC_EXCLUDES="
/dev
/proc
/run
/sys
/tmp
/usr/doc
/usr/obj
/usr/share/doc
/usr/src
/var/apt
/var/cache
'/var/db/munin/*.tmp'
/var/lib/amavis/amavisd.sock
/var/lib/amavis/tmp
/var/lib/amavis/virusmails
'/var/lib/clamav/*.tmp'
/var/lib/elasticsearch
/var/lib/metche
/var/lib/mongodb
'/var/lib/munin/*tmp*'
/var/lib/mysql
/var/lib/php/sessions
/var/lib/php5
/var/lib/postgres
/var/lib/postgresql
/var/lib/sympa
/var/lock
/var/run
/var/spool/postfix
/var/spool/smtpd
/var/spool/squid
/var/state
/var/tmp
lost+found
'.nfs.*'
'lxc/*/rootfs/tmp'
'lxc/*/rootfs/usr/doc'
'lxc/*/rootfs/usr/obj'
'lxc/*/rootfs/usr/share/doc'
'lxc/*/rootfs/usr/src'
'lxc/*/rootfs/var/apt'
'lxc/*/rootfs/var/cache'
'lxc/*/rootfs/var/lib/php5'
'lxc/*/rootfs/var/lib/php/sessions'
'lxc/*/rootfs/var/lock'
'lxc/*/rootfs/var/run'
'lxc/*/rootfs/var/state'
'lxc/*/rootfs/var/tmp'
/home/mysqltmp
"
##### FUNCTIONS #######################################################
local_tasks() {
log "START LOCAL_TASKS"
# You can comment or uncomment sections below to customize the backup
## OpenLDAP : example with slapcat
# slapcat -n 0 -l ${LOCAL_BACKUP_DIR}/config.ldap.bak
# slapcat -n 1 -l ${LOCAL_BACKUP_DIR}/data.ldap.bak
# slapcat -l ${LOCAL_BACKUP_DIR}/ldap.bak
## MySQL
## Purge previous dumps
# rm -f ${LOCAL_BACKUP_DIR}/mysql.*.gz
# rm -rf ${LOCAL_BACKUP_DIR}/mysql
# rm -rf ${LOCAL_BACKUP_DIR}/mysqlhotcopy
# rm -rf /home/mysqldump
# find ${LOCAL_BACKUP_DIR}/ -type f -name '*.err' -delete
## example with global and compressed mysqldump
# mysqldump --defaults-extra-file=/etc/mysql/debian.cnf -P 3306 \
# --opt --all-databases --force --events --hex-blob 2> ${LOCAL_BACKUP_DIR}/mysql.bak.err | gzip --best > ${LOCAL_BACKUP_DIR}/mysql.bak.gz
# last_rc=$?
# if [ ${last_rc} -ne 0 ]; then
# error "mysqldump (global compressed) returned an error ${last_rc}, check ${LOCAL_BACKUP_DIR}/mysql.bak.err"
# rc=101
# fi
## example with compressed SQL dump (with data) for each databases
# mkdir -p -m 700 ${LOCAL_BACKUP_DIR}/mysql/
# for i in $(mysql --defaults-extra-file=/etc/mysql/debian.cnf -P 3306 -e 'show databases' -s --skip-column-names \
# | grep --extended-regexp --invert-match "^(Database|information_schema|performance_schema|sys)"); do
# mysqldump --defaults-extra-file=/etc/mysql/debian.cnf --force -P 3306 --events --hex-blob $i 2> ${LOCAL_BACKUP_DIR}/${i}.err | gzip --best > ${LOCAL_BACKUP_DIR}/mysql/${i}.sql.gz
# last_rc=$?
# if [ ${last_rc} -ne 0 ]; then
# error "mysqldump (${i} compressed) returned an error ${last_rc}, check ${LOCAL_BACKUP_DIR}/${i}.err"
# rc=102
# fi
# done
## Dump all grants (requires 'percona-toolkit' package)
# mkdir -p -m 700 ${LOCAL_BACKUP_DIR}/mysql/
# pt-show-grants --flush --no-header 2> ${LOCAL_BACKUP_DIR}/mysql/all_grants.err > ${LOCAL_BACKUP_DIR}/mysql/all_grants.sql
# last_rc=$?
# if [ ${last_rc} -ne 0 ]; then
# error "pt-show-grants returned an error ${last_rc}, check ${LOCAL_BACKUP_DIR}/mysql/all_grants.err"
# rc=103
# fi
# Dump all variables
# mysql -A -e"SHOW GLOBAL VARIABLES;" 2> ${LOCAL_BACKUP_DIR}/MySQLCurrentSettings.err > ${LOCAL_BACKUP_DIR}/MySQLCurrentSettings.txt
# last_rc=$?
# if [ ${last_rc} -ne 0 ]; then
# error "mysql (variables) returned an error ${last_rc}, check ${LOCAL_BACKUP_DIR}/MySQLCurrentSettings.err"
# rc=104
# fi
## example with SQL dump (schema only, no data) for each databases
# mkdir -p -m 700 ${LOCAL_BACKUP_DIR}/mysql/
# for i in $(mysql --defaults-extra-file=/etc/mysql/debian.cnf -P 3306 -e 'show databases' -s --skip-column-names \
# | grep --extended-regexp --invert-match "^(Database|information_schema|performance_schema|sys)"); do
# mysqldump --defaults-extra-file=/etc/mysql/debian.cnf --force -P 3306 --no-data --databases $i 2> ${LOCAL_BACKUP_DIR}/${i}.schema.err > ${LOCAL_BACKUP_DIR}/mysql/${i}.schema.sql
# last_rc=$?
# if [ ${last_rc} -ne 0 ]; then
# error "mysqldump (${i} schema) returned an error ${last_rc}, check ${LOCAL_BACKUP_DIR}/${i}.schema.err"
# rc=105
# fi
# done
## example with *one* uncompressed SQL dump for *one* database (MYBASE)
# mkdir -p -m 700 ${LOCAL_BACKUP_DIR}/mysql/MYBASE
# chown -RL mysql ${LOCAL_BACKUP_DIR}/mysql/
# mysqldump --defaults-extra-file=/etc/mysql/debian.cnf --force -Q \
# --opt --events --hex-blob --skip-comments -T ${LOCAL_BACKUP_DIR}/mysql/MYBASE MYBASE 2> ${LOCAL_BACKUP_DIR}/mysql/MYBASE.err
# last_rc=$?
# if [ ${last_rc} -ne 0 ]; then
# error "mysqldump (MYBASE) returned an error ${last_rc}, check ${LOCAL_BACKUP_DIR}/mysql/MYBASE.err"
# rc=106
# fi
## example with two dumps for each table (.sql/.txt) for all databases
# for i in $(echo SHOW DATABASES | mysql --defaults-extra-file=/etc/mysql/debian.cnf -P 3306 \
# | grep --extended-regexp --invert-match "^(Database|information_schema|performance_schema|sys)" ); do
# mkdir -p -m 700 /home/mysqldump/$i ; chown -RL mysql /home/mysqldump
# mysqldump --defaults-extra-file=/etc/mysql/debian.cnf --force -P 3306 -Q --opt --events --hex-blob --skip-comments \
# --fields-enclosed-by='\"' --fields-terminated-by=',' -T /home/mysqldump/$i $i 2> /home/mysqldump/$i.err"
# last_rc=$?
# if [ ${last_rc} -ne 0 ]; then
# error "mysqldump (${i} files) returned an error ${last_rc}, check /home/mysqldump/$i.err"
# rc=107
# fi
# done
## example with mysqlhotcopy
# mkdir -p -m 700 ${LOCAL_BACKUP_DIR}/mysqlhotcopy/
# mysqlhotcopy MYBASE ${LOCAL_BACKUP_DIR}/mysqlhotcopy/ 2> ${LOCAL_BACKUP_DIR}/mysqlhotcopy/MYBASE.err
# last_rc=$?
# if [ ${last_rc} -ne 0 ]; then
# error "mysqlhotcopy returned an error ${last_rc}, check ${LOCAL_BACKUP_DIR}/mysqlhotcopy/MYBASE.err"
# rc=108
# fi
## example for multiples MySQL instances
# mysqladminpasswd=$(grep -m1 'password = .*' /root/.my.cnf|cut -d" " -f3)
# grep --extended-regexp "^port\s*=\s*\d*" /etc/mysql/my.cnf | while read instance; do
# instance=$(echo "$instance"|awk '{ print $3 }')
# if [ "$instance" != "3306" ]
# then
# mysqldump -P $instance --opt --all-databases --hex-blob -u mysqladmin -p$mysqladminpasswd 2> ${LOCAL_BACKUP_DIR}/mysql.${instance}.err | gzip --best > ${LOCAL_BACKUP_DIR}/mysql.${instance}.bak.gz
# last_rc=$?
# if [ ${last_rc} -ne 0 ]; then
# error "mysqldump (instance ${instance}) returned an error ${last_rc}, check ${LOCAL_BACKUP_DIR}/mysql.${instance}.err"
# rc=107
# fi
# fi
# done
## PostgreSQL
## Purge previous dumps
# rm -rf ${LOCAL_BACKUP_DIR}/pg.*.gz
# rm -rf ${LOCAL_BACKUP_DIR}/pg-backup.tar
# rm -rf ${LOCAL_BACKUP_DIR}/postgresql/*
## example with pg_dumpall (warning: you need space in ~postgres)
# su - postgres -c "pg_dumpall > ~/pg.dump.bak"
# mv ~postgres/pg.dump.bak ${LOCAL_BACKUP_DIR}/
## another method with gzip directly piped
# (
# cd /var/lib/postgresql;
# sudo -u postgres pg_dumpall | gzip > ${LOCAL_BACKUP_DIR}/pg.dump.bak.gz
# )
## example with all tables from MYBASE excepts TABLE1 and TABLE2
# pg_dump -p 5432 -h 127.0.0.1 -U USER --clean -F t --inserts -f ${LOCAL_BACKUP_DIR}/pg-backup.tar -t 'TABLE1' -t 'TABLE2' MYBASE
## example with only TABLE1 and TABLE2 from MYBASE
# pg_dump -p 5432 -h 127.0.0.1 -U USER --clean -F t --inserts -f ${LOCAL_BACKUP_DIR}/pg-backup.tar -T 'TABLE1' -T 'TABLE2' MYBASE
## example with compressed PostgreSQL dump for each databases
# mkdir -p -m 700 ${LOCAL_BACKUP_DIR}/postgresql
# chown postgres:postgres ${LOCAL_BACKUP_DIR}/postgresql
# (
# cd /var/lib/postgresql
# dbs=$(sudo -u postgres psql -U postgres -lt | awk -F\| '{print $1}' |grep -v template*)
# for databases in $dbs ; do sudo -u postgres /usr/bin/pg_dump --create -U postgres -d $databases | gzip --best -c > ${LOCAL_BACKUP_DIR}/postgresql/$databases.sql.gz ; done
# )
## MongoDB
## don't forget to create use with read-only access
## > use admin
## > db.createUser( { user: "mongobackup", pwd: "PASS", roles: [ "backup", ] } )
## Purge previous dumps
# rm -rf ${LOCAL_BACKUP_DIR}/mongodump/
# mkdir -p -m 700 ${LOCAL_BACKUP_DIR}/mongodump/
# mongodump --quiet -u mongobackup -pPASS -o ${LOCAL_BACKUP_DIR}/mongodump/
# if [ $? -ne 0 ]; then
# echo "Error with mongodump!"
# fi
## Redis
## Purge previous dumps
# rm -rf ${LOCAL_BACKUP_DIR}/redis/
# rm -rf ${LOCAL_BACKUP_DIR}/redis-*
## Copy dump.rdb file for each found instance
# for instance in $(find /var/lib/ -mindepth 1 -maxdepth 1 '(' -type d -o -type l ')' -name 'redis*'); do
# if [ -f "${instance}/dump.rdb" ]; then
# name=$(basename $instance)
# mkdir -p ${LOCAL_BACKUP_DIR}/${name}
# cp -a "${instance}/dump.rdb" "${LOCAL_BACKUP_DIR}/${name}"
# gzip "${LOCAL_BACKUP_DIR}/${name}/dump.rdb"
# fi
# done
## ElasticSearch
## Take a snapshot as a backup.
## Warning: You need to have a path.repo configured.
## See: https://wiki.evolix.org/HowtoElasticsearch#snapshots-et-sauvegardes
# curl -s -XDELETE "localhost:9200/_snapshot/snaprepo/snapshot.daily" >> "${LOGFILE}"
# curl -s -XPUT "localhost:9200/_snapshot/snaprepo/snapshot.daily?wait_for_completion=true" >> "${LOGFILE}"
## Clustered version here
## It basically the same thing except that you need to check that NFS is mounted
# if ss | grep ':nfs' | grep -q 'ip\.add\.res\.s1' && ss | grep ':nfs' | grep -q 'ip\.add\.res\.s2'
# then
# curl -s -XDELETE "localhost:9200/_snapshot/snaprepo/snapshot.daily" >> "${LOGFILE}"
# curl -s -XPUT "localhost:9200/_snapshot/snaprepo/snapshot.daily?wait_for_completion=true" >> "${LOGFILE}"
# else
# echo 'Cannot make a snapshot of elasticsearch, at least one node is not mounting the repository.'
# fi
## If you need to keep older snapshot, for example the last 10 daily snapshots, replace the XDELETE and XPUT lines by :
# for snapshot in $(curl -s -XGET "localhost:9200/_snapshot/snaprepo/_all?pretty=true" | grep -Eo 'snapshot_[0-9]{4}-[0-9]{2}-[0-9]{2}' | head -n -10); do
# curl -s -XDELETE "localhost:9200/_snapshot/snaprepo/${snapshot}" | grep -v -Fx '{"acknowledged":true}'
# done
# date=$(/bin/date +%F)
# curl -s -XPUT "localhost:9200/_snapshot/snaprepo/snapshot_${date}?wait_for_completion=true" >> "${LOGFILE}"
## RabbitMQ
## export config
# rabbitmqadmin export ${LOCAL_BACKUP_DIR}/rabbitmq.config >> "${LOGFILE}"
## MegaCli config
# megacli -CfgSave -f ${LOCAL_BACKUP_DIR}/megacli_conf.dump -a0 >/dev/null
## Dump network routes with mtr and traceroute (warning: could be long with aggressive firewalls)
network_targets="8.8.8.8 www.evolix.fr travaux.evolix.net"
mtr_bin=$(command -v mtr)
if [ -n "${mtr_bin}" ]; then
for addr in ${network_targets}; do
${mtr_bin} -r "${addr}" > "${LOCAL_BACKUP_DIR}/mtr-${addr}"
done
fi
traceroute_bin=$(command -v traceroute)
if [ -n "${traceroute_bin}" ]; then
for addr in ${network_targets}; do
${traceroute_bin} -n "${addr}" > "${LOCAL_BACKUP_DIR}/traceroute-${addr}" 2>&1
done
fi
server_state_dir="${LOCAL_BACKUP_DIR}/server-state"
dump_server_state_bin=$(command -v dump-server-state)
if [ -z "${dump_server_state_bin}" ]; then
error "dump-server-state is missing"
rc=1
else
if [ "${SYSTEM}" = "linux" ]; then
${dump_server_state_bin} --all --force --dump-dir "${server_state_dir}"
last_rc=$?
if [ ${last_rc} -ne 0 ]; then
error "dump-server-state returned an error ${last_rc}, check ${server_state_dir}"
rc=1
fi
else
${dump_server_state_bin} --all --force --dump-dir "${server_state_dir}"
last_rc=$?
if [ ${last_rc} -ne 0 ]; then
error "dump-server-state returned an error ${last_rc}, check ${server_state_dir}"
rc=1
fi
fi
fi
## Dump rights
# getfacl -R /var > ${server_state_dir}/rights-var.txt
# getfacl -R /etc > ${server_state_dir}/rights-etc.txt
# getfacl -R /usr > ${server_state_dir}/rights-usr.txt
# getfacl -R /home > ${server_state_dir}/rights-home.txt
log "STOP LOCAL_TASKS"
}
build_rsync_main_cmd() {
###################################################################
# /!\ WARNING /!\ WARNING /!\ WARNING /!\ WARNING /!\ WARNING /!\ #
###################################################################
# DO NOT USE COMMENTS in rsync lines #
# DO NOT ADD WHITESPACES AFTER \ in rsync lines #
# It breaks the command and destroys data #
# You should not modify this, unless you are really REALLY sure #
###################################################################
# Create a temp file for excludes and includes
includes_file="$(mktemp --tmpdir "${PROGNAME}.includes.XXXXXX")"
excludes_file="$(mktemp --tmpdir "${PROGNAME}.excludes.XXXXXX")"
# … and add them to the list of files to delete at exit
temp_files="${includes_file} ${excludes_file}"
trap "rm -f ${temp_files}" EXIT
# Store includes/excludes in files
# without blank lines of comments (# or ;)
echo "${RSYNC_INCLUDES}" | sed -e 's/\s*\(#\|;\).*//; /^\s*$/d' > "${includes_file}"
echo "${RSYNC_EXCLUDES}" | sed -e 's/\s*\(#\|;\).*//; /^\s*$/d' > "${excludes_file}"
# Rsync command
cmd="$(command -v rsync)"
# Rsync main options
cmd="${cmd} --archive"
cmd="${cmd} --itemize-changes"
cmd="${cmd} --quiet"
cmd="${cmd} --stats"
cmd="${cmd} --human-readable"
cmd="${cmd} --relative"
cmd="${cmd} --partial"
cmd="${cmd} --delete"
cmd="${cmd} --delete-excluded"
cmd="${cmd} --force"
cmd="${cmd} --ignore-errors"
cmd="${cmd} --log-file=${RSYNC_LOGFILE}"
cmd="${cmd} --rsh='ssh -p ${SSH_PORT} -o \"ConnectTimeout ${SSH_CONNECT_TIMEOUT}\"'"
# Rsync excludes
while read line ; do
cmd="${cmd} --exclude ${line}"
done < "${excludes_file}"
# Rsync local sources
cmd="${cmd} ${default_includes}"
while read line ; do
cmd="${cmd} ${line}"
done < "${includes_file}"
# Rsync remote destination
cmd="${cmd} root@${SSH_SERVER}:/var/backup/"
# output final command
echo "${cmd}"
}
build_rsync_canary_cmd() {
# Rsync command
cmd="$(command -v rsync)"
# Rsync options
cmd="${cmd} --rsh='ssh -p ${SSH_PORT} -o \"ConnectTimeout ${SSH_CONNECT_TIMEOUT}\"'"
# Rsync local source
cmd="${cmd} ${CANARY_FILE}"
# Rsync remote destination
cmd="${cmd} root@${SSH_SERVER}:/var/backup/"
# output final command
echo "${cmd}"
}
sync_tasks() {
n=0
server=""
if [ "${SERVERS_FALLBACK}" = "1" ]; then
# We try to find a suitable server
while :; do
server=$(pick_server "${n}")
test $? = 0 || exit 2
if test_server "${server}"; then
break
else
server=""
n=$(( n + 1 ))
fi
done
else
# we force the server
server=$(pick_server "${n}")
fi
SSH_SERVER=$(echo "${server}" | cut -d':' -f1)
SSH_PORT=$(echo "${server}" | cut -d':' -f2)
log "START SYNC_TASKS - server=${server}"
# default paths, depending on system
if [ "${SYSTEM}" = "linux" ]; then
default_includes="/bin /boot /lib /opt /sbin /usr"
else
default_includes="/bsd /bin /sbin /usr"
fi
# reset Rsync log file
if [ -n "$(command -v truncate)" ]; then
truncate -s 0 "${RSYNC_LOGFILE}"
else
printf "" > "${RSYNC_LOGFILE}"
fi
# Build the final Rsync command
rsync_main_cmd=$(build_rsync_main_cmd)
# … log it
log "SYNC_TASKS - Rsync main command : ${rsync_main_cmd}"
# … execute it
eval "${rsync_main_cmd}"
rsync_main_rc=$?
# Copy last lines of rsync log to the main log
tail -n 30 "${RSYNC_LOGFILE}" >> "${LOGFILE}"
if [ ${rsync_main_rc} -ne 0 ]; then
error "rsync returned an error ${rsync_main_rc}, check ${LOGFILE}"
rc=201
else
# Build the canary Rsync command
rsync_canary_cmd=$(build_rsync_canary_cmd)
# … log it
log "SYNC_TASKS - Rsync canary command : ${rsync_canary_cmd}"
# … execute it
eval "${rsync_canary_cmd}"
fi
log "STOP SYNC_TASKS - server=${server}"
}
# Call test_server with "HOST:PORT" string
# It will return with 0 if the server is reachable.
# It will return with 1 and a message on stderr if not.
test_server() {
item=$1
# split HOST and PORT from the input string
host=$(echo "${item}" | cut -d':' -f1)
port=$(echo "${item}" | cut -d':' -f2)
# Test if the server is accepting connections
ssh -q -o "ConnectTimeout ${SSH_CONNECT_TIMEOUT}" "${host}" -p "${port}" -t "exit"
# shellcheck disable=SC2181
if [ $? = 0 ]; then
# SSH connection is OK
return 0
else
# SSH connection failed
new_error=$(printf "Failed to connect to \`%s' within %s seconds" "${item}" "${SSH_CONNECT_TIMEOUT}")
log "${new_error}"
SERVERS_SSH_ERRORS=$(printf "%s\\n%s" "${SERVERS_SSH_ERRORS}" "${new_error}" | sed -e '/^$/d')
return 1
fi
}
# Call pick_server with an optional positive integer to get the nth server in the list.
pick_server() {
increment=${1:-0}
list_length=$(echo "${SERVERS}" | wc -w)
if [ "${increment}" -ge "${list_length}" ]; then
# We've reached the end of the list
new_error="No more server available"
log "${new_error}"
SERVERS_SSH_ERRORS=$(printf "%s\\n%s" "${SERVERS_SSH_ERRORS}" "${new_error}" | sed -e '/^$/d')
# Log errors to stderr
printf "%s\\n" "${SERVERS_SSH_ERRORS}" >&2
return 1
fi
# Extract the day of month, without leading 0 (which would give an octal based number)
today=$(/bin/date +%e)
# A salt is useful to randomize the starting point in the list
# but stay identical each time it's called for a server (based on hostname).
salt=$(hostname | cksum | cut -d' ' -f1)
# Pick an integer between 0 and the length of the SERVERS list
# It changes each day
item=$(( (today + salt + increment) % list_length ))
# cut starts counting fields at 1, not 0.
field=$(( item + 1 ))
echo "${SERVERS}" | cut -d' ' -f${field}
}
log() {
msg="${1:-$(cat /dev/stdin)}"
pid=$$
printf "[%s] %s[%s]: %s\\n" \
"$(/bin/date +"${DATE_FORMAT}")" "${PROGNAME}" "${pid}" "${msg}" \
>> "${LOGFILE}"
}
error() {
msg="${1:-$(cat /dev/stdin)}"
pid=$$
printf "[%s] %s[%s]: %s\\n" \
"$(/bin/date +"${DATE_FORMAT}")" "${PROGNAME}" "${pid}" "${msg}" \
>&2
}
main() {
START_EPOCH=$(/bin/date +%s)
log "START GLOBAL - VERSION=${VERSION} LOCAL_TASKS=${LOCAL_TASKS} SYNC_TASKS=${SYNC_TASKS}"
# shellcheck disable=SC2174
mkdir -p -m 700 ${LOCAL_BACKUP_DIR}
## Force umask
umask 077
## Initialize variable to store SSH connection errors
SERVERS_SSH_ERRORS=""
## Verify other evobackup process and kill if needed
if [ -e "${PIDFILE}" ]; then
pid=$(cat "${PIDFILE}")
# Does process still exist ?
if kill -0 "${pid}" 2> /dev/null; then
# Killing the childs of evobackup.
for ppid in $(pgrep -P "${pid}"); do
kill -9 "${ppid}";
done
# Then kill the main PID.
kill -9 "${pid}"
printf "%s is still running (PID %s). Process has been killed" "$0" "${pid}\\n" >&2
else
rm -f "${PIDFILE}"
fi
fi
echo "$$" > "${PIDFILE}"
# Initialize a list of files to delete at exit
# Any file added to the list will also be deleted at exit
temp_files="${PIDFILE}"
# shellcheck disable=SC2064
trap "rm -f ${temp_files}" EXIT
# Update canary to keep track of each run
update-evobackup-canary --who "${PROGNAME}"
if [ "${LOCAL_TASKS}" = "1" ]; then
local_tasks
fi
if [ "${SYNC_TASKS}" = "1" ]; then
sync_tasks
fi
STOP_EPOCH=$(/bin/date +%s)
if [ "${SYSTEM}" = "openbsd" ]; then
start_time=$(/bin/date -f "%s" -j "${START_EPOCH}" +"${DATE_FORMAT}")
stop_time=$(/bin/date -f "%s" -j "${STOP_EPOCH}" +"${DATE_FORMAT}")
else
start_time=$(/bin/date --date="@${START_EPOCH}" +"${DATE_FORMAT}")
stop_time=$(/bin/date --date="@${STOP_EPOCH}" +"${DATE_FORMAT}")
fi
duration=$(( STOP_EPOCH - START_EPOCH ))
log "STOP GLOBAL - start='${start_time}' stop='${stop_time}' duration=${duration}s"
tail -20 "${LOGFILE}" | mail -s "[info] EvoBackup - Client ${HOSTNAME}" ${MAIL}
}
# set all programs to C language (english)
export LC_ALL=C
# Error on unassigned variable
set -u
# Default return-code (0 == succes)
rc=0
# execute main funciton
main
exit ${rc}

View file

@ -1,43 +0,0 @@
#!/bin/sh
# Script backups incrementaux
# Evolix (c) 2007
CONFDIR=/etc/evobackup/
DATE=$(date +"%d-%m-%Y")
LOGFILE=/var/log/evobackup-sync.log
TMPDIR=/tmp/evobackup/
JAILDIR=/backup/jails/
INCDIR=/backup/incs/
MYMAIL=jdoe@example.com
mkdir -p $TMPDIR
for i in $( ls $CONFDIR ); do
mkdir -p "$INCDIR"$i
# hard copy everyday
cp -alx $JAILDIR$i $INCDIR$i/$DATE
# list actual inc backups
for j in $( ls $INCDIR$i ); do
echo $j
done > "$TMPDIR"$i.files
# list non-obsolete inc backups
for j in $( cat $CONFDIR$i ); do
MYDATE=$( echo $j | cut -d. -f1 )
BEFORE=$( echo $j | cut -d. -f2 )
date -d "$(date $MYDATE) $BEFORE" "+%d-%m-%Y"
done > "$TMPDIR"$i.keep
# delete obsolete inc backups
for j in $( grep -v -f "$TMPDIR"$i.keep "$TMPDIR"$i.files ); do
echo "Suppression du backup $j ($i)"
cd $INCDIR$i
rm -rf $j
done
done | tee -a $LOGFILE | mail -s "[info] EvoBackup - incrementaux" $MYMAIL

3
server/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
*.swp
.vagrant
build

258
server/CHANGELOG.md Normal file
View file

@ -0,0 +1,258 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
### Changed
### Deprecated
### Removed
### Fixed
### Security
## [22.11] - 2022-11-28
### Added
* check-canary: new subcommand to check canary files and content
### Changed
* stats: filter active jails and columnize the output
## [22.07] - 2022-07-20
### Changed
* check-setup: check minifirewall version only if minifirewall is present
* check-setup: get minifirewall version from internal variable (there is no other backward compatible way)
* check-setup: use findmnt with mountpoint instead of target
## [22.06] - 2022-06-28
### Added
* bkctld-init: create "incs/\<jail\>" directory for jails
### Fixed
* shell syntax error when ${btrfs_bin} variable is empty
* read_variable + read_numerical_variable: keep the last found value only
* Debian 8 findmnt(8) support
### Security
## [22.04] - 2022-04-20
### Added
* Run the test suite on Bullseye (ext4/btrfs) in addition of Stretch and Buster (ext4/btrfs)
* Tell sed to follow symlinks
* Add a header in `bkctld status` output and improved columns width.
* bkctld-check-setup: compatibility with minifirewall 22.03+
### Changed
* change versioning pattern
## [2.12.0] - 2021-11-02
### Changed
* btrfs depends on the btrfd-progs package instead of btrfs-tools
## [2.11.1] - 2021-06-30
### Changed
* bkctld-rename: abort operation if incs exist with the new name
## [2.11.0] - 2021-06-29
### Changed
* bkctld-remove: remove config directory
### Fixed
* force flag must be exported
## [2.10.0] - 2021-06-29
### Added
* bkctld-archive: archive a jail
* bkctld-rename: rename a jail and all its incs and configuration…
### Removed
* Do not print out date, log level and process name on stdout/stderr
## [2.9.0] - 2021-02-22
### Added
* bkctld-init: install check_policy template
* bkctld-upgrade-config: install check_policy template if missing
* test: bkctld check-incs shouldn't fail without incs_policy file
### Changed
* Rename incs_policy template
* bkctld-check-incs: Correct shellsheck warnings
### Fixed
* tests: clean jail configuration after each test
* bkctld-check-incs: Protect `jail_config_epoch`
## [2.8.0] - 2020-11-28
### Added
* bkctld: new inc-lock and inc-unlock command
## [2.7.1] - 2020-11-28
### Fixed
* bkctld-upgrade-config is executable
## [2.7.0] - 2020-11-13
### Added
* bkctld: add a [-f|--force] option to remove confirmation on some commands
* bkctld-remove: confirmation before removal of jails if not in force mode
* bkctld-rm: delete empty jails in incs directory
### Changed
* Better help message composition and formating
* bkctld-rm: list jails from incs directory
## [2.6.0] - 2020-10-07
### Added
* bkctld: add a [-V|--version] option to display release number
* bkctld: add a [-h|--help|-?] option to display help message
## [2.5.1] - 2020-10-07
### Changed
* bkctld: Replace xargs with a simple loop
## [2.5.0] - 2020-09-25
### Fixed
* restore compatibility with Debian <10
## [2.4.1] - 2020-08-28
### Added
* jails and incs lists are sorted alphanumerically
### Fixed
* bkctld-check-setup: forgot to increment the summary
## [2.4.0] - 2020-08-19
### Added
* New command bkctld upgrade-config to move the legacy config file "/etc/evobackup/<jail>" to the new config structure "/etc/evobackup/<jail>.d/incs_policy"
### Changed
* bkctld-update: start jail after upgrade if it was started before
* bkctld: don't replace SSH host keys when creating/updating a jail
* Split check into check-jails and check-setup
* bkctld-check-jails checks if jails
* bkctld-check-setup checks if the partition is mounted and writable, if firewall is configured and if all jails are in their expected state
* create new ssh keys for new jails instead of copying those from the host
## [2.3.3] - 2020-05-28
### Fixed
* On sync, add trailing slash to rsync command
## [2.3.2] - 2020-05-03
### Changed
* Display help message if mandatory arguments are missing.
* Don't recreate jail on sync if it already exists
* Don't sync the whole firewall file, just remake rules for the current jail
* On sync, if local jail is running, reload remote jail if already running, start if not
## [2.3.1] - 2020-04-22
### Added
* State the age of the current "rm" process when killing it
* Give the new PID after killing the previous "rm" process
### Fixed
* typos
* forgotten quotes
## [2.3.0] - 2020-04-20
### Changed
* Rewrite log messages and format
## [2.2.2] - 2020-04-19
### Changed
* Reorganize temp files and lock files
### Fixed
* Properly call subcommands in bkctld-check-incs and bkctld-check-last-incs
* Log start time in bkctld-rm
## [2.2.1] - 2020-04-18
### Changed
* check-incs.sh and check-last-incs.sh are embedded in bkctld
## [2.2.0] - 2020-04-17
### Added
* Shellcheck directives to have 0 warnings and errors
* Ability to override critical/warning thresholds per jail for bkctld-check
* Support new location for jail configuration (/etc/evobackup/<jail_name>.d/)
* Lock per jail and inc when creating incs
* Global lock when removing incs (kill the currently running instance)
* Create a blank SSH "authorized_keys" file on jail init
* Many new tests with BATS
* Check for firewall configuration in bkcld-check
* Run the test suite on Buster (ext4/btrfs) in addition of Stretch (ext4/btrfs)
### Changed
* Extract variables and heper functions to reduce repetition of knowledge
* Consistent naming of variables in scripts and functions
* Consistent log messages between functions ad commands
* Raise errors if required function arguments are missing
* Configure locales in Vagrant VM
* Split BATS tests file and use helper functions
* Improve "lib" detection
* Revamp the README

661
server/LICENSE Normal file
View file

@ -0,0 +1,661 @@
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.
A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate. Many developers of free software are heartened and
encouraged by the resulting cooperation. However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.
The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community. It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server. Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.
An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals. This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU Affero General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Remote Network Interaction; Use with the GNU General Public License.
Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software. This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time. Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source. For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code. There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<http://www.gnu.org/licenses/>.

122
server/README.md Normal file
View file

@ -0,0 +1,122 @@
Bkctld (aka server-side evobackup)
=========
bkctld helps you manage the receiving side of a backup infrastructure.
It is licensed under the AGPLv3.
With bkctld you create and manage "jails". They contain a chrooted and dedicated SSH server, with its own TCP port and optionally its own set of iptables rules.
With bkctld you can have hundreds of jails, one for each client to push its data (using Rsync/SFTP). Each client can only see its own data.
In addition to the traditional "ext4" filesystem, bkctld also supports the btrfs filesystem and manages subvolumes automatically.
With bkctld you can create "timestamped" copies of the data, to keep different versions of the same data at different points in time. If the filesystem is btrfs, it creates subvolumes snapshots, otherwise it creates copies with hard-links (for file-level deduplication).
With btrfs you can have a data retention policy to automatically destroy timestamped copies of your data. For example, keep a copy for the last 5 days and the first day of the last 3 months.
~~~
Backup server
************
Client 1 ------ SSH/Rsync -------> * tcp/2222 *
************
Client 2 ------ SSH/Rsync -------> * tcp/2223 *
************
~~~
This method uses standard tools (ssh, rsync, cp -al, btrfs subvolume) and has been used for many years by Evolix to backup hundreds of servers, totaling many terabytes of data, each day. bkctld has been tested on Debian Jessie (8), Stretch (9) and Buster (10) and should be compatible with other Debian versions or derived distributions like Ubuntu.
A large enough volume must be mounted on `/backup`, we recommend the usage of **BTRFS** so you can use sub-volumes and snapshots.
This volume can also be encrypted with **LUKS**.
## Security considerations
The client obviously has access to its uploaded data (in the chroot), but the timestamped copies are outside the chroot, to reduce the risk of complete backup erasure from a compromised client.
It means that **if the client server is compromised**, an attacker can destroy the latest copy of the backed up data, but not the timestamped copies.
And **if the backup server is compromised** an attacker has complete access to all the backup data (inside and outside the jails), but they don't have any access to the client.
This architecture is as secure as SSH, Rsync, chroot and iptables are.
## Install
See the [installation guide](https://intra.evolix.net/OutilsInternes/bkctld) for instructions.
## Testing
You can deploy test environments with Vagrant :
~~~
vagrant up
~~~
To destroy Vagrant VMs :
~~~
vagrant destroy
~~~
### Deployment
Run `vagrant rsync-auto` in a terminal for automatic synchronization of
your local code with Vagrant VM :
~~~
vagrant rsync-auto
~~~
### Bats
You can run [bats](https://github.com/sstephenson/bats) tests with
the *test* provisioner :
~~~
vagrant provision --provision-with test
~~~
You can also run the tests from inside the VM
~~~
localhost $ vagrant ssh buster-btrfs
vagrant@buster-btrfs $ sudo -i
root@buster-btrfs # bats /vagrant/test/*.bats
~~~
[comment]: <> (* pour vim)
You should shellcheck your bats files, but with shellcheck > 0.4.6, because the 0.4.0 version doesn't support bats syntax.
## Usage
See [docs/usage.md](docs/usage.md).
The man(1) page, in troff(7) language, can be generated with pandoc:
~~~
pandoc -f markdown \
-t man usage.md \
--template default.man \
-V title=bkctld \
-V section=8 \
-V date="$(date '+%d %b %Y')" \
-V footer="$(git describe --tags)" \
-V header="bkctld man page"
~~~
#### Client configuration
You can backup various systems in the evobackup jails : Linux, BSD,
Windows, macOS. The only need is Rsync or an SFTP client.
~~~
rsync -av -e "ssh -p SSH_PORT" /home/ root@SERVER_NAME:/var/backup/home/
~~~
An example synchronization script is present in `zzz_evobackup`,
clone the evobackup repository and read the **CLIENT CONFIGURATION**
section of the manual.
~~~
git clone https://gitea.evolix.org/evolix/evobackup.git
cd evobackup
man ./docs/bkctld.8
~~~

69
server/Vagrantfile vendored Normal file
View file

@ -0,0 +1,69 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :
# Load ~/.VagrantFile if exist, permit local config provider
vagrantfile = File.join("#{Dir.home}", '.VagrantFile')
load File.expand_path(vagrantfile) if File.exists?(vagrantfile)
Vagrant.configure('2') do |config|
config.vm.synced_folder "./", "/vagrant", type: "rsync", rsync__exclude: [ '.vagrant', '.git', 'build' ]
config.ssh.shell="/bin/sh"
config.vm.provider :libvirt do |libvirt|
libvirt.storage :file, :size => '10G', :device => 'vdb'
end
$install = <<SCRIPT
ln -fs /vagrant/bkctld /usr/sbin/bkctld
ln -fs /vagrant/lib /usr/lib/bkctld
ln -fs /vagrant/tpl /usr/share/bkctld
ln -fs /vagrant/bash_completion /usr/share/bash-completion/completions/bkctld
ln -fs /vagrant/bkctld.conf /etc/default/bkctld
ln -fs /vagrant/bkctld.service /etc/systemd/system/bkctld.service && systemctl daemon-reload
mkdir -p /usr/lib/nagios/plugins/
SCRIPT
$deps = <<SCRIPT
DEBIAN_FRONTEND=noninteractive apt-get -yq install openssh-server btrfs-progs rsync lsb-base coreutils sed dash mount openssh-sftp-server libc6 bash-completion duc-nox cryptsetup bats
SCRIPT
$pre_part = <<SCRIPT
sed --follow-symlinks --in-place -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \
sed --follow-symlinks --in-place -e 's/# fr_FR.UTF-8 UTF-8/fr_FR.UTF-8 UTF-8/' /etc/locale.gen && \
echo 'LANG="fr_FR.UTF-8"'>/etc/default/locale && \
dpkg-reconfigure --frontend=noninteractive locales && \
update-locale LANG=fr_FR.UTF-8
lsof | awk '/backup/ { print $2 }' | xargs --no-run-if-empty kill -9
grep -q /backup /proc/mounts && umount -R /backup
exit 0
SCRIPT
$post_part = <<SCRIPT
mkdir -p /backup
mount /dev/vdb /backup
SCRIPT
nodes = [
{ :version => "stretch", :fs => "btrfs" },
{ :version => "stretch", :fs => "ext4" },
{ :version => "buster", :fs => "btrfs" },
{ :version => "buster", :fs => "ext4" },
{ :version => "bullseye", :fs => "btrfs" },
{ :version => "bullseye", :fs => "ext4" }
]
nodes.each do |i|
config.vm.define "#{i[:version]}-#{i[:fs]}" do |node|
node.vm.hostname = "bkctld-#{i[:version]}-#{i[:fs]}"
node.vm.box = "debian/#{i[:version]}64"
config.vm.provision "deps", type: "shell", :inline => $deps
config.vm.provision "install", type: "shell", :inline => $install
config.vm.provision "pre_part", type: "shell", :inline => $pre_part
config.vm.provision "part", type: "shell", :inline => "mkfs.btrfs -f /dev/vdb" if "#{i[:fs]}" == "btrfs"
config.vm.provision "part", type: "shell", :inline => "mkfs.ext4 -q -F /dev/vdb" if "#{i[:fs]}" == "ext4"
config.vm.provision "post_part", type: "shell", :inline => $post_part
config.vm.provision "test", type: "shell", :inline => "bats /vagrant/test/*.bats"
end
end
end

29
server/bash_completion Normal file
View file

@ -0,0 +1,29 @@
# bkctld(8) completion
#
# Copyright (c) 2017 Victor Laborie <vlaborie@evolix.fr>
#
# shellcheck shell=bash
function _bkctld()
{
local cur prev commands jails keys
cur=${COMP_WORDS[COMP_CWORD]};
prev=${COMP_WORDS[COMP_CWORD-1]};
commands=$(find /usr/lib/bkctld/ -name "bkctld-*" -exec basename {} \; | sed 's/^bkctld-//')
if [ $COMP_CWORD -eq 1 ]; then
COMPREPLY=($(compgen -W '${commands}' -- ${cur}))
elif [ $COMP_CWORD -eq 2 ]; then
[ -f /etc/default/bkctld ] && source /etc/default/bkctld
[ -z "${JAILDIR}" ] && JAILDIR='/backup/jails'
jails=$(ls "${JAILDIR}")
COMPREPLY=($(compgen -W "${jails}" -- ${cur}))
elif [ $COMP_CWORD -eq 3 ]; then
keys=$(ls *.pub)
COMPREPLY=($(compgen -W "${keys}" -- ${cur}))
fi
return 0
} &&
complete -F _bkctld bkctld

179
server/bkctld Executable file
View file

@ -0,0 +1,179 @@
#!/bin/sh
#
# bkctld is a shell script to create and manage a backup server which will
# handle the backup of many servers (clients).
#
# Authors: Victor Laborie <vlaborie@evolix.fr>
# Jérémy Lecour <jlecour@evolix.fr>
# Benoît Série <bserie@evolix.fr>
# Gregory Colpart <reg@evolix.fr>
# Romain Dessort <rdessort@evolix.fr>
# Tristan Pilat <tpilat@evolix.fr>
# Licence: AGPLv3
#
set -u
if [ "$(id -u)" -ne 0 ]; then
echo "You need to be root to run ${0} !" >&2
exit 1
fi
basedir=$(dirname "$0")
if [ "${basedir}" = "/usr/local/sbin" ] && [ -d "/usr/local/lib/bkctld" ]; then
LIBDIR='/usr/local/lib/bkctld'
elif [ "${basedir}" = "/usr/sbin" ] && [ -d "/usr/lib/bkctld" ]; then
LIBDIR='/usr/lib/bkctld'
elif [ -d './lib' ]; then
LIBDIR='lib'
else
echo "Failed to find a suitable lib directory for bkctld." >&2
exit 1
fi
# shellcheck source=lib/includes
. "${LIBDIR}/includes"
# Parse options
# based on https://gist.github.com/deshion/10d3cb5f88a21671e17a
if [ "$#" = "0" ]; then
show_help
exit 1
fi
while :; do
case $1 in
-h|-\?|--help)
show_help
exit 0
;;
-V|--version)
show_version
exit 0
;;
-f|--force)
export FORCE=1
;;
--no-header)
export HEADER=0
;;
*)
# Default case: If no more options then break out of the loop.
break
;;
esac
shift
done
subcommand="${1:-}"
case "${subcommand}" in
"inc" | "rm" | "check-jails" | "check-setup" | "check-canary" | "stats" | "list")
"${LIBDIR}/bkctld-${subcommand}"
;;
"check")
# backward compatibility
"${LIBDIR}/bkctld-check-jails"
;;
"check-incs")
option="${2:-}"
if [ "${option}" = "all" ] || [ -z "${option}" ]; then
"${LIBDIR}/bkctld-check-incs"
elif [ "${option}" = "last" ]; then
"${LIBDIR}/bkctld-check-last-incs"
else
show_help
exit 1
fi
;;
"init" | "is-on")
jail_name="${2:-}"
if [ -z "${jail_name}" ]; then
show_help
exit 1
else
"${LIBDIR}/bkctld-${subcommand}" "${jail_name}"
fi
;;
"key" | "port" | "ip")
jail_name="${2:-}"
option="${3:-}"
if [ "${jail_name}" = "all" ] || [ -z "${jail_name}" ]; then
show_help
exit 1
else
"${LIBDIR}/bkctld-${subcommand}" "${jail_name}" "${option}"
fi
;;
"start" | "stop" | "reload" | "restart" | "sync" | "update" | "remove" | "firewall" | "upgrade-config" | "archive")
jail_name="${2:-}"
if [ "${jail_name}" = "all" ]; then
for jail in $("${LIBDIR}/bkctld-list"); do
"${LIBDIR}/bkctld-${subcommand}" "${jail}"
done
elif [ -z "${jail_name}" ]; then
show_help
exit 1
else
"${LIBDIR}/bkctld-${subcommand}" "${jail_name}"
fi
;;
"status")
jail_name="${2:-}"
if [ "${HEADER}" = "1" ]; then
printf '%-30s %-10s %-10s %-25s %-20s\n' 'JAIL NAME' 'STATUS' 'PORT' 'RETENTION (DAY/MONTH)' 'IP'
fi
if [ "${jail_name}" = "all" ] || [ -z "${jail_name}" ]; then
for jail in $("${LIBDIR}/bkctld-list"); do
"${LIBDIR}/bkctld-${subcommand}" "${jail}"
done
else
"${LIBDIR}/bkctld-${subcommand}" "${jail_name}"
fi
;;
"inc-lock" | "inc-unlock")
if [ "${subcommand}" = "inc-lock" ]; then
lock_status=on
elif [ "${subcommand}" = "inc-unlock" ]; then
lock_status=off
else
show_help
exit 1
fi
pattern="${2:-}"
if [ "${pattern}" = "all" ]; then
target_path_pattern=$(incs_path "*/*")
elif [ -n "${pattern}" ]; then
# Check if pattern is a jail name
if jails_with_incs_list | grep --silent --fixed-strings --line-regexp "${pattern}"; then
debug "${pattern} is a jail, change pattern to ${pattern}/*"
# then change attern to all subdirectories
target_path_pattern=$(incs_path "${pattern}/*")
else
# or use it as is
target_path_pattern=$(incs_path "${pattern}")
fi
else
show_help
exit 1
fi
for target_path in ${target_path_pattern}; do
"${LIBDIR}/bkctld-inc-lock" "${lock_status}" "${target_path}"
done
echo "finish"
;;
"rename")
jail_name="${2:-}"
new_jail_name="${3:-}"
if [ -z "${jail_name}" ] || [ -z "${new_jail_name}" ]; then
show_help
exit 1
else
"${LIBDIR}/bkctld-${subcommand}" "${jail_name}" "${new_jail_name}"
fi
;;
*)
show_help
exit 1
;;
esac

179
server/bkctld.8 Normal file
View file

@ -0,0 +1,179 @@
.Dd December 27, 2018
.Dt BKCTLD 8
.Os
.Sh NAME
.Nm bkctld
.Nd tool to manage evobackup jails
.Sh SYNOPSIS
.Nm
.Op Ar operand...
.Sh DESCRIPTION
.Nm
is a shell script that creates and manages a backup server
which can handle the backups of many other servers (clients).
.Pp
It uses
.Xr ssh 1
and
.Xr chroot 8
to sandbox every client's backups.
Each client will upload it's data every day
using
.Xr rsync 1
in it's
.Xr chroot 8
(using the root account).
.Pp
Prior backups are stored incrementally outside of the
.Xr chroot 8
using
.Xr ln 1
hard links or BTRFS snapshots.
(So they can not be affected by the client),
which backups are kept over time can be configured in the jail's nominal
.Xr evobackup-incl 5
configuration file.
.Pp
A large enough volume must be mounted on
.Pa /backup ,
if the filesystem is formatted with BTRFS,
.Nm
will use sub-volumes and snapshots to save space.
.Pp
It's default settings can be overridden in
.Xr bkctld.conf 5
file.
.Pp
The following operands are available:
.Bl -tag -width Ds
.It Cm init Ar jailname
Create an evobackup jail
.It Cm update Cm all | Ar jailname
Update an evobackup jail
.It Cm remove Cm all | Ar jailname
Remove an evobackup jail
.It Cm start Cm all | Ar jailname
Start an evobackup jail
.It Cm stop Cm all | Ar jailname
Stop an evobackup jail
.It Cm reload Cm all | Ar jailname
Reload an evobackup jail
.It Cm restart Cm all | Ar jailname
Restart an evobackup jail
.It Cm sync Cm all | Ar jailname
Sync an evobackup jail, the mirror server is defined by the
.Ev $NODE
variable in
.Pa /etc/default/bkctld
.It Cm status Op Ar jailname
Print the status of all jails or only
.Op Ar jailname .
.It Cm key Ar jailname Op Ar keyfile
Print or set the
.Xr ssh 1
public key of an evobackup jail
.It Cm port Ar jailname Op Cm auto | Ar port
Print or set the
.Xr ssh 1
.Op Ar port
of an evobackup jail.
Using
.Op Cm auto
will set it to the next available port.
.It Cm ip Ar jailname Op Cm all | Ar address
Print or set the whitelisted IP
.Op Ar address
for an evobackup jail.
.Op Cm all
allows unrestricted access and is the default.
.It Cm inc
Generate incremental backups
.It Cm rm
Remove old incremental backups
.El
.Sh FILES
.Bl -tag -width Ds
.It Pa /etc/default/bkctld
Template for
.Xr bkctld.conf 5
.It Pa /usr/share/bkctld/incl.tpl
Default rules for the incremental backups are stored here.
.El
.Sh EXAMPLES
Before creating a jail and backing up a client,
the backup server administrator will need:
.Bl -bullet
.It
The host name of the client system.
.It
The public RSA
.Xr ssh 1
key for the
.Dq root
user of the client system,
it is recommended the private key be password-less if automation is desired.
.It
The IPv4 address of the client system is needed
if the administrator wishes to maintain a whitelist,
see
.Va FIREWALL_RULES
in
.Xr bkctld.conf 5
.El
.Pp
He can then create the jail:
.Bd -literal -offset indent
# bkctld init CLIENT_HOST_NAME
# bkctld key CLIENT_HOST_NAME /root/CLIENT_HOST_NAME.pub
# bkctld ip CLIENT_HOST_NAME CLIENT_IP_ADDRESS
# bkctld start CLIENT_HOST_NAME
# bkctld status CLIENT_HOST_NAME
.Ed
.Pp
And override the default
.Xr evobackup-incl 5
rules
.Bd -literal -offset indent
# $EDITOR /etc/evobackup/CLIENT_HOST_NAME
.Ed
.Pp
To sync itself,
the client server will need to install
.Xr rsync 1 .
It can then be run manually:
.Bd -literal -offset indent
# rsync -av -e "ssh -p JAIL_PORT" /home/ root@BACKUP_SERVER:/var/backup/home/
.Ed
.Pp
If a more automated setup is required,
a script can be written in any programming language.
In this case,
it may be useful to validate the backup server's identity before hand.
.Bd -literal -offset indent
# ssh -p JAIL_PORT BACKUP_SERVER
.Ed
.Pp
A
.Xr bash 1
example to be run under the
.Dq root
user's
.Xr crontab 5
can be found in the
.Lk https://gitea.evolix.org/evolix/evobackup/src/branch/master/zzz_evobackup "source repository"
.\" .Sh EXIT STATUS
.\" For sections 1, 6, and 8 only.
.\" .Sh DIAGNOSTICS
.\" For sections 1, 4, 6, 7, 8, and 9 printf/stderr messages only.
.Sh SEE ALSO
.Xr rsync 1 ,
.Xr ssh-keygen 1 ,
.Xr bkctld 5 ,
.Xr evobackup-incl 5 ,
.Xr chroot 8 ,
.Xr cron 8 ,
.Xr sshd 8
.Sh AUTHORS
.An Victor Laborie
.\" .Sh CAVEATS
.\" .Sh BUGS

19
server/bkctld.conf Normal file
View file

@ -0,0 +1,19 @@
# bkctld.conf(5)
# Defaults for bkctld(8) command (evobackup)
# sourced by /usr/sbin/bkctld and /etc/init.d/bkctld
#CONFDIR='/etc/evobackup'
#JAILDIR='/backup/jails'
#INCDIR='/backup/incs'
#TPLDIR='/usr/share/bkctld'
#INDEX_DIR='/backup/index'
#LOCALTPLDIR='/usr/local/share/bkctld'
#SSHD_PID='/var/run/sshd.pid'
#SSHD_CONFIG='/etc/ssh/sshd_config'
#AUTHORIZED_KEYS='/root/.ssh/authorized_keys'
#FIREWALL_RULES=''
#LOGLEVEL=6
#NODE=''
#ARCHIVESDIR='/backup/archives'
#WARNING=48
#CRITICAL=72

67
server/bkctld.conf.5 Normal file
View file

@ -0,0 +1,67 @@
.Dd December 28, 2018
.Dt BKCTLD.CONF 5
.Os
.Sh NAME
.Nm bkctld.conf
.Nd configuration file for
.Xr bkctld 8
.Sh SYNOPSIS
.D1 name=[value]
.Sh DESCRIPTION
The
.Nm
file contains variables that override the behavior of the
.Xr bkctld 8
script.
By default, it is located at
.Pa /etc/default/bkctld .
.Pp
Each line must be a valid
.Xr bash 1
variable definition.
Lines beginning with the
.Sq #
character are comments and are ignored.
The order of the definitions does not matter.
.Pp
The following variables may be defined:
.Bl -tag -width Ds
.It Va CONFDIR
Directory where
.Xr evobackup-incl 5
files are kept.
It's default value is
.Pa /etc/evobackup/ .
.It Va JAILDIR
Directory where the jails are stored,
it is recommended that this be inside a BTRFS file system.
It's default value is
.Pa /backup/jails/ .
.It Va INCDIR
Directory where incremental backups are stored,
it is recommended that this be inside a BTRFS file system.
It's default value is
.Pa /backup/incs/ .
.It Va TPLDIR
Directory where the default configuration files are stored.
It's default value is
.Pa /usr/share/bkctld/ .
.It Va LOCALTPLDIR
Directory where custom configuration files are stored.
It's default is
.Pa /usr/local/share/bkctld/ .
.It Va LOGLEVEL
Defines the amount of information to log, follows the same scale as in
.In syslog.h
and defaults to 6.
.It Va FIREWALL_RULES
Configuration file containing the firewall rules that govern jail access.
This file must be sourced by your firewall.
It does not have a default value and, if unset,
.Xr bkctld 8
will not automatically update the firewall.
.El
.Sh SEE ALSO
.Xr bash 1 ,
.Xr evobackup-incl 5 ,
.Xr bkctld 8

14
server/bkctld.service Normal file
View file

@ -0,0 +1,14 @@
[Unit]
Documentation=man:bkctld(8)
Description=Backup manager using rsync and OpenSSH chroot.
[Service]
Type=oneshot
ExecStart=/usr/sbin/bkctld start all
ExecStop=/usr/sbin/bkctld stop all
RemainAfterExit=true
KillMode=control-group
GuessMainPID=no
[Install]
WantedBy=multi-user.target

View file

@ -0,0 +1,86 @@
BKCTLD.CONF(5) - File Formats Manual
# NAME
**bkctld.conf** - configuration file for
bkctld(8)
# SYNOPSIS
> name=\[value]
# DESCRIPTION
The
**bkctld.conf**
file contains variables that override the behavior of the
bkctld(8)
script.
By default, it is located at
*/etc/default/bkctld*.
Each line must be a valid
bash(1)
variable definition.
Lines beginning with the
'#'
character are comments and are ignored.
The order of the definitions does not matter.
The following variables may be defined:
*CONFDIR*
> Directory where
> evobackup-incl(5)
> files are kept.
> It's default value is
> */etc/evobackup/*.
*JAILDIR*
> Directory where the jails are stored,
> it is recommended that this be inside a BTRFS file system.
> It's default value is
> */backup/jails/*.
*INCDIR*
> Directory where incremental backups are stored,
> it is recommended that this be inside a BTRFS file system.
> It's default value is
> */backup/incs/*.
*TPLDIR*
> Directory where the default configuration files are stored.
> It's default value is
> */usr/share/bkctld/*.
*LOCALTPLDIR*
> Directory where custom configuration files are stored.
> It's default is
> */usr/local/share/bkctld/*.
*LOGLEVEL*
> Defines the amount of information to log, follows the same scale as in
> &lt;*syslog.h*>
> and defaults to 6.
*FIREWALL\_RULES*
> Configuration file containing the firewall rules that govern jail access.
> This file must be sourced by your firewall.
> It does not have a default value and, if unset,
> bkctld(8)
> will not automatically update the firewall.
# SEE ALSO
bash(1),
evobackup-incl(5),
bkctld(8)
OpenBSD 6.4 - December 28, 2018

54
server/docs/debian.md Normal file
View file

@ -0,0 +1,54 @@
# Debian Package
The **bkctld** package can be built from the **debian** branch of
this git repository with git-buildpackage and sbuild.
## Dependencies
Install Debian dependencies :
~~~
apt install git-buildpackage sbuild
~~~
Add your user to sbuild :
~~~
sbuild-adduser <username>
~~~
*You must logout and re-login or use `newgrp sbuild` in your current shell*
You need a schroot definition in */etc/schroot/schroot.conf*, eg :
~~~
[sid]
description=Debian sid (unstable)
directory=/srv/chroot/sid
groups=root,sbuild
root-groups=root,sbuild
aliases=unstable,default
~~~
Build the sbuild chroot :
~~~
sbuild-createchroot --include=eatmydata,ccache,gnupg unstable /srv/chroot/sid http://deb.debian.org/debian
~~~
## Build
You must be in the **debian** branch :
~~~
git checkout debian
~~~
Launch git-buildpackage :
~~~
gbp buildpackage
~~~
The generated build files (including the `.deb`) are located in the `/tmp/bkctld/` directory.

View file

@ -0,0 +1,80 @@
EVOBACKUP-INCL(5) - File Formats Manual
# NAME
**evobackup-incl** - incremental backup configuration
# SYNOPSIS
> \+%Y-%m-%d.-%day
# DESCRIPTION
Located by default in
*/etc/evobackup/*,
each
**evobackup-incl**
file is named after the
bkctld(8)
backup for which the rules it contains must apply.
The rules it defines decide which incremental backups are kept when running
# bkctld rm
Each line defines a single rule.
The first part of the rule describes when the backup was taken,
the second part decides how long to keep it.
Lines beginning with the
'#'
character are comments and are ignored.
The order of the rules does not matter.
Evobackups that do not have their nominal
**evobackup-incl**
file use the default rules defined in
*/usr/share/bkctld/inc.tpl*
# EXAMPLES
Keep today's backup:
+%Y-%m-%d.-0day
Keep yesterday's backup:
+%Y-%m-%d.-1day
Keep the first day of this month:
+%Y-%m-01.-0month
Keep the first day of last month:
+%Y-%m-01.-1month
Keep backups for every 15 days:
+%Y-%m-01.-1month
+%Y-%m-15.-1month
Keep a backup of the first day of january:
+%Y-01-01.-1month
Keep backups of the last 4 days and the first day of the last 2 months:
+%Y-%m-%d.-0day
+%Y-%m-%d.-1day
+%Y-%m-%d.-2day
+%Y-%m-%d.-3day
+%Y-%m-01.-0month
+%Y-%m-01.-1month
# SEE ALSO
bkctld(8),
cron(8),
*/etc/evobackup/tpl/inc.tpl*
OpenBSD 6.4 - December 28, 2018

63
server/docs/install.md Normal file
View file

@ -0,0 +1,63 @@
# Install
## Install from package
The install documentation is [here](https://intra.evolix.net/OutilsInternes/bkctld)
## Instal from sources
Warning: `cp`-ing the files without `-n` or `-i` will replace existing files !
~~~
# git clone https://gitea.evolix.org/evolix/evobackup.git
# cd evobackup
# cp server/bkctld /usr/local/sbin/
# mkdir -p /usr/local/lib/bkctld
# cp server/lib/* /usr/local/lib/bkctld/
# mkdir -p /usr/local/share/bkctld
# cp server/tpl/* /usr/local/share/bkctld/
# cp server/bkctld.service /lib/systemd/system/
# mkdir -p /usr/local/share/doc/bkctld
# cp client/zzz_evobackup /usr/local/share/doc/bkctld/
# mkdir -p /usr/local/share/bash_completion/
# cp server/bash_completion /usr/local/share/bash_completion/bkctld
# cp server/bkctld.conf /etc/default/bkctld
~~~
## Chroot dependencies
The chroot jails depend on these packages
~~~
apt install \
bash \
coreutils \
sed \
dash \
mount \
rsync \
openssh-server \
openssh-sftp-server \
libc6-i386 \
libc6
~~~
## Client dependencies
The clients only require OpenSSH and Rsync.
### Cron job for incremental backups
Edit the root crontab
~~~
# $editor /etc/cron.d/bkctld
+ MAILTO=alert4@evolix.net
+ 30 11 * * * root /usr/sbin/bkctld inc && /usr/sbin/bkctld rm
+ 30 23 * * * root /usr/share/scripts/check-incs.sh 1> /dev/null
~~~
## Notes
If you want mutiples backups in a day (1 per hour maximum) you can
run `bkctld inc` multiples times, if you want to keep incremental
backups **for ever**, just don't run `bkctld rm`.

207
server/docs/usage.md Normal file
View file

@ -0,0 +1,207 @@
BKCTLD(8) - System Manager's Manual
# NAME
**bkctld** - tool to manage evobackup jails
# SYNOPSIS
**bkctld**
\[*operand...*]
# DESCRIPTION
**bkctld**
is a shell script that creates and manages a backup server
which can handle the backups of many other servers (clients).
It uses
ssh(1)
and
chroot(8)
to sandbox every client's backups.
Each client will upload it's data every day
using
rsync(1)
in it's
chroot(8)
(using the root account).
Prior backups are stored incrementally outside of the
chroot(8)
using
ln(1)
hard links or BTRFS snapshots.
(So they can not be affected by the client),
which backups are kept over time can be configured in the jail's nominal
evobackup-incl(5)
configuration file.
A large enough volume must be mounted on
*/backup*,
if the filesystem is formatted with BTRFS,
**bkctld**
will use sub-volumes and snapshots to save space.
It's default settings can be overridden in
bkctld.conf(5)
file.
The following operands are available:
**init** *jailname*
> Create an evobackup jail
**update** **all** | *jailname*
> Update an evobackup jail
**remove** **all** | *jailname*
> Remove an evobackup jail
**start** **all** | *jailname*
> Start an evobackup jail
**stop** **all** | *jailname*
> Stop an evobackup jail
**reload** **all** | *jailname*
> Reload an evobackup jail
**restart** **all** | *jailname*
> Restart an evobackup jail
**sync** **all** | *jailname*
> Sync an evobackup jail, the mirror server is defined by the
> `$NODE`
> variable in
> */etc/default/bkctld*
**status** \[*jailname*]
> Print the status of all jails or only
> \[*jailname*].
**key** *jailname* \[*keyfile*]
> Print or set the
> ssh(1)
> public key of an evobackup jail
**port** *jailname* \[**auto** | *port*]
> Print or set the
> ssh(1)
> \[*port*]
> of an evobackup jail.
> Using
> \[**auto**]
> will set it to the next available port.
**ip** *jailname* \[**all** | *address*]
> Print or set the whitelisted IP
> \[*address*]
> for an evobackup jail.
> \[**all**]
> allows unrestricted access and is the default.
**inc**
> Generate incremental backups
**rm**
> Remove old incremental backups
# FILES
*/etc/default/bkctld*
> Template for
> bkctld.conf(5)
*/usr/share/bkctld/incl.tpl*
> Default rules for the incremental backups are stored here.
# EXAMPLES
Before creating a jail and backing up a client,
the backup server administrator will need:
* The host name of the client system.
* The public RSA
ssh(1)
key for the
"root"
user of the client system,
it is recommended the private key be password-less if automation is desired.
* The IPv4 address of the client system is needed
if the administrator wishes to maintain a whitelist,
see
*FIREWALL\_RULES*
in
bkctld.conf(5)
He can then create the jail:
# bkctld init <JAIL_NAME>
# bkctld key <JAIL_NAME> /root/<JAIL_NAME>.pub
# bkctld ip <JAIL_NAME> <IP_OR_CIDR>
# bkctld start <JAIL_NAME>
# bkctld status <JAIL_NAME>
And override the default
evobackup-incl(5)
rules
# $EDITOR /etc/evobackup/<JAIL_NAME>.d/incs_policy
To sync itself,
the client server will need to install
rsync(1).
It can then be run manually:
# rsync -av -e "ssh -p <JAIL_PORT>" /home/ root@<BACKUP_SERVER>:/var/backup/home/
If a more automated setup is required,
a script can be written in any programming language.
In this case,
it may be useful to validate the backup server's identity before hand.
# ssh -p <JAIL_PORT> root@<BACKUP_SERVER> -t exit
A
bash(1)
example to be run under the
"root"
user's
crontab(5)
can be found in the
[source repository](https://gitea.evolix.org/evolix/evobackup/src/branch/master/zzz_evobackup)
# SEE ALSO
rsync(1),
ssh-keygen(1),
bkctld(5),
evobackup-incl(5),
chroot(8),
cron(8),
sshd(8)
# AUTHORS
Victor Laborie
OpenBSD 6.4 - December 27, 2018

79
server/evobackup-incl.5 Normal file
View file

@ -0,0 +1,79 @@
.Dd December 28, 2018
.Dt EVOBACKUP-INCL 5
.Os
.Sh NAME
.Nm evobackup-incl
.Nd incremental backup configuration
.Sh SYNOPSIS
.D1 +%Y-%m-%d.-%day
.Sh DESCRIPTION
Located by default in
.Pa /etc/evobackup/ ,
each
.Nm
file is named after the
.Xr bkctld 8
backup for which the rules it contains must apply.
.Pp
The rules it defines decide which incremental backups are kept when running
.Bd -literal -offset indent
# bkctld rm
.Ed
.Pp
Each line defines a single rule.
The first part of the rule describes when the backup was taken,
the second part decides how long to keep it.
Lines beginning with the
.Sq #
character are comments and are ignored.
The order of the rules does not matter.
.Pp
Evobackups that do not have their nominal
.Nm
file use the default rules defined in
.Pa /usr/share/bkctld/inc.tpl
.Sh EXAMPLES
Keep today's backup:
.Bd -literal -offset indent
+%Y-%m-%d.-0day
.Ed
.Pp
Keep yesterday's backup:
.Bd -literal -offset indent
+%Y-%m-%d.-1day
.Ed
.Pp
Keep the first day of this month:
.Bd -literal -offset indent
+%Y-%m-01.-0month
.Ed
.Pp
Keep the first day of last month:
.Bd -literal -offset indent
+%Y-%m-01.-1month
.Ed
.Pp
Keep backups for every 15 days:
.Bd -literal -offset indent
+%Y-%m-01.-1month
+%Y-%m-15.-1month
.Ed
.Pp
Keep a backup of the first day of january:
.Bd -literal -offset indent
+%Y-01-01.-1month
.Ed
.Pp
Keep backups of the last 4 days and the first day of the last 2 months:
.Bd -literal -offset indent
+%Y-%m-%d.-0day
+%Y-%m-%d.-1day
+%Y-%m-%d.-2day
+%Y-%m-%d.-3day
+%Y-%m-01.-0month
+%Y-%m-01.-1month
.Ed
.Sh SEE ALSO
.Xr bkctld 8 ,
.Xr cron 8 ,
.Pa /etc/evobackup/tpl/inc.tpl

51
server/lib/bkctld-archive Executable file
View file

@ -0,0 +1,51 @@
#!/bin/sh
#
# Description: Archive jail and all dated copies (incs)
# Usage: archive <jailname>|all
# Return codes:
# * 101 : jail archival aborted
#
# shellcheck source=./includes
LIBDIR="$(dirname $0)" && . "${LIBDIR}/includes"
jail_name="${1:?}"
if [ -z "${jail_name}" ]; then
show_help && exit 1
fi
jail_path=$(jail_path "${jail_name}")
test -d "${jail_path}" || error "${jail_name}: jail not found" 2
archive_jail_path=$(archive_path "${jail_name}")
test -d "${archive_jail_path}" && error "${jail_name}: archive already exists" 2
if [ "${FORCE}" != "1" ]; then
answer=""
while :; do
printf "> Are you sure you want to archive jail \`%s'? [Y,n,?] " "${jail_name}"
read -r answer
case $answer in
[Yy]|"" )
break
;;
[Nn] )
tty -s && echo "Abort." >&2
exit 101
;;
* )
printf "y - yes, execute actions and exit\n"
printf "n - no, don't execute actions and exit\n"
printf "? - print this help\n"
;;
esac
done
fi
"${LIBDIR}/bkctld-is-on" "${jail_name}" && "${LIBDIR}/bkctld-stop" "${jail_name}"
mkdir -p "$(dirname "${archive_jail_path}")"
mv "${jail_path}" "${archive_jail_path}"
notice "Archive jail \`${jail_name}' : OK"

59
server/lib/bkctld-check-canary Executable file
View file

@ -0,0 +1,59 @@
#!/bin/sh
#
# Description: check canary file
# Usage: check-canary [<jailname>|all]
#
# shellcheck source=./includes
LIBDIR="$(dirname $0)" && . "${LIBDIR}/includes"
return=0
nb_crit=0
nb_warn=0
nb_ok=0
nb_unkn=0
output=""
date=$(date +"%Y-%m-%d")
# Check each jail status
check_jail() {
jail_name=$1
jail_path=$(jail_path "${jail_name}")
canary_absolute_file="${jail_path}/var/backup/${CANARY_RELATIVE_FILE}"
if [ -f "${canary_absolute_file}" ]; then
if grep --quiet --fixed-string "${date}" "${canary_absolute_file}"; then
nb_ok=$((nb_ok + 1))
output="${output}OK - ${jail_name} - entries found for ${date} in ${CANARY_RELATIVE_FILE} file\n"
else
nb_crit=$((nb_crit + 1))
output="${output}CRITICAL - ${jail_name} - No entry for ${date} in ${CANARY_RELATIVE_FILE} file\n"
[ "${return}" -le 2 ] && return=2
fi
else
nb_crit=$((nb_crit + 1))
output="${output}CRITICAL - ${jail_name} - missing ${CANARY_RELATIVE_FILE} file\n"
[ "${return}" -le 2 ] && return=2
fi
}
for jail_name in $(jails_list); do
check_jail "${jail_name}"
done
[ "${return}" -ge 0 ] && header="OK"
[ "${return}" -ge 1 ] && header="WARNING"
[ "${return}" -ge 2 ] && header="CRITICAL"
[ "${return}" -ge 3 ] && header="UNKNOWN"
printf "%s - %s UNK / %s CRIT / %s WARN / %s OK\n\n" "${header}" "${nb_unkn}" "${nb_crit}" "${nb_warn}" "${nb_ok}"
printf "${output}" | grep -E "^UNKNOWN"
printf "${output}" | grep -E "^CRITICAL"
printf "${output}" | grep -E "^WARNING"
printf "${output}" | grep -E "^OK"
exit "${return}"

60
server/lib/bkctld-check-incs Executable file
View file

@ -0,0 +1,60 @@
#!/bin/sh
#
# Description: Run check on all expected incs of all jails
# Usage: check-incs all
#
set -u
# shellcheck source=./includes
LIBDIR="$(dirname "$0")" && . "${LIBDIR}/includes"
# default return value is 0 (succes)
rc=0
# loop for each configured jail
for jail_name in $("${LIBDIR}/bkctld-list"); do
incs_policy_file=$(current_jail_incs_policy_file "${jail_name}")
# Today in seconds from epoch
today_epoch=$(date +"%s")
# Today in ISO format
today_iso=$(date +"%Y-%m-%d")
if [ -n "${incs_policy_file}" ]; then
# get jail last configuration date
jail_config_epoch=$(date --date "$(stat -c %y "${incs_policy_file}")" +"%s")
# read each line in jail configuration
while read line; do
## TODO
# deal with empty lines
# inc date in ISO format
inc_iso=$(relative_date "${line}")
# inc date in seconds from epoch
inc_epoch=$(date --date "${inc_iso}" +"%s")
# skip line if date is in the future
if [ "${inc_epoch}" -gt "${today_epoch}" ]; then
echo "INFO: ${jail_name} : no inc expected for ${inc_iso}"
else
# check if the configuration changed after the inc date
# or if it's today's inc
if [ "${jail_config_epoch}" -lt "${inc_epoch}" ] \
|| [ "${today_iso}" = "${inc_iso}" ]; then
# Error if inc is not found
if ! inc_exists "${jail_name}" "${inc_iso}*"; then
echo "ERROR: ${jail_name} : missing inc for ${inc_iso}" >&2
rc=1
fi
else
echo "INFO: ${jail_name} : no inc expected for ${inc_iso}"
fi
fi
done < "${incs_policy_file}"
else
echo "INFO: ${jail_name} : no inc expected at all"
fi
done
exit $rc

78
server/lib/bkctld-check-jails Executable file
View file

@ -0,0 +1,78 @@
#!/bin/sh
#
# Description: Run check on jails (NRPE output)
# Usage: check-jails
#
# shellcheck source=./includes
LIBDIR="$(dirname $0)" && . "${LIBDIR}/includes"
return=0
nb_crit=0
nb_warn=0
nb_ok=0
nb_unkn=0
output=""
# Check each jail status
check_jail() {
jail_name=$1
jail_path=$(jail_path "${jail_name}")
cur_time=$(date "+%s")
last_conn=$(stat --format=%Y "${jail_path}/var/log/lastlog")
date_diff=$(( (cur_time - last_conn) / (60*60) ))
check_policy_file=$(current_jail_check_policy_file "${jail_name}")
if [ -f "${check_policy_file}" ]; then
local_critical=$(read_numerical_variable "${check_policy_file}" "CRITICAL")
local_warning=$(read_numerical_variable "${check_policy_file}" "WARNING")
else
unset local_critical
unset local_warning
fi
# reset to default values if missing local value
: ${local_critical:=${CRITICAL}}
: ${local_warning:=${WARNING}}
if [ "${local_critical}" -gt "0" ] && [ "${date_diff}" -gt "${local_critical}" ]; then
nb_crit=$((nb_crit + 1))
output="${output}CRITICAL - ${jail_name} - ${date_diff} hours (${local_warning}/${local_critical})\n"
[ "${return}" -le 2 ] && return=2
elif [ "${local_warning}" -gt "0" ] && [ "${date_diff}" -gt "${local_warning}" ]; then
nb_warn=$((nb_warn + 1))
output="${output}WARNING - ${jail_name} - ${date_diff} hours (${local_warning}/${local_critical})\n"
[ "${return}" -le 1 ] && return=1
else
nb_ok=$((nb_ok + 1))
output="${output}OK - ${jail_name} - ${date_diff} hours (${local_warning}/${local_critical})\n"
fi
}
for jail_name in $(jails_list); do
jail_path=$(jail_path "${jail_name}")
if [ -f "${jail_path}/var/log/lastlog" ]; then
check_jail "${jail_name}"
else
nb_unkn=$((nb_unkn + 1))
output="${output}UNKNOWN - ${jail_name} doesn't have lastlog !\n"
[ "${return}" -le 3 ] && return=3
fi
done
[ "${return}" -ge 0 ] && header="OK"
[ "${return}" -ge 1 ] && header="WARNING"
[ "${return}" -ge 2 ] && header="CRITICAL"
[ "${return}" -ge 3 ] && header="UNKNOWN"
printf "%s - %s UNK / %s CRIT / %s WARN / %s OK\n\n" "${header}" "${nb_unkn}" "${nb_crit}" "${nb_warn}" "${nb_ok}"
printf "${output}" | grep -E "^UNKNOWN"
printf "${output}" | grep -E "^CRITICAL"
printf "${output}" | grep -E "^WARNING"
printf "${output}" | grep -E "^OK"
exit "${return}"

View file

@ -0,0 +1,31 @@
#!/bin/sh
#
# Description: Run check on the last inc of all jails
# Usage: check-incs last
#
set -u
# shellcheck source=./includes
LIBDIR="$(dirname $0)" && . "${LIBDIR}/includes"
# default return value is 0 (succes)
rc=0
# loop for each found jail
for jail_name in $("${LIBDIR}/bkctld-list"); do
incs_policy_file=$(current_jail_incs_policy_file "${jail_name}")
if [ -n "${incs_policy_file}" ]; then
# inc date in seconds from epoch
inc_date=$(date +"%Y-%m-%d")
# Error if inc is not found
if ! inc_exists "${jail_name}" "${inc_date}*"; then
echo "ERROR: ${jail_name} : missing inc for ${inc_date}" >&2
rc=1
fi
else
echo "INFO: ${jail_name} : no inc expected at all"
fi
done
exit $rc

93
server/lib/bkctld-check-setup Executable file
View file

@ -0,0 +1,93 @@
#!/bin/sh
#
# Description: Run check on jails (NRPE output)
# Usage: check setup
#
# shellcheck source=./includes
LIBDIR="$(dirname $0)" && . "${LIBDIR}/includes"
return=0
nb_crit=0
nb_warn=0
nb_ok=0
nb_unkn=0
output=""
# Verify backup partition is mounted and writable
findmnt -O rw --mountpoint "${BACKUP_PARTITION}" > /dev/null
if [ "$?" -ne 0 ]; then
nb_crit=$((nb_crit + 1))
output="${output}CRITICAL - Backup disk \`/backup' is not mounted (or read-only) !\n"
return=2
else
nb_ok=$((nb_ok + 1))
output="${output}OK - Backup disk \`/backup' is mounted and writable.\n"
fi
# Check if the firewall file is sourced
minifirewall_config=/etc/default/minifirewall
if [ -n "${FIREWALL_RULES}" ] \
&& [ -r "${FIREWALL_RULES}" ] \
&& [ -f "${minifirewall_config}" ]; then
minifirewall_version=$(grep -E -o "^VERSION=(\S+)" /etc/init.d/minifirewall | head -1 | cut -d '=' -f 2 | tr -d "'" | tr -d '"')
if [ -n "${minifirewall_version}" ] && dpkg --compare-versions "${minifirewall_version}" ge "22.03"; then
# Minifirewall 22.03+ includes files automatically
nb_ok=$((nb_ok + 1))
output="${output}OK - Firewall file \`${FIREWALL_RULES}' is present.\n"
else
if grep -qE "^(\.|source) ${FIREWALL_RULES}" "${minifirewall_config}"; then
nb_ok=$((nb_ok + 1))
output="${output}OK - Firewall file \`${FIREWALL_RULES}' is sourced by \`${minifirewall_config}'.\n"
else
nb_warn=$((nb_warn + 1))
output="${output}WARNING - Firewall file \`${FIREWALL_RULES}' doesn't seem to be sourced by \`${minifirewall_config}'\n"
[ "${return}" -le 1 ] && return=1
fi
fi
fi
# Check if jails are started
nb_on=0
nb_off=0
for jail_name in $(jails_list); do
if "${LIBDIR}/bkctld-is-on" "${jail_name}"; then
nb_on=$((nb_on + 1))
else
expected_state="ON"
check_policy_file=$(current_jail_check_policy_file "${jail_name}")
if [ -f "${check_policy_file}" ]; then
expected_state=$(read_variable "${check_policy_file}" "EXPECTED_STATE")
fi
if [ "${expected_state}" != "OFF" ]; then
nb_off=$((nb_off + 1))
fi
fi
done
if [ "${nb_off}" -eq 0 ]; then
output="${output}OK - all jails are in their expected state.\n"
nb_ok=$((nb_ok + 1))
else
output="${output}CRITICAL - ${nb_off} jail(s) shouldn't be OFF !\n"
nb_crit=$((nb_crit + 1))
[ "${return}" -le 2 ] && return=2
fi
[ "${return}" -ge 0 ] && header="OK"
[ "${return}" -ge 1 ] && header="WARNING"
[ "${return}" -ge 2 ] && header="CRITICAL"
[ "${return}" -ge 3 ] && header="UNKNOWN"
printf "%s - %s UNK / %s CRIT / %s WARN / %s OK\n\n" "${header}" "${nb_unkn}" "${nb_crit}" "${nb_warn}" "${nb_ok}"
printf "${output}" | grep -E "^UNKNOWN"
printf "${output}" | grep -E "^CRITICAL"
printf "${output}" | grep -E "^WARNING"
printf "${output}" | grep -E "^OK"
exit "${return}"

41
server/lib/bkctld-firewall Executable file
View file

@ -0,0 +1,41 @@
#!/bin/sh
#
# Description: Update firewall rules
# Usage: firewall [<jailname>|all]
#
# shellcheck source=./includes
LIBDIR="$(dirname $0)" && . "${LIBDIR}/includes"
jail_name="${1:?}"
if [ -z "${jail_name}" ]; then
show_help && exit 1
fi
jail_path=$(jail_path "${jail_name}")
iptables_input_accept() {
jail_name="${1}"
port="${2}"
ip="${3}"
debug "Accept \`${ip}:${port}' for jail \`${jail_name}'"
echo "/sbin/iptables -A INPUT -p tcp --sport 1024: --dport ${port} -s ${ip} -j ACCEPT #${jail_name}"
}
if [ -n "${FIREWALL_RULES}" ]; then
# remove existing rules for this jail
[ -f "${FIREWALL_RULES}" ] && sed --follow-symlinks --in-place "/#${jail_name}$/d" "${FIREWALL_RULES}"
if [ -d "${jail_path}" ]; then
port=$("${LIBDIR}/bkctld-port" "${jail_name}")
# Add a rule for each IP
for ip in $("${LIBDIR}/bkctld-ip" "${jail_name}"); do
iptables_input_accept "${jail_name}" "${port}" "${ip}" >> "${FIREWALL_RULES}"
done
# Restart the firewall
[ -f /etc/init.d/minifirewall ] && /etc/init.d/minifirewall restart >/dev/null
fi
notice "Firewall updated for jail \`${jail_name}'"
else
notice "Skip jail \`${jail_name}' : FIREWALL_RULES variable is empty."
fi

78
server/lib/bkctld-inc Executable file
View file

@ -0,0 +1,78 @@
#!/bin/sh
#
# Description: Make dated copies (incs) of jails
# Usage: inc
#
# shellcheck source=./includes
LIBDIR="$(dirname $0)" && . "${LIBDIR}/includes"
create_inc_btrfs() {
jail_name=${1:?}
inc_name=${2:?}
jail_path=$(jail_path "${jail_name}")
inc_path=$(inc_path "${jail_name}" "${inc_name}")
btrfs_bin=$(command -v btrfs)
if [ -z "${btrfs_bin}" ]; then
error "btrfs not found. Please install btrfs-progs."
fi
if dry_run; then
echo "[dry-run] btrfs subvolume snapshot of ${jail_path} to ${inc_path}"
else
mkdir --parents "$(dirname "${inc_path}")"
# create a btrfs readonly snapshot from the jail
${btrfs_bin} subvolume snapshot -r "${jail_path}" "${inc_path}" | debug
fi
}
create_inc_ext4() {
jail_name=${1:?}
inc_name=${2:?}
jail_path=$(jail_path "${jail_name}")
inc_path=$(inc_path "${jail_name}" "${inc_name}")
if dry_run; then
echo "[dry-run] copy of ${jail_path} to ${inc_path}"
else
mkdir --parents "$(dirname "${inc_path}")"
# create a copy of the jail with hard links
cp --archive --link --one-file-system "${jail_path}/" "${inc_path}"
fi
}
inc_name=$(date +"%Y-%m-%d-%H")
jails_list=$(jails_list)
jails_total=$(echo $jails_list | wc -w)
jails_count=0
for jail_name in ${jails_list}; do
jails_count=$((jails_count+1))
jail_path=$(jail_path "${jail_name}")
inc_path=$(inc_path "${jail_name}" "${inc_name}")
incs_policy_file=$(current_jail_incs_policy_file ${jail_name})
# If no incs policy is found, we don't create incs
if [ -n "${incs_policy_file}" ]; then
# If inc directory is not present, we proceed with inc creation
if [ ! -d "${inc_path}" ]; then
info "Progress: jail ${jails_count} out of ${jails_total}"
notice "Create inc \`${inc_name}' for jail \`${jail_name}' : start"
if is_btrfs "${jail_path}"; then
create_inc_btrfs "${jail_name}" "${inc_name}"
else
create_inc_ext4 "${jail_name}" "${inc_name}"
fi
notice "Create inc \`${inc_name}' for jail \`${jail_name}' : finish"
else
warning "Skip inc \`${inc_name}' for jail \`${jail_name}' : it already exists."
fi
else
notice "Skip jail \`${jail_name}' : incs policy is missing"
fi
done

53
server/lib/bkctld-inc-lock Executable file
View file

@ -0,0 +1,53 @@
#!/bin/sh
#
# Description: Lock or unlock dated copies (incs) on BTRFS formatted volumes
# Usage: inc-<lock|unlock> <all|jailname[/inc]>
#
# shellcheck source=./includes
LIBDIR="$(dirname $0)" && . "${LIBDIR}/includes"
lock_status="${1:?}"
target_path="${2:?}"
lock_target() {
target="${1:?}"
btrfs_bin=$(command -v btrfs)
if [ -z "${btrfs_bin}" ]; then
error "btrfs not found. Please install btrfs-progs."
fi
if is_btrfs "${target}"; then
${btrfs_bin} property set -ts "${target}" ro true
info "Lock ${target}: done".
else
info "Lock ${target}: not BTRFS, nothing done".
fi
}
unlock_target() {
target="${1:?}"
btrfs_bin=$(command -v btrfs)
if [ -z "${btrfs_bin}" ]; then
error "btrfs not found. Please install brtfs-progs."
fi
if is_btrfs "${target}"; then
${btrfs_bin} property set -ts "${target}" ro false
info "Unlock ${target}: done."
else
info "Unlock ${target}: not BTRFS, nothing done."
fi
}
# this directory test must be quoted,beacause of the probable globbing
if [ -d ${target_path} ]; then
if [ "${lock_status}" = "on" ]; then
lock_target "${target_path}"
elif [ "${lock_status}" = "off" ]; then
unlock_target "${target_path}"
else
error "Unknown lock status \`${lock_status}'."
exit 1
fi
else
error "\`${target_path}': no such file or directory."
exit 1
fi

37
server/lib/bkctld-init Executable file
View file

@ -0,0 +1,37 @@
#!/bin/sh
#
# Description: Initialize a new jail
# Usage: init <jailname>
#
# shellcheck source=./includes
LIBDIR="$(dirname $0)" && . "${LIBDIR}/includes"
jail_name="${1:?}"
if [ -z "${jail_name}" ]; then
show_help && exit 1
fi
jail_path=$(jail_path "${jail_name}")
incs_path=$(incs_path "${jail_name}")
test -d "${jail_path}" && error "Skip jail \`${jail_name}' : it already exists"
# Create config, jails and incs directories
mkdir --parents "${CONFDIR}" "${JAILDIR}" "${INCDIR}"
if is_btrfs "$(dirname "${JAILDIR}")" || is_btrfs "${JAILDIR}"; then
btrfs_bin=$(command -v btrfs)
if [ -z "${btrfs_bin}" ]; then
error "btrfs not found. Please install btrfs-progs."
fi
${btrfs_bin} subvolume create "${jail_path}"
else
mkdir --parents "${jail_path}"
fi
mkdir --parents "${incs_path}"
setup_jail_chroot "${jail_name}"
setup_jail_config "${jail_name}"
notice "Create jail \`${jail_name}' : OK"

48
server/lib/bkctld-ip Executable file
View file

@ -0,0 +1,48 @@
#!/bin/sh
#
# Description: Set or get allowed(s) ip(s)
# Usage: ip <jailname> [<ip>|all]
#
# shellcheck source=./includes
LIBDIR="$(dirname $0)" && . "${LIBDIR}/includes"
jail_name="${1:?}"
ip="${2:-}"
if [ ! -n "${jail_name}" ]; then
show_help && exit 1
fi
jail_path=$(jail_path "${jail_name}")
test -d "${jail_path}" || error "${jail_name}: jail not found" 2
jail_sshd_config="${jail_path}/${SSHD_CONFIG}"
if [ -z "${ip}" ]; then
# parse IP addresses from AllowUsers directives in sshd config
grep -E "^AllowUsers" "${jail_sshd_config}" \
| grep -E -o "root@[^ ]+" \
| while read allow; do
echo "${allow}" | cut -d'@' -f2
done
else
if [ "${ip}" = "all" ] || [ "${ip}" = "0.0.0.0/0" ]; then
new_ips="0.0.0.0/0"
else
existing_ips=$("${LIBDIR}/bkctld-ip" "${jail_name}")
new_ips=$(echo ${existing_ips} ${ip} | xargs -n1 | grep -v "0.0.0.0/0" | sort | uniq)
fi
allow_users="AllowUsers"
for new_ip in ${new_ips}; do
allow_users="${allow_users} root@${new_ip}"
done
if grep -q -E "^AllowUsers" "${jail_sshd_config}"; then
sed --follow-symlinks --in-place "s~^AllowUsers .*~${allow_users}~" "${jail_sshd_config}"
else
error "No \`AllowUsers' directive found in \`${jail_sshd_config}'"
fi
notice "Update IP whitelist with \`${ip}' for jail \`${jail_name}' : OK"
"${LIBDIR}/bkctld-reload" "${jail_name}"
"${LIBDIR}/bkctld-firewall" "${jail_name}"
fi

32
server/lib/bkctld-is-on Executable file
View file

@ -0,0 +1,32 @@
#!/bin/sh
#
# Description: Check if a SSH server is on (exit 0) or not (exit 100)
# Usage: is-on <jailname>
#
# shellcheck source=./includes
LIBDIR="$(dirname $0)" && . "${LIBDIR}/includes"
jail_name="${1:?}"
if [ -z "${jail_name}" ]; then
show_help && exit 1
fi
jail_path=$(jail_path "${jail_name}")
test -d "${jail_path}" || error "${jail_name}: jail not found" 2
jail_pid_file="${jail_path}/${SSHD_PID}"
# Error codes are references in "includes" file
return=100
if [ -f "${jail_pid_file}" ]; then
pid=$(cat "${jail_pid_file}")
ps -p "${pid}" > /dev/null && return=0
fi
if [ "${return}" -gt 0 ]; then
rm -f "${jail_pid_file}"
grep -q "${jail_path}/proc" /proc/mounts && umount --lazy "${jail_path}/proc/"
grep -q "${jail_path}/dev" /proc/mounts && umount --lazy --recursive "${jail_path}/dev"
fi
exit "${return}"

29
server/lib/bkctld-key Executable file
View file

@ -0,0 +1,29 @@
#!/bin/sh
#
# Description: Set or get ssh pubic key
# Usage: key <jailname> [<keyfile>]
#
# shellcheck source=./includes
LIBDIR="$(dirname $0)" && . "${LIBDIR}/includes"
jail_name="${1:?}"
keyfile="${2:-}"
if [ ! -n "${jail_name}" ]; then
show_help && exit 1
fi
jail_path=$(jail_path "${jail_name}")
test -d "${jail_path}" || error "${jail_name}: jail not found" 2
if [ -z "${keyfile}" ]; then
if [ -f "${jail_path}/${AUTHORIZED_KEYS}" ]; then
cat "${jail_path}/${AUTHORIZED_KEYS}"
fi
else
test -r "${keyfile}" || error "SSH key \`${keyfile}' for jail \`${jail_name}' is missing or is not readable."
cat "${keyfile}" > "${jail_path}/${AUTHORIZED_KEYS}"
chmod 600 "${jail_path}/${AUTHORIZED_KEYS}"
notice "Update SSH key \`${keyfile}' for jail \`${jail_name}' : OK"
fi

13
server/lib/bkctld-list Executable file
View file

@ -0,0 +1,13 @@
#!/bin/sh
#
# Description: List jails
# Usage: list
#
set -eu
# shellcheck source=./includes
LIBDIR="$(dirname $0)" && . "${LIBDIR}/includes"
[ -d "${JAILDIR}" ] || exit 0
jails_list

36
server/lib/bkctld-port Executable file
View file

@ -0,0 +1,36 @@
#!/bin/sh
#
# Description: Set or get SSH port
# Usage: port <jailname> [<port>|auto]
#
# shellcheck source=./includes
LIBDIR="$(dirname $0)" && . "${LIBDIR}/includes"
jail_name="${1:?}"
port="${2:-}"
if [ ! -n "${jail_name}" ]; then
show_help && exit 1
fi
jail_path=$(jail_path "${jail_name}")
test -d "${jail_path}" || error "${jail_name}: jail not found" 2
jail_sshd_config="${jail_path}/${SSHD_CONFIG}"
if [ -z "${port}" ]; then
grep -E "Port [0-9]+" "${jail_sshd_config}"|grep -oE "[0-9]+"
else
if [ "${port}" = "auto" ]; then
port=$(grep -h Port "${JAILDIR}"/*/"${SSHD_CONFIG}" 2>/dev/null | grep -Eo "[0-9]+" | sort -n | tail -1)
port=$((port+1))
[ "${port}" -le 1 ] && port=2222
fi
sed --follow-symlinks --in-place "s/^Port .*/Port ${port}/" "${jail_sshd_config}"
notice "Update SSH port \`${port}' for jail \`${jail_name}' : OK"
"${LIBDIR}/bkctld-reload" "${jail_name}"
"${LIBDIR}/bkctld-firewall" "${jail_name}"
fi

26
server/lib/bkctld-reload Executable file
View file

@ -0,0 +1,26 @@
#!/bin/sh
#
# Description: Reload SSH server
# Usage: reload [<jailname>|all]
#
# shellcheck source=./includes
LIBDIR="$(dirname $0)" && . "${LIBDIR}/includes"
jail_name="${1:?}"
if [ -z "${jail_name}" ]; then
show_help && exit 1
fi
jail_path=$(jail_path "${jail_name}")
test -d "${jail_path}" || error "${jail_name}: jail not found" 2
"${LIBDIR}/bkctld-is-on" "${jail_name}" || exit 0
pid=$(cat "${jail_path}/${SSHD_PID}")
if kill -HUP "${pid}"; then
notice "Reload jail \`${jail_name}' : OK [${pid}]"
else
error "Reload jail \`${jail_name}' : failed [${pid}]"
fi

81
server/lib/bkctld-remove Executable file
View file

@ -0,0 +1,81 @@
#!/bin/sh
#
# Description: Remove jail and all dated copies (incs)
# Usage: remove <jailname>|all
# Return codes:
# * 101 : jail removal aborted
#
# shellcheck source=./includes
LIBDIR="$(dirname $0)" && . "${LIBDIR}/includes"
jail_name="${1:?}"
if [ -z "${jail_name}" ]; then
show_help && exit 1
fi
jail_path=$(jail_path "${jail_name}")
incs_path=$(incs_path "${jail_name}")
if ! test -d "${jail_path}"; then
if [ "${FORCE}" = "1" ]; then
warning "${jail_name}: jail not found (ignore in FORCE mode)"
exit 0
else
error "${jail_name}: jail not found" 2
fi
fi
if [ "${FORCE}" != "1" ]; then
answer=""
while :; do
printf "> Are you sure you want to delete jail \`%s'? [Y,n,?] " "${jail_name}"
read -r answer
case $answer in
[Yy]|"" )
break
;;
[Nn] )
tty -s && echo "Abort." >&2
exit 101
;;
* )
printf "y - yes, execute actions and exit\n"
printf "n - no, don't execute actions and exit\n"
printf "? - print this help\n"
;;
esac
done
fi
"${LIBDIR}/bkctld-is-on" "${jail_name}" && "${LIBDIR}/bkctld-stop" "${jail_name}"
rm -f "${CONFDIR}/${jail_name}"
rm -rf "$(jail_config_dir "${jail_name}")"
btrfs_bin=$(command -v btrfs)
if [ -z "${btrfs_bin}" ]; then
error "btrfs not found. Please install btrfs-progs."
fi
if is_btrfs "${jail_path}"; then
${btrfs_bin} subvolume delete "${jail_path}" | debug
else
rm -rf "${jail_path:?}" | debug
fi
# TODO: use functions here
if [ -d "${incs_path}" ]; then
incs=$(ls "${incs_path}")
for inc in ${incs}; do
inc_inode=$(stat --format=%i "${incs_path}/${inc}")
if [ "${inc_inode}" -eq 256 ]; then
${btrfs_bin} subvolume delete "${incs_path}/${inc}" | debug
else
warning "You need to purge \`${incs_path}/${inc}' manually"
fi
done
rmdir --ignore-fail-on-non-empty "${incs_path}" | debug
fi
"${LIBDIR}/bkctld-firewall" "${jail_name}"
notice "Delete jail \`${jail_name}' : OK"

83
server/lib/bkctld-rename Executable file
View file

@ -0,0 +1,83 @@
#!/bin/sh
#
# Description: Rename a jail
# Usage: rename <jailname> <new-jailname>
# Return codes:
# * 1: error
#
# shellcheck source=./includes
LIBDIR="$(dirname $0)" && . "${LIBDIR}/includes"
jail_name="${1:?}"
new_jail_name="${2:?}"
if [ -z "${jail_name}" ] || [ -z "${new_jail_name}" ]; then
show_help && exit 1
fi
jail_path=$(jail_path "${jail_name}")
incs_path=$(incs_path "${jail_name}")
jail_config_dir=$(jail_config_dir "${jail_name}")
legacy_config_file="${CONFDIR}/${jail_name}"
test -d "${jail_path}" || error "${jail_name}: jail not found" 2
new_jail_path=$(jail_path "${new_jail_name}")
new_incs_path=$(incs_path "${new_jail_name}")
new_jail_config_dir=$(jail_config_dir "${new_jail_name}")
new_legacy_config_file="${CONFDIR}/${new_jail_name}"
test -d "${new_jail_path}" && error "${new_jail_name}: jail already exists" 2
test -d "${new_incs_path}" && error "${new_jail_name}: incs already exists" 2
"${LIBDIR}/bkctld-is-on" "${jail_name}" 2>/dev/null
case "$?" in
0)
jail_initial_status="on"
;;
100)
jail_initial_status="off"
;;
*)
unset jail_initial_status
error "Error evaluating jail \`${jail_name}' state. bkctld-is-on exited with \`$?'"
;;
esac
test "${jail_initial_status}" = "on" && "${LIBDIR}/bkctld-stop" "${jail_name}"
if dry_run; then
echo "[dry-run] rename ${jail_path} to ${new_jail_path}"
else
mv "${jail_path}" "${new_jail_path}"
fi
if [ -d "${incs_path}" ]; then
if dry_run; then
echo "[dry-run] rename ${incs_path} to ${new_incs_path}"
else
mv "${incs_path}" "${new_incs_path}"
fi
fi
if [ -d "${jail_config_dir}" ]; then
if dry_run; then
echo "[dry-run] rename ${jail_config_dir} to ${new_jail_config_dir}"
else
mv "${jail_config_dir}" "${new_jail_config_dir}"
fi
fi
if [ -f "${legacy_config_file}" ]; then
if dry_run; then
mv "${legacy_config_file}" "${new_legacy_config_file}"
else
echo "[dry-run] rename ${legacy_config_file} to ${new_legacy_config_file}"
fi
fi
# Reset firewall for new jail name
"${LIBDIR}/bkctld-firewall" "${jail_name}"
"${LIBDIR}/bkctld-firewall" "${new_jail_name}"
test "${jail_initial_status}" = "on" && "${LIBDIR}/bkctld-start" "${new_jail_name}"
notice "Rename jail \`${jail_name}' to \`${new_jail_name}' : OK"

21
server/lib/bkctld-restart Executable file
View file

@ -0,0 +1,21 @@
#!/bin/sh
#
# Description: Restart SSH server
# Usage: restart [<jailname>|all]
#
set -eu
# shellcheck source=./includes
LIBDIR="$(dirname $0)" && . "${LIBDIR}/includes"
jail_name="${1:?}"
if [ -z "${jail_name}" ]; then
show_help && exit 1
fi
jail_path=$(jail_path "${jail_name}")
test -d "${jail_path}" || error "${jail_name}: jail not found" 2
"${LIBDIR}/bkctld-is-on" "${jail_name}" && "${LIBDIR}/bkctld-stop" "${jail_name}"
"${LIBDIR}/bkctld-start" "${jail_name}"

160
server/lib/bkctld-rm Executable file
View file

@ -0,0 +1,160 @@
#!/bin/sh
#
# Description: Remove old dated copies (incs) according to policy
# Usage: rm
#
# shellcheck source=./includes
LIBDIR="$(dirname $0)" && . "${LIBDIR}/includes"
kill_or_clean_lockfile() {
lock_file=${1:-}
if [ -f "${lock_file}" ]; then
# Get Process ID from the lock file
pid=$(cat "${lock_file}")
if [ -n "${pid}" ]; then
if kill -0 "${pid}" 2> /dev/null; then
# Kill the children
pkill -9 --parent "${pid}"
# Kill the parent
kill -9 "${pid}"
# Only one bkctld-rm can run in parallel, the latest wins
lockfile_date=$(date --date "@$(stat -c %Y ${lock_file})" +"%Y-%m-%d %H:%M:%S")
warning "Process \`${pid}' (started at ${lockfile_date}) has been killed by \`$$'"
else
warning "Process not found at PID \`${pid}'. Ignoring lock file \`${lock_file}'."
fi
else
warning "Empty lockfile \`${lock_file}'. It should contain a PID."
fi
# Remove the lock file
rm -f ${lock_file}
fi
}
incs_to_delete() {
jail_name=${1:?}
incs_policy_file=${2:?}
incs_policy_keep_file=$(new_tmp_file "${jail_name}.incs_policy_keep")
incs_list_file=$(new_tmp_file "${jail_name}.incs_list")
# loop for each line in jail configuration
for incs_policy_line in $(grep "^\+" ${incs_policy_file}); do
# inc date in ISO format
incs_policy_date=$(relative_date ${incs_policy_line})
echo ${incs_policy_date} >> "${incs_policy_keep_file}"
done
for inc_name in $(incs_list "${jail_name}"); do
echo "${inc_name}" >> ${incs_list_file}
done
# shellcheck disable=SC2046
incs_to_delete=$(grep -v -f "${incs_policy_keep_file}" "${incs_list_file}")
rm -f "${incs_policy_keep_file}" "${incs_list_file}"
echo ${incs_to_delete}
}
delete_inc_btrfs() {
jail_name=$1
inc_name=$2
inc_path=$(inc_path "${jail_name}" "${inc_name}")
btrfs_bin=$(command -v btrfs)
if [ -z "${btrfs_bin}" ]; then
error "btrfs not found. Please install btrfs-progs."
fi
if dry_run; then
echo "[dry-run] delete btrfs subvolume ${inc_path}"
else
${btrfs_bin} subvolume delete "${inc_path}" | debug
fi
}
delete_inc_ext4() {
jail_name=$1
inc_name=$2
inc_path=$(inc_path "${jail_name}" "${inc_name}")
if dry_run; then
echo "[dry-run] delete ${inc_path} with rsync from empty directory"
else
empty=$(new_tmp_dir "empty")
rsync --archive --delete "${empty}/" "${inc_path}/"
rmdir "${inc_path}/"
rmdir "${empty}"
fi
}
delete_empty_inc() {
jail_name=$1
incs_path=$(incs_path "${jail_name}")
empty_incs_list=$(find "${incs_path}" -mindepth 0 -maxdepth 0 -type d -empty)
for empty_inc in ${empty_incs_list}; do
if dry_run; then
echo "[dry-run] Delete empty \`${empty_inc}'"
else
rmdir "${empty_inc}"
notice "Delete empty \`${empty_inc}' : OK"
fi
done
}
lock_file="${LOCKDIR}/rm-global.lock"
# shellcheck disable=SC2064
trap "rm -f ${lock_file}; cleanup_tmp;" 0
kill_or_clean_lockfile "${lock_file}"
new_lock_file "${lock_file}"
# We list jails in "incs" directory, not in "jails" directory
# so we can clean old incs after a jail is archived
jails_list=$(jails_with_incs_list)
jails_total=$(echo $jails_list | wc -w)
jails_count=0
for jail_name in ${jails_list}; do
jails_count=$((jails_count+1))
incs_policy_file=$(current_jail_incs_policy_file ${jail_name})
# If no incs policy is found, we don't remove incs
if [ -n "${incs_policy_file}" ]; then
# shellcheck disable=SC2046
incs_to_delete=$(incs_to_delete "${jail_name}" "${incs_policy_file}")
incs_total=$(echo ${incs_to_delete} | wc -w)
incs_count=0
if [ -n "${incs_to_delete}" ]; then
debug "Incs to be deleted for \`${jail_name}' : $(echo "${incs_to_delete}" | tr '\n', ',' | sed 's/,$//')."
for inc_name in ${incs_to_delete}; do
incs_count=$((incs_count+1))
info "Progress: jail ${jails_count} out of ${jails_total} - inc ${incs_count} out of ${incs_total}"
notice "Delete inc \`${inc_name}' for jail \`${jail_name}' : start"
inc_path=$(inc_path "${jail_name}" "${inc_name}")
if is_btrfs "${inc_path}"; then
delete_inc_btrfs "${jail_name}" "${inc_name}"
else
delete_inc_ext4 "${jail_name}" "${inc_name}"
fi
notice "Delete inc \`${inc_name}' for jail \`${jail_name}' : finish"
done
else
notice "Skip jail \`${jail_name}' : no inc to delete"
fi
else
notice "Skip jail \`${jail_name}' : incs policy is missing"
fi
# Delete empty incs directory for jail
delete_empty_inc "${jail_name}"
done
# Remove the lock file and cleanup tmp files
rm -f "${lock_file}"
cleanup_tmp

43
server/lib/bkctld-start Executable file
View file

@ -0,0 +1,43 @@
#!/bin/sh
#
# Description: Start SSH Server
# Usage: start <jailname>|all
#
# shellcheck source=./includes
LIBDIR="$(dirname $0)" && . "${LIBDIR}/includes"
jail_name="${1:?}"
if [ -z "${jail_name}" ]; then
show_help && exit 1
fi
jail_path=$(jail_path "${jail_name}")
test -d "${jail_path}" || error "${jail_name}: jail not found" 2
"${LIBDIR}/bkctld-is-on" "${jail_name}" && exit 0
# Prepare the chroot
mount_jail_fs "${jail_name}"
# Start SSH in the chroot
chroot "${jail_path}" /usr/sbin/sshd -E /var/log/authlog || error "Failed to start SSH for jail \`${jail_name}'"
pidfile="${jail_path}/${SSHD_PID}"
# Wait for SSH to be up
# shellcheck disable=SC2034
for try in $(seq 1 10); do
if [ -f "${pidfile}" ]; then
pid=$(cat "${pidfile}")
break
else
pid=""
sleep 0.3
fi
done
if [ -n "${pid}" ]; then
notice "Start jail \`${jail_name}' : OK [${pid}]"
else
error "Failed to fetch SSH PID for jail \`${jail_name}' within 3 seconds"
fi

53
server/lib/bkctld-stats Executable file
View file

@ -0,0 +1,53 @@
#!/bin/sh
#
# Description: Display stats on jails (size, last connection…)
# Usage: stats
#
# shellcheck source=./includes
LIBDIR="$(dirname $0)" && . "${LIBDIR}/includes"
mkdir -p "${INDEX_DIR}"
lsof "${IDX_FILE}" >/dev/null 2>&1 || nohup sh -s -- <<EOF >/dev/null 2>&1 &
ionice -c3 "${DUC}" index -d "${IDX_FILE}" "${JAILDIR}"
touch "${INDEX_DIR}/.lastrun.duc"
EOF
[ ! -f "${INDEX_DIR}/.lastrun.duc" ] && notice "First run of DUC still in progress ..." && exit 0
[ ! -f ${IDX_FILE} ] && error "Index file doesn't exits !"
printf "Last update of index file : "
stat --format=%Y "${INDEX_DIR}/.lastrun.duc" | xargs -i -n1 date -R -d "@{}"
duc_output=$(mktemp)
stat_output=$(mktemp)
incs_output=$(mktemp)
jail_patterns_list=$(mktemp)
# shellcheck disable=SC2064
trap "rm ${duc_output} ${incs_output} ${stat_output} ${jail_patterns_list}" 0
"${DUC}" ls --database "${IDX_FILE}" "${JAILDIR}" > "${duc_output}"
jails_list | sed -e "s/^\(.*\)$/\\\\b\1\\\\b/" > "${jail_patterns_list}"
grep -f "${jail_patterns_list}" "${duc_output}" | awk '{ print $2 }' | while read jail_name; do
jail_path=$(jail_path "${jail_name}")
stat --format=%Y "${jail_path}/var/log/lastlog" | xargs -i -n1 date -d "@{}" "+%d-%m-%Y" >> "${stat_output}"
incs_policy_file=$(current_jail_incs_policy_file "${jail_name}")
incs_policy="0"
if [ -r "${incs_policy_file}" ]; then
days=$(grep "^\+" "${incs_policy_file}" | grep --count "day")
months=$(grep "^\+" "${incs_policy_file}" | grep --count "month")
incs_policy="${days}/${months}"
fi
echo "${incs_policy}" >> "${incs_output}"
done
(
echo "<jail> <size> <incs> <lastconn>"
paste "${duc_output}" "${incs_output}" "${stat_output}" | awk '{ printf("%s %s %s %s\n", $2, $1, $3, $4); }'
) | column -t

30
server/lib/bkctld-status Executable file
View file

@ -0,0 +1,30 @@
#!/bin/sh
#
# Description: Display status of SSH server
# Usage: [--no-header] status [<jailname>|all]
#
# shellcheck source=./includes
LIBDIR="$(dirname $0)" && . "${LIBDIR}/includes"
jail_name="${1:?}"
if [ ! -n "${jail_name}" ]; then
show_help && exit 1
fi
[ -d "${JAILDIR}/${jail_name}" ] || error "${jail_name} : jail is missing.\nUse '$0 status [all]' to get the status of all jails."
incs_policy_file=$(current_jail_incs_policy_file ${jail_name})
incs_policy="0"
if [ -r "${incs_policy_file}" ]; then
days=$(grep "^\+" "${incs_policy_file}" | grep --count "day")
months=$(grep "^\+" "${incs_policy_file}" | grep --count "month")
incs_policy="${days}/${months}"
fi
status="OFF"
"${LIBDIR}/bkctld-is-on" "${jail_name}" && status="ON "
port=$("${LIBDIR}/bkctld-port" "${jail_name}")
ip=$("${LIBDIR}/bkctld-ip" "${jail_name}" | xargs | tr -s ' ' ',')
echo "${jail_name} ${status} ${port} ${incs_policy} ${ip}" | awk '{ printf("%- 30s %- 10s %- 10s %- 25s %- 20s\n", $1, $2, $3, $4, $5); }'

31
server/lib/bkctld-stop Executable file
View file

@ -0,0 +1,31 @@
#!/bin/sh
#
# Description: Stop SSH server
# Usage: stop [<jailname>|all]
#
# shellcheck source=./includes
LIBDIR="$(dirname $0)" && . "${LIBDIR}/includes"
jail_name="${1:?}"
if [ -z "${jail_name}" ]; then
show_help && exit 1
fi
jail_path=$(jail_path "${jail_name}")
test -d "${jail_path}" || error "${jail_name}: jail not found" 2
"${LIBDIR}/bkctld-is-on" "${jail_name}" || exit 0
pid=$(cat "${jail_path}/${SSHD_PID}")
pkill --parent "${pid}"
if kill "${pid}"; then
notice "Stop jail \`${jail_name}' : OK [${pid}]"
umount --lazy --recursive "${jail_path}/dev"
umount --lazy "${jail_path}/proc/"
else
error "Stop jail \`${jail_name}' : failed [${pid}]"
fi

67
server/lib/bkctld-sync Executable file
View file

@ -0,0 +1,67 @@
#!/bin/sh
#
# Description: Sync jail configuration and state on other node(s)
# Usage: sync [<jailname>|all]
#
# shellcheck source=./includes
LIBDIR="$(dirname $0)" && . "${LIBDIR}/includes"
jail_name="${1:?}"
if [ -z "${jail_name}" ]; then
show_help && exit 1
fi
jail_path=$(jail_path "${jail_name}")
jail_config_dir=$(jail_config_dir "${jail_name}")
test -d "${jail_path}" || error "${jail_name}: jail not found" 2
[ -n "${NODE}" ] || error "Sync need config of \$NODE in /etc/default/bkctld !"
ssh "${NODE}" "${LIBDIR}/bkctld-is-on ${jail_name} 2>/dev/null"
# return code 2 is for "missing jail" error
if [ "$?" -eq 2 ]; then
# Init jail on remote server
ssh "${NODE}" "${LIBDIR}/bkctld-init ${jail_name}" | debug
fi
# Sync jail structure and configuration on remote server
rsync -a "${jail_path}/" "${NODE}:${jail_path}/" --exclude proc/* --exclude sys/* --exclude dev/* --exclude run --exclude var/backup/*
# Sync config (new structure)
if [ -d "${jail_config_dir}" ]; then
rsync -a --delete "${jail_config_dir}/" "${NODE}:${jail_config_dir}/"
else
ssh "${NODE}" "rm -rf ${jail_config_dir}" | debug
fi
# Sync config (legacy structure)
if [ -e "${CONFDIR}/${jail_name}" ]; then
rsync -a "${CONFDIR}/${jail_name}" "${NODE}:${CONFDIR}/${jail_name}"
else
ssh "${NODE}" "rm -f ${CONFDIR}/${jail_name}" | debug
fi
if [ -n "${FIREWALL_RULES}" ]; then
ssh "${NODE}" "${LIBDIR}/bkctld-firewall ${jail_name}" | debug
ssh "${NODE}" "test -x /etc/init.d/minifirewall && /etc/init.d/minifirewall restart" | debug
fi
# Sync state on remote server
if "${LIBDIR}/bkctld-is-on" "${jail_name}"; then
# fetch state of remote jail
ssh "${NODE}" "${LIBDIR}/bkctld-is-on ${jail_name} 2>/dev/null"
case "$?" in
0)
# jail is already running : reload it
ssh "${NODE}" "${LIBDIR}/bkctld-reload ${jail_name}" | debug
;;
100)
# jail is stopped : start it
ssh "${NODE}" "${LIBDIR}/bkctld-start ${jail_name}" | debug
;;
*)
error "Error evaluating jail \`${jail_name}' state. bkctld-is-on exited with \`$?'"
;;
esac
else
ssh "${NODE}" "${LIBDIR}/bkctld-stop ${jail_name}" | debug
fi

38
server/lib/bkctld-update Executable file
View file

@ -0,0 +1,38 @@
#!/bin/sh
#
# Description: Update binaries and libraries
# Usage: update [<jailname>|all]
#
# shellcheck source=./includes
LIBDIR="$(dirname $0)" && . "${LIBDIR}/includes"
jail_name="${1:?}"
if [ ! -n "${jail_name}" ]; then
show_help && exit 1
fi
jail_path=$(jail_path "${jail_name}")
test -d "${jail_path}" || error "${jail_name}: jail not found" 2
"${LIBDIR}/bkctld-is-on" "${jail_name}" 2>/dev/null
case "$?" in
0)
jail_initial_status="on"
;;
100)
jail_initial_status="off"
;;
*)
unset jail_initial_status
error "Error evaluating jail \`${jail_name}' state. bkctld-is-on exited with \`$?'"
;;
esac
test "${jail_initial_status}" = "on" && "${LIBDIR}/bkctld-stop" "${jail_name}"
setup_jail_chroot "${jail_name}"
test "${jail_initial_status}" = "on" && "${LIBDIR}/bkctld-start" "${jail_name}"
notice "Update jail \`${jail_name}' : OK"

View file

@ -0,0 +1,68 @@
#!/bin/sh
#
# Description: Upgrade configuration to new convention
# Usage: upgrade-config [<jailname>|all]
#
# shellcheck source=./includes
LIBDIR="$(dirname $0)" && . "${LIBDIR}/includes"
jail_name="${1:?}"
if [ ! -n "${jail_name}" ]; then
show_help && exit 1
fi
jail_path=$(jail_path "${jail_name}")
test -d "${jail_path}" || error "${jail_name}: jail not found" 2
legacy_incs_policy_file="${CONFDIR}/${jail_name}"
incs_policy_file=$(jail_incs_policy_file "${jail_name}")
if [ -h "${legacy_incs_policy_file}" ]; then
if [ -f "${incs_policy_file}" ]; then
info "${jail_name}: config is already upgraded"
else
warning "${jail_name}: symlink present but inc policy file \`${incs_policy_file}' not found"
fi
elif [ ! -e "${legacy_incs_policy_file}" ] ; then
if [ -f "${incs_policy_file}" ]; then
# create a symlink for backward compatibility
ln -s "${incs_policy_file}" "${legacy_incs_policy_file}"
info "${jail_name}: config has been symlinked"
else
warning "${jail_name}: inc policy file \`${incs_policy_file}' not found"
fi
elif [ -f "${legacy_incs_policy_file}" ]; then
# Create directory if missing
mkdir -p "$(jail_config_dir "${jail_name}")"
# move the main config file
mv "${legacy_incs_policy_file}" "${incs_policy_file}"
# create a symlink for backward compatibility
ln -s "${incs_policy_file}" "${legacy_incs_policy_file}"
# create a check_policy file if missing
touch "$(jail_check_policy_file "${jail_name}")"
info "${jail_name}: config has been upgraded"
fi
check_policy_file=$(jail_check_policy_file "${jail_name}")
if [ ! -f "${check_policy_file}" ]; then
check_policy_tpl="${TPLDIR}/check_policy.tpl"
test -f "${LOCALTPLDIR}/check_policy.tpl" && check_policy_tpl="${LOCALTPLDIR}/check_policy.tpl"
mkdir --parents "$(dirname "${check_policy_file}")"
install -m 0640 "${check_policy_tpl}" "${check_policy_file}"
info "${jail_name}: check_policy template ha been installed"
fi
legacy_incs_policy_tpl="${LOCALTPLDIR}/inc.tpl"
incs_policy_tpl="${LOCALTPLDIR}/incs_policy.tpl"
if [ -f "${legacy_incs_policy_tpl}" ]; then
# Create directory if missing
mkdir -p "$(jail_config_dir "${jail_name}")"
# move the main config file
mv -f "${legacy_incs_policy_tpl}" "${incs_policy_tpl}"
info "${jail_name}: incs_policy local template has been renamed"
fi

467
server/lib/includes Executable file
View file

@ -0,0 +1,467 @@
#!/bin/sh
#
# Config for bkctld
#
# shellcheck disable=SC2034
[ -f /etc/default/bkctld ] && . /etc/default/bkctld
VERSION="22.11"
LIBDIR=${LIBDIR:-/usr/lib/bkctld}
CONFDIR="${CONFDIR:-/etc/evobackup}"
BACKUP_DISK="${BACKUP_DISK:-}"
BACKUP_PARTITION="${BACKUP_PARTITION:-/backup}"
JAILDIR="${JAILDIR:-${BACKUP_PARTITION}/jails}"
INCDIR="${INCDIR:-${BACKUP_PARTITION}/incs}"
TPLDIR="${TPLDIR:-/usr/share/bkctld}"
LOCALTPLDIR="${LOCALTPLDIR:-/usr/local/share/bkctld}"
LOCKDIR="${LOCKDIR:-/run/lock/bkctld}"
ARCHIVESDIR="${ARCHIVESDIR:-${BACKUP_PARTITION}/archives}"
INDEX_DIR="${INDEX_DIR:-${BACKUP_PARTITION}/index}"
IDX_FILE="${IDX_FILE:-${INDEX_DIR}/bkctld-jails.idx}"
CANARY_RELATIVE_FILE="${CANARY_RELATIVE_FILE:-/zzz_evobackup_canary}"
SSHD_PID="${SSHD_PID:-/run/sshd.pid}"
SSHD_CONFIG="${SSHD_CONFIG:-/etc/ssh/sshd_config}"
AUTHORIZED_KEYS="${AUTHORIZED_KEYS:-/root/.ssh/authorized_keys}"
FIREWALL_RULES="${FIREWALL_RULES:-}"
LOGLEVEL="${LOGLEVEL:-6}"
CRITICAL="${CRITICAL:-48}"
WARNING="${WARNING:-24}"
DUC=$(command -v duc-nox || command -v duc)
FORCE="${FORCE:-0}"
HEADER="${HEADER:-1}"
show_version() {
cat <<END
bkctld version ${VERSION}
Copyright 2004-2022 Evolix <info@evolix.fr>,
Victor Laborie <vlaborie@evolix.fr>,
Jérémy Lecour <jlecour@evolix.fr>
and others.
bkctld comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to redistribute it under certain conditions.
See the GNU Affero General Public License v3.0 for details.
END
}
show_help() {
cat <<EOF
Usage: bkctld [options] <subcommand> [arguments]
Options
-h|--help|-? Display help
-V|--version Display version, authors and license
Subcommands:
EOF
for filename in ${LIBDIR}/bkctld-*; do
desc=$(grep -E "^# Description:" "${filename}"|sed "s/^# Description: //")
usage=$(grep -E "^# Usage:" "${filename}"|sed "s/^# Usage: //")
printf " %- 32s %s\n" "${usage}" "${desc}"
done
printf "\n"
}
is_quiet() {
test ${QUIET} -eq 1
}
is_verbose() {
test ${VERBOSE} -eq 1
}
log_date() {
echo "[$(date +"%Y-%m-%d %H:%M:%S")]"
}
process_name() {
basename $0
}
debug() {
msg="${1:-$(cat /dev/stdin)}"
if [ "${LOGLEVEL}" -ge 7 ]; then
echo "${msg}"
logger -t bkctld -p daemon.debug "$(process_name) ${msg}"
fi
}
info() {
msg="${1:-$(cat /dev/stdin)}"
if [ "${LOGLEVEL}" -ge 6 ]; then
tty -s && echo "${msg}"
logger -t bkctld -p daemon.info "$(process_name) ${msg}"
fi
}
notice() {
msg="${1:-$(cat /dev/stdin)}"
tty -s && echo "${msg}"
[ "${LOGLEVEL}" -ge 5 ] && logger -t bkctld -p daemon.notice "$(process_name) ${msg}"
}
warning() {
msg="${1:-$(cat /dev/stdin)}"
tty -s && echo "${msg}" >&2
if [ "${LOGLEVEL}" -ge 4 ]; then
tty -s || echo "${msg}" >&2
logger -t bkctld -p daemon.warning "$(process_name) ${msg}"
fi
}
# Return codes
# 1 : generic error
# 2 : jail not found
# > 100 : subcommands specific errors
error() {
msg="${1:-$(cat /dev/stdin)}"
rc="${2:-1}"
tty -s && echo "${msg}" >&2
if [ "${LOGLEVEL}" -ge 5 ]; then
tty -s || echo "${msg}" >&2
logger -t bkctld -p daemon.error "$(process_name) ${msg}"
fi
exit ${rc}
}
dry_run() {
test "$DRY_RUN" = "1"
}
current_time() {
date +"%H:%M:%S"
}
# Returns true if the given path is on a btrfs filesystem
is_btrfs() {
path=$1
inode=$(stat --format=%i "${path}")
test "$inode" -eq 256
}
# Returns the list of jails found in the "jails" directory (default)
jails_list() {
# TODO: try if this command works the same :
# find "${JAILDIR}" -mindepth 1 -maxdepth 1 -type d -printf '%f\n'
find "${JAILDIR}" -mindepth 1 -maxdepth 1 -type d | sed 's!.*/!!' | sort -h
}
# Returns the list of jails found in the "incs" directory
jails_with_incs_list() {
find "${INCDIR}" -mindepth 1 -maxdepth 1 -type d | sed 's!.*/!!' | sort -h
}
# Returns the complete path of a jail
jail_path() {
jail_name=${1:?}
echo "${JAILDIR}/${jail_name}"
}
jail_config_dir() {
jail_name=${1:?}
echo "${CONFDIR}/${jail_name}.d"
}
jail_incs_policy_file() {
jail_name=${1:?}
jail_config_dir=$(jail_config_dir "${jail_name}")
echo "${jail_config_dir}/incs_policy"
}
# Returns the complete path of an archived jail
archive_path() {
jail_name=${1:?}
echo "${ARCHIVESDIR}/${jail_name}"
}
# Returns the path of incs for a jail
incs_path() {
jail_name=${1:?}
echo "${INCDIR}/${jail_name}"
}
# Returns the path of a specific inc for a jail
inc_path() {
jail_name=${1:?}
inc_name=${2:?}
echo "${INCDIR}/${jail_name}/${inc_name}"
}
# Test the existence of an inc pattern for a jail
inc_exists() {
jail_name=${1-?}
inc_pattern=${2-?}
inc_path=$(inc_path "${jail_name}" "${inc_pattern}")
# inc_path must not be quoted because it can contain globs
ls -d ${inc_path} > /dev/null 2>&1
}
# Returns the list of all incs for a jail
incs_list() {
jail_name=${1:?}
find "$(incs_path "${jail_name}")" -mindepth 1 -maxdepth 1 -type d | sed 's!.*/!!' | sort -h
}
# Return the list of empty incs directories
empty_incs_list() {
find ${INCDIR} -mindepth 1 -maxdepth 1 -type d -empty
}
current_jail_incs_policy_file() {
jail_name=${1:?}
new_file="$(jail_incs_policy_file "${jail_name}")"
old_file="${CONFDIR}/${jail_name}"
if [ -f "${new_file}" ]; then
echo "${new_file}"
elif [ -f "${old_file}" ]; then
echo "${old_file}"
else
echo ""
fi
}
jail_check_policy_file() {
jail_name=${1:?}
jail_config_dir=$(jail_config_dir "${jail_name}")
echo "${jail_config_dir}/check_policy"
}
current_jail_check_policy_file() {
jail_name=${1:?}
new_file="$(jail_check_policy_file "${jail_name}")"
# old_file="${JAILDIR}/${jail_name}/etc/bkctld-check"
if [ -f "${new_file}" ]; then
echo "${new_file}"
# elif [ -f "${old_file}" ]; then
# echo "${old_file}"
else
echo ""
fi
}
# relative_date "+%Y-%m-%d.-2day"
relative_date() {
format=$(echo $1 | cut -d'.' -f1)
time_jump=$(echo $1 | cut -d'.' -f2)
reference_date=$(date "${format}")
past_date=$(date --date "${reference_date} ${time_jump}" +"%Y-%m-%d")
echo ${past_date}
}
new_tmp_file() {
name=${1:-}
mktemp --tmpdir=/tmp "bkctld.${$}.${name}.XXXXX"
}
new_tmp_dir() {
name=${1:-}
mktemp --directory --tmpdir=/tmp "bkctld.${$}.${name}.XXXXX"
}
cleanup_tmp() {
find /tmp -name "bkctld.${$}.*" -delete
}
new_lock_file() {
lock_file=${1:-}
lock_dir=$(dirname "${lock_file}")
mkdir --parents "${lock_dir}" && echo $$ > ${lock_file} || error "Failed to acquire lock file '${lock_file}'"
}
pkg_version() {
# $(command -v ssh) -V 2>&1 | grep -iEo 'OpenSSH_(\S+)' | cut -d '_' -f2
dpkg-query -W -f='${Version}\n' $1 \
| sed 's/[~+-].\+//' \
| sed 's/.\+://' \
| sed 's/p.*//' \
| cut -d. -f1,2
}
ssh_keygen_with_prefix() {
# openssh-client 7.9 provides ssh-keygen with "-f prefix_path" option
dpkg --compare-versions "$(pkg_version 'openssh-client')" ge "7.9"
}
setup_jail_chroot() {
jail_name=${1:?}
jail_path=$(jail_path "${jail_name}")
passwd="${TPLDIR}/passwd"
shadow="${TPLDIR}/shadow"
group="${TPLDIR}/group"
sshrc="${TPLDIR}/sshrc"
[ -f "${LOCALTPLDIR}/passwd" ] && passwd="${LOCALTPLDIR}/passwd"
[ -f "${LOCALTPLDIR}/shadow" ] && shadow="${LOCALTPLDIR}/shadow"
[ -f "${LOCALTPLDIR}/group" ] && group="${LOCALTPLDIR}/group"
[ -f "${LOCALTPLDIR}/sshrc" ] && group="${LOCALTPLDIR}/sshrc"
cd "${jail_path}" || error "${jail_name}: failed to change directory to ${jail_path}."
umask 077
info "1 - Creating the chroot"
rm -rf ./bin
rm -rf ./lib
rm -rf ./lib64
rm -rf ./run
rm -rf ./usr
rm -rf ./var/run
# Let's not delete the existing SSH host keys,
# otherwise the clients will have to accept the new keys
mkdir -p ./dev
mkdir -p ./proc
mkdir -p ./usr/bin
mkdir -p ./usr/sbin
mkdir -p ./usr/lib
mkdir -p ./usr/lib/x86_64-linux-gnu
mkdir -p ./usr/lib/openssh
mkdir -p ./usr/lib64
mkdir -p ./etc/ssh
mkdir -p ./var/log
mkdir -p ./run/sshd
# shellcheck disable=SC2174
mkdir -p ./root/.ssh --mode 0700
# shellcheck disable=SC2174
mkdir -p ./var/backup --mode 0700
ln -s ./usr/bin ./bin
ln -s ./usr/lib ./lib
ln -s ./usr/lib64 ./lib64
ln -s --target-directory=./var ../run
touch ./var/log/lastlog ./var/log/wtmp ./run/utmp
info "2 - Copying essential files"
#
if ssh_keygen_with_prefix; then
# Generate SSH host keys if missing in jail
ssh-keygen -A -f "${jail_path}"
else
# Copy SSH host keys from host if missing in jail
for key in /etc/ssh/*_key; do
cp --no-clobber ${key} ${jail_path}${key};
done
fi
touch "./${AUTHORIZED_KEYS}"
chmod 600 "./${AUTHORIZED_KEYS}"
cp "${passwd}" ./etc
cp "${shadow}" ./etc
cp "${group}" ./etc
cp "${sshrc}" ./etc/ssh
info "3 - Copying binaries"
cp -f /lib/ld-linux.so.2 ./lib 2>/dev/null || cp -f /lib64/ld-linux-x86-64.so.2 ./lib64
cp /lib/x86_64-linux-gnu/libnss* ./lib/x86_64-linux-gnu
for dbin in \
/bin/sh \
/bin/ls \
/bin/mkdir \
/bin/cat \
/bin/rm \
/bin/sed \
/usr/bin/rsync \
/usr/bin/lastlog \
/usr/bin/touch \
/usr/sbin/sshd \
/usr/lib/openssh/sftp-server\
; do
cp -f "${dbin}" "./${dbin}";
for lib in $(ldd "${dbin}" | grep -Eo "/.*so.[0-9\.]+"); do
cp -p "${lib}" "./${lib}"
done
done
}
setup_jail_config() {
jail_name=${1:?}
jail_path=$(jail_path "${jail_name}")
jail_sshd_config="${jail_path}/${SSHD_CONFIG}"
sshd_config_tpl="${TPLDIR}/sshd_config"
test -f "${LOCALTPLDIR}/sshd_config" && sshd_config_tpl="${LOCALTPLDIR}/sshd_config"
info "4 - Copie default sshd_config"
install -m 0640 "${sshd_config_tpl}" "${jail_sshd_config}"
info "5 - Copie default inc configuration"
incs_policy_tpl="${TPLDIR}/incs_policy.tpl"
test -f "${LOCALTPLDIR}/incs_policy.tpl" && incs_policy_tpl="${LOCALTPLDIR}/incs_policy.tpl"
jail_incs_policy_file=$(jail_incs_policy_file "${jail_name}")
mkdir --parents "$(dirname "${jail_incs_policy_file}")"
install -m 0640 "${incs_policy_tpl}" "${jail_incs_policy_file}"
check_policy_tpl="${TPLDIR}/check_policy.tpl"
test -f "${LOCALTPLDIR}/check_policy.tpl" && check_policy_tpl="${LOCALTPLDIR}/check_policy.tpl"
jail_check_policy_file=$(jail_check_policy_file "${jail_name}")
mkdir --parents "$(dirname "${jail_check_policy_file}")"
install -m 0640 "${check_policy_tpl}" "${jail_check_policy_file}"
"${LIBDIR}/bkctld-port" "${jail_name}" auto
}
is_mounted_inside_jail() {
target=${1:?}
# TODO: try to find why it doesn't work with this findmnt(8) command
# findmnt --target "${target}" --tab-file /proc/mounts
grep -q "${target}" /proc/mounts
}
mount_jail_fs() {
jail_name=${1:?}
jail_path=$(jail_path "${jail_name}")
is_mounted_inside_jail "${jail_path}/dev" || mount -nt tmpfs "dev-${jail_name}" "${jail_path}/dev"
[ -e "dev/console" ] || mknod -m 622 "${jail_path}/dev/console" c 5 1
chown root:tty "${jail_path}/dev/console"
[ -e "dev/null" ] || mknod -m 666 "${jail_path}/dev/null" c 1 3
[ -e "dev/zero" ] || mknod -m 666 "${jail_path}/dev/zero" c 1 5
[ -e "dev/ptmx" ] || mknod -m 666 "${jail_path}/dev/ptmx" c 5 2
chown root:tty "${jail_path}/dev/ptmx"
[ -e "dev/tty" ] || mknod -m 666 "${jail_path}/dev/tty" c 5 0
chown root:tty "${jail_path}/dev/tty"
[ -e "dev/random" ] || mknod -m 444 "${jail_path}/dev/random" c 1 8
[ -e "dev/urandom" ] || mknod -m 444 "${jail_path}/dev/urandom" c 1 9
mkdir -p "${jail_path}/dev/pts"
is_mounted_inside_jail "${jail_path}/dev/pts" || mount -t devpts -o gid=4,mode=620 none "${jail_path}/dev/pts"
mkdir -p "${jail_path}/dev/shm"
is_mounted_inside_jail "${jail_path}/dev/shm" || mount -t tmpfs none "${jail_path}/dev/shm"
is_mounted_inside_jail "${jail_path}/proc" || mount -t proc "proc-${jail_name}" "${jail_path}/proc"
ln -fs "${jail_path}/proc/self/fd" "${jail_path}/dev/fd"
ln -fs "${jail_path}/proc/self/fd/0" "${jail_path}/dev/stdin"
ln -fs "${jail_path}/proc/self/fd/1" "${jail_path}/dev/stdout"
ln -fs "${jail_path}/proc/self/fd/2" "${jail_path}/dev/stderr"
ln -fs "${jail_path}/proc/kcore" "${jail_path}/dev/core"
}
read_variable() {
file=${1:?}
var_name=${2:?}
pattern="^\s*${var_name}=.+"
grep --extended-regexp --only-matching "${pattern}" "${file}" | tail -1 | cut -d= -f2
}
read_numerical_variable() {
file=${1:?}
var_name=${2:?}
pattern="^\s*${var_name}=-?[0-9]+"
grep --extended-regexp --only-matching "${pattern}" "${file}" | tail -1 | cut -d= -f2
}

276
server/test/checks.bats Normal file
View file

@ -0,0 +1,276 @@
#!/usr/bin/env bats
# shellcheck disable=SC1089,SC1083,SC2154
load test_helper
@test "Check jails OK" {
run /usr/lib/bkctld/bkctld-check-jails
assert_equal "0" "$status"
}
@test "Check jails OK for default values" {
touch "${JAILPATH}/var/log/lastlog"
# With default values (2 days critical, 1 day warning),
# a freshly connected jail should be "ok"
run /usr/lib/bkctld/bkctld-check-jails
assert_equal "0" "$status"
}
@test "Check jails WARNING for default values" {
lastlog_date=$(date -d -2days --iso-8601=seconds)
touch --date="${lastlog_date}" "${JAILPATH}/var/log/lastlog"
# With default values (2 days critical, 1 day warning),
# a 2 days old jail should be "warning"
run /usr/lib/bkctld/bkctld-check-jails
assert_equal "1" "$status"
}
@test "Check jails CRITICAL for default values" {
lastlog_date=$(date -d -3days --iso-8601=seconds)
touch --date="${lastlog_date}" "${JAILPATH}/var/log/lastlog"
# With default values (2 days critical, 1 day warning),
# a 3 days old jail should be "critical"
run /usr/lib/bkctld/bkctld-check-jails
assert_equal "2" "$status"
}
@test "Check jails OK for custom values" {
lastlog_date=$(date -d -3days --iso-8601=seconds)
touch --date="${lastlog_date}" "${JAILPATH}/var/log/lastlog"
cat > "/etc/evobackup/${JAILNAME}.d/check_policy" <<OUT
CRITICAL=120
WARNING=96
OUT
# With custom values (5 days critical, 4 days warning),
# a 3 days old jail should be "ok"
run /usr/lib/bkctld/bkctld-check-jails
assert_equal "0" "$status"
}
@test "Check jails WARNING for custom values" {
lastlog_date=$(date -d -3days --iso-8601=seconds)
touch --date="${lastlog_date}" "${JAILPATH}/var/log/lastlog"
cat > "/etc/evobackup/${JAILNAME}.d/check_policy" <<OUT
CRITICAL=96
WARNING=48
OUT
# With custom values (4 days critical, 3 days warning),
# a 3 days old jail should be "warning"
run /usr/lib/bkctld/bkctld-check-jails
assert_equal "1" "$status"
}
@test "Check jails CRITICAL for custom values" {
lastlog_date=$(date -d -10days --iso-8601=seconds)
touch --date="${lastlog_date}" "${JAILPATH}/var/log/lastlog"
cat > "/etc/evobackup/${JAILNAME}.d/check_policy" <<OUT
CRITICAL=96
WARNING=48
OUT
# With custom values (4 days critical, 3 days warning),
# a 10 days old jail should be "critical"
run /usr/lib/bkctld/bkctld-check-jails
assert_equal "2" "$status"
}
@test "Check jails OK for disabled WARNING" {
lastlog_date=$(date -d -2days --iso-8601=seconds)
touch --date="${lastlog_date}" "${JAILPATH}/var/log/lastlog"
cat > "/etc/evobackup/${JAILNAME}.d/check_policy" <<OUT
WARNING=0
OUT
# With custom values (warning disabled, default critical),
# a 2 days old jail should still be "ok"
run /usr/lib/bkctld/bkctld-check-jails
assert_equal "0" "$status"
}
@test "Check jails WARNING for disabled CRITICAL" {
lastlog_date=$(date -d -3days --iso-8601=seconds)
touch --date="${lastlog_date}" "${JAILPATH}/var/log/lastlog"
cat > "/etc/evobackup/${JAILNAME}.d/check_policy" <<OUT
CRITICAL=0
OUT
# With custom values (critical disabled, default warning),
# a 3 days old jail should only be "warning"
run /usr/lib/bkctld/bkctld-check-jails
assert_equal "1" "$status"
}
@test "Custom jails values are parsed with only integers after equal" {
lastlog_date=$(date -d -3days --iso-8601=seconds)
touch --date="${lastlog_date}" "${JAILPATH}/var/log/lastlog"
cat > "/etc/evobackup/${JAILNAME}.d/check_policy" <<OUT
CRITICAL=0 # foo
OUT
# With custom values (critical disabled, default warning),
# a 3 days old jail should only be "warning"
run /usr/lib/bkctld/bkctld-check-jails
assert_equal "1" "$status"
}
@test "Commented custom values are ignored" {
lastlog_date=$(date -d -3days --iso-8601=seconds)
touch --date="${lastlog_date}" "${JAILPATH}/var/log/lastlog"
cat > "/etc/evobackup/${JAILNAME}.d/check_policy" <<OUT
# CRITICAL=0
OUT
# With commented custom values (critical disabled),
# a 3 days old jail should still be "critical"
run /usr/lib/bkctld/bkctld-check-jails
assert_equal "2" "$status"
}
@test "Invalid custom values are ignored" {
lastlog_date=$(date -d -3days --iso-8601=seconds)
touch --date="${lastlog_date}" "${JAILPATH}/var/log/lastlog"
cat > "/etc/evobackup/${JAILNAME}.d/check_policy" <<OUT
CRITICAL=foo
OUT
# With commented custom values (critical disabled),
# a 3 days old jail should still be "critical"
run /usr/lib/bkctld/bkctld-check-jails
assert_equal "2" "$status"
}
@test "Check setup WARNING if firewall rules are not sourced" {
/usr/lib/bkctld/bkctld-start ${JAILNAME}
mkdir --parents /etc/minifirewall.d/
firewall_rules_file="/etc/minifirewall.d/bkctld"
set_variable "/etc/default/bkctld" "FIREWALL_RULES" "${firewall_rules_file}"
echo "" > "${firewall_rules_file}"
# Without sourcing
echo "" > "/etc/default/minifirewall"
# … the check should be "warning"
run /usr/lib/bkctld/bkctld-check-setup
assert_equal "1" "$status"
}
@test "Check setup OK if firewall rules are sourced" {
/usr/lib/bkctld/bkctld-start ${JAILNAME}
mkdir --parents /etc/minifirewall.d/
firewall_rules_file="/etc/minifirewall.d/bkctld"
set_variable "/etc/default/bkctld" "FIREWALL_RULES" "${firewall_rules_file}"
echo "" > "${firewall_rules_file}"
# Sourcing file with '.'
echo ". ${firewall_rules_file}" > "/etc/default/minifirewall"
# … the check should be "ok"
run /usr/lib/bkctld/bkctld-check-setup
assert_equal "0" "$status"
# Sourcing file with 'source'
echo "source ${firewall_rules_file}" > "/etc/default/minifirewall"
# … the check should be "ok"
run /usr/lib/bkctld/bkctld-check-setup
assert_equal "0" "$status"
}
@test "Check setup CRITICAL if jail is stopped" {
run /usr/lib/bkctld/bkctld-check-setup
assert_equal "2" "$status"
}
@test "Check setup OK if all jails are started" {
/usr/lib/bkctld/bkctld-start ${JAILNAME}
run /usr/lib/bkctld/bkctld-check-setup
assert_equal "0" "$status"
}
@test "Check setup OK if jail is supposed to be stopped" {
cat > "/etc/evobackup/${JAILNAME}.d/check_policy" <<OUT
EXPECTED_STATE=OFF
OUT
run /usr/lib/bkctld/bkctld-check-setup
assert_equal "0" "$status"
}
@test "Check setup CRITICAL if backup partition is not mounted" {
umount --force /backup
run /usr/lib/bkctld/bkctld-check-setup
mount /dev/vdb /backup
assert_equal "2" "$status"
}
@test "Check setup CRITICAL if backup partition is read-only" {
mount -o remount,ro /backup
run /usr/lib/bkctld/bkctld-check-setup
mount -o remount,rw /backup
assert_equal "2" "$status"
}
@test "Check-last-incs OK if jail is present" {
/usr/lib/bkctld/bkctld-inc
run /usr/lib/bkctld/bkctld-check-last-incs
assert_equal "0" "$status"
}
@test "Check-last-incs Error if jail is missing" {
run /usr/lib/bkctld/bkctld-check-last-incs
assert_equal "1" "$status"
}
@test "Check-incs OK" {
/usr/lib/bkctld/bkctld-inc
run /usr/lib/bkctld/bkctld-check-incs
assert_equal "0" "$status"
}
@test "Check-incs doesn't fail without incs_policy file" {
# Delete all possible incs polixy files
rm -f /etc/evobackup/${JAILNAME}
rm -rf /etc/evobackup/${JAILNAME}.d/incs_policy
# Run bkctld-check-incs and store stderr in a file
local stderrPath="${BATS_TMPDIR}/${BATS_TEST_NAME}.stderr"
/usr/lib/bkctld/bkctld-check-incs 2> ${stderrPath}
# Verify if
run grep -E "^stat:" ${stderrPath}
assert_failure
}
# TODO: write many more tests for bkctld-check-incs
@test "Check-canary fails if a canary file doesn't exist" {
run /usr/lib/bkctld/bkctld-check-canary "${JAILNAME}"
assert_equal "$status" "2"
assert_line "CRITICAL - ${JAILNAME} - missing /zzz_evobackup_canary file"
}
@test "Check-canary fails if a canary is missing today's entries" {
today="$(date +%Y-%m-%d)"
touch "${JAILPATH}/var/backup/zzz_evobackup_canary"
run /usr/lib/bkctld/bkctld-check-canary "${JAILNAME}"
assert_equal "$status" "2"
assert_line "CRITICAL - ${JAILNAME} - No entry for ${today} in /zzz_evobackup_canary file"
}
@test "Check-canary succeeds if a canary has today's entries" {
echo "$(date "+%FT%T%z") bats-test" >> "${JAILPATH}/var/backup/zzz_evobackup_canary"
run /usr/lib/bkctld/bkctld-check-canary "${JAILNAME}"
assert_success
}

View file

@ -0,0 +1,101 @@
#!/usr/bin/env bats
# shellcheck disable=SC1089,SC1083,SC2154
load test_helper
@test "Without SSH key" {
run cat "${JAILPATH}/root/.ssh/authorized_keys"
assert_equal "$output" ""
}
@test "With SSH key" {
keyfile=/root/bkctld.key.pub
/usr/lib/bkctld/bkctld-key "${JAILNAME}" "${keyfile}"
# The key should be present in the SSH authorized_keys file
run cat "${JAILPATH}/root/.ssh/authorized_keys"
assert_equal "$output" "$(cat ${keyfile})"
}
@test "Custom port" {
/usr/lib/bkctld/bkctld-start "${JAILNAME}"
/usr/lib/bkctld/bkctld-port "${JAILNAME}" "${PORT}"
# A jail should be accessible on the specified SSH port
run nc -vz 127.0.0.1 "${PORT}"
assert_success
}
@test "No IP restriction" {
# A jail has no IP restriction by default in SSH config
run grep "root@0.0.0.0/0" "${JAILPATH}/etc/ssh/sshd_config"
assert_success
}
@test "Single IP restriction" {
# When an IP is added for a jail
/usr/lib/bkctld/bkctld-ip "${JAILNAME}" "10.0.0.1"
# An IP restriction should be present in SSH config
run grep "root@10.0.0.1" "${JAILPATH}/etc/ssh/sshd_config"
assert_success
}
@test "Multiple IP restrictions" {
# When multiple IP are added for a jail
/usr/lib/bkctld/bkctld-ip "${JAILNAME}" "10.0.0.1"
/usr/lib/bkctld/bkctld-ip "${JAILNAME}" "10.0.0.2"
# The corresponding IP restrictions should be present in SSH config
run grep -E -o "root@10.0.0.[0-9]+" "${JAILPATH}/etc/ssh/sshd_config"
assert_line "root@10.0.0.1"
assert_line "root@10.0.0.2"
}
@test "Removing IP restriction" {
# Add an IP
/usr/lib/bkctld/bkctld-ip "${JAILNAME}" "10.0.0.1"
# Remove IP
/usr/lib/bkctld/bkctld-ip "${JAILNAME}" "0.0.0.0/0"
# All IP restrictions should be removed from SSH config
run grep "root@0.0.0.0/0" "${JAILPATH}/etc/ssh/sshd_config"
assert_success
}
@test "Missing AllowUsers" {
# Remove AllowUsers directive in SSH config
sed --follow-symlinks --in-place '/^AllowUsers/d' "${JAILPATH}/etc/ssh/sshd_config"
# An error should be raised when trying to add an IP restriction
run /usr/lib/bkctld/bkctld-ip "${JAILNAME}" "10.0.0.1"
assert_failure
}
@test "SSH connectivity" {
/usr/lib/bkctld/bkctld-start "${JAILNAME}"
/usr/lib/bkctld/bkctld-port "${JAILNAME}" "${PORT}"
/usr/lib/bkctld/bkctld-key "${JAILNAME}" /root/bkctld.key.pub
ssh_options="-p ${PORT} -i /root/bkctld.key -oStrictHostKeyChecking=no"
# A started jail should be accessible via SSH
run ssh ${ssh_options} root@127.0.0.1 ls
assert_success
/usr/lib/bkctld/bkctld-stop "${JAILNAME}"
# A stopped jail should not be accessible via SSH
run ssh ${ssh_options} root@127.0.0.1 ls
assert_failure
}
@test "Rsync connectivity" {
/usr/lib/bkctld/bkctld-start "${JAILNAME}"
/usr/lib/bkctld/bkctld-port "${JAILNAME}" "${PORT}"
/usr/lib/bkctld/bkctld-key "${JAILNAME}" /root/bkctld.key.pub
ssh_options="-p ${PORT} -i /root/bkctld.key -oStrictHostKeyChecking=no"
# A started jail should be accessible via Rsync
run rsync -a -e "ssh ${ssh_options}" /tmp/ root@127.0.0.1:/var/backup/
assert_success
/usr/lib/bkctld/bkctld-stop "${JAILNAME}"
# A stopped jail should not be accessible via Rsync
run rsync -a -e "${ssh_options}" /tmp/ root@127.0.0.1:/var/backup/
assert_failure
}

235
server/test/incs.bats Normal file
View file

@ -0,0 +1,235 @@
#!/usr/bin/env bats
# shellcheck disable=SC1089,SC1083,SC2154
load test_helper
@test "Inc policy after jail init" {
# An incs_policy file should exist
run test -e "${CONFDIR}/${JAILNAME}.d/incs_policy"
[ "${status}" -eq 0 ]
}
@test "Inc directory after jail init" {
# An incs_policy file should exist
run test -d "${INCDIR}/${JAILNAME}"
[ "${status}" -eq 0 ]
}
@test "Normal inc creation" {
/usr/lib/bkctld/bkctld-inc
if is_btrfs "/backup"; then
# On a btrfs filesystem, the inc should be a btrfs volume
run is_btrfs "${INCSPATH}/${INC_NAME}"
assert_success
else
# On an ext4 filesystem, the inc should be a regular directory
run test -d "${INCSPATH}/${INC_NAME}"
assert_success
fi
}
@test "Normal inc creation (with old incs policy)" {
mv "${CONFDIR}/${JAILNAME}.d/incs_policy" "${CONFDIR}/${JAILNAME}"
/usr/lib/bkctld/bkctld-inc
if is_btrfs "/backup"; then
# On a btrfs filesystem, the inc should be a btrfs volume
run is_btrfs "${INCSPATH}/${INC_NAME}"
assert_success
else
# On an ext4 filesystem, the inc should be a regular directory
run test -d "${INCSPATH}/${INC_NAME}"
assert_success
fi
}
@test "No inc creation without inc policy" {
# Remove inc_policy
rm -f "${CONFDIR}/${JAILNAME}.d/incs_policy"
# … and old file
rm -f "${CONFDIR}/${JAILNAME}"
/usr/lib/bkctld/bkctld-inc
run test -d "${INCSPATH}/${INC_NAME}"
assert_failure
}
@test "Recent inc is kept after 'rm'" {
# Setup simple incs policy
echo "+%Y-%m-%d.-0day" > "${CONFDIR}/${JAILNAME}.d/incs_policy"
# Prepare an inc older than the policy
recent_inc_path="${INCSPATH}/${INC_NAME}"
# Create the inc, then run 'rm'
/usr/lib/bkctld/bkctld-inc
/usr/lib/bkctld/bkctld-rm
# Recent inc should be present
run test -d "${recent_inc_path}"
assert_success
}
@test "Older inc is removed by 'rm'" {
# Setup simple incs policy
echo "+%Y-%m-%d.-0day" > "${CONFDIR}/${JAILNAME}.d/incs_policy"
# Prepare an inc older than the policy
recent_inc_path="${INCSPATH}/${INC_NAME}"
older_inc_name=$(date -d -1days +"%Y-%m-%d-%H")
older_inc_path="${INCSPATH}/${older_inc_name}"
# Create the inc, rename it to make it older, then run 'rm'
/usr/lib/bkctld/bkctld-inc
mv "${recent_inc_path}" "${older_inc_path}"
/usr/lib/bkctld/bkctld-rm
# Older inc should be removed
run test -d "${older_inc_path}"
assert_failure
}
@test "All incs are removed by 'rm' with empty inc policy" {
# Setup empty incs policy
echo "" > "${CONFDIR}/${JAILNAME}.d/incs_policy"
inc_path="${INCSPATH}/${INC_NAME}"
# Create the inc
/usr/lib/bkctld/bkctld-inc
# Inc should be removed
run test -d "${inc_path}"
assert_success
# Remove incs
/usr/lib/bkctld/bkctld-rm
# Inc should be removed
run test -d "${inc_path}"
assert_failure
}
@test "empty inc directory are removed" {
# Create an inc
/usr/lib/bkctld/bkctld-inc
# no inc should be kept
echo '' > "${CONFDIR}/${JAILNAME}.d/incs_policy"
# The inc directory is present
run test -d "${INCSPATH}"
assert_success
/usr/lib/bkctld/bkctld-rm
# The inc directory is absent
run test -d "${INCSPATH}"
assert_failure
}
@test "BTRFS based inc can be unlock with complex pattern" {
if is_btrfs "/backup"; then
# Prepare an inc older than the policy
recent_inc_path="${INCSPATH}/${INC_NAME}"
older_inc_name=$(date -d -1month +"%Y-%m-%d-%H")
older_inc_path="${INCSPATH}/${older_inc_name}"
# Create the inc, rename it to make it older, then run 'rm'
/usr/lib/bkctld/bkctld-inc
mv "${recent_inc_path}" "${older_inc_path}"
# run 'inc' again to remake today's inc
/usr/lib/bkctld/bkctld-inc
# inc should be locked
run touch "${older_inc_path}/var/log/lastlog"
assert_failure
# unlock inc
pattern="${JAILNAME}/$(date -d -1month +"%Y-%m-*")"
bkctld inc-unlock "${pattern}"
# inc should be unlocked
run touch "${older_inc_path}/var/log/lastlog"
assert_success
# other inc should still be locked
run touch "${recent_inc_path}/var/log/lastlog"
assert_failure
else
# On an ext4 filesystem it's always true
run true
assert_success
fi
}
@test "BTRFS based inc can be unlock with jail name" {
if is_btrfs "/backup"; then
# Prepare an inc older than the policy
recent_inc_path="${INCSPATH}/${INC_NAME}"
older_inc_name=$(date -d -1month +"%Y-%m-%d-%H")
older_inc_path="${INCSPATH}/${older_inc_name}"
# Create the inc, rename it to make it older, then run 'rm'
/usr/lib/bkctld/bkctld-inc
mv "${recent_inc_path}" "${older_inc_path}"
# run 'inc' again to remake today's inc
/usr/lib/bkctld/bkctld-inc
# incs should be locked
run touch "${recent_inc_path}/var/log/lastlog"
assert_failure
run touch "${older_inc_path}/var/log/lastlog"
assert_failure
# unlock incs
pattern="${JAILNAME}"
bkctld inc-unlock "${pattern}"
# incs should be unlocked
run touch "${recent_inc_path}/var/log/lastlog"
assert_success
run touch "${older_inc_path}/var/log/lastlog"
assert_success
else
# On an ext4 filesystem it's always true
run true
assert_success
fi
}
@test "BTRFS based inc can be unlock with 'all' pattern" {
if is_btrfs "/backup"; then
# Prepare an inc older than the policy
recent_inc_path="${INCSPATH}/${INC_NAME}"
older_inc_name=$(date -d -1month +"%Y-%m-%d-%H")
older_inc_path="${INCSPATH}/${older_inc_name}"
# Create the inc, rename it to make it older, then run 'rm'
/usr/lib/bkctld/bkctld-inc
mv "${recent_inc_path}" "${older_inc_path}"
# run 'inc' again to remake today's inc
/usr/lib/bkctld/bkctld-inc
# incs should be locked
run touch "${recent_inc_path}/var/log/lastlog"
assert_failure
run touch "${older_inc_path}/var/log/lastlog"
assert_failure
# unlock incs
pattern="all"
bkctld inc-unlock "${pattern}"
# incs should be unlocked
run touch "${recent_inc_path}/var/log/lastlog"
assert_success
run touch "${older_inc_path}/var/log/lastlog"
assert_success
else
# On an ext4 filesystem it's always true
run true
assert_success
fi
}
# TODO: add many tests for incs (creation and removal)

113
server/test/main.bats Executable file
View file

@ -0,0 +1,113 @@
#!/usr/bin/env bats
# shellcheck disable=SC1089,SC1083,SC2154
load test_helper
@test "Filesystem type" {
if is_btrfs "/backup"; then
# On a btrfs filesystem, the jail should be a btrfs volume
run is_btrfs "${JAILPATH}"
assert_success
else
# On an ext4 filesystem, the jail should be a regular directory
run test -d "${JAILPATH}"
assert_success
fi
}
@test "New jail should have a incs_policy file" {
run test -f "/etc/evobackup/${JAILNAME}.d/incs_policy"
assert_success
}
@test "New jail should have a check_policy file" {
run test -f "/etc/evobackup/${JAILNAME}.d/check_policy"
assert_success
}
@test "A jail should be able to be started" {
/usr/lib/bkctld/bkctld-start "${JAILNAME}"
pid=$(cat "${JAILPATH}/${SSHD_PID}")
# A started jail should have an SSH pid file
run ps --pid "${pid}"
assert_success
}
@test "A jail should be able to be stopped" {
/usr/lib/bkctld/bkctld-start "${JAILNAME}"
pid=$(cat "${JAILPATH}/${SSHD_PID}")
/usr/lib/bkctld/bkctld-stop "${JAILNAME}"
# A stopped jail should not have an SSH pid file
run ps --pid "${pid}"
assert_failure
}
@test "A jail should be able to be reloaded" {
/usr/lib/bkctld/bkctld-start "${JAILNAME}"
/usr/lib/bkctld/bkctld-reload "${JAILNAME}"
# A reloaded jail should mention the restart in the authlog
run grep "Received SIGHUP; restarting." "${JAILPATH}/var/log/authlog"
assert_success
}
@test "A jail should be able to be restarted" {
/usr/lib/bkctld/bkctld-start "${JAILNAME}"
pid_before=$(cat "${JAILPATH}/${SSHD_PID}")
/usr/lib/bkctld/bkctld-restart "${JAILNAME}"
pid_after=$(cat "${JAILPATH}/${SSHD_PID}")
# A restarted jail should have a different pid
refute_equal "${pid_before}" "${pid_after}"
}
@test "A jail should be able to be renamed" {
/usr/lib/bkctld/bkctld-start "${JAILNAME}"
new_name="${JAILNAME}-new"
# A started jail should report to be ON
run /usr/lib/bkctld/bkctld-rename "${JAILNAME}" "${new_name}"
assert_success
run /usr/lib/bkctld/bkctld-is-on "${new_name}"
assert_success
# change variable to new name,for teardown
JAILNAME="${new_name}"
}
@test "A jail should be able to be archived" {
/usr/lib/bkctld/bkctld-start "${JAILNAME}"
# A started jail should report to be ON
run /usr/lib/bkctld/bkctld-is-on "${JAILNAME}"
assert_success
run /usr/lib/bkctld/bkctld-archive "${JAILNAME}"
assert_success
# A started jail should report to be OFF
run /usr/lib/bkctld/bkctld-is-on "${JAILNAME}"
assert_failure
run test -d "${JAILPATH}"
assert_failure
run test -d "/backup/archives/${JAILNAME}"
assert_success
}
@test "Status should return information" {
run /usr/lib/bkctld/bkctld-status "${JAILNAME}"
assert_success
}
@test "ON/OFF status can be retrived with 'is-on'" {
/usr/lib/bkctld/bkctld-start "${JAILNAME}"
# A started jail should report to be ON
run /usr/lib/bkctld/bkctld-is-on "${JAILNAME}"
assert_success
/usr/lib/bkctld/bkctld-stop "${JAILNAME}"
# A stopped jail should not report to be ON
run /usr/lib/bkctld/bkctld-is-on "${JAILNAME}"
assert_failure
}

View file

@ -0,0 +1,142 @@
# shellcheck disable=SC2154 shell=bash
# shellcheck disable=SC2034
setup() {
. /usr/lib/bkctld/includes
rm -f /root/bkctld.key*
ssh-keygen -t rsa -N "" -f /root/bkctld.key -q
set_variable "/etc/default/bkctld" "BACKUP_DISK" "/dev/vdb"
JAILNAME=$(random_jail_name)
JAILPATH="/backup/jails/${JAILNAME}"
INCSPATH="/backup/incs/${JAILNAME}"
PORT=$(random_port)
INC_NAME=$(inc_name_today)
/usr/lib/bkctld/bkctld-init "${JAILNAME}"
}
teardown() {
remove_variable "/etc/default/bkctld" "BACKUP_DISK"
FORCE=1 /usr/lib/bkctld/bkctld-remove "${JAILNAME}" \
&& rm -rf "${INCSPATH}" "/etc/evobackup/${JAILNAME}" "/etc/evobackup/${JAILNAME}.d"
}
random_jail_name() {
tr -cd '[:alnum:]' < /dev/urandom | fold -w15 | head -n1
}
random_port() {
awk -v min=2222 -v max=2999 'BEGIN{srand(); print int(min+rand()*(max-min+1))}'
}
inc_name_today() {
date +"%Y-%m-%d-%H"
}
set_variable() {
file=${1:?}
var_name=${2:?}
var_value=${3:-}
if grep -qE "^\s*${var_name}=" "${file}"; then
sed --follow-symlinks --in-place "s|^\s*${var_name}=.*|${var_name}=${var_value}|" "${file}"
else
echo "${var_name}=${var_value}" >> "${file}"
fi
}
remove_variable() {
file=${1:?}
var_name=${2:?}
sed --follow-symlinks --in-place "s|^\s*${var_name}=.*|d" "${file}"
}
is_btrfs() {
path=$1
inode=$(stat --format=%i "${path}")
test ${inode} -eq 256
}
flunk() {
{ if [ "$#" -eq 0 ]; then cat -
else echo "$@"
fi
} >&2
return 1
}
assert_success() {
if [ "$status" -ne 0 ]; then
flunk "command failed with exit status $status"
elif [ "$#" -gt 0 ]; then
assert_output "$1"
fi
}
assert_failure() {
if [ "$status" -eq 0 ]; then
flunk "expected failed exit status"
elif [ "$#" -gt 0 ]; then
assert_output "$1"
fi
}
assert_equal() {
if [ "$1" != "$2" ]; then
{ echo "expected: $1"
echo "actual: $2"
} | flunk
fi
}
refute_equal() {
if [ "$1" = "$2" ]; then
echo "expected $1 to not be equal to $2" | flunk
fi
}
assert_output() {
local expected
if [ $# -eq 0 ]; then expected="$(cat -)"
else expected="$1"
fi
assert_equal "$expected" "$output"
}
assert_line() {
if [ "$1" -ge 0 ] 2>/dev/null; then
assert_equal "$2" "${lines[$1]}"
else
local line
for line in "${lines[@]}"; do
if [ "$line" = "$1" ]; then return 0; fi
done
flunk "expected line \`$1'"
fi
}
refute_line() {
if [ "$1" -ge 0 ] 2>/dev/null; then
local num_lines="${#lines[@]}"
if [ "$1" -lt "$num_lines" ]; then
flunk "output has $num_lines lines"
fi
else
local line
for line in "${lines[@]}"; do
if [ "$line" = "$1" ]; then
flunk "expected to not find line \`$line'"
fi
done
fi
}
# shellcheck disable=SC2145
assert() {
if ! "$@"; then
flunk "failed: $@"
fi
}

View file

@ -0,0 +1,3 @@
## Uncomment and adapt thresholds (values are in hours)
# WARNING=24
# CRITICAL=48

View file

@ -0,0 +1,6 @@
+%Y-%m-%d.-0day
+%Y-%m-%d.-1day
+%Y-%m-%d.-2day
+%Y-%m-%d.-3day
+%Y-%m-01.-0month
+%Y-%m-01.-1month

View file

@ -1,4 +1,4 @@
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
sshd:x:100:65534::/var/run/sshd:/usr/sbin/nologin

View file

@ -2,7 +2,8 @@ Port 2222
Protocol 2
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
UsePrivilegeSeparation yes
KeyRegenerationInterval 3600
@ -10,7 +11,7 @@ ServerKeyBits 768
SyslogFacility AUTH
LogLevel INFO
LoginGraceTime 120
PermitRootLogin yes
PermitRootLogin without-password
StrictModes yes
RSAAuthentication yes
PubkeyAuthentication yes
@ -29,7 +30,8 @@ PrintMotd no
PrintLastLog yes
TCPKeepAlive yes
UseLogin no
UseDNS no
Subsystem sftp /usr/lib/openssh/sftp-server
AllowUsers root@IP root@::ffff:IP
AllowUsers root@0.0.0.0/0

3
server/tpl/sshrc Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
/usr/bin/lastlog -Su root

View file

@ -1,146 +0,0 @@
#!/bin/sh
#
# Script evobackup client
# $Id: evobackup_cron_daily_client,v 1.21 2010-08-22 10:15:42 gcolpart Exp $
#
# port SSH
SSH_PORT=2228
# systeme de la machine ("linux" ou "bsd")
SYSTEME=linux
# mail de remontee Evolix
MAIL=jdoe@example.com
NODE=$(expr `date +%d` % 2)
# operations specifiques
mkdir -p -m 700 /home/backup
# Dump LDAP
# slapcat -l /home/backup/ldap.bak
# Dump MySQL
# mysqldump --defaults-extra-file=/etc/mysql/debian.cnf \
# --opt --all-databases | gzip --best > /home/backup/mysql.bak.gz
# for i in $(echo SHOW DATABASES | mysql | grep -v ^Database); \
# do mkdir -p /home/mysqldump/$i ; chown -R mysql /home/mysqldump ; \
# mysqldump --defaults-extra-file=/etc/mysql/debian.cnf -Q --opt -T \
# /home/mysqldump/$i $i; done
# Dump par base
# mkdir -p -m 700 /home/mysqldump/BASE
# chown -R mysql /home/mysqldump/
# mysqldump --defaults-extra-file=/etc/mysql/debian.cnf -Q \
# --opt -T /home/mysqldump/BASE BASE
# mkdir -p /home/mysqlhotcopy/
# mysqlhotcopy BASE /home/mysqlhotcopy/
# Dump instanceS MySQL
#oldIFS=$IFS
#IFS=$'\n'
#
## Recherche du mot de passe mysqladmin
#mysqladminpasswd=`cat /root/.my.cnf |grep -m1 'password = .*' |cut -d" " -f3`
#
## Determination des instances MySQL disponibles sur le serveur (hors 3306)
#for instance in `cat /etc/mysql/my.cnf |grep "port\s*=\s\d*"`
#do
# instance=${instance// /}
# instance=${instance// /}
# instance=${instance//port=/}
# if [ "$instance" != "3306" ]
# then
# mysqldump -P $instance --opt --all-databases -u mysqladmin -p$mysqladminpasswd > /home/backup/mysql.$instance.bak
# fi
#done
#
#IFS=$old_IFS
# Dump PostgreSQL
# su - postgres -c "pg_dumpall > ~/pg.dump.bak"
# mv ~postgres/pg.dump.bak /home/backup/
# Exemple de backups...
# On sauvegarde les tables d'une base sauf des exceptions
# pg_dump -p 5432 -h 127.0.0.1 -U USER --clean -F t --inserts -f /home/backup/pg-backup.tar -t 'TABLE1' -t 'TABLE2' BASE
# On sauvegarde uniquement certaines tables d'une base
# pg_dump -p 5432 -h 127.0.0.1 -U USER --clean -F t --inserts -f /home/backup/pg-backup.tar -T 'TABLE1' -T 'TABLE2' BASE
# Dump MBR / table partitions
# dd if=/dev/sda of=/home/backup/MBR bs=512 count=1 2>&1 | egrep -v "(records in|records out|512 bytes)"
# sfdisk -d /dev/sda > /home/backup/partitions 2>&1 | egrep -v "(Warning: extended partition does not start at a cylinder boundary|DOS and Linux will interpret the contents differently)"
# Dump routes
# traceroute -n 8.8.8.8 > /home/backup/traceroute-8.8.8.8
# mtr -r 8.8.8.8 > /home/backup/mtr-8.8.8.8
# traceroute -n backup.evolix.net > /home/backup/traceroute-backup.evolix.net
# mtr -r backup.evolix.net > /home/backup/mtr-backup.evolix.net
# traceroute -n www.evolix.fr > /home/backup/traceroute-www.evolix.fr
# mtr -r www.evolix.fr > /home/backup/mtr-www.evolix.fr
# traceroute -n www.evolix.net > /home/backup/traceroute-www.evolix.net
# mtr -r www.evolix.net > /home/backup/mtr-www.evolix.net
HOSTNAME=$(hostname)
DATE=$(/bin/date +"%d-%m-%Y")
DEBUT=$(/bin/date +"%d-%m-%Y ; %H:%M")
if [ $SYSTEME = "linux" ]; then
rep="/bin /boot /lib /opt /sbin /usr"
else
rep="/bsd /bin /boot /sbin /usr"
fi
rsync -av --delete --ignore-errors \
--exclude "lost+found" \
--exclude ".nfs.*" \
--exclude "/var/log" \
--exclude "/var/log/evobackup*" \
--exclude "/var/lib/mysql" \
--exclude "/var/lib/postgres" \
--exclude "/var/lib/sympa" \
--exclude "/var/run" \
--exclude "/var/lock" \
--exclude "/var/state" \
--exclude "/var/apt" \
--exclude "/var/cache" \
--exclude "/usr/src" \
--exclude "/usr/doc" \
--exclude "/usr/share/doc" \
--exclude "/usr/obj" \
--exclude "dev" \
--exclude "/var/spool/postfix" \
--exclude "/var/lib/amavis/amavisd.sock" \
--exclude "/var/lib/munin/munin-update.stats.tmp" \
--exclude "/var/lib/php5" \
--exclude "/var/spool/squid" \
$rep \
/etc \
/root \
/var \
/home \
/srv \
/vmlinuz \
-e "ssh -p $SSH_PORT" \
root@node$NODE.backup.example.com:/var/backup/ \
| tail -20 >> /var/log/evobackup.log
FIN=$(/bin/date +"%d-%m-%Y ; %H:%M")
echo "EvoBackup - $HOSTNAME - START $DEBUT" \
>> /var/log/evobackup.log
echo "EvoBackup - $HOSTNAME - STOP $FIN" \
>> /var/log/evobackup.log
tail -10 /var/log/evobackup.log | \
mail -s "[info] EvoBackup - Client $HOSTNAME" \
$MAIL