restrict file transfer in rsync, scp, sftp?

Carsten Andrich carsten.andrich at
Sun Nov 12 21:35:38 AEDT 2023

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,



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)

More information about the openssh-unix-dev mailing list