Commit Graph

47 Commits (master)

Author SHA1 Message Date
Christoph Anton Mitterer 7adb32c7e9 ssh_filter_btrbk.sh: further harden the shell execution environment
• In principle the special `IFS`-variable could be set to some unexpected non-
  standard value.
  Unsetting it causes its default to be used.
• Locales and in particular their characters sets are quite complex in POSIX and
  may have many subtle implications.
  For example, the pattern matching notation (used in `case`-compound-commands
  or some forms of parameter expansion) are in principle only defined for
  character strings. While some shells handle it gracefully, the behaviour is
  undefined if, for example, the character set is UTF-8 and a variable contains
  bytes that do not form valid caracters in that.
  Actually, there are quite some more implications.

  Also, pathnames, in POSIX, are strings of bytes excluding 0x0.

  For these reasons, the locale is set to the `C`/`POSIX`-locale.

Signed-off-by: Christoph Anton Mitterer <mail@christoph.anton.mitterer.name>
2023-03-25 16:02:04 +01:00
Christoph Anton Mitterer 5b8c1f8f7a ssh_filter_btrbk.sh: minor improvements
• Set shell options in one command.
• Homogeneously use local variables for function positional parameters in all
  places.
• In redirections, omit `1` for standard output.
• Homogeneously use `if`-compount-commands instead of `[ … ] && …` in all
  places.
• Homogeneously use curly brackets with parameter expansion.

Signed-off-by: Christoph Anton Mitterer <mail@christoph.anton.mitterer.name>
2023-03-25 16:02:04 +01:00
Christoph Anton Mitterer b274bd1d50 ssh_filter_btrbk.sh: replace OpenSSH’s deprecated SSH_CLIENT
OpenSSH’s environment variable `SSH_CLIENT` has been deprecated in upstream
commit f37e246f858cdd79be4f4e158b7b04778d1cb7e9 (2002-09-19) and replaced by
`SSH_CONNECTION`.

Both contain more than just the remote information, thus adapted the log message
to reflect that.

Since this might be used by 3rd-party programs (like fail2ban), added a specific
note to the changelog.

Signed-off-by: Christoph Anton Mitterer <mail@christoph.anton.mitterer.name>
2023-03-25 16:02:04 +01:00
Christoph Anton Mitterer ee5a543e0b ssh_filter_btrbk.sh: use printf instead of echo
In spirit, POSIX considers `echo` rather obsolete (it was just kept because of
its widespread use).

It’s also not possible to use `echo` portably unless it’s `-n`-option (as the
first argument) and escape sequences are omitted.
While neither was the case here, it’s better style to just always use `printf`
in order to avoid any future confusion when both are used.

Signed-off-by: Christoph Anton Mitterer <mail@christoph.anton.mitterer.name>
2023-03-25 16:02:04 +01:00
Christoph Anton Mitterer ddc9b810de ssh_filter_btrbk.sh: convert to POSIX sh
This commit finishes the work from the previous one and converts
ssh_filter_btrbk.sh to (mostly) pure POSIX Shell Command Language.

Instead of bash’s `=~`-operator for its `[[ … ]]`-compound-command it uses
`grep`.
At the time of writing, bash has at least the `nocasematch`-shell-option which
would have a negatve security impact for this program. While it’s not enabled
per default single users could potentially change that, not realising the
consequences.
Thus, moving away from this may also provide some hardening.

Unlike bash’s `=~`-operator, which matches against the whole string at once,
`grep` matches the pattern against each line of input.
This would allow for attacks by including a newline in the SSH command like in:
    SSH_ORIGINAL_COMMAND="readlink /dev/stdout
    cat /etc/shadow"
but is prevented by the general exclusion of newlines in commit TODO.

`grep` may return an exit status of `0` when used with its `-q`-option, even
when an error occurred.
Since this program is intended specifically for security purposes this shall be
avoided, even if such case is unlikely, and therefore its standard output and
standard error are redirected to `/dev/null` instead.

Further, using just:
    local formatted_restrict_path_list="$(printf '%s' "$restrict_path_list" | sed 's/|/", "/g')"
rather than:
    local formatted_restrict_path_list=""; formatted_restrict_path_list="$(printf '%s' "$restrict_path_list" | sed 's/|/", "/g')"
prevent `set -e` to take effect if the pipeline within the command substitution
fails, as the returned exit status of the whole command is the result of
`local`, not that of the assignment.
This is however no security problem here, as `formatted_restrict_path_list` is
only used for informative pruposes.

Signed-off-by: Christoph Anton Mitterer <mail@christoph.anton.mitterer.name>
2023-03-25 16:02:04 +01:00
Christoph Anton Mitterer ac1fd38beb ssh_filter_btrbk.sh: remove unnecessary bashishms
ssh_filter_btrbk.sh is mainly intended for security purposes and should
therefore itself be written with that in mind.
It is written for bash, which greatly extends the POSIX Shell Command Language
and is incompatible with it in some niche cases.

For several reasons, it seems a good idea to convert the program to (mostly)
pure POSIX Shell Command Language:
• People may try to use the program with other shells (for example when bash is
  not available) and make errors.
More pure `sh` implementations like dash …
• … have far less code and also less dependencies, which possibly also reduces
  the chance for bugs or exploits,
• … are less dynamic in development (and have thus possibly a lower chance of
 incompatible changes) …
• … and may run faster.

This commit replaces any unnecessary “bashishms” with purely POSIX compatible
code, with the exception of the `local`-built-in, which is however supported by
most POSIX compatible shells (including dash, klibc-utils’s `sh` and BusyBox’
`sh`) in some way.

Signed-off-by: Christoph Anton Mitterer <mail@christoph.anton.mitterer.name>
2023-03-25 16:02:04 +01:00
Christoph Anton Mitterer 5d79c012c4 ssh_filter_btrbk.sh: double quote variables expansions
Double quote any variable expansions that might ever contain field separators.

Signed-off-by: Christoph Anton Mitterer <mail@christoph.anton.mitterer.name>
2023-03-25 16:02:04 +01:00
Christoph Anton Mitterer 1980c1d939 ssh_filter_btrbk.sh: use single quotes where possible
In strings that don’t contain `'` nor do any expansions, use single quotes to
avoid any future unintended expansions or escapes.

Signed-off-by: Christoph Anton Mitterer <mail@christoph.anton.mitterer.name>
2023-03-25 16:02:04 +01:00
Christoph Anton Mitterer 36d6ba7d07 ssh_filter_btrbk.sh: disallow newlines in the SSH command
This disallows newline (that is: LF characters) in the SSH command, which could
have been exploited for arbitrary code execution, since commit
77a39282de.

Example:
    # export SSH_ORIGINAL_COMMAND=$'readlink /dev/stdout\ncat /etc/shadow'
    # ssh_filter_btrbk.sh

Since `readlink` is a generally allowed command, this works with any of
ssh_filter_btrbk.sh’s options.
But most likely, other commands that are “added” via `allow_cmd()` can be used,
too.

Signed-off-by: Christoph Anton Mitterer <mail@christoph.anton.mitterer.name>

# Please enter the commit message for your changes. Lines starting
# with '#' will be kept; you may remove them yourself if you want to.
# An empty message aborts the commit.
#
# Date:      Wed Nov 30 04:29:53 2022 +0100
#
# On branch fix-remote-code-execution
# Your branch and 'origin/fix-remote-code-execution' have diverged,
# and have 1 and 1 different commits each, respectively.
#   (use "git pull" to merge the remote branch into yours)
#
# Changes to be committed:
#	modified:   ssh_filter_btrbk.sh
#
# Untracked files:
#	ORIG
#
2022-12-02 01:43:29 +01:00
Christoph Anton Mitterer 914f9286c7 btrbk: add bzip3 compression
This adds support for bzip3 [1].

 [1] https://github.com/kspalaiologos/bzip3

Signed-off-by: Christoph Anton Mitterer <mail@christoph.anton.mitterer.name>

Cosmetics: swap order pbzip2 / bzip3

Signed-off-by: Axel Burri <axel@tty0.ch>
2022-11-16 00:45:39 +01:00
Axel Burri 177f8547e3 btrbk: add backend btrfs-progs-doas 2022-02-08 01:06:04 +01:00
Axel Burri 77a39282de ssh_filter_btrbk.sh: allow quoted files 2021-08-18 02:08:28 +02:00
Axel Burri f7d3823d5d ssh_filter_btrbk.sh: fix files are always absolute 2021-08-18 02:08:28 +02:00
Axel Burri 58212de771 ssh_filter_btrbk.sh: fix alternation regex
Security vulnerability fixed in alternation regex. Specialy crafted
commands may be executed without being propely checked.

Affects all versions >= btrbk-v0.23.0

Regression from:

   ccb5ed5e71 ssh_filter_btrbk: allow "realpath" and "cat /proc/self/mounts" on targets

Reported by: @protree (responsible disclosure)
2021-03-21 13:24:59 +01:00
Lukas Straub 3562e75a70 btrbk: add support for zstandard (zstd) compression 2020-12-26 15:46:20 +01:00
Axel Burri ec037952cf btrbk: add "compat" config option (busybox: add test -d command)
Add compat, compat_local, compat_remote configuration options.

Used for busybox: instead of running `readlink -e` (which is not
available on busybox), run `readlink -f` followed by `test -d`.
2020-08-28 21:19:21 +02:00
Axel Burri 73b339fe01 documentation: fix spelling 2020-02-09 16:14:50 +01:00
Axel Burri c03e960d90 ssh_filter_btrbk.sh: exclude "btrfs subvolume show|list" from restrict-path
btrbk requires "btrfs subvolume list|show" queries from the mount
point in order to build btrfs trees. This conflicts with tightly set
--restrict-path.
2020-01-02 17:56:03 +01:00
Ryan Young 0f21df15c2 ssh_filter_btrbk.sh: whitelist mkdir for 'btrbk archive' operations 2019-10-27 12:24:00 +01:00
Axel Burri 3631cf6c7f ssh_filter_btrbk.sh: cosmetics: show unsafe character 2019-09-08 18:23:30 +02:00
Axel Burri 6227bb591a ssh_filter_btrbk.sh: return exit status 255 on error
This makes btrbk regard ssh_filter_btrbk errors as ssh errors, as ssh
also returns exit status 255 if an error occurred.
2019-09-08 18:23:29 +02:00
Axel Burri 8d0d7edda7 ssh_filter_btrbk.sh: adaptions, use mbuffer for rate_limit 2019-08-05 14:54:04 +02:00
Axel Burri 0e6c1f9025 btrbk: fix regression: call "sudo readlink" for backend=btrfs-progs-sudo
It is possible that the subvolume path is not accessible by the user
calling btrbk. When resolving mount points, "readlink" is used on the
path, which also needs to be wrapped with "sudo".
2018-12-05 22:01:07 +01:00
Axel Burri 526e332b02 ssh_filter_btrbk.sh: bugfix: ignore --restrict-path for "btrfs subvolume list"
btrbk now runs "btrfs subvolume list" from the mountpoint instead of
the volume path, which for some users is not below --restrict-path. As
the output of "btrfs subvolume list" is the same (complete btrfs tree
for the filesystem), it is ok to ignore the restrict-path here.
2018-10-10 22:51:13 +02:00
Axel Burri 069304f3bb btrbk: use system_list_mountinfo(), remove system_list_mounts(); rename fs_spec -> mount_source
Reasons for changing to `cat /proc/self/mountinfo`:
 - `/proc/self/mounts` (or `/proc/mounts`) lacks extra info
   (namespaces) and is not documented in kernel (deprecated?).
 - findmnt(8) also uses /proc/self/mountinfo

Refs:
 - https://www.kernel.org/doc/Documentation/filesystems/proc.txt
 - https://bugzilla.redhat.com/show_bug.cgi?id=491924
 - https://git.kernel.org/pub/scm/linux/kernel/git/bwh/linux-stable.git/commit/?id=2d4d4864ac08caff5c204a752bd004eed4f08760
2018-08-27 14:54:32 +02:00
Axel Burri 78cec36e30 ssh_filter_btrbk: tighten decompress match expression 2018-07-12 18:26:35 +02:00
Axel Burri cb5e361f7a btrbk: add --rootid command option for "btrfs subvolume show" 2018-07-09 16:13:00 +02:00
Axel Burri b37ef84e36 btrbk: always read mountpoints; include all snapshots from mountpoint as candidates for best common parent
Dropped readin of subvolid and realpath by btrfs_subvolume_show(), we
now always read /proc/self/mounts (and call readlink).

When picking the best common parent in get_best_parent(), we want to
list as many snapshots as possible. For now, we list all from the
mountpoint of snaproot ($sroot/<snapshot_dir>), due to a bug in
btrfs-progs [1]. Also added code (commented out) to list snapshots
from all known mountpoints.

  [1] https://github.com/kdave/btrfs-progs/issues/96
2018-05-10 11:48:05 +02:00
Axel Burri b1f3936826 ssh_filter_btrbk: bugfix: use "lzop" instead of "lzo" for lzo compression command 2017-08-21 14:42:01 +02:00
Axel Burri ee17c1a2b4 ssh_filter_btrbk: accept mbuffer command (stream_compress) 2017-08-21 14:39:40 +02:00
Axel Burri 690a8158ed ssh_filter_btrbk: always allow pipes through compression commands 2017-03-18 12:19:07 +01:00
Axel Burri da70158c24 ssh_filter_btrbk: correctly handle --sudo option 2017-03-18 12:19:07 +01:00
Axel Burri 3b7ede773a btrbk: bugfix: make sure rate limiting comes after compression in cmd_pipe 2017-03-18 12:18:47 +01:00
Axel Burri cb82bd5fa4 btrbk: add supoort for "backend btrfs-progs-sudo" option; adaptions in ssh_filter_btrbk.sh 2017-01-04 15:04:22 +01:00
Axel Burri 8f7d3e3c3d ssh_filter_btrbk: bugfix: use eval when running $SSH_ORIGINAL_COMMAND (does not faile with pipes) 2016-08-21 11:51:55 +02:00
Axel Burri deeb12c069 ssh_filter_btrbk: allow stream compression if --compress option is set. 2016-08-19 17:36:40 +02:00
TZdyrski edffbd4af9 ssh_filter_btrbk: update ssh_filter_btrbk.sh to use readlink
bugfix for: 796b6bd9bf

Replace realpath with readlink in allowed commands. Commit 796b6bd substituted readlink for realpath in file "btrbk"; this commit propagates the change to ssh_filter_btrbk.sh.
2016-08-19 01:05:02 +02:00
Axel Burri 81feb41619 ssh_filter_btrbk: allow access to "/" if no path restrictions are set. 2016-04-25 16:58:56 +02:00
Axel Burri 407d25f604 ssh_filter_btrbk: cosmetics: fix indentation (remove tabs) 2016-03-31 17:24:24 +02:00
Axel Burri ccb5ed5e71 ssh_filter_btrbk: allow "realpath" and "cat /proc/self/mounts" on targets 2016-03-31 17:24:24 +02:00
Axel Burri f01304df35 ssh_filter_btrbk: refactoring/hardening:
- switched to bash interpreter
- enable fine-grained (--source, --target, ...) capabilities by command-line options
- added "--restrict_path" command-line option
- added sudo flag
- added man-page
- print SSH_ORIGINAL_COMMAND in error message
2015-09-10 14:02:32 +02:00
Axel Burri bab8f1771b ssh_filter_btrbk: no fail if either $LOGNAME or $SSH_CLIENT are not set; added log_cmd() function; use relative path for "logger" command; cosmetics 2015-07-08 18:08:19 +02:00
Yaroslav Halchenko f8c64c4f27 ssh_filter_btrbk: fail if any command fails, or var is undefined 2015-07-08 18:02:21 +02:00
Axel Burri c23674fca8 btrbk: catch exact error from "btrfs subvolume show"; instruct user to fix ssh_filter_btrbk.sh if it rejected the ssh command 2015-05-19 18:22:55 +02:00
Axel Burri bea010dce0 btrbk, ssh_filter_btrbk.sh: set PATH=/sbin:/bin:/usr/sbin:/usr/bin and call "btrfs" instead of using absolute "/sbin/btrfs". for compatibility with all distros out there.
- debian jessie (stable): btrfs-tools-3.17-1.1: `/sbin/btrfs`
  - debian sid (unstable): btrfs-tools-4.0-2: `/bin/btrfs`
  - gentoo: sys-fs/btrfs-progs-4.0: `/sbin/btrfs`
  - arch: btrfs-progs-4.0-2: `/usr/bin/btrfs`
2015-05-18 21:18:57 +02:00
Axel Burri 34e7ad07ec ssh_filter_btrbk: removed unneeded calls to btrfs-progs 2015-04-28 21:19:46 +02:00
Axel Burri 60b2951916 ssh_filter_btrbk: added ssh_filter_btrbk.sh (ssh wrapper/filter script) 2015-02-09 11:42:44 +01:00