Is it possible to send email via the amazon ses smtp service with a iam role account

amazon-iamamazon-ses

I have an IAM role with the following policy attached:

{
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "*",
      "Resource": "*"
    }
  ]
}

As you can see, full access is granted.

I use the following python to get the convert the IAM credentials to SMTP credentials:

#!/usr/bin/env python

from __future__ import print_function

import base64
import hashlib
import hmac
import json
import struct
import urllib2

METADATA_BASE = 'http://169.254.169.254/2012-01-12/meta-data'


def main():
    access_key_id, secret_access_key = get_access_creds()
    username, password = get_smtp_creds(access_key_id, secret_access_key)

    print('SMTP Username: %s' % username)
    print('SMTP Password: %s' % password)


def get_access_creds():
    url_handle = urllib2.urlopen('%s/iam/security-credentials' %
                                 (METADATA_BASE,))
    role_name = url_handle.read()
    url_handle.close()

    url_handle = urllib2.urlopen('%s/iam/security-credentials/%s' %
                                 (METADATA_BASE, role_name))
    sec_cred_doc = url_handle.read()
    url_handle.close()

    sec_cred_data = json.loads(sec_cred_doc)
    access_key_id =  buffer(sec_cred_data['AccessKeyId'])
    secret_access_key = buffer(sec_cred_data['SecretAccessKey'])

    return access_key_id, secret_access_key


def get_smtp_creds(access_key_id, secret_access_key):
    message = 'SendRawEmail'
    version = 0x02

    sig= hmac.new(
        secret_access_key,
        msg=message,
        digestmod=hashlib.sha256)
    sig_bytes = sig.digest()
    sig_and_version_bytes = (struct.pack('B', version) + sig_bytes)
    smtp_password = base64.b64encode(sig_and_version_bytes)

    return access_key_id, smtp_password

if __name__ == '__main__':
    main()

When I run this code, some SMTP username and password are output. When I try to send a message with those with say swaks, for example, it fails. Here's an example command line:

swaks -s email-smtp.us-east-1.amazonaws.com --from wt@example.com --to wt@example.com --auth-user <smtp username from script above> --auth-password <smtp password from script above> --tls

Example.com is, of course, a placeholder. The real domain has been verified on my AWS SES account.

In fact, if I run the same code to convert from an IAM user instead of discovering the role credentials from the meta-data, I can use the username and password to send email just fine.

AFAICT, this just isn't allowed with IAM role credentials, which is lame if it's true. I was planning on generating a Postfix config to allow processes on the box to send mail to localhost and have that routed to the SES service. I was trying to avoid putting IAM user credentials on the servers. However, it looks like there may not be a way to avoid that now.

Any thoughts?

Best Answer

You can use this project to send SMTP without credentials using IAM role instead https://github.com/loopingz/aws-smtp-relay