#!/bin/bash ## Note that the shebang is not used, but it's the login shell that ## will execute this command. 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 ADMIN CONNECTION" if [ -z "$1" ] || ! [[ "$1" =~ ^[a-zA-Z0-9._-]+$ ]]; then log "INVALID SETUP, ARG IS: '$1'" echo "Your command has been rejected. Contact administrator." exit 1 fi label="$1" 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" =~ ^"ssh-key add ssh-rsa "[a-zA-Z0-9/+]+" "[a-zA-Z0-9._-]+"@"[a-zA-Z0-9._-]+""$ ]]; then log "ACCEPTED: $SSH_ORIGINAL_COMMAND" ## Interpret \ to allow passing spaces (want to avoid possible issue with \n) #read -a ssh_args <<< "${SSH_ORIGINAL_COMMAND}" ssh_args=(${SSH_ORIGINAL_COMMAND}) # echo "Would accept: $SSH_ORIGINAL_COMMAND" >&2 exec sudo /usr/local/sbin/ssh-key add "$label" "${ssh_args[@]:2}" elif [[ "$SSH_ORIGINAL_COMMAND" =~ ^"ssh-key ls"$ ]]; then log "ACCEPTED: $SSH_ORIGINAL_COMMAND" ## Interpret \ to allow passing spaces (want to avoid possible issue with \n) #read -a ssh_args <<< "${SSH_ORIGINAL_COMMAND}" ssh_args=(${SSH_ORIGINAL_COMMAND}) # echo "Would accept: $SSH_ORIGINAL_COMMAND" >&2 exec /usr/local/sbin/ssh-key ls "$label" "${ssh_args[@]:2}" elif [[ "$SSH_ORIGINAL_COMMAND" =~ ^"ssh-key rm "[a-zA-Z0-9._-]+$ ]]; then log "ACCEPTED: $SSH_ORIGINAL_COMMAND" ## Interpret \ to allow passing spaces (want to avoid possible issue with \n) #read -a ssh_args <<< "${SSH_ORIGINAL_COMMAND}" ssh_args=(${SSH_ORIGINAL_COMMAND}) # echo "Would accept: $SSH_ORIGINAL_COMMAND" >&2 exec sudo /usr/local/sbin/ssh-key rm "$label" "${ssh_args[@]:2}" elif [[ "$SSH_ORIGINAL_COMMAND" =~ ^"request-recovery-key "[a-zA-Z0-9._-]+$ ]]; then log "ACCEPTED: $SSH_ORIGINAL_COMMAND" ## Interpret \ to allow passing spaces (want to avoid possible issue with \n) #read -a ssh_args <<< "${SSH_ORIGINAL_COMMAND}" ssh_args=(${SSH_ORIGINAL_COMMAND}) # echo "Would accept: $SSH_ORIGINAL_COMMAND" >&2 exec sudo /usr/local/sbin/request-recovery-key "$label" "${ssh_args[@]:1}" else log "NOT MATCHING ANY ALLOWED COMMAND" reject fi ## For other commands, like `find` or `md5`, that could be used to ## challenge the backups and check that archive is actually ## functional, I would suggest to write a simple command that takes no ## arguments, so as to prevent allowing wildcards or suspicious ## contents. Letting `find` go through is dangerous for instance ## because of the `-exec`. And path traversal can be done also when ## allowing /my/path/* by using '..'. This is why a fixed purpose ## embedded executable will be much simpler to handle, and to be honest ## we don't need much more.