SSH filter script for raw targets on remote host
- Dominant language
- Perl
- Stars
- 2.1k
- Forks
- 139
- PR merge metrics
- No merged PRs in 30d
Description
I couldn't find a filtered ssh shell for backup on a remote server as raw files. I made a script for that:
```
#!/bin/bash
set -e
set -u
export PATH=/sbin:/bin:/usr/sbin:/usr/bin
enable_log=
use_sudo=
restrict_path_list=
allow_list=
log_cmd()
{
if [[ -n "$enable_log" ]]; then
logger -p $1 -t ssh_filter_btrbk.sh "$2 (Name: ${LOGNAME:-}; Remote: ${SSH_CLIENT:-})${3:+: $3}: $SSH_ORIGINAL_COMMAND"
fi
}
allow_cmd()
{
allow_list="${allow_list}|$1"
}
reject_and_die()
{
local reason=$1
log_cmd "auth.err" "btrbk REJECT" "$reason"
echo "ERROR: ssh_filter_btrbk.sh: ssh command rejected: $reason: $SSH_ORIGINAL_COMMAND" 1>&2
exit 1
}
run_cmd()
{
log_cmd "auth.info" "btrbk ACCEPT"
$use_sudo $SSH_ORIGINAL_COMMAND
}
reject_filtered_cmd()
{
# note that the backslash is NOT a metacharacter in a POSIX bracket expression!
option_match='-[a-zA-Z-]+' # matches short as well as long options
file_match='[0-9a-zA-Z_@+./-]+' # matches file path (equal to $file_match in btrbk)
if [[ -n "$restrict_path_list" ]]; then
# match any of restrict_path_list with or without trailing slash,
# or any file/directory (matching file_match) below restrict_path
path_match="(${restrict_path_list})(/|/${file_match})?"
else
# match any absolute file/directory (matching file_match)
path_match="/${file_match}"
fi
find_option_match='-[a-zA-Z-]+( [a-zA-Z0-9+]+)?'
# allow multiple paths (e.g. "btrfs subvolume snapshot ")
btrfs_cmd_match="^(${allow_list})( ${option_match})*( (of=)?$path_match)+( ${find_option_match})*$"
if [[ ! $SSH_ORIGINAL_COMMAND =~ $btrfs_cmd_match ]] ; then
reject_and_die "disallowed command${restrict_path_list:+ (restrict-path: \"${restrict_path_list//|/\", \"}\")}"
fi
}
allow_cmd "test"
allow_cmd "dd status=none"
allow_cmd "find"
restrict_path_list=/home/btrbk/backups
# remove leading "|" on alternation lists
allow_list=${allow_list#\|}
restrict_path_list=${restrict_path_list#\|}
case "$SSH_ORIGINAL_COMMAND" in
*\$*) reject_and_die "unsafe character" ;;
*\&*) reject_and_die "unsafe character" ;;
*\(*) reject_and_die "unsafe character" ;;
*\{*) reject_and_die "unsafe character" ;;
*\;*) reject_and_die "unsafe character" ;;
*\<*) reject_and_die "unsafe character" ;;
*\>*) reject_and_die "unsafe character" ;;
*\`*) reject_and_die "unsafe character" ;;
*\|*) reject_and_die "unsafe character" ;;
*\.\./*) reject_and_die "directory traversal" ;;
*)
reject_filtered_cmd
#echo $SSH_ORIGINAL_COMMAND
run_cmd
;;
esac
```
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reviewing the proposed SSH filter script in the issue, including its command filtering and restricted backup path. Determine how it should be integrated with btrbk for raw remote backups, then verify that allowed commands work and unsafe or out-of-path commands are rejected.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- bash
- Domain
- cli, security
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100