Archive for the ‘Cloud’ Category

Sending Emails With Attachments using Amazon SES

leave a comment »

Amazon Simple Email Service (Amazon SES) is a very reliable email service provided by Amazon for sending emails – transactional, communication to your customers, registration or bulk emails like newsletters etc.
It is easy to set up and also scales well. In addition to all this, it is quite cheap. Gone are the days when one had to pay steep prices to the hosting provider for email campaigns with all kinds of cap/limit set to it.
With SES you can send 1000s of emails in a day and even if your limit exceeds, you can request them for raising the threshold. Along with high deliverability, Amazon SES also provides real-time access to your sending statistics and built-in notifications for bounces and complaints to help you fine-tune your email-sending strategy.

So how does one get started? They have written quite a good documentation here, so I will not dwell into that.

My focus here is to share the way to do it in php. There are many ways to download the required package but I used aws phar. You need pear to download phar and set it up.

Setting up phar

  1. sudo apt-get install pear (If you don’t have pear already)
  2. sudo pear -D auto_discover=1 install pear.amazonwebservices.com/sdk

Now , to send an email with attachment – here is the code:

Include the phar file

require '/some path/php/lib/php/AWSSDKforPHP/aws.phar';
use Aws\Ses\SesClient;
global $client;

Create client object

$client = SesClient::factory(array(
'key' => 'your key',
'secret' => 'your secret',
'region' => 'your region'

The file you want to attach in the email

$myfile = "path to file to be attached";
$file_size = filesize($myfile);
$handle = fopen($myfile, "r");

Read the file content

$content = fread($handle, $file_size);

Format $content using RFC 2045 semantics using chunk_split. It inserts \r\n at the end of every chunk. This is required by your smtp client – else they just reject your attachment.

$content = chunk_split(base64_encode($content));
$header = "";
$message = "some html string";

You need to put a unique boundary to the multipart message

$uid = md5(uniqid(time()));
$header = "From: ".$source_email_id." <".$source_email_id.">\r\n";
$header .= "Reply-To: ".$replyto_email_id."\r\n";
$header .= "To: ".$dest_email_id."\r\n";
$header .= "Bcc: ".$bcc_email_id."\r\n";
$header .= "Subject: ".$subject_of_the_email."\r\n";
$header .= "MIME-Version: 1.0\r\n";
$header .= "Content-Type: multipart/mixed; boundary=\"".$uid."\"\r\n\r\n";
$header .= "This is a multi-part message in MIME format.\r\n";
$header .= "--".$uid."\r\n";
$header .= "Content-type:text/html; charset=iso-8859-1\r\n";
$header .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
$header .= $message."\r\n\r\n";
$header .= "--".$uid."\r\n";
$header .= "Content-Type: text/csv; name=\"".$myfile."\"\r\n";
use different types here

$header .= "Content-Transfer-Encoding: base64\r\n";
$header .= "Content-Disposition: attachment; filename=\"".$myfile."\"\r\n\r\n";
$header .= $content."\r\n\r\n";
$header .= "--".$uid."--";
$msg['RawMessage']['Data'] = base64_encode($header);
$msg['RawMessage']['Source']= $src;
$msg['RawMessage']['Destinations'] = array($dest);

Now send the mail

$result = $client->sendRawEmail($msg);
//save the MessageId which can be used to track the request
$msg_id = $result->get('MessageId');

So as you would have observed, there are quite a few complications that one has to handle while sending an email with attachment like the unique id, putting proper end characters at the end of your message chunks, base 64 encoding etc.

Hope this helps.


Written by rationalspace

June 6, 2014 at 6:52 pm

Posted in Cloud, Utilities

Making FTP work on Amazon EC2

leave a comment »

Though FTP is not a great way to transfer files on a server due to security issues, sometimes, due to reasons like specific requirements of business partners’ etc, you have to set it up. The better way to transfer files however, is SFTP. I already wrote a blog about how to set it up here.

Now about FTP setting up.

  1. Check whether vsftpd is there on your server. If not , install it. sudo apt-get install vsftpd
  2. Check if port 21 is open. telnet IP 21. If not, go to your EC2 dashboard, check the security group to which your server is attached, edit it – Add port 21 there and save.
  3. Edit vsftpd.conf
    1. vi /etc/vsftpd.conf
    2. Disable anonymous login :
    3. Allow local users to be able to login :
    4. Allow users to write in their FTP directory :
    5. Restrict users to their local directory: chroot_local_user=YES
    6. Check your listen address :
    7. Save file and restart ftp :
      /etc/init.d/vsftpd restart
    8. Do a netstat and check output
      netstat -a | grep 21
      It should show
      tcp 0 0* LISTEN
  4. You may need to open passive mode instead of active if your firewalls or client’s firewalls don’t allow communication. To make passive mode work, you need to do some more extra stuff
    1. Make sure ports greater than 1024 are open in your security group. So add a range 1024-1048 and save.
    2. In vsftpd.conf , specify the range of ports that will be used for opening a passive connection.
    3. It turns out that vsftpd advises the incoming PASV command the internal IP of EC2 instance, which FTP clients would not be able to resolve. To solve this problem, we explicitly tell vsftp to use our public IP address instead of asking the server for it. If you don’t have an Elastic IP associated with the instance, you will need to enable pasv_addr_resolveand provide your public DNS
    4. Restart vsftpd.
  5. You may also want to read up on passive vs active modes. I found a nice answer here on stackoverflow.

Written by rationalspace

May 27, 2014 at 5:09 pm

Posted in Cloud, Security, Utilities

Tagged with , ,

%d bloggers like this: