I would like to restrict some users on my server to only being able to execute certain commands. To do this, the most common approach that I could find is to use rbash
.
While I can find many websites talking about rbash, I am having trouble to find any information how to use it right. The most common approach that I could find was to create a symlink from /bin/rbash
to /bin/bash
, set the restricted users’ login shell to /bin/rbash
and then set a custom PATH
in ~/.bash_profile
in the user home directory.
However, I was quite shocked to find out that with this setup users can still copy files to the server using scp
and they can even open an unrestricted shell by using ssh user@host -t bash
! What seems to be happening is that the SSH server is passing the command to the login shell on the server using -c
, so ssh user@host -t bash
causes the server to run /bin/rbash -c bash
, which works because .bash_profile
is not executed yet to restrict the path. scp
similarly causes the server to run /bin/rbash -c scp
.
Now I have come across the ForceCommand
directive of sshd. This directive basically always causes the configured command to be passed as -c
to the login shell, ignoring any command that the client has specified. So if ForceCommand
is set to rbash
, that will always execute the command /bin/rbash -c rbash
on the server, regardless whether the client was called with -t bash
or as scp
or whatever. Unfortunately, /bin/rbash -c rbash
causes the .bash_profile
not to be executed, so we end up with a restricted shell but a normal PATH
, so we can just call bash
there to escape it.
What I would like to achieve:
- There should be no way to avoid the restricted shell for users connecting via SSH
- Ideally, it would still be possible to execute commands that are permitted in the restricted shell by using
ssh user@server permitted_command
- The configuration should not be SSH-only, so users logging in for example on the TTY should also be restricted.
After experimenting with this for a while it seems to me that the root of the problem is that the security of
rbash
depends onPATH
being set, but in most setupsPATH
is set after SSH specifies its custom commands, whereas it needs to be specified before.As a solution, rather than specifying
/bin/rbash
(symlink to/bin/bash
as the login shell), I have created a shell script/usr/local/bin/rbash
and used that as the login shell instead. The shell script has the following content:I also experimented with the
SetEnv
directive of sshd and tried to set thePATH
there. However, I found this solution less practical because it sets the configuration only for SSH, and also it caused lots of errors while running/etc/profile
, because the commands used there could not be found. Also, there seems to be a risk that some other sshd directives would allow the client to override certain environment variables again.