diff --git a/client/CHANGELOG.md b/client/CHANGELOG.md index 4065645..8de2b31 100644 --- a/client/CHANGELOG.md +++ b/client/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * 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 ### Deprecated diff --git a/client/zzz_evobackup b/client/zzz_evobackup index 9beccfb..191e15f 100755 --- a/client/zzz_evobackup +++ b/client/zzz_evobackup @@ -182,9 +182,11 @@ local_tasks() { # 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 @@ -199,9 +201,10 @@ local_tasks() { ## 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 -s -U postgres -d $databases | gzip --best -c > ${LOCAL_BACKUP_DIR}/postgresql/$databases.sql.gz ; done + # cd - > /dev/null ## MongoDB @@ -265,10 +268,19 @@ local_tasks() { #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) - for addr in 8.8.8.8 www.evolix.fr travaux.evolix.net; do - mtr -r ${addr} > ${LOCAL_BACKUP_DIR}/mtr-${addr} - traceroute -n ${addr} > ${LOCAL_BACKUP_DIR}/traceroute-${addr} 2>&1 - done + 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" @@ -392,12 +404,18 @@ sync_tasks() { update-evobackup-canary --who "${PROGNAME}" - # /!\ DO NOT USE COMMENTS in the rsync command /!\ - # It breaks the command and destroys data, simply remove (or add) lines. - # Remote shell command RSH_COMMAND="ssh -p ${SSH_PORT} -o 'ConnectTimeout ${SSH_CONNECT_TIMEOUT}'" + ################################################################### + # /!\ 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 # + # => Only remove (or add) lines. # + ################################################################### + # ignore check because we want it to split the different arguments to $rep # shellcheck disable=SC2086 rsync --archive \ @@ -420,6 +438,7 @@ sync_tasks() { --exclude "/var/lib/metche" \ --exclude "/var/lib/munin/*tmp*" \ --exclude "/var/db/munin/*.tmp" \ + --exclude "/var/lib/mongodb" \ --exclude "/var/lib/mysql" \ --exclude "/var/lib/php5" \ --exclude "/var/lib/php/sessions" \ @@ -597,8 +616,6 @@ export LC_ALL=C # Error on unassigned variable set -u -# Fail if a pipeline member returns an error (cf. https://sipb.mit.edu/doc/safe-shell/) -set -o pipefail # Default return-code (0 == succes) rc=0 diff --git a/server/CHANGELOG.md b/server/CHANGELOG.md index 0c21896..3012189 100644 --- a/server/CHANGELOG.md +++ b/server/CHANGELOG.md @@ -18,6 +18,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### 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 diff --git a/server/README.md b/server/README.md index 9d93fa9..6c9247f 100644 --- a/server/README.md +++ b/server/README.md @@ -39,7 +39,7 @@ This architecture is as secure as SSH, Rsync, chroot and iptables are. ## Install -See the [installation guide](docs/install.md) for instructions. +See the [installation guide](https://intra.evolix.net/OutilsInternes/bkctld) for instructions. ## Testing @@ -49,6 +49,12 @@ 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 diff --git a/server/bkctld b/server/bkctld index 03535d3..0ee7c87 100755 --- a/server/bkctld +++ b/server/bkctld @@ -53,6 +53,9 @@ while :; do -f|--force) export FORCE=1 ;; + --no-header) + export HEADER=0 + ;; *) # Default case: If no more options then break out of the loop. break @@ -64,7 +67,7 @@ done subcommand="${1:-}" case "${subcommand}" in - "inc" | "rm" | "check-jails" | "check-setup" | "stats" | "list") + "inc" | "rm" | "check-jails" | "check-setup" | "check-canary" | "stats" | "list") "${LIBDIR}/bkctld-${subcommand}" ;; "check") @@ -116,7 +119,9 @@ case "${subcommand}" in ;; "status") jail_name="${2:-}" - printf '%-30s %-10s %-10s %-25s %-20s\n' 'JAIL NAME' 'STATUS' 'PORT' 'RETENTION (DAY/MONTH)' 'IP' + 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}" diff --git a/server/docs/install.md b/server/docs/install.md index 5760174..a956ac4 100644 --- a/server/docs/install.md +++ b/server/docs/install.md @@ -2,15 +2,7 @@ ## Install from package -A Debian package is available in the Evolix repository - -~~~ -echo "deb http://pub.evolix.net/ stretch" >> /etc/apt/sources.list -apt update -apt install bkctld -~~~ - -Then edit `/etc/default/bkctld` +The install documentation is [here](https://intra.evolix.net/OutilsInternes/bkctld) ## Instal from sources diff --git a/server/lib/bkctld-check-canary b/server/lib/bkctld-check-canary new file mode 100755 index 0000000..c2de38a --- /dev/null +++ b/server/lib/bkctld-check-canary @@ -0,0 +1,59 @@ +#!/bin/sh +# +# Description: check canary file +# Usage: check-canary [|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}" \ No newline at end of file diff --git a/server/lib/bkctld-stats b/server/lib/bkctld-stats index 8e69f12..1f0d2ce 100755 --- a/server/lib/bkctld-stats +++ b/server/lib/bkctld-stats @@ -15,27 +15,29 @@ ionice -c3 "${DUC}" index -d "${IDX_FILE}" "${JAILDIR}" touch "${INDEX_DIR}/.lastrun.duc" EOF -[ ! -f "${INDEX_DIR}/.lastrun.duc" ] && notice "First run of DUC always in progress ..." && exit 0 +[ ! -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 "@{}" -echo " " | awk '{ printf("%- 30s %- 10s %- 10s %- 15s\n", $1, $2, $3, $4); }' duc_output=$(mktemp) stat_output=$(mktemp) incs_output=$(mktemp) +jail_patterns_list=$(mktemp) # shellcheck disable=SC2064 -trap "rm ${duc_output} ${incs_output} ${stat_output}" 0 +trap "rm ${duc_output} ${incs_output} ${stat_output} ${jail_patterns_list}" 0 -"${DUC}" ls -d "${IDX_FILE}" "${JAILDIR}" > "${duc_output}" +"${DUC}" ls --database "${IDX_FILE}" "${JAILDIR}" > "${duc_output}" -awk '{ print $2 }' "${duc_output}" | while read jail_name; do +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_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") @@ -45,4 +47,7 @@ awk '{ print $2 }' "${duc_output}" | while read jail_name; do echo "${incs_policy}" >> "${incs_output}" done -paste "${duc_output}" "${incs_output}" "${stat_output}" | awk '{ printf("%- 30s %- 10s %- 10s %- 15s\n", $2, $1, $3, $4); }' +( + echo " " + paste "${duc_output}" "${incs_output}" "${stat_output}" | awk '{ printf("%s %s %s %s\n", $2, $1, $3, $4); }' +) | column -t diff --git a/server/lib/bkctld-status b/server/lib/bkctld-status index b7cadbb..5546d63 100755 --- a/server/lib/bkctld-status +++ b/server/lib/bkctld-status @@ -1,7 +1,7 @@ #!/bin/sh # # Description: Display status of SSH server -# Usage: status [|all] +# Usage: [--no-header] status [|all] # # shellcheck source=./includes diff --git a/server/lib/includes b/server/lib/includes index 3653c40..59c31c8 100755 --- a/server/lib/includes +++ b/server/lib/includes @@ -6,7 +6,7 @@ [ -f /etc/default/bkctld ] && . /etc/default/bkctld -VERSION="22.07" +VERSION="22.11" LIBDIR=${LIBDIR:-/usr/lib/bkctld} CONFDIR="${CONFDIR:-/etc/evobackup}" @@ -20,6 +20,7 @@ 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}" @@ -29,6 +30,7 @@ CRITICAL="${CRITICAL:-48}" WARNING="${WARNING:-24}" DUC=$(command -v duc-nox || command -v duc) FORCE="${FORCE:-0}" +HEADER="${HEADER:-1}" show_version() { cat <> "${JAILPATH}/var/backup/zzz_evobackup_canary" + + run /usr/lib/bkctld/bkctld-check-canary "${JAILNAME}" + assert_success +} \ No newline at end of file