Restrict User to rbash via SSH – How to Guide

bashssh

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.

Best Answer

After experimenting with this for a while it seems to me that the root of the problem is that the security of rbash depends on PATH being set, but in most setups PATH 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:

#!/bin/bash -l
export PATH=/usr/local/rbin
exec /bin/bash -r "$@"

I also experimented with the SetEnv directive of sshd and tried to set the PATH 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.