Executing commands upon remote machines via secure email

Posted by Steve on Thu 12 Apr 2007 at 20:48

I recently came across the grunt package which is designed to allow you to execute commands remotely, via the delivery of GPG-signed email. Since documentation is scant this introductory article was born.

Once installed there are three commands that can be used:

gruntsend

This allows you to send a list of commands to your mail server, where they will be executed. You'll be prompted to sign your mail, and this will then be sent.

gruntrecieve

This is the part of the program which reads in the encrypted command(s), verifies the signature and if they are valid executes them.

gruntrun

This command simply executes a simple command upon the remote host - without you needing to write it to a temporary file and cause it to be uploaded as you would with gruntsend.

To be clear about how the process works we'll show it running upon two machines:

To get started we'll need to install the package upon both our local and remote machines - the remote system obviously needs it to receive the commands from your mail server, check the signatures and do the execution magic. The local system also needs the package installed such that the encrypted magic can be generated.

To get started you'll need to install the package:

root@local:~# apt-get install grunt
...

root@remote:~# apt-get install grunt
...
Remote Setup

Once you've installed the system we can look at hooking it up. The server-side should be configured first, since that is the part which will execute the commands. Unfortunately this is probably a part you'll need to manage yourself. The gruntreceive script will expect to read an encrypted message upon its STDIN, and then execute it after checking that the signature was both valid and one that it is configured to trust.

What does this mean? Well it means that you'll most likely need to use procmail, or something similar to pass the message to your grunt installation. (You could also use sieve, or possibly even fetchmail to do this...)

As a very simple example you could configure procmail such that messages with the subject of "---GRUNT_SIGNED_JOB_EMAIL---" (the default) will be decoded and executed if valid.

Here is a simple recipe to achieve this for your ~/.procmailrc file:

:0
*(Subject:).*(---GRUNT_SIGNED_JOB_EMAIL---)
|/usr/bin/gruntreceive

The next thing to do is to give the system a list of keyids which it should process signed messages from. I've done this with the following two commands :

mkdir ~/.grunt
echo "CD4C0D9D" >> ~/.grunt/validsigs.txt

(Here "CD4C0D9D" is my key-id. As determined by running "gpg --list-key steve@example.com")

Note: you'll need GPG installed upon this system, and the keyring should contain your key so that the signature can be checked.

Local Setup

The local machine doesn't require anything special. It just needs to have the package installed and be able to send outgoing email.

To use the system you should simply create a small shell script with your commands in it:

#!/bin/sh
#   ~/tmp.sh
id
uname -a
df

Once you have that file you can send that to the remote system and cause it to be executed by running:

gruntsend ~/tmp.sh steve@example.com /tmp/output.new

We've given this script three arguments:

All being well after a few minutes you should see your output appear upon the remote system.

Rather than using gruntsend to upload and execute a file you can also use gruntrun to send a command. For example:

gruntrun steve@example.com "touch /tmp/blah; uptime > /tmp/blah.uptime"

Note: you'll need GPG installed upon this system, and the keyring should contain your key so that the signature can be checked.

This concludes our introduction to grunt. Whilst it isn't a perfect solution because there is no simple means of getting the output back (it would be nice if a reply mail were sent automatically containing the output) and you can't run interactive commands such as "sudo /etc/init.d/apache2 stop" (which will require a password) it can come in handy for quick jobs on the road.


This article can be found online at the Debian Administration website at the following bookmarkable URL (along with associated comments):

This article is copyright 2007 Steve - please ask for permission to republish or translate.