Mailing List Archive

restrict file transfer in rsync, scp, sftp?
I am supporting a site that allows members to upload release files. I
have inherited this site which was previously existing. The goal is
to allow members to file transfer to and from their project area for
release distribution but not to allow general shell access and not to
allow access to other parts of the system.

Currently rsync and old scp has been restricted using a restricted
shell configuration. But of course that does not limit sftp. And of
course sftp can be chrooted which would work okay for us. Use the
ForceCommand internal-sftp configuration to put the process in a
chroot. But then that configuration blocks rsync.

Match ... other stuff
Match ALL
ChrootDirectory /releases
ForceCommand internal-sftp
AllowTcpForwarding no
X11Forwarding no

I have not been able to deduce a way to set up sftp-in-a-chroot *only*
when sftp is requested and allow rsync when rsync is requested and
allow rsync to work normally when rsync is requested.

Is there a way to allow rsync, scp and sftp but restrict the user to
only upload and download from specific directories? Something like if
the user is invoking sftp then chroot sftp but if the user is invoking
rsync then invoke the custom restricted shell.

I hate to have to tell everyone that we can only securely allow one of
either rsync or sftp but not both. But at this point I think it must
be one or the other and either-or seems not possible.

Thanks!
Bob
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: restrict file transfer in rsync, scp, sftp? [ In reply to ]
On Sat, 11 Nov 2023, Bob Proulx wrote:

> I am supporting a site that allows members to upload release files. I
> have inherited this site which was previously existing. The goal is
> to allow members to file transfer to and from their project area for
> release distribution but not to allow general shell access and not to
> allow access to other parts of the system.
>
> Currently rsync and old scp has been restricted using a restricted
> shell configuration. But of course that does not limit sftp. And of
> course sftp can be chrooted which would work okay for us. Use the
> ForceCommand internal-sftp configuration to put the process in a
> chroot. But then that configuration blocks rsync.
>
> Match ... other stuff
> Match ALL
> ChrootDirectory /releases
> ForceCommand internal-sftp
> AllowTcpForwarding no
> X11Forwarding no
>
> I have not been able to deduce a way to set up sftp-in-a-chroot *only*
> when sftp is requested and allow rsync when rsync is requested and
> allow rsync to work normally when rsync is requested.

You can do this using a custom setuid shell or forcecommand (it needs
to be setuid because chroot requires privileges). It can look at
the contents of $SSH_ORIGINAL_COMMAND and decide on whether to run
rsync or chroot then run sftp-server.

It is possible to do this without setuid, but the forcecommand would
need to live inside the ChrootDirectory along with everything else
sftp-server and rsync needs.

If you're on Linux, then maybe you could cook something up using
namespaces and bind mounts to simplify this.

-d
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: restrict file transfer in rsync, scp, sftp? [ In reply to ]
On 12.11.23 03:52, Damien Miller wrote:
> On Sat, 11 Nov 2023, Bob Proulx wrote:
>
>> I am supporting a site that allows members to upload release files. I
>> have inherited this site which was previously existing. The goal is
>> to allow members to file transfer to and from their project area for
>> release distribution but not to allow general shell access and not to
>> allow access to other parts of the system.
>>
>> Currently rsync and old scp has been restricted using a restricted
>> shell configuration. But of course that does not limit sftp. And of
>> course sftp can be chrooted which would work okay for us. Use the
>> ForceCommand internal-sftp configuration to put the process in a
>> chroot. But then that configuration blocks rsync.
>>
>> Match ... other stuff
>> Match ALL
>> ChrootDirectory /releases
>> ForceCommand internal-sftp
>> AllowTcpForwarding no
>> X11Forwarding no
>>
>> I have not been able to deduce a way to set up sftp-in-a-chroot *only*
>> when sftp is requested and allow rsync when rsync is requested and
>> allow rsync to work normally when rsync is requested.
> You can do this using a custom setuid shell or forcecommand (it needs
> to be setuid because chroot requires privileges). It can look at
> the contents of $SSH_ORIGINAL_COMMAND and decide on whether to run
> rsync or chroot then run sftp-server.
>
> It is possible to do this without setuid, but the forcecommand would
> need to live inside the ChrootDirectory along with everything else
> sftp-server and rsync needs.
>
> If you're on Linux, then maybe you could cook something up using
> namespaces and bind mounts to simplify this.

A while ago I used the following bubblewrap-based login shell to
implement said Linux namespace and bind mount solution to give
restricted shell access to a mostly trusted user. Using bwrap saves the
perilous trouble of writing a safe setuid solution yourself. Could be
extended by looking at $SSH_ORIGINAL_COMMAND to get the sftp/rsync
behavior you're looking for. Obviously, no guarantees about its safety.
For example, a "Subsystem sftp" directive in the sshd_config will bypass
the login shell, IIRC.

Best regards,
Carsten

---

#!/bin/bash

set -euo pipefail

(exec bwrap \
        --ro-bind /bin /bin \
        --ro-bind /usr /usr \
        --ro-bind /lib /lib \
        --ro-bind /lib64 /lib64 \
        --dir /home \
        --dir /run/user/$(id -u) \
        --dir /tmp \
        --dir /var \
        --symlink ../tmp var/tmp \
        --bind /home/user /home/user \
        --proc /proc \
        --dev /dev \
        --chdir /home/user \
        --unshare-all \
        --file 11 /etc/passwd \
        --file 12 /etc/group \
        --file 13 /etc/bash.bashrc \
        --file 14 /etc/hostname \
        --file 15 /etc/localtime \
        --file 16 /etc/nsswitch.conf \
        --file 17 /etc/profile \
        /bin/bash "$@"
    ) \
    11< <(getent passwd $UID 65534) \
    12< <(getent group $(id -g) 65534) \
    13< <(cat /etc/bash.bashrc) \
    14< <(cat /etc/hostname) \
    15< <(cat /etc/localtime) \
    16< <(cat /etc/nsswitch.conf) \
    17< <(cat /etc/profile)

_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: restrict file transfer in rsync, scp, sftp? [ In reply to ]
TL;DR: I'll jump down the rabbit hole of creating a ForceCommand which
does the chroot selection itself or not. Thanks!

Damien Miller wrote:
> Bob Proulx wrote:
> > Match ALL
> > ChrootDirectory /releases
> > ForceCommand internal-sftp
> ...
> You can do this using a custom setuid shell or forcecommand (it needs
> to be setuid because chroot requires privileges). It can look at
> the contents of $SSH_ORIGINAL_COMMAND and decide on whether to run
> rsync or chroot then run sftp-server.

The problem I hit with that idea is that then the chroot requires a
full chroot system setup rather than the internal-sftp which works
internally and does not require the full chroot environment. The
shared libraries needed is not too much issue but the user accounts
are kept in an SQL datbase so wiring that it seemed messy. That's the
reason I was trying to deduce a method to use "ForceCommand
internal-sftp" which works directly.

I have entertained the idea of splitting the host into two hosts. One
would have an IP address for sftp and the other would have an IP
address for rsync and the two would not need to overlap. That's a
possibility because the host size could be very small. If this were a
*BSD system I would use a vnet jail. This is a Linux system. (Maybe
this will be the motivation for me to learn Linux containers.)

> It is possible to do this without setuid, but the forcecommand would
> need to live inside the ChrootDirectory along with everything else
> sftp-server and rsync needs.

The setuid requirement itself is not a problem. The attraction of
internal-sftp is that it is already there and already self-contained.
The problem of needing the user account database in the chroot makes
doing it without internal-sftp to be messy.

Though maybe I have avoided it too quickly and should just work the
problem and see. I am going to jump into this rabbit hole and see
what I find there. Though I am torn between it and the brute force
idea of splitting the host into separate sftp and rsync dedicated
transfer ones. But then people would need to be switched from one dns
name which I am sure they have coded to another that they would need
to learn. I'll jump into the ForceCommand handler for a bit and see
what I learn by working that side of the problem.

> If you're on Linux, then maybe you could cook something up using
> namespaces and bind mounts to simplify this.

I neglected to say one more thing that figures into the problem. The
storage space is on an NFS mount. Which honestly has more benefits
than problems. There are several hosts that share the storage space.
This does not prevent doing clever things. But it can make things
more interesting. If possible keeping things simple and plain is my
goal.

Thanks!
Bob
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: restrict file transfer in rsync, scp, sftp? [ In reply to ]
Carsten Andrich wrote:
> A while ago I used the following bubblewrap-based login shell to implement
> said Linux namespace and bind mount solution to give restricted shell access
> to a mostly trusted user. Using bwrap saves the perilous trouble of writing
> a safe setuid solution yourself. Could be extended by looking at
> $SSH_ORIGINAL_COMMAND to get the sftp/rsync behavior you're looking for.
> Obviously, no guarantees about its safety. For example, a "Subsystem sftp"
> directive in the sshd_config will bypass the login shell, IIRC.

This is one of those ideas that appears at first glance to be so very
different from my normal thinking such that it shakes my mental
foundations of how to look at the problem! Which I appreciate very
much! It is going to take me a little bit of time to process this
idea. It's more clever than I can internalize all at once.

> (exec bwrap \
> ...
> --file 11 /etc/passwd \
> --file 12 /etc/group \
> --file 13 /etc/bash.bashrc \
> --file 14 /etc/hostname \
> --file 15 /etc/localtime \
> --file 16 /etc/nsswitch.conf \
> --file 17 /etc/profile \
> ...
> 11< <(getent passwd $UID 65534) \
> 12< <(getent group $(id -g) 65534) \
> 13< <(cat /etc/bash.bashrc) \
> 14< <(cat /etc/hostname) \
> 15< <(cat /etc/localtime) \
> 16< <(cat /etc/nsswitch.conf) \
> 17< <(cat /etc/profile)

I did not realize the capability to namespace open file descriptors to
files was possible. And here you are using it very cleverly to set up
the user accounts in the chroot. That's very clever and very cool!

I have not been familiar with bubblewrap previously. I see that in
the OS distribution being used that it is "new" in the grand scheme of
things and so would not have previously been available. Which makes
this a good time to reevaluate technology and try new things.

Thanks!
Bob
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: restrict file transfer in rsync, scp, sftp? [ In reply to ]
On Sat, Nov 11, 2023 at 7:16?PM Bob Proulx <bob@proulx.com> wrote:
>
> I am supporting a site that allows members to upload release files. I
> have inherited this site which was previously existing. The goal is
> to allow members to file transfer to and from their project area for
> release distribution but not to allow general shell access and not to
> allow access to other parts of the system.

The simplest answer is "don't bother". Switch to FTPS, which is
supported with quite simple tools like vsftpd and is vastly simpler to
entirely segregate user spaces for.

If you have a compelling need to support scp and/or rsync, you can
look at the old "rssh" tools, I used to publish RHEL wrappers for that
at https://github.com/nkadel/rssh-chroot-tools , but stopped
maintaining my copy years ago. They're far more burdensome, and
maintaining the SFTP based "only see the upload or download folder"
configs is a lot more work, than simply using vsftpd and FTPS.
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: restrict file transfer in rsync, scp, sftp? [ In reply to ]
On 12.11.23 01:08, Bob Proulx wrote:
> Currently rsync and old scp has been restricted using a restricted
> shell configuration. But of course that does not limit sftp. And of
> course sftp can be chrooted which [...] blocks rsync.
[...]
> I hate to have to tell everyone that we can only securely allow one of
> either rsync or sftp but not both. But at this point I think it must
> be one or the other and either-or seems not possible.

Call me cheap, but I'd try having the sshd listen on a second port and
put the chroot+sftp config into a "Match LocalPort ..." block.

Yes, that means the users cannot use a single .ssh/config entry for all
the access modes, but considering that the chroot will change the
apparently-absolute pathes for SFTP, anyway ...

Kind regards,
--
Jochen Bern
Systemingenieur

Binect GmbH