How to restrict ssh port forwarding, without denying it?
Suppose I have created an account whose login shell is actually a script which does not permit an interactive login, and only allows a very limited, specific set of commands to be remotely executed.
Nevertheless, ssh
allows the user of this account to forward ports, which is a hole.
Now, the twist is that I actually want that account to set up a specific port forwarding configuration when the ssh
session is established. But it must be impossible configure arbitrary port forwarding.
(It is an acceptable solution if the permitted port forwarding configuration is unconditionally established as part of the every session.)
Solution 1:
Turns out, OpenSSH has a feature for this, for restricting -L
style opens on the server side. The feature is available in two ways.
In the server configuration file there is a
PermitOpen
option. This option can be used to specify hosts and ports for which forwards can be established. This option can be used inside aMatch
block, so it can be restricted by user, group, or hostname or IP address pattern.In an
authorized_keys
file, options can be associated with a particular key. There is apermitopen
option which works similarly to the server-config one.
Notes/Limitations:
The option
AllowTcpForwarding
disables all forwarding in both directions, preventing listening ports from being set up on the server, as well as active forwards.There is no
PermitOpen
access control for-R
style connections. This is probably okay. What it means is that the users can usessh
to open various non-privileged ports for listening on the server. Where these connect to on the other side of the SSH connection is the client's problem. If we restrict forwarding in the-L
direction, the user has no way of using those-R
ports (at least not throughssh
, if that user is not able to create an arbitrary interactive session).There doesn't seem to be a way to create an empty list of permitted opens, to prevent users from making any
-L
style connections whatsoever. However, a workaround is to use a harmless, nonexistent or impossible host name, such as the empty string. Concretely,permitopen=":1234"
does the trick.