This site uses cookies for analytics. By continuing to browse this site, you agree to use this.  Learn more

SSH Proxying without allowing shell access

Disallowing shell access in the sshd_config

Posted on April 11, 2019

Why do you want to do it?

There may be many reasons why you want to do it, but for us a simple reason comes to mind. We want to allow users to use a jumphost to jump into our IPv6 net from IPv4, but they don't need shell access for it. So by allowing them to jump, but denying a shell, we have a jumphost with way fewer security concerns than if it was just a normal SSH Host.
This way, with a small edit of the .ssh/config, we can provide a nearly transparent jump with just an added intermediate authentication to go through.

How to do it in sshd_config

The first solution coming to most minds would be some combination of AllowUsers, DenyUsers or the group variant. That seems easiest and you can easily implement either a blacklist or whitelist, but it won't work, since denying a user also denies them the ability to make use of the jumphost feature.

Another solution would be to give the users the nologin executable as a shell, which will work for denying them access to the host itself, but feels like a rather inelegant solution. It's much better to simply define the solution in the sshd_config, since there it's a single option, and it doesn't rely on the correct configuration of every user's shell, which adds a further risk that something can go wrong.

With the thought that we want a simple, central solution in mind, let's look at our options. In the sshd_config, we want to either define a whitelist or a blacklist, so the Match keyword is a natural candidate to do it.

Here is an example for a whitelist:
Match *,!CEO,!admin,!bobthejanitor,!randomguyfromthestreet
This matches everyone except CEO, admin, bobthejanitor and randomguyfromthestreet. So an easy whitelist is set. If you have more than a handful of users, you can easily match a group, like so:
Match Group !shellusers
That matches if the group is not shellusers. Maybe you have way more normal users than jumphost users, then you may want to match with a blacklist, also easily done.

Here is an example for a blacklist:

Match CTO,jump1,karlthebeancounter
This matches CTO, jump1 and karlthebeancounter. Of course, you can match for groups, again, that's a more easy way if the user numbers get higher.
Match Group jumpers
That matches if the group is jumpers, so you can just confine the jumphostusers into the group jumpers.

Now that we have a match for the jumphost users, let's get to denying the shell access. From what I've seen, there are two very simple solutions to that. For the examples we use a simple whitelist, but of course every form of matching described earlier will work too.

Match *,!admin
   ForceCommand /bin/true

This overrides every command send with /bin/true, so no shell or execution of programs through ssh. Basically, it is a much nicer version of the nologin-shell described above. Still, I feel that this is still not the most elegant and efficient solution, since it will still run the command. That step is not needed I feel, and the next solution is more elegant to my mind.

Match *,!admin
   MaxSessions 0

This version tells the SSH the number of allowed open shell, login or subsystem sessions permitted per network connection. So with this set to 0, none of the above is allowed, but it is still permitting proxying, which is just what we want. I feel this is the most elegant solution, since it will disallow commands and shells, and does it without substituting it with a small command, so forgoing the (in my mind) unnecessary step.

There may be other solutions, but I feel the 'MaxSessions 0' solution is doing exactly what we want from the jumphost, so this is the
one implemented on our jumphost. The 'ForceCommand' and nologin solutions work too, but through executing a command they take an extra
step, which, given current hardware, is not really noticeable, but can be avoided, so why not avoid it?


To configure a jumphost in sshd_config for a set of users, you can either use a whitelist for shellaccess or a blacklist for just jumping.
So for a quick reference here are the matches you put at the end of the sshd_config:



Match *,!root,!user1,!user2
   MaxSessions 0


Match Group !shellusers
   MaxSessions 0



Match jumpuser1,jumpuser2,jumpuser3
   MaxSessions 0
Match Group jumpusergroup
   MaxSessions 0