Restrict a User to SSH Forced Command

5 minute read

We are all using SSH in our daily tasks. It is mostly used for the connection to the remote host, but as we know, we are able to execute the command over the SSH and get the output back to our local terminal.

Sometimes we need to perform some automated routine tasks on the remote server. Backup execution is one of the most used tasks. I’m sure you can think of an additional few tasks that could be done. So, what is wrong with that, you may ask? The main issue for such a scenario is that once we are set an SSH user for such task, it will get the full access to our remote system.

NOT GOOD!

Fortunately, we can use a great SSH feature called forced command within the authorized_keys file.

The command is bound to an SSH key, so when the user is trying to execute a random command, the only output that will be received is the output of the command configured previously by the admin.

Command structure

The structure of the forced command within the authorized_keys file.

<command> <ssh public key> <comment>

Example:

command="date" ssh-rsa AAAAB3Nz..(omit output)..cMOAIubywZCB vagrant@client1

Command in action

Let’s try to execute a number of commands with the command “date” on the server (see example above) and see the output.

$ ssh vagrant@server1 "date"
Mon Apr 22 09:35:15 UTC 2019
$ ssh vagrant@server1 "ls /var/lib"
Mon Apr 22 09:35:37 UTC 2019
$ ssh vagrant@server1
Mon Apr 22 09:35:08 UTC 2019
Connection to server1 closed.

As we can see, any command including the connection attempt results in the output of the command “date”, which we set as the forced command.

Environment variable

The command that is passed to the remote host, stored in the environment variable - SSH_ORIGINAL_COMMAND.
We could debug the behavior of the forced command by “echo” the command we pass to the remote host, back to us.

command="echo $SSH_ORIGINAL_COMMAND" ssh-rsa AAAAB3Nz..(omit output)..cMOAIubywZCB vagrant@client1
$ ssh vagrant@server1 "df -h"
df -h

Multiple commands execution

The forced command supports only one single command per a single SSH key pair.
In order to bypass this, we could place a simple bash script as the command.
* The example below is taken from the SSH, The Secure Shell: The Definitive Guide book by O’Reilly.

#!/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)
         /bin/ps
         ;;
      q)
         /bin/echo "Goodbye"
         exit 0
         ;;
      *)
         /bin/echo "Invalid choice '$ans': please try again"
         ;;
   esac

   /bin/echo "Your choice:"
   read ans
done
exit 0

Place the script into the appropriate location and set the executable flag for the user.
Within the authorized_keys file, place the path to the script.

command="/usr/bin/local/tasks_script.sh" ssh-rsa AAAAB3Nz..(omit output)..cMOAIubywZCB vagrant@client1

The output of the execution will be the following:
Note the output for not existing “test” command.

$ ssh vagrant@server1
Welcome!
Your choices are:
1       See today's date
2       See who's logged in
3       See current processes
q       Quit
Your choice:
1
Mon Apr 22 12:35:37 UTC 2019
Your choice:
2
vagrant  pts/0        2019-04-22 12:24 (10.0.2.2)
vagrant  pts/1        2019-04-22 12:35 (172.28.128.14)
Your choice:
3
  PID TTY          TIME CMD
 2028 pts/1    00:00:00 test_script.sh
 2035 pts/1    00:00:00 ps
Your choice:
test
Invalid choice 'test': please try again
Your choice:
q
Connection to server1 closed.

Additional SSH arguments

When required, additional connection options may be configured for the connection in order to limit the permissions of the user.
An example of the options that may be set:

  • no-agent-forwarding - Forbids authentication agent forwarding when this key is used for authentication.
  • no-port-forwarding - Forbids TCP forwarding when this key is used for authentication.
  • no-pty - Prevents tty allocation (a request to allocate a pty will fail).
  • no-X11-forwarding - Forbids X11 forwarding when this key is used for authentication.

Search through the authorized keys man pages for more options.

The example configuration will look like the following:

command="df -h",no-port-forwarding,no-X11-forwarding ssh-rsa AAAAB3Nz..(omit output)..cMOAIubywZCB vagrant@client1

Rsync usage

Back to our first case scenario. Use rsync for the backup.

The rsync could be used in both directions:

  • The user backup data from the server.
  • the user backup data to the server.

Backup data from the server

command="/usr/bin/rsync -azv --server --sender --delete /home/vagrant/backup/ ." ssh-rsa AAAAB3Nz..(omit output)..cMOAIubywZCB vagrant@client1

Flags:

  • a - Archive mode. Include the following flags:
    • r - Recurse into directories
    • l - Copy symlinks as symlinks
    • p - Preserve permissions
    • t - Preserve modification times
    • g - Preserve group
    • o - Preserve owner (super-user only)
    • D - Preserve device files (super-user only) and special files
  • z - Compress file data during the transfer
  • v - Verbose output
  • server - The option is used only on the server side because of the login restriction to the rsync command
  • sender - The option is used only on the server side because of the login restriction to the rsync command
  • delete - Delete extraneous files from dest dirs

From the output below we can see that the files received successfully from the server.

$ rsync -azv --delete -e "ssh" vagrant@server1:/home/vagrant/backup/ backup/
receiving file list ... done
created directory backup
./
file1
file2
file3
file6
file8
total: matches=0  hash_hits=0  false_alarms=0 data=20

sent 122 bytes  received 432 bytes  1,108.00 bytes/sec
total size is 20  speedup is 0.04

Backup data to the server

command="/usr/bin/rsync -azv --server --delete . /home/vagrant/backup/" ssh-rsa AAAAB3Nz..(omit output)..cMOAIubywZCB vagrant@client1

Flags:

  • a - Archive mode. Include the following flags:
    • r - Recurse into directories
    • l - Copy symlinks as symlinks
    • p - Preserve permissions
    • t - Preserve modification times
    • g - Preserve group
    • o - Preserve owner (super-user only)
    • D - Preserve device files (super-user only) and special files
  • z - Compress file data during the transfer
  • v - Verbose output
  • server - The option is used only on the server side because of the login restriction to the rsync command
  • delete - Delete extraneous files from dest dirs

From the output below we can see that the files successfully copied to the server.

$ rsync -azv --delete -e "ssh" backup/ vagrant@server1:/home/vagrant/backup/
building file list ... done
created directory /home/vagrant/backup
delta-transmission enabled
./
file1
file2
file3
file6
file8

sent 378 bytes  received 188 bytes  1,132.00 bytes/sec
total size is 20  speedup is 0.04

For more rsync options, refer to the man page.

Conclusion

By using a simple forces command provided by the SSH, we can make our system a bit more secure.

Tags:

Updated: