3

My users are shared across a number of machines via LDAP.

For one of those machines (let's call it 'fileserf'), I would like to restrict some users in what they can do (actually: prevent them from logging into an interactive session via ssh). On the other machines, these users should be able to use ssh normally.

So my initial idea was to use the internal-sftp subsystem, along the lines of:

Match group sftponly
     ChrootDirectory %h
     X11Forwarding no
     AllowTcpForwarding no
     ForceCommand internal-sftp

This works ok as it restricts only the members of the (local) group sftponly on a single host fileserf, but unfortunately the internal-sftp subsystem only allows sftp and not scp (or rsync).

So I did some more research and found rssh, which seems to allow me to do exactly what I want to do (permission-wise).

Now the problem is that I cannot set the login-shell of those users to /usr/bin/rssh in my LDAP, because that would mean that they would be restricted on all machines, not just on fileserf.

So my idea is to override the login shell via some configuration in fileserf's sshd_config:

Match group sftponly
     X11Forwarding no
     AllowTcpForwarding no
     ForceCommand /usr/bin/rssh

Unfortunately this doesn't seem to work, since now the users get a Connection closed whenever they try to sftp into the machine:

$ ssh user@fileserf 

This account is restricted by rssh.
Allowed commands: scp sftp 

If you believe this is in error, please contact your system administrator.

Connection to fileserf closed.

$ sftp user@fileserf
Connection closed
$

How can I make ForceCommand work with rssh?

Alternatively, How can I configure sshd to override the login-shell for a group of users?

umläute
  • 6,472
  • 1
    If you can add these users to a local group, perhaps you can create local users which shadow them? – muru Feb 04 '16 at 11:13

2 Answers2

4

The rssh manpage indicates it should be the login shell of these users:

The  system  administrator  should  install the shell on the restricted
system.  Then the password file entry  of  any  user  for  whom  it  is
desireable  to  provide  restricted  access should be edited, such that
their shell is rssh. For example:

      luser:x:666:666::/home/luser:/usr/bin/rssh

With the ForceCommand, only that command is run. When you run scp or sftp, commands are run by SSH (scp, /usr/lib/openssh/sftp-server, respectively), and of course they can't be run unless the program executed by ForceCommand uses SSH_ORIGINAL_COMMAND to do so. So, for rssh to do its job, it has to be the login shell, not a ForceCommand.

Related:


You can, instead, use a wrapper script that will use rssh instead of the login shell to execute commands. For example:

/usr/local/bin/wrapper-shell:

#! /bin/sh
rssh -c "$SSH_ORIGINAL_COMMAND"

And in /etc/ssh/sshd_config:

Match group sftponly
     X11Forwarding no
     AllowTcpForwarding no
     ForceCommand /usr/local/bin/wrapper-shell

With /usr/local/bin/wrapper-shell being executable should work.

muru
  • 72,889
  • that's why the title of my question says [how to] "make sshd override login shell". updated the question-body to reflect that... – umläute Feb 04 '16 at 11:09
  • 1
    @umläute you should understand that SSH can't override the login shell. The login shell is what it is, ForceCommand doesn't change that. Try running a shell script as a ForceCommand which prints $SHELL. – muru Feb 04 '16 at 11:12
  • @umläute see update. – muru Feb 04 '16 at 11:32
  • the update seems promising; i tried something like that before but failed; i will try again following your suggestion when i'm back at the machine. – umläute Feb 04 '16 at 20:38
  • actually that did the trick; i don't know why my prior tests with such a wrapper script failed (esp. since my wrapper was identical to yours :-() – umläute Feb 04 '16 at 20:48
2

We had the same problem: a server must allow scp sftp and rsync for all users but no connection with command line. User database is in ldap and we cannot modify /etc/passwd locally. rssh was therefore not an option.

One solution I have found is by using ForceCommand and a shell script. In /etc/ssh/sshd_config adding these lines:

Match user *
    X11Forwarding no
    AllowTcpForwarding no
    ForceCommand /usr/local/bin/wrapper-shell user1 user2 user3

Where userX are special users allowed to log in via ssh. The wrapper-shell script, which do the actual filtering, is:

#!/bin/sh
SSHCMD=`echo "$SSH_ORIGINAL_COMMAND" | awk '{ print $1 }'`
ME=`id -u -n`
DOIT=Maybe
# Root is always allowed in order to not being locked out
for n in root $*
do
  if [ "$ME" = "$n" ]
  then
    DOIT=YES
    break
  fi
done
if [ "$DOIT" = YES -o "$SSHCMD" = "scp" -o "$SSHCMD" = "rsync" -o "$SSHCMD" = /usr/lib/openssh/sftp-server ]
then
    sh -c "$SSH_ORIGINAL_COMMAND"
else
    cat <<EOF 1>&2

This account is restricted and the command is not allowed.

User $ME is locked out.

If you believe this is in error, please contact your system administrator.
EOF
    exit 1
fi