Systems, Tools, and Terminal Science

Main menu

Post navigation

Restricting public keys

It may be the case that while you’re happy to allow a user or process to have
public key authentication access to your server via the
~/.ssh/authorized_keys file, you don’t necessarily want to give them a full
shell, or you may want to restrict them from doing things like SSH port
forwarding or X11 forwarding.

One method that’s supposed to prevent users from accessing a shell is by
defining their shell in /etc/passwd as /bin/false, which does indeed
prevent them from logging in with the usual ssh or ssh command syntax. This
isn’t a good approach because it still allows port forwarding and other
SSH-enabled services.

If you want to restrict the use of logins with a public key, you can prepend
option pairs to its line in the authorized_keys file. Some of the most useful
options here include:

from="<hostname/ip>" — Prepending from="*.example.com" to the key line
would only allow public-key authenticated login if the connection was
coming from some host with a reverse DNS of example.com. You can also put
IP addresses in here. This is particularly useful for setting up automated
processes through keys with null passphrases.

command="<command>" — Means that once authenticated, the command
specified is run, and the connection is closed. Again, this is useful in
automated setups for running only a certain script on successful
authentication, and nothing else.

no-agent-forwarding — Prevents the key user from forwarding
authentication requests to an SSH agent on their client, using the -A or
ForwardAgent option to ssh.

no-port-forwarding — Prevents the key user from forwarding ports using
-L and -R.

Use of these options goes a long way to making your public key authentication
setup harder to exploit, and is very consistent with the principle of least
privilege. To see a complete list of the options available, check out the
man page for sshd.

I believe that the use of no-port-forwarding also blocks dynamic port forwarding (-D).

Once you close port forwarding with no-port-forwarding, you can open specific ports with permitopen. In addition, I believe that use of permitopen implies no-port-forwarding. For example::
no-pty,permitopen=”localhost:143″,permitopen=”localhost:25″ ssh-rsa AAAAB3Nz…
prevents use of any ports except 25 and 143. Unfortunately, it is my experience that once you cannot use permitopen to open reverse or dynamic ports, so with any restriction of ports using either no-port-forwarding or permitopen you lose the ability to do reverse or dynamic port forwarding.