Last active
August 29, 2015 14:08
-
-
Save micw/339fcf01b4c99c728080 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# This script can be used as wrapper for rsync in authorized_keys. It restricts rsync the following way: | |
# - restrict target directory to be under /backups/backup-rsync-push/${1}/target/ where $1 is an argument from authorized_keys | |
# - restrict target directory to be exactly 1 level below this directory | |
# - restrict flags | |
# - restrict arguments | |
# - force --fake-super argument | |
err() { | |
echo "--------------------------------------------------------------------" >&2 | |
echo "ERROR ON REMOTE SIDE:" >&2 | |
echo "$*" >&2 | |
echo "--------------------------------------------------------------------" >&2 | |
} | |
if [ $# -ne 1 ]; then | |
err "CLIENT not set in authorized_keys" | |
exit 1 | |
fi | |
DIR="/backups/backup-rsync-push/${1}/target/" | |
if [ ! -d "$DIR" ]; then | |
err "Client dir not found." | |
exit 1 | |
fi | |
ARGS=( $SSH_ORIGINAL_COMMAND ) | |
ARG_COUNT="${#ARGS[@]}" | |
shopt -s extglob | |
do_rsync() { | |
CMD="/usr/bin/rsync --fake-super --server" | |
if [ $ARG_COUNT -lt 3 ]; then | |
err "Supplied rsync command had too few args" | |
exit 1 | |
fi | |
ARG_N1="${ARGS[$(( ARG_COUNT - 2 ))]}" | |
if [ "$ARG_N1" != "." ]; then | |
err "the arg before the last arg must be a dot, not $ARG_N1" | |
exit 1 | |
fi | |
PATH="${ARGS[$(( ARG_COUNT - 1 ))]}" | |
if ! [[ "$PATH" =~ ^[a-zA-Z0-9_-]+/$ ]]; then | |
err "The last arg must be a path that matches [a-zA-Z0-9_-]+/ , not $PATH" | |
exit 1 | |
fi | |
for ARG in "${ARGS[@]:1:$(( ARG_COUNT - 3 ))}"; do | |
case $ARG in | |
-+(v|l|o|g|D|t|p|A|X|r|e.|i)Lsf ) | |
# allowed flags. requires "shopt -s extglob" to be set outside this function | |
CMD="$CMD $ARG" | |
;; | |
"--sender"|"--delete-during"|"--numeric-ids") | |
# added to command | |
CMD="$CMD $ARG" | |
;; | |
"--fake-super"|"--server") | |
# silently ignored | |
;; | |
*) | |
err "rsync arg not allowed: $ARG" | |
exit 1 | |
;; | |
esac | |
done | |
TARGET="${DIR}${PATH}" | |
$CMD . "${TARGET}" | |
exit 1 | |
} | |
case "${ARGS[0]}" in | |
"rsync") | |
do_rsync | |
;; | |
*) | |
err "Command denied: $SSH_ORIGINAL_COMMAND" | |
exit 1 | |
;; | |
esac |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment