Make sshd override login shell of a group of users
Solution 1
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.
Solution 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
Related videos on Youtube
umläute
Updated on September 18, 2022Comments
-
umläute over 1 year
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 hostfileserf
, but unfortunately theinternal-sftp
subsystem only allowssftp
and notscp
(orrsync
).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 onfileserf
.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 tosftp
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 withrssh
?Alternatively, How can I configure
sshd
to override the login-shell for a group of users?-
muru over 8 yearsIf you can add these users to a local group, perhaps you can create local users which shadow them?
-
-
umläute over 8 yearsthat's why the title of my question says [how to] "make sshd override login shell". updated the question-body to reflect that...
-
muru over 8 years@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 aForceCommand
which prints$SHELL
. -
muru over 8 years@umläute see update.
-
umläute over 8 yearsthe 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 over 8 yearsactually 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 :-()