How to: Restrict Users to SCP and SFTP and Block SSH Shell Access with rssh

Thanks to

FTP is insecure protocol, but file-transfer is required all time. You can use OpenSSH Server to transfer file using SCP and SFTP (secure ftp) without setting up an FTP server. However, this feature also grants ssh shell access to a user. Basically OpenSSH requires a valid shell. Here is how sftp works:

SCP/SFTP -> SSHD -> Call sftpd subsystem -> Requires a shell -> User can login to server and run other commands.

In this article series we will help you provide secure restricted file-transfer services to your users without resorting to FTP. It also covers chroot jail setup instructions to lock down users to their own home directories (allow users to transfer files but not browse the entire Linux / UNIX file system of the server) as well as per user configurations.

rssh ~ a restricted shell

rssh is a restricted shell for use with OpenSSH, allowing only scp and/or sftp. It now also includes support for rdist, rsync, and cvs. For example, if you have a server which you only want to allow users to copy files off of via scp, without providing shell access, you can use rssh to do that.

Supported operations using rssh

Restricted shell only allows following operations only:

  • scp – Secure file copy
  • sftp – Secure FTP
  • cvs – Concurrent Versions System ~ you can easily retrieve old versions to see exactly which change caused the bug
  • rsync – Backup and sync file system
  • rdist – Backup / RDist program maintains identical copies of files on multiple hosts.

Install rssh

CentOS / Fedora / RHEL Linux rssh installation

Visit Dag’s repo to grab rssh package
# cd /tmp
# wget
# rpm -ivh rssh-2.3.2-1.2.el5.rf.i386.rpm

Debian / Ubuntu Linux rssh installation

Use apt-get command:
$ sudo apt-get install rssh

FreeBSD installation

# cd /usr/ports/shells/rssh
# make install clean

Make sure you build binary with rsync support.

rssh configuration file

  • Default configuration file is located at /etc/rssh.conf (FreeBSD – /usr/local/etc/rssh.conf)
  • Default rssh binary location /usr/bin/rssh (FreeBSD – /usr/local/bin/rssh)
  • Default port none – ( openssh 22 port used – rssh is shell with security features)

Configure:  /etc/rssh.conf

#vi  /etc/rssh.conf

# This is the default rssh config file

# set the log facility. “LOG_USER” and “user” are equivalent.
logfacility = LOG_USER

# Leave these all commented out to make the default action for rssh to lock
# users out completely…


# set the default umask
umask = 022

# If you want to chroot users, use this to set the directory where the root of
# the chroot jail will be located.
# if you DO NOT want to chroot users, LEAVE THIS COMMENTED OUT.
chrootpath = /usr/local/chroot

# You can quote anywhere, but quotes not required unless the path contains a
# space… as in this example.

# EXAMPLES of configuring per-user options

#user=rudy:077:000100: # the path can simply be left out to not chroot
#user=rudy:077:000100 # the ending colon is optional

#user=rudy:011:001000: # cvs, with no chroot
#user=rudy:011:010000: # rdist, with no chroot
#user=rudy:011:100000: # rsync, with no chroot
#user=rudy:011:000001: # svnserve, with no chroot
#user=”rudy:011:000010:/usr/local/chroot” # whole user string can be quoted
#user=rudy:01″1:000010:/usr/local/chroot” # or somewhere in the middle, freak!
#user=rudy:’011:000010:/usr/local/chroot’ # single quotes too

We will auto create a chroot forder by a script  thanks to:

Then we add a script which will help create rssh user very fast without mistake:

#vi /usr/local/sbin/


function user_add() {
export SFTPUSER=”${1}”
useradd -m -d “/usr/local/chroot/home/$SFTPUSER” -s /usr/bin/rssh “$SFTPUSER”
passwd “$SFTPUSER”
tail -1 /etc/passwd >> /usr/local/chroot/etc/passwd

#chmod 711 /usr/local/chroot/home
echo “User ${1} added successful.”

function user_del() {
export SFTPUSER=”${1}”
userdel “$SFTPUSER”
rm -r “/usr/local/chroot/home/$SFTPUSER”
echo “User ${1} deleted successful.”

function key_add() {
export SFTPUSER=”${1}”
mkdir -m 755 “/usr/local/chroot/home/$SFTPUSER/.ssh”
chown root:”$SFTPUSER” “/usr/local/chroot/home/$SFTPUSER/.ssh”
vi “/usr/local/chroot/home/$SFTPUSER/.ssh/authorized_keys”

echo -n -e “add user: press a , delete user: press d or quit: press q? ”
read action

if [ -z “$action” ]
echo -n “Parameter missing.”
exit 1
elif [ “$action” = “a” ]
echo -n “Username: ”
read username

if [ -z “$username” ]
echo “Parameter missing. Did you forget the username?”
exit 1
user_add $username
echo -n -e “\nDo you want to add key? (y/n) ”
read key
if [ “$key” = “y” ]
key_add $username
exit 0
elif [ “$action” = “d” ]
echo -n “Username (l for list): ”
read username
if [ -z “$username” ]
echo “Parameter missing. Did you forget the username?”
exit 1
elif [ $username = “l” ]
echo -e “\nUsers:”
awk -v LIMIT=500 -F: ‘($3>=LIMIT) && ($3!=65534)’ /etc/passwd | cut -d: -f1
echo -n -e “\nUsername: ”
read username
user_del $username
user_del $username
elif [ “$action” = “q” ]
exit 0
echo “Oops! Something went wrong.”
exit 1



We add a limit user with rssh shell and chroot to their own /home/rsshuser ; this user can use sftp, scp, rsync to their chroot home folder only.

PS: we can install fail2ban to protect our ssh service; use ssh key for scp or rsync without enter user/password.