I have a person who will need access to my SSH server, but I want them to have limited access to programs. All they should be using is ssh, to login to another server. My server is an access point to another server. I don't want this user to run programs other than the ssh program they need to get on the other network.

Ideally, when they login, they would be redirected to another SSH login, and not have any other immediate option to do anything else.

No SSH users have root permissions.

How might I be able to set this up? I am thinking I can do it with their bashrc files. I'll write a secondary login script that executes when they login. Is there a way for a user to login to an SSH server, and ignore their bashrc file on login? Is there a better way I should consider?

  • 3
    Every time someone suggests implementing security functionality via their .bashrc, Bruce Schneier's inner child takes another long, sad draught of tequilla. Jul 18 '15 at 3:35
  • another way, that i have used before, in a case like this, is connection relaying. but i wrote a program to do it so i cannot suggest how you could do it. it listens on a port other than 22 or a different IP address, makes a new TCP connect to sshd on another host and passes all traffic both ways. the user must the be using an ID key known to the next host instead of keys on the middle host and connect to the alternate port/address.
    – Skaperen
    Jul 18 '15 at 9:40

Consider using a ForceCommand directive in sshd_config. For example, I use these to force groups of users to a set of servers:

Match Group group1
       ForceCommand ssh -t group1.fqdn

Match Group="*,!local,!group2,!root"
       ForceCommand ssh -t group3.fqdn

You could use:

Match User foo
    ForceCommand ssh -t target-host
  • 1
    this disables the user from managing their ssh keys. maybe this is a good thing in some cases.
    – Skaperen
    Jul 18 '15 at 9:43
  • @Skaperen not necessarily. It does if the authorised keys are in the default location in the gateway server, but we can configure the gateway server sshd to look elsewhere, or use a lookup command which will contact the target server. Or, as in my case, NFS home directories shared across both servers.
    – muru
    Jul 18 '15 at 10:09
  • Out of curiosity, does this get executed in place of the shell? I'm wondering what would happen if you tried to suspend the "inner" SSH session (Enter ~ Crtl-Z)
    – IMSoP
    Jul 18 '15 at 15:37
  • @IMSoP the docs say the command is run using the login shell of the user using the -c option (unless the command is internal-sftp). And CR-~-^z suspended the whole connection.
    – muru
    Jul 18 '15 at 16:04

You thought to edit the bashrc file. I would take a look at limiting their access to all bash commands other than ssh this way they can . This link has good information.

Another thought is to setup a ssh pass through tunnel without access to a login. This link might be useful as well. This might be easier to configure.

  • I did not know about the ForceCommand directive in sshd_config as pointed out by @muru. I recommend muru's solution above.
    – Carl Trask
    Jul 18 '15 at 3:40

Simply set the user's login shell to a shell script instead of bash or sh containing the ssh syntax to second endpoint. All logins, unless they explicitly define a shell with -s in ssh syntax, would redirect as you requested.

I can get out of BASHRC limitations by various methods. If you expect them to be malicious make sure they cannot specify alternate shell on login.

Trap user sigint so they cant Ctrl + C out and check on exit of ssh for exit code 0, otherwise exit completely or retry indefinitely. Your choice.


You can do this somewhat transparently by forcing the user to use a ProxyCommand locally, treating your own server as an SSH bastion host.

On your server (the bastion), restrict the user to nc as follows in sshd_config:

Match User restricted_usr
  ForceCommand nc -w 600 restricted_usr_vm 22

On the client (assuming OpenSSH) in ~/.ssh/config:

Host myserver
  ProxyCommand ssh bastion nc -w 600 restricted_usr_vm 22

(Windows users can use ssh proxies via PuTTY by using PuTTY's plink).

Though, thanks to your ForceCommand, I'm pretty sure the ssh command is ignored; ProxyCommand ssh bastion I am a bannana should have the same effect. A direct connection (lacking ProxyCommand) from the user will result in a raw SSH dump to restricted_usr_vm.

As noted in a comment to another answer here, ForceCommand will make it very hard to manage SSH key access to the bastion host. I can think of two easy solutions: (1) Install a passwordless SSH key for that user on the bastion that grants access to the target host and have that user's crontab on bastion run scp restricted_usr_vm:.ssh/authorized_keys ~/.ssh/ or (2) Create a web form (like GitHub's) to allow uploading that file. (3) NFS can also work, but I'm not so fond of it because the .ssh directory could become compromised by somebody with root (or the same UID) on any system that mounts it.

I posted a very similar answer (with more detail on ProxyCommand) to the very similar ServerFault question Username based SSH proxy.

I like this a lot better than ForceCommand ssh -t restricted_usr_vm because it deals with timeouts better and ssh -t is kind of clunky (and, perhaps by now in the past, sometimes unreliable). I'm also guessing that things like scp won't work through this method while they'll work perfectly via ProxyCommand.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.