110

I'm starting a very little hosting company for a few friends and little clients, nothing big.

I want to give my "clients" the right to manage their files on the server. I hate FTP as it is not secure and it's in my opinion obsolete.

So I'd like to allow my users to connect through SFTP but not allow them to connect through SSH. (I know, I know, SFTP is using SSH). But I was just wondering, is it possible?

So I wouldn't have to install a FTP service on the server and everything would be awesome!

Maniero
  • 135
  • 1
  • 1
  • 9
Tommy B.
  • 1,403
  • 2
  • 14
  • 14

8 Answers8

146

Starting with version 4.9 OpenSSH (not available in centos 5.x but ChrootDirectory feature was backported) has an internal-sftp subsystem:

Subsystem sftp internal-sftp

And then block other uses:

Match group sftponly
     ChrootDirectory /upload/%u
     X11Forwarding no
     AllowTcpForwarding no
     AllowAgentForwarding no
     ForceCommand internal-sftp

Add your users to the sftponly group. The chroot directory must be owned by root, and cannot be group-writeable, so create a subdirectory for each user, e.g. uploads or home/$username that's owned by the appropriate user (if you match their home directory, it will be the default working directory when connecting). I'd also set /bin/false as the user's shell.

As an example, users can then upload single files with:

sftp username@hostname <<< 'put filename.ext uploads/'

(scp will hopefully soon be modified to use sftp so this will become easier)

Mark
  • 126
  • 1
  • 5
Rob Wouters
  • 1,899
  • 1
  • 11
  • 4
  • Wow! Super-awesome! I'll test this out and come back here to validate. Thanks a lot! – Tommy B. Jan 28 '12 at 20:48
  • +1 for the ChrootDirectory thing! – Kyle Jan 30 '12 at 18:30
  • 1
    After doing this, my sftponly user cant access by ssh and is able to connect by sftp. However it can't see any file at all! In spite these files have permission for this user. :-( – Emilio Nicolás Jan 15 '15 at 10:17
  • 5
    In case you want to do this and find an entry in your sshd_config with "/usr/lib/openssh/sftp-server" already existing, check here: http://serverfault.com/questions/660160/openssh-difference-between-internal-sftp-and-sftp-server -- internal-sftp is "newer, better and easier" – Xosofox Jul 16 '15 at 10:57
  • 1
    Home directory should not only be owned by root, but also has 755 permission (no write access), which makes this chroot additional receipt not usable in most cases. – Victor Gavro Mar 14 '20 at 22:12
  • How can you set /bin/false as user shell for the group sftponly instead of each user individually? – leonheess Apr 03 '20 at 09:29
  • 1
    @leonheess The shell is a user attribute, so you would need to do a batch: `sudo groupmems -lg sftponly | sudo xargs -n1 usermod -s /bin/false` – copycat Feb 17 '21 at 23:13
  • @VictorGavro, in deed, but you can add a directory inside the user's (chrooted) home dir, and then the user can do whatever in there. – Sam Sirry Apr 19 '22 at 09:23
22

There is a shell scponly what does this. It can chroot too.

Stone
  • 6,941
  • 1
  • 19
  • 33
4

Checkout rssh which is a fake shell that allows sftp but denies ssh

More about RSSH

http://www.pizzashack.org/rssh/

RPMs

http://pkgs.repoforge.org/rssh/

You can configure rssh to allow / deny different behaviours like sft, scp etc.

Chris
  • 597
  • 1
  • 6
  • 18
  • Nice. This is the easiest way to config without touching sshd_config at all. Just change the shell in passwd file and done. – Tomofumi Aug 22 '18 at 07:47
  • 1
    `rssh` seems to be obsolete now (there is no this package in debian buster anymore), they say, there is `rush` instead of it. I did not tried it, i am moving to openssh with internal-sftp. – user3132194 Apr 01 '20 at 09:59
1

I use the method of specifying the user shell as /bin/false as mentioned. However, you must ensure that /bin/shell is in /etc/shells. Then it works ssh=no ftp=ok.

I also use vsftpd and add this
chroot_local_user=YES to /etc/vsftpd/vsftpd.conf so that ftp-ers can't see date other then their own.

Advantage to these simple changes are no annoying config to ssh config for each user.

denpick
  • 11
  • 1
0

You can modify /etc/passwd and give that user a fake shell so that he can not use ssh.

splattne
  • 28,348
  • 19
  • 97
  • 147
jcisio
  • 588
  • 1
  • 9
  • 22
  • 12
    Did you test this? – splattne Jan 29 '12 at 08:49
  • 10
    When I try setting the shell to `/bin/false` neither ssh *or* sftp works – Brad Mace Mar 14 '13 at 22:34
  • 2
    /bin/false is to disallow any sort of login, that is not the correct approach here. The accepted answer from Rob Wouters' is how you should limit users to SFTP only, not by changing the shell. If you did want to change the shell @Stone's asnwer would be a good idea. – jwbensley Aug 07 '14 at 10:46
  • 1
    so WHAT shell should be used assuming /bin/bash is not acceptable and /bin/false or /sbin/nologin deny access? – Putnik Nov 20 '17 at 23:07
0

Don't forget to find the line UsePAM yes and comment it:

#UsePAM yes

Without disabling this, your SSH server would crash on reloading/restarting. Since you do not need fancy functions of PAM, this is fine.

HBruijn
  • 72,524
  • 21
  • 127
  • 192
  • 1
    Commenting out lines that you don't understand is generally a bad idea. If you don't know what PAM is for, just leave it set however your distro has it set as a default. – mbbush Nov 10 '20 at 05:22
  • Why? / why not? unclear – MrR Dec 06 '21 at 09:23
0

Configuring ssh to enable only sftp for some selected users is a good idea and it works properly, provided that you you install either scponly or rssh.

rssh works fine, unless you need to configure jail, in this case try to follow instruction provided by CHROOT manuals is crazy, leading to "copy" large parts of system executables and library just below "each user jail", including rssh shell itself. It is a space-wasting method.

scponly needs a deep understanding in configuration leading to ever-present problem of login rejection in case of jail setup.

The straightforward way to allow "ftp" functionalities with jail properly working, SSL/TLS support for secure transactions and login is to use an "old-but-working" VSFTPD, which installs quickly and cleanly and offers all configurability as needed and, last but not least: it works!

Maurizio.

chicks
  • 3,639
  • 10
  • 26
  • 36
Maurizio
  • 21
  • 1
-1

This is the way i set up SFTP and disallowing SSH.

please do the following:

  1. First create sftp user and group sftp

  2. Create separate directory as root for the SFTP files: sudo mkdir -p /home/sftpdir

  3. Have a tested sshd_config file that allows SSH over port 22 but also SFTP on random port for security reasons

#$OpenBSD: sshd_config,v 1.101 2017/03/14 07:19:07 djm Exp $
# This is the sshd server system-wide configuration file.  See
# sshd_config(5) for more information.
# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin
# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented.  Uncommented options override the
# default value.

Port 38250 Port 22 PasswordAuthentication no 
ChallengeResponseAuthentication no

# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication.  Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'. UsePAM yes X11Forwarding yes PrintMotd no
# Allow client to pass locale environment variables AcceptEnv LANG LC_*
#DenyUsers sftpuser

# override default of no subsystems Subsystem       sftp    internal-sftp 
Match group sftp 
Match User sftpuser 
Match LocalPort 38250 
ForceCommand internal-sftp 
ChrootDirectory /home/sftpdir 
PermitTunnel no 
AllowAgentForwarding no 
X11Forwarding no    
AllowTcpForwarding no
  1. Restart and check status of sshd service
    sudo service sshd restart
    
    service sshd status
  1. Create a Shell file. Add execution to echo a notification message

    sudo touch /bin/sftponly
    echo -e '#!/bin/sh\necho "This account is limited to SFTP access only."' | sudo tee -a  /bin/sftponly

  1. Give execution permissions and append to shells file
    sudo chmod a+x /bin/sftponly
    echo "/bin/sftponly" | sudo tee -a /etc/shells
  1. finally Test and you should not be able to connect.

  2. A template to use SFTP client with a SSH key and basic verbosity:

    sftp -v -oPort=$RANDOM_PORT -i ~/.ssh/$SSH_KEY.pem sftpuser@$HOST