#!/bin/bash ## Note that the shebang is not used, but it's the login shell that ## will execute this command. RSYNC_KEY_PATH=/etc/rsync/keys RECOVER_KEY_PATH=${RSYNC_KEY_PATH}/recover exname=$(basename "$0") mkdir -p /var/log/rsync LOG="/var/log/rsync/$exname.log" ssh_connection=(${SSH_CONNECTION}) SSH_SOURCE_IP="${ssh_connection[0]}:${ssh_connection[1]}" log() { printf "%s [%s] %s - %s\n" \ "$(date --rfc-3339=seconds)" "$$" "$SSH_SOURCE_IP" "$*" \ >> "$LOG" } log "NEW RECOVER CONNECTION" if [ -z "$1" ] || ! [[ "$1" =~ ^[a-z0-9]+$ ]]; then log "INVALID SETUP, ARG 1 SHOULD BE MD5 AND IS: '$1'" echo "Your command has been rejected. Contact administrator." exit 1 fi md5="$1" log "RECOVER KEY $md5" if [ -z "$2" ] || ! [[ "$2" =~ ^[a-zA-Z0-9._-]+$ ]]; then log "INVALID SETUP, IDENT IS: '$1'" echo "Your command has been rejected. Contact administrator." exit 1 fi ident="$2" log "IDENTIFIED AS $ident" reject() { log "REJECTED: $SSH_ORIGINAL_COMMAND" # echo "ORIG: $SSH_ORIGINAL_COMMAND" >&2 echo "Your command has been rejected and reported to sys admin." >&2 exit 1 } if [[ "$SSH_ORIGINAL_COMMAND" =~ [\&\(\{\;\<\>\`\$\}] ]]; then log "BAD CHARS DETECTED" # echo "Bad chars: $SSH_ORIGINAL_COMMAND" >&2 reject fi if [[ "$SSH_ORIGINAL_COMMAND" =~ ^"rsync --server --sender -"[vnloHgDtpArRzCeiLsfx\.]+(" --"[a-z=%-]+|" --partial-dir .rsync-partial")*" . /var/mirror/$ident"(|/.*)$ ]]; then ## Interpret \ to allow passing spaces (want to avoid possible issue with \n) #read -a ssh_args <<< "${SSH_ORIGINAL_COMMAND}" ssh_args=(${SSH_ORIGINAL_COMMAND}) last_arg="${ssh_args[@]: -1:1}" if ! new_path=$(realpath "$last_arg" 2>/dev/null); then log "FINAL PATH INVALID" reject fi if [[ "$new_path" != "$last_arg" ]] && [[ "$new_path" != "/var/mirror/$ident/"* ]] && [[ "$new_path" != "/var/mirror/$ident" ]]; then log "FINAL PATH SUSPICIOUS" reject fi sudo /usr/local/sbin/ssh-update-keys if ! [ -e "${RECOVER_KEY_PATH}/$md5" ]; then log "RECOVERY KEY $md5 JUST EXPIRED" reject fi log "ACCEPTED RECOVER COMMAND: $SSH_ORIGINAL_COMMAND" sudo "${ssh_args[@]}" errlvl="$?" for key_file in "${RECOVER_KEY_PATH}/$md5"{,.pub}; do [ -e "$key_file" ] || continue sudo touch "$key_file" ## Update modified time to keep key longer done exit "$errlvl" else log "REFUSED COMMAND AS IT DOESN'T MATCH ANY EXPECTED COMMAND" reject fi