Ssh – How to give someone ssh access to upload files remotely

rsyncssh

I want to give someone permission to host some simple files on my Ubuntu webserver. This is for an IRC logging bot. I'd like to give them passwordless ssh/scp/rsync/sftp access. However I want to be able to restrict what they can do, I don't want to give them a full ssh shell in otherwords. I'd also like to be able to limit the amount of disk space they can take up, so they can't use more than (say) 200MB of my disk in total.

Bonus options that aren't required but might be nice: Limit what sort of files they can upload? (Mime type maybe?) Log when they upload a file? Limit their bandwidth?

What are my options?

Best Answer

On Ubuntu/Debian, you can install the scponly shell to restrict them to scp/sftp only. Just install the package and change their shell to /usr/bin/scponly:

sudo aptitude install scponly
sudo usermod -s /usr/bin/scponly USERNAME

The disk space problem is likely best solved with filesystem quotas. Unfortunately I have little experience with them.

If you want to get fancier (restricting filetypes and such) you'll probably need to write your own script to validate the commands being passed from the client. The simplest script would be a shell script that performs a test similar to this one:

if [[ $SSH_ORIGINAL_COMMAND = "scp -f *txt" ]]
then
   exec $SSH_ORIGINAL_COMMAND
fi

That would allow downloading .txt files. Quick tests indicate the filename is not passed as part of the scp command when sending. So it may not be possible in that case.

The script would be set as the forced command for the user's key. (The ``command="blah"'' field in authorized_keys.) It can also be set as the "ForceCommand" option for a Match group in sshd_config, like so:

Match group scponly ForceCommand /usr/local/sbin/scpwrapper

Then add the users to be so restricted to the "scponly" group.

EDIT: By request, here's the script I use to enforce rsync-only access:

#!/bin/bash
# 
# Verify that rsync command appears to be a legitimate rsnapshot command.
# Requires >= bash 3.x
#
# Ben Beuchler
# 6/4/07

# rsync needs to be operating in "server" mode.
re_server='rsync --server'

# Match both -x and --word options
re_options=' +-{1,2}[[:alpha:]-]+'

# Match legal paths
re_paths=' +[-[:alnum:]_./]+'

# Build the full regex
r="^${re_server}(${re_options})+(${re_paths}){2}$"

echo $SSH_ORIGINAL_COMMAND >> ssh_log

if [[ $SSH_ORIGINAL_COMMAND =~ $r ]]
then
        exec $SSH_ORIGINAL_COMMAND
else
        echo "Invalid rsync command."
fi

Use that script as a forced command (either by "command=" in ~/.ssh/authorized_keys or using a "Match" block in sshd_config as noted above) and it will reject everything except rsync commands. With a little tweaking it could be made to only accept specific rsync commands.