K=/root/.ssh/backup_key B=/srv/backups/s1-etc SSH="ssh -i $K -o BatchMode=yes -o ConnectTimeout=5 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR" # What a dry run would still send: changed files, not just directory times. pending() { timeout 60 rsync -ani --delete -M--fake-super -e "$SSH" /etc/ bkp@10.99.0.2:$B/ 2>/dev/null | grep -Ev '^\.d\.\.t\.+ ' >"$LAB_STATE/pending" [ "${PIPESTATUS[0]}" -eq 0 ] } # The backup timers: timers whose service runs rsync to the peer. timers() { local t s x f for t in $(systemctl list-unit-files --type=timer --no-legend | awk '{ print $1 }'); do s=$(systemctl show -p Unit --value "$t") x=$(systemctl show -p ExecStart --value "$s" 2>/dev/null | sed -n 's/.*path=\([^ ;]*\).*/\1/p') { systemctl cat "$s" 2>/dev/null; [ -f "$x" ] && cat "$x"; } | grep -q 'rsync' || continue echo "$t" done } t1() { timers | head -n1; } task 1 "/etc backed up to the peer as bkp with rsync and its own key" need "user bkp exists and isn't root" 'id bkp && [ "$(id -u bkp)" != 0 ]' need "/root/.ssh/backup_key is a key without a passphrase" 'ssh-keygen -y -P "" -f $K' need "bkp's authorized_keys holds the backup key" 'h=$(getent passwd bkp | cut -d: -f6); grep -qF "$(awk "{ print \$2 }" $K.pub)" $h/.ssh/authorized_keys' need "root logs in to the peer as bkp with the key" 'timeout 15 $SSH bkp@10.99.0.2 true /dev/null | grep -q "^Finished"' task 3 "/etc/motd deleted and restored with its owner and mode" need "/etc/motd exists" test -f /etc/motd need "it's the file the lab wrote" '[ "$(md5sum