Passwordless SSH between two machines using certificates

I’ve been meaning to post this somewhere useful for a while now, so here it is.

Assumption

Machine A wants to connect with SSH without passwords (with cert) to Machine B

Method

On Machine A:

ssh-keygen

Make sure you pick no pass phrase.

scp .ssh/id_rsa.pub user@machineb:.ssh/id_rsa.tmp

On Machine B:


cat id_rsa.tmp >> authorized_keys
chmod 600 authorized_keys

Connect as normal from machine A to machine B

Emailing attachments directly to a Dropbox folder…

I’ve been toying with this idea for a while now, wanting to email attachments to my Dropbox account into a specific folder. There are lots of canned solutions to do this, but most of them require you to trust some third party with your documents. If you’re ok with that check out this post.

I decided my paranoia was high and I would not trust a third party. To achieve autonomous Dropbox emailing I figured I’d need to do the following:

  1. Install Dropbox on my headless Ubuntu server.
  2. Create an email account to receive the email attachments (let’s say dropbox@mydomain.com).
  3. Modify the postfix installation to redirect mail to dropbox@mydomain.com to a PHP script.
  4. Create a PHP script to process the inbound email stream and strip out all attachments saving them to a folder.

Install Dropbox

Lots of links for this one out there, not going to rehash it but the basics are:

  1. Download the latest Dropbox.
  2. Run it.
  3. Use the link supplied to link your account to your server.
  4. Create a service to run Dropbox at start.
  5. Do an initial sync.

You can follow the instructions here, or Google for it.

Create Email Account

I created a user called dropbox  and ran the install above as that user. One note if you follow the link, I did not do the auto startup as a cron job but as a standard service in /etc/init.d

Modify Postfix

I created a new transport in master.cf:


dropbox unix - n n - 50 pipe
flags=R user=dropbox argv=/usr/bin/php /usr/local/bin/dropboxattach/dropbox.php -o SENDER=${sender} -m USER=${user} EXTENSION=${extension}

then I added an entry to my main.cf to define different transport options:

transport_maps = hash:/etc/postfix/transport

Now edit /etc/postfix/transport and add an entry for your email address receiving the dropbox attachments:

dropbox@mydomain.com  dropbox:

then run

postmap transport 

to (re)build the transport database

Finally reload postfix

postfix reload 

The PHP Script

I found this nifty little Mime Mail Parser script at http://code.google.com/p/php-mime-mail-parser/, download the two files and add it to your code source. Here is the script I created to intercept the mail and parse for attachments. Check comments for explanation.


<?php

require_once('MimeMailParser.class.php');

// phrase to check for in SUBJECT to make sure only valid emails are processed
$check = "Add to dropbox";

// location to save attachments to
$save_dir = "/home/dropbox/Dropbox/attachments";

// temporary file name for incoming mail message
$file = "/tmp/mail.message." . microtime(true);

// delete the temp file if it exists, just in case
if (file_exists($file)) {
unlink($file);
}

// export the mail message to the temporary file
$data = file_get_contents("php://stdin");
file_put_contents($file, $data);

// parse the contents of the message and save attachments
$Parser = new MimeMailParser();
$Parser->setPath($file);

// get the subject and check for valid "phrase"
$subject = $Parser->getHeader('subject');

if (!($subject == $check)) {
// delete the temp mail message
if (file_exists($file)) {
unlink($file);
}
exit();
}

// get all attachments and save to directory
$attachments = $Parser->getAttachments();
foreach($attachments as $attachment) {
// get the attachment name
$filename = $attachment->filename;
// write the file to the directory you want to save it in
if ($fp = fopen($save_dir.$filename, 'w')) {
while($bytes = $attachment->read()) {
fwrite($fp, $bytes);
}
fclose($fp);
}
}

// delete the temp file (probably redundant but just in case)
if (file_exists($file)) {
unlink($file);
}

?>

For some “security” I added a “catch phrase” that must be the subject as a kind of “authentication”. Remember to save the script into the same directory as the Mail Parser code and everything should work.

That was it, I can now email dropbox@mydomain.com and it appears in my dropbox folder Attachments .. AWESOME!