Executing commands upon remote machines via secure email

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

Tags: , ,

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:

  • Remote
    • This is a machine which is running an SMTP server - this is where your mails will end up, and where your commands will be executed.
  • Local
    • This is any machine which has grunt installed and is used to send the command to the remote machine.

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:

  • The local filename of commands to upload, and execute remotely.
  • The email address to send the script to.
  • The path upon the remote system to place the output within.

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.

 

 


Posted by dkg (216.254.xx.xx) on Thu 12 Apr 2007 at 22:07
[ View dkg's Scratchpad | View Weblogs ]
It's nice to see this kind of infrastructure being built. Thanks for the pointer, Steve.

At first glance, i was concerned about replays, given the nature of SMTP.

But looking through the source, i see that /usr/bin/gruntreceive is storing a list of md5sum hashes of messages already received, and rejecting if the message is a repeat. Very nice.

[ Parent | Reply to this comment ]

Posted by Steve (62.30.xx.xx) on Thu 12 Apr 2007 at 22:09
[ View Steve's Scratchpad | View Weblogs ]

:)

There is some discussion about the security starting from this thread, which discusses the reply attack possability and the solution which you've discovered.

Steve

[ Parent | Reply to this comment ]

Posted by chris (217.8.xx.xx) on Fri 13 Apr 2007 at 07:21
[ View Weblogs ]
Should that be replay rather than reply? Not trying to be picky - just confused :)

[ Parent | Reply to this comment ]

Posted by jonesy (210.185.xx.xx) on Fri 13 Apr 2007 at 06:54
[ View Weblogs ]
That looks pretty cool, could be useful from an email-enabled mobile phone too.

Just a typo I noticed Steve;
echo "CD4C0D9D" >> ~/.grant/validsigs.txt
should be
echo "CD4C0D9D" >> ~/.grunt/validsigs.txt

Cheers!

[ Parent | Reply to this comment ]

Posted by Steve (80.68.xx.xx) on Fri 13 Apr 2007 at 09:23
[ View Steve's Scratchpad | View Weblogs ]

I've updated the text to fix that typo now, thanks!

Steve

[ Parent | Reply to this comment ]

Posted by chris (217.8.xx.xx) on Fri 13 Apr 2007 at 07:47
[ View Weblogs ]
Interesting article. All I need to do now is go read up on how procmail and exim4 delivering mail to $HOME/Maildir plays together. Adding a .procmailrc started putting mail in /var/mail/chris instead - off to the docs.

[ Parent | Reply to this comment ]

Posted by Ledbo (82.16.xx.xx) on Sat 14 Apr 2007 at 12:00
I added


if $h_subject contains "---GRUNT_SIGNED_JOB_EMAIL---"
then
pipe "/usr/bin/gruntreceive"
finish
endif

to my .forward file, just to get it working.

Using exim4 and Maildir delivery on etch.

[ Parent | Reply to this comment ]

Posted by Anonymous (213.243.xx.xx) on Thu 19 Apr 2007 at 15:41
what about using ssh with pki authentication?

[ Parent | Reply to this comment ]

Posted by Steve (80.68.xx.xx) on Thu 19 Apr 2007 at 15:51
[ View Steve's Scratchpad | View Weblogs ]

Sure you could do that, search the site for details. Still that won't work for email .. obviously!

Steve

[ Parent | Reply to this comment ]

Sign In

Username:

Password:

[Register|Advanced]

 

Flattr

 

Current Poll

What do you use for configuration management?








( 76 votes ~ 0 comments )