Automating Tasks with SSH

From docwiki
Jump to: navigation, search


Motivation

Besides interactive login, SSH can also be used to automate thing by directly executing remote commands and also connecting STDIN and STDOUT to transfer date.

To understand the following examples, make sure you know about Redirecting and Piping input and output of commands.


Executing a remote command

Lets assume you have created an alias for your host with the name myweb. Then you can do. E.g:

$ ssh myweb "find /var/www"

This would list all files below /var/www on the remote server and the output is displayed on your local server. This means you could also redirect the output on your local server. Either to a command or to a file:

$ ssh myweb "find /var/www" | grep \\.png > images-on-my-webserver.txt

So the above example runs the same find command on the myweb server. The output is transported via the ssh channel and available as STDOUT on our local server. On our local server we filter it through the grep command to only contain lines that end with .png and finally we redirect the output on our local server to the file images-on-my-webserver.txt

Now of course it we could save a bit of bandwidth if we would already filter on the remote side:

$ ssh myweb "find /var/www | grep \\.png" > images-on-my-webserver.txt

(note the different positions of the " )

We can also redirect the input to commands.

E.g.

$ echo bla | ssh myweb "cat - > test.txt"
$ raspistill -w 320 -h 240 -n -t 1 -o - | ssh myweb "cat - > /var/www/livecam.jpg"
$ dd if=/dev/sdc bs=1M | ssh myweb "dd bs=1M of=disk.img"

The first example just creates a file text.txt on the remote server with the content bla. The second example could be run on your raspberry PI and uses the raspistill to read an image from the camera and write it to STDOUT (-o - ). Instead of storing the file locally the file is directly transmitted to the remote host where it is cat into a file named livecam.jpg

The last example uses the program "dd" which directly reads from a raw image of a hard drive or an other block device. In this example we read the disk /dev/sdc. This could e.g. by your usb-thumb drive. On the remote machine we store this on a file named disk.img. This way you could copy the image of a USB thumb drive directly to a file on a remote machine. You could even directly write it to an other stick! Of course, reading from a disk will need root privileges.

Protecting your SSH key for automatic execution

As you can see from the examples above this is quite useful for automation. E.g. you want to run the tool that transmits the images on startup of your raspberry pi and then e.g. every 2 minutes. But in order to do this you would need an SSH key without passwords, because you do not always want someone who types in the password when the machine starts. And if you would store the passphrase alongside the key then it is of no use neither.

SSH has a good solution for the above problem. It is possible to limit what can be executed with a certain key. .ssh/authorized_keys has one line for each key that is allowed to login. You can prefix this line with a number of options to limit what the key is allowed to do:

command="/root/mybackup.sh",from="10.11.12.14",no-port-forwarding,no-pty ssh-rsa AAAAB7....

So the usual line would start with ssh-rsa AA... and before that we give the options to limit what can be done with the key. We will cover the port-forwarding later. The from= allows to limit the IP addresses from where this key can be used. This is useful if it is always from the same IP anyways. The important part is the command=. This allows to say which command will be executed when someone connects with that key. The user can specify other commands but that will be ignored by the server and only the command in the command= option will be used.

In the example above the script could generate some data to be backed up and stored somewhere by our local server. So this could be like this:

$ ssh -i /opt/backupkey myweb do-backup | /opt/tools/mytapebackup.sh 

So we would use a file named backupkey that holds the private part of the key and use it to login to myweb. It says it wants to run "do-backup" but that is ignored. The output of the remote script will then be piped into a local script named mytapebackup.sh that processes the output and e.g. writes it to a tape drive.

If someone would break into our server and steal the backupkey file they could use it to trigger the backup and read the data but otherwise they can not do anything on the remote machine.

Exercises

  • create the file bla.txt on a remote machine and write the output of the local "hostname" command to it. Use only ssh and no scp.
  • create a new key-pair with the name testkey and teskey.pub. Install that key on a remote machine in the authorized_keys file and prefix it with a command= option to limit what can be done with it. Choose e.g. the /usr/bin/uptime command. Test if the limitation works.