The authorized_keys has a command="..." option that restricts a key to a single command. Is there a way to restrict a key to multiple commands? E.g. by having a regex there, or by editing some other configuration file?

up vote 5 down vote accepted

No. Is is not "allowed" command, but "forced" command (as ForceCommand option).

The only possibility is to use different keys for different commands or read parameters from stdin.

You can have only one command per key, because the command is “forced”.

But you can use a wrapper script. The called command gets the original command line as environment variable $SSH_ORIGINAL_COMMAND, which it can evaluate.

E.g. put this in ~/.ssh/allowed-commands.sh:

#!/bin/sh
#
# You can have only one forced command in ~/.ssh/authorized_keys. Use this
# wrapper to allow several commands.

case "$SSH_ORIGINAL_COMMAND" in
    "systemctl restart cups")
        systemctl restart cups
        ;;
    "shutdown -r now")
        shutdown -r now
        ;;
    *)
        echo "Access denied"
        exit 1
        ;;
esac

Then reference it in ~/.ssh/authorized_keys with

command="/home/user/.ssh/allowed-commands.sh",…

In the great SSH, The Secure Shell: The Definitive Guide book by O'Reilly, in chapter eight, there is a nice example given using a script like the following:

#!/bin/sh

/bin/echo "Welcome!
Your choices are:
1       See today's date
2       See who's logged in
3       See current processes
q       Quit"

/bin/echo "Your choice:"

read ans

while [ "$ans" != "q" ]
do
   case "$ans" in
      1)
         /bin/date
         ;;
      2)
         /usr/bin/who
         ;;
      3)
         /usr/bin/top
         ;;
      q)
         /bin/echo "Goodbye"
         exit 0
         ;;
      *)
         /bin/echo "Invalid choice '$ans': please try again"
         ;;
   esac
   /bin/echo "Your choice:"
   read ans
done
exit 0

Using this in your .authorized_keys file like:

command="/path/to/your/script.sh" <ssh-key>

...gives you this when doing ssh:

Welcome!
Your choices are:
1       See today's date
2       See who's logged in
3       See current processes
q       Quit
Your choice:
  • But such script basically breaks scp, sftp and all the other stuff you might find useful some day. – Jakuje Oct 4 '16 at 20:30
  • 2
    @Jakuje Isn't this valid for the command option in general? – gf_ Oct 6 '16 at 9:47

Other approaches use e.g. a restricted shell for the given user or use a wrapper which restrains commands to al files/scripts found in a specific directory, thus allowing to augment the list of commands without changing the wrapper.

Another article describes a generic script, which also permits command line arguments to the allowed commands, but allows to lock them down with rules expressed as regular expressions.

This example would be expressed the following way:

command="only systemctl shutdown"

And an .onlyrules files would be crafted with this content:

\:^systemctl restart cups$:{p;q}
\:^shutdown -r now$:{p;q}

The advantage of this 'only' approach is that there is no need to write individual scripts for each user and situation.

  • The problem with changing the shell is that it will apply to all logins, even those with a key that is not intended to be restricted. Moreover if you only shell login and no administrator access you cannot just change your configured shell to whatever you want. But you can still edit your authorized_keys file. – kasperd Mar 12 '17 at 22:28
  • You can use a "restricted shell" as a ForcedCommand – Georg Lehner Mar 14 '17 at 2:06
  • It occurs to me, for the situation where the account being used is a normal user account, and the actions required are privileged, that one could rely on sudo to do the checking, and set the authorized_keys command option to "sudo $SSH_ORIGINAL_COMMAND"? – Steve Dee Aug 15 at 18:35

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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