GithubHelp home page GithubHelp logo

lcrea / aws-ses-email-redirect Goto Github PK

View Code? Open in Web Editor NEW
11.0 3.0 1.0 64 KB

AWS SES inbound email redirect service based on S3 and Lambda function

License: Other

JavaScript 100.00%
aws-lambda aws-s3 aws-ses email-forwarding mail redirect forwarder nodejs

aws-ses-email-redirect's Introduction

AWS SES Inbound Email Redirect Service

A Lambda function to redirect SES inbound emails to an external address as an attachment, relatively easy to configure, with no data lost in the message's header and fully standard compliant.

Features

Any of these settings are configurable through Lambda environment variables:

  • Handling more than one custom email address, leveraging an alias table to map internal → external addresses.
  • Defining a default From / To email address (if not in the alias table).
  • Customizing the redirect message.
  • Sending errors' copy via email to an administrator.

Why this project?

Many privates or small businesses decide to buy a domain and to configure one or more custom email addresses. But because each one of them already have a personal email account somewhere else (Google, Yahoo, Hotmail, etc…) they don't want a full email box, but just a service that redirects the emails.

Thanks to AWS SES + S3 + Lambda, with a relative small effort to orchestrate these three services, this is doable in a professional/production way and barely for free!

I know that around the web there are already a lot of solutions to accomplish this. The problem is that, most of them, are just a "it works" solution. They don't really satisfy some requirements, like:

  • being able to map more than one custom address to one or more external email
  • respect the IETF and W3C email standard specifics
  • define an administrator email address to handle any potential error

About email standards and specifics

First of all, let's make it clear what the differences are between redirect and forward:

  • Forward means sending a new email to one or more addresses, including the original message in the body indented. This means loosing almost any of the original header fields – especially FROM and TO – and altering the original body.
  • Redirect means sending a new email to one or more addresses, altering – as little as possible – only the header part. The idea behind redirect is trying to save as much information as possible from the original message (possibly, leaving it untouched).

So, as you can imagine, doing a simply copy and paste of a message, overwriting just the FROM and TO fields, and sending it to a new address, means loosing lots of information within the header, like:

  • FROM
  • TO (this is the most dangerous!)
  • Message ID
  • DATE
  • SPAM information
  • Custom fields
  • Message path through servers

What do IETF and W3C say? Basically, there are two official ways to solve it:

  1. The Good one — Using the "resent headers": that is, renaming the original TO and FROM headers in Resent-To and Resent-From, set the new FROM and TO headers, copy everything else, send the new message. Doing like this, some header changes and someone else is overwritten, but even if the data lost is little, there is still.
  2. The Best one — Attaching the original message to a new one: the original message is encapsulated to a new one, using the special Content-type: message/rfc822. Doing like this the original message remains completely untouched.

The latter one is what this project is all about: implementing a service to redirect messages leaving them untouched, compliant to standards.

For more information about this topic, you can check these two links:

Costs

The moment I wrote this file, these are the actual costs per service:

  • Lambda:
    • 0$ for the first 1 Million requests and 400 000 GB/seconds, both per month.
  • S3:
    • 0.023$/GB (worst case).
  • SES:
    • Sending (from an EC2 instance or Lambda function):
      • $0 for the first 62,000 emails sent per month.
    • Receiving:
      • $0 for the first 1,000 emails received per month.

To sum up, the implementation to this redirect service is barely 100% free.

More information at these links:

How to use it

The following instructions don't pretend to be an exhaustive step-by-step walk through, but only a general guide about how to install, configure and use this software.
For anything related to AWS services, domains or DNS entries, please refer to the official documentations.

Requirements

  • A proprietary domain with the rights to change DNS entries (using Route 53 is not mandatory).
  • One or more external email addresses (Gmail, Yahoo, Hotmail, etc…).
  • Node.js and npm installed in your local environment.
  • An AWS account with these services already configured:
    • S3 private bucket.
    • SES outbound with domain and external emails verified (if you need more freedom, you have to send a request to Amazon to switch your account out from the sandbox mode. For most cases, sandbox mode is fine).

Installing

  1. Download and pack the function:
    • Clone this repository:
      • git clone https://github.com/lcrea/aws-ses-email-redirect.git
    • Install the dependencies (no dev required):
      • npm install --production
    • Pack everything in a zip file:
      • zip -r9 aws-ses-email-redirect.zip .
  2. Configure the Lambda function:
    • Login to your AWS account
    • Create a new Lambda function (ex. aws-ses-email-redirect) in the same region where you already configured SES
    • Set as resources consumed by Lambda function:
      • CloudWatch Logs (automatically created by AWS)
      • S3: choose one object key (ex. myfolder/mail) in your bucket (ex. my-bucket) and give it the permission to read and delete within it
      • SES (this will be automatically created in the next step)
    • Set as runtime engine: Node.js (latest version)
    • Upload your zip file aws-ses-email-redirect.zip
    • Set as handler file: lambda/app.handler
    • Next, configure the environment variables (see below 👇 )
  3. Configure SES inbound service:
    • Login to your AWS account
    • Create a new rule set in SES > Email Receiving
    • Define how many email addresses (recipients) you need for your domain (ex. [email protected])
    • Create two actions in this order:
      1. S3: set the bucket (my-bucket) and the object key prefix (myfolder/mail) above
      2. Lamdba: select the lambda function (aws-ses-email-redirect) and Event as invocation type (this will be the trigger).

That's it!
If you have correctly set permissions for Lamdba function, S3 and configured the environment variables (see below 👇 ), your redirect service is already working 👏

Environment variables

Login to your AWS account and go to your Lambda function (aws-ses-email-redirect). Here you have to configure the following variables:

  • MANDATORY

    • DOMAIN: your proprietary domain (mydomain.com)
    • BUCKET_NAME: this is your full S3 bucket + object key (my-bucket/myfolder/mail). You can think of it like the path where you are gonna save your emails
    • DEFAULT_EMAIL_FROM: this is the from address without the domain part to use in the redirected message (ex. no-reply). This address does not need to exist! It's just the from field the you're gonna see in the redirected email: it can be whatsoever.
    • DEFAULT_EMAIL_TO: this is the address to which redirect messages if not found in the alias table or if you haven't configured it (ex. [email protected])
    • REDIRECT_MESSAGE: a default message to include in the body of the redirected email
  • OPTIONAL

    • ALIASES: if you want to map more than one proprietary address to more than one external address, you need to specify an alias table as a JSON object like this: {"me": "[email protected]", "info": "[email protected]"}. Again, internal proprietary addresses are without the domain part.
    • ERROR_EMAIL_TO: if you want to be notified by email of any possible errors in the redirect process, instead of checking them in the AWS CloudWatch logs, you can define an email address as an administrator.

How does the alias table work?

The idea is strongly inspired by the Postfix alias map file. It's just a set (actually, a JSON Object) of inward addresses mapped to outward addresses, like this:

{
    "me": "[email protected]",
    "info": "[email protected]",
    "job": "[email protected]",
}

So, if the custom domain is "mydomain.com" whoever will send an email to [email protected] will be redirected to [email protected]; to [email protected] will be redirected to [email protected]; and so on. Also, thanks to the DEFAULT_EMAIL_FROM variable defined above, if an email is sent to an address not in the alias table, but defined in the SES inbound settings (like [email protected]), it will be redirect to that address that works as a catch all. That's the reason why the alias table is "optional": most people don't even need it.

Alias table examples:

1 inward -> 1 outward email address

Configure [email protected] in the SES inbound section. Then, inside the Lambda function, set:

DEFAULT_EMAIL_TO = [email protected]

No alias table is required.

3 inward -> 1 outward email addresses

Configure [email protected], [email protected], [email protected] in the SES inbound section. Then, inside the Lambda function, set:

DEFAULT_EMAIL_TO = [email protected]   // This works like a catchall

Again, no alias table is required.

3 inward -> 2 outward email addresses

Configure [email protected], [email protected], [email protected] in the SES inbound section. Then, inside the Lambda function, set:

ALIASES = { "me": "[email protected]" }
DEFAULT_EMAIL_TO = [email protected]   // This works like a catchall

Built With

Author

Luca Crea — https://www.linkedin.com/in/lucacrea

License

This project is licensed under the MIT License. See the LICENSE.txt file for details.

aws-ses-email-redirect's People

Contributors

lcrea avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

rodrigopedra

aws-ses-email-redirect's Issues

How to redirect one email to multiple mail addresses?

Hi, thank you for publishing this great piece of code.

I have a quick question because, from the documentation, it is not quite clear how to specify 1:n redirect. (e.g. I have email [email protected] and I want all emails sent to multiple email addresses like [email protected], [email protected] etc.)

Shall I pass all the emails as a comma-separated list or as a JSON array?

From the code, I would guess that the comma-separated list is correct, but I am a newbie regarding nodeJS.
Could you possibly update the documentation?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.