SFTP user include/exclude without preventing SSH login

I have been asked to see if we can restrict SFTP access to authorised users only. There will be business users who will log on with SSH, but they are locked into a menu. They will have write access to the production data to do their job, but we don't want them to have access to read/write the files with SFTP or anything else for that matter.

For plain FTP, we would use the /etc/ftpusers file and re-create it each night with all users in /etc/passwd except those in the allowed list. Not clever, but it worked.

We're running RHEL / Centos 6.3 and the server is running vsftp is installed for plain FTP along with openssh-server-5.3p1-81.el6_3.x86_64 The sshd_config file defines sftp as starting up /usr/libexec/openssh/sftp-server

Any suggestions? Badly, the users home directory is a common area with the application & data below it, so I can't just enforce the chroot jail. User SSH login is by userid/password rather than certificate. Not sure if that helps or hinders.

Thanks, in advance,
Robin

Maybe setting up sshd_config with a Match block and a ForceCommand for the users you don't want to have SFTP access would prevent spawning the SFTP subsystem?

I'd also test it against SCP attempts.

Worst case, you could try running two SSHD daemons, on different interfaces. Set up one for your clients to ONLY run what you want - set the SFTP subsystem to /dev/null, for example. Set up the other SSHD daemon for everyone else. Then use the Match blocks in the two sshd_config files to control access, probably based on group membership.

1 Like

Thanks for the suggestion achenle.

Are you suggesting effectively switching SFTP to another port? Who cares if SSH is used for login on that port too, we control that so our SFTP/FTP only accounts have shell /dev/null. That might prove fun for those wishing to use SFTP though. If I set up the client side ssh_config to use the changed port, then I guess that everyone will get it by default. It's a puzzler.

I can't get a match block in the SFTP bit of sshd_config file. It is not supported.

Robin
Liverpool/Blackburn
UK

As mentioned before, spawning a second instance of SSH daemon running on a different port would be the easiest approach.

You may also want to use something like rssh (rssh - restricted shell for scp/sftp) as the default shell and restrict all users to SFTP/SSH *ONLY*. You can even use rssh in both daemons, each one using its own copy of rssh.conf.

Keep in mind that rssh is not an official package and there are no pre-compiled packages available so you'll need to compile it yourself.

One benefit of this is that you won't need to mess with sshd_config and potentially break something else.

rssh is also compatible with older versions of SSH so it should work just fine with "ancient" versions.

It still doesn't let me explicitly allow/prevent people SFTP access though. They would merely have to re-direct to the alternate port, and that sort of info will need to be published to those people/servers that we do want to have SFTP access.

For a server to have access, we'd have to update the client side ssh_config I suppose, but that will mean any user of that server could then open the connection to the alternate SSH port that we want to protect by default.

Am I missing something? By the way, I'm hoping that any SSH connection with a command will execute /etc/profile first. Is that the case? If not, then I'm lost, because a user could just:-

ssh user1@server1 "cat secure_file" > my_copy
vi my_copy
cat my_copy | ssh user1@server1 "dd of=secure_file"

Am I just depressing myself unnecessarily?

Robin

Possibility:
OpenSSH has chroot functionality in current versions. On the type of subsystem. Basically you just need to add lines like below to your

/etc/ssh/sshd_config file.
Subsystem sftp internal-sftp

Match group sftpusers
     ChrootDirectory /var/www/someplace/safe
     X11Forwarding no
     AllowTcpForwarding no
     ForceCommand internal-sftp

Next create a group sftpusers with command

groupadd sftpusers

The last step is then to create a user belonging to group sftpusers:

useradd -g sftpusers -d /var/www/xy/backup/files username 

restart your ssh service:

/etc/init.d/sshd restart 

This only affects sftp access only. And users in the sftpusers group only.

/var/www/someplace/safe is completely your decision. All this is on the assumption that I understood what you want. What you presented seems an almost unworkable melange of stuff as is. So feel free to ignore this.

Jim,

So close! I've turned your suggestion around and now have:-

:
:
:
# override default of no subsystems
Subsystem       sftp    /bin/false

# Example of overriding settings on a per-user basis
Match Group sftpusers
        X11Forwarding no
        AllowTcpForwarding no
        ForceCommand /usr/libexec/openssh/sftp-server

.... which blocks anyone who doesn't have group sftpusers assigned (secondary group allowed) but unfortunately it doesn't let them SSH login.

Bother.

I will get digging some more on the OpenBSD site, as I think that they are the source for whet we have.

Robin

I have a solution and would welcome opinions, especially those that can pick holes in it.
I now have my three groups of users.

  1. Users allowed SFTP only - set the account to have a shell of /etc/false
  2. Users allowed SSH login and SFTP, normal user creation
  3. Users allowed SSH login only, set them a secondary group of sshrestr

Then in /etc/ssh/sshd_config, code this towards the end:-

Match Group sshrestr
     ForceCommand     /usr/local/bin/ssh_restricted

Then, in /usr/local/bin/ssh_restricted, pop in the following:-

#!/bin/ksh
if [ -z "$SSH_ORIGINAL_COMMAND" ]
then
   exec `grep "^\`id -un\`:" /etc/passwd|cut -f7 -d":"`
else
   logger "Access denied attempting \"$SSH_ORIGINAL_COMMAND\""
   if [ "$SSH_ORIGINAL_COMMAND" != \
        "/usr/sbin/sftp-server -m /etc/ssh/sshd_config" ]
   then
      print "Access denied"
   fi
   exit
fi

The bit in green may need to be adjusted depending what you see in the syslog. That part is only to prevent the SFTP client getting a horrible error. This seems to prevent scp and remote commands with ssh, although I'm sure it could easily be adjusted to cater for them if we were to need them. This only prevents remote commands for users with the sshrestr group, so things such as backups, application updates etc. over ssh would be unaffected if run by any other user.

Does anyone have anything glaringly obvious, or even something subtle that is missed by this?

Thanks, in advance,
Robin
Liverpool/Blackburn
UK

I forgot about 'service' accounts that should not be logged on to directly, even if the password is known, but I've hit upon another suggestion posted elsewhere that I should include.

If you have an account that should not login, but it runs services, you can just set the default shell to /dev/null, /bin/false etc. as you choose, however with use of su - userid -s /bin/ksh you can still switch user to it if you need to.

To start services (probably at boot or scripted) you would:-

su - userid -s /bin/ksh start_script

It stops login, but allows function. Of course, there are bound to be things that will fall foul of this arrangement, but I thought it would be honorable to include it for anyone finding this thread, to have it available to consider.

Robin