How to bind an SSH public key to a specific command

In the client-server architecture used by the SSH protocol, a client can authenticate by providing a tunneled clear text password or by using a public/private key pair: this is called public key authentication. A user who logs in via a public key on a remote machine has complete access to the command line; in certain situations, however, it may be useful to associate a public key to a single specific command, for security reasons.

In this tutorial we see how to copy a public key to an SSH server, and how to bind it to a specific command.

In this tutorial you will learn:

  • How to copy an public key to an SSH server
  • How to bind an SSH public key to a specific command
How to bind an ssh public key to a specific command
How to bind an SSH public key to a specific command – Photo by Jordan Harrison on Unsplash
Software Requirements and Linux Command Line Conventions
Category Requirements, Conventions or Software Version Used
System Distribution agnostic
Software openssh
Other None
Conventions # – requires given linux-commands to be executed with root privileges either directly as a root user or by use of sudo command
$ – requires given linux-commands to be executed as a regular non-privileged user

The “authorized_keys” file

Public key authentication is based on the use of a public/private key pair to access a remote machine running the SSH server. The private part of the keypair is kept secure on the client machine, while the public key is  copied on the the server. Authorized public keys on the server are written, one per line, into the appropriate authorized_keys file. Its location can be configured, but the file is typically found under the ~/.ssh directory.



In order to copy a public key to an SSH server, we can use the ssh-copy-id command. Supposing the server is listening to the default SSH port (22), and we want to copy the ~/.ssh/id_rsa.pub public key, as the “foo” user on the “bar” host, we would run:

$ ssh-copy-id -i ~/.ssh/id_rsa.pub foo@bar

In order for the command to succeed, we will be requested to provide the user login password. If everything goes as expected, we should finally see a message confirming the key has been copied:

    Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'foo@bar'"
and check to make sure that only the key(s) you wanted were added.

If the SSH server was configured to use a non-standard port, we can specify it by using the -p option and pass the port number as argument:

$ ssh-copy-id -i ~/.ssh/id_rsa.pub -p <portnumber> foo@bar

Once a key has been copied on the server, it will appear in the appropriate “authorized_key” file. If you take a look at it, you will see the following format is used:

<key-type> <key-content> <optional-comment>

The key-type section reports the type of key (e.g. ecdsa, rsa); the key-content is the actual content of the key, base64-encoded, and the comment, which is optional, is automatically added at key creation time, and typically consists into the username and the hostname of the client machine on which the key was generated. Here is an example:

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCS9exhL3nTEd9g9b14F0NLJ6glRi2aWQS7N5mWwtjmchy+9IfQNXUDME2EUfKzxumAZsqWvPxcUms9OkYil6R0CaP/YepninjiUec5lBU6jo1iG/xgTzNJYsHPde6fQmmCh+vdZbIf8+DDK+rVS7eLTWZViQzFpH8rBjT9hhAk1aWEtZp1b2ZbvVikNCTpZ+V7IDW/EtDNKyiJjZvUMmipDwf4+BPKUkTva+PBcxHrOa4U6poNvHIzq8ud+5YUPquV0kzywUprnMmusHlF/NpD6IolMM+of2OT/+plqh69KQs7DHsecXyKIhiDh08bU8c7QWuVTjj2GatvEoC4mbBGxqr7atOKmUB9yRzgQi+tEnAqUCqKn2naFVDwB1iMROmFPBAZxByHhTjjVEPfpQJi4TKIuMgvhmKmYaJCfIs2bl4MzE2PfKbSiAAG1sEAuS7QfWw5o0z2UWcGscJPRabtkjq6Gcfzwxi/50ogbuRcZ4Ia8dx3c0nCqRX1zSwXmEs= foo@bar

Binding a public key to a specific command

In order to bind an SSH public key to a specific command, we must use another optional field in the “authorized_keys” file. This field precedes the “key-type”, and can be used to specify various connection options. In this case, what we want to do, is to pass the full path of the executable we want to associate with the key.



Just as an example, suppose we want the df -h / command, which displays the available and used space in the root filesystem, to be the only one allowed when using the public key for authentication. Sticking to the previous example, we would modify the entry in the “authorized_keys” file the following way:

command="/usr/bin/df -h /" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCS9exhL3nTEd9g9b14F0NLJ6glRi2aWQS7N5mWwtjmchy+9IfQNXUDME2EUfKzxumAZsqWvPxcUms9OkYil6R0CaP/YepninjiUec5lBU6jo1iG/xgTzNJYsHPde6fQmmCh+vdZbIf8+DDK+rVS7eLTWZViQzFpH8rBjT9hhAk1aWEtZp1b2ZbvVikNCTpZ+V7IDW/EtDNKyiJjZvUMmipDwf4+BPKUkTva+PBcxHrOa4U6poNvHIzq8ud+5YUPquV0kzywUprnMmusHlF/NpD6IolMM+of2OT/+plqh69KQs7DHsecXyKIhiDh08bU8c7QWuVTjj2GatvEoC4mbBGxqr7atOKmUB9yRzgQi+tEnAqUCqKn2naFVDwB1iMROmFPBAZxByHhTjjVEPfpQJi4TKIuMgvhmKmYaJCfIs2bl4MzE2PfKbSiAAG1sEAuS7QfWw5o0z2UWcGscJPRabtkjq6Gcfzwxi/50ogbuRcZ4Ia8dx3c0nCqRX1zSwXmEs= foo@bar

The command will be automatically executed each time we try to connect:

    $ ssh foo@bar
    Filesystem      Size  Used Avail Use% Mounted on
    /dev/root        15G  2.3G   12G  17% /
    Connection to XXX.XXX.X.XX closed.

In certain situations we may need to perform more complex operations requiring the use of more than a single command, and include some logic. In those cases we can create a script and specify its path as the command.

Bypassing the key

You must always make sure you have another mean of authentication when you bind an SSH key to a single command, otherwise you may be locked out of the server. If you have another authorized key available, you can explicitly use it for the connection:

$ ssh -o "IdentitiesOnly=yes" -F /dev/null -i /path/to/alternative/private/key foo@bar



In the example above, by using -o IdentitiesOnly=yes we specified we only want to use the key we passed as argument to the -i option, and we used -F /dev/null to be sure no configuration file is parsed, since in it, the restricted key could be associated to the remote machine.

As an alternative, if the SSH server is configured to allow tunneled clear text password authentication, we can temporarily disable public key authentication by running:

$ ssh -o PubKeyAuthentication=no foo@bar

Conclusions

In this tutorial we saw how to bind an SSH public key to a single specific command. We also saw how to copy a public key on a server, and how to temporarily bypass the use of a restricted key.



Comments and Discussions
Linux Forum