36 ms·
A serverless email server on AWS using S3 and SES
- primitivesuave 7y agoThanks for putting this together and documenting it so well. I’ve had to build this solution twice now, and far less elegantly. The S3 PUT charges caught me off guard the first time (receiving lots of marketing/spam email will cost $1/1000 emails). I ended up putting small emails up to 400 kB in dynamoDB and only using S3 for large emails and attachments, which could be a means of cost reduction in this solution as well.
- mactunes 7y agoHonest question: how did you arrive at 1$/1000 mails? When I look at S3 peicing it says 0.005$/1000 PUTs. Are there a lot of requests made or am I missing something else?
- lowdose 7y agoYes this is legit! Got it to work on a throwaway domain under 30 minutes.
- z3t4 7y agoWhat about email signing?
- eeZah7Ux 7y agoAfter surrendering all your data to a cloud provider?
- vidarh 7y agoSigning e-mail servers two different purposes: Authenticating the actual sender vs. authenticating the server or service controlling the domain for reputation purposes. If you trust Amazon enough to use their cloud services, there's little reason not to trust them for the latter. Doesn't mean trusting them with respect to the former. Things like DKIM makes no assertion that the content was sent by the right person; just that whomever controls the domain has trusted the service in question to send e-mail on their behalf.
- z3t4 7y agoMaking the data someone else's problem. :P One cool thing with the cloud is that you can work with the data without it leaving the "cloud". If the consumer of the data, eg the e-mail client is also in the cloud, it really doesn't matter where the HDD is located.
- abjKT26nO8 7y agoI don't know anything about serverless --- to this day I fail to understand what this word is even supposed to mean. And the deployment diagram[1] sure looks complicated to me. I think I prefer old-school servers. [1]: <https://raw.githubusercontent.com/0x4447/0x4447-product-s3-email/assets/diagram.png> https://raw.githubusercontent.com/0x4447/0x4447-product-s3-e...
- chrischattin 7y agoThe term serverless is such a misnomer. While this is a cool project, you'd use 3 different servers at a minimum here.
- sfifs 7y agoIt's pretty well understood by now that serverless is meant to connote that you (the firm owning the application) don't manage the server(s). Someone else does it while you just bring your application code.
- chrischattin 7y agoCorrect. It is a misleading term, imo.
- scarface74 7y agoIt’s no more “misleading” than having a “bug” in your code. Does anyone with even an iota of computer experience think “Serverless” means that their software is being run by leprechrauns? Nowhere else on HN is willfully not taking the time to learn about technology celebrated except when it comes to cloud concepts.
- chrischattin 7y agoThe more you understand the architecture, the more absurd it sounds to call it serverless. Edit: Replying to the below comment... No, it's like calling produce you didn't grow yourself but came from a farm, farmless produce.
- coder1977 7y agoHow does this compare to setting up something like sendy (sendy.co) on lightsail and connecting to SES?
- arno1 7y ago> This stack was created out of frustration due to the fact that to this day there's no easy way to have a full email server without the overhead of installing and configuring all servers needed to handle incoming and outgoing messages. Interesting approach, though I solved this frustration by the use of a Docker and kept "my data is mine" + "no vendor lock-in" + "I control all the gears" approach. (Though, it's not perfect since VPS is ran by "someone" else.. but that place where you run this stack can be easily changed at your convenience). Simple docker-compose.yml with 3 images and voila. This AWS S3 SES setup looks far more complex than what I did using only 3 docker images: the postfix (for smtp), dovecot (for imap), opendkim (for email sigining & verification). It's really easy to fire-up a VPS with a single click nowadays. If someone is interested in the images I am using: - https://git.nixaid.com/arno/postfix https://git.nixaid.com/arno/postfix - https://git.nixaid.com/arno/dovecot https://git.nixaid.com/arno/dovecot - https://git.nixaid.com/arno/opendkim https://git.nixaid.com/arno/opendkim Then you just feed the images with the right configs (main.cf, master.cf, .., dovecot.conf, opendkim.conf). It's also possible to template the configs and make the variable-based configs. Make things scale friendly. I am also using Terraform to automate the server deployment/DNS record updates so it is easy to get from 0 to 100. The only drawback is that you are the one to maintain the OS/SW upgrades, security, etc.. but that's something I really want to do by myself instead of relying on someone else :-)
- coder1001 7y agoDo you mind writing a blog post somewhere explaining to noobs how this can be done? This will be a great post with lots of traffic I imagine! Thanks, great work!
- Boulth 7y agoWow, this is cool! JSON structures resemble JMAP. I wonder what'd be the effort to add JMAP endpoint to this?
- smokeyfish 7y agoJMAP as in the JSON Meta Application Protocol?
- chrismorgan 7y agoJMAP is a radically different beast. The similarities between this thing’s JSON format for sending and JMAP’s Email data type are superficial only: they’re both JSON and are representing the same thing, so it should be no surprise that they look similar. But that’s a quite tiny part of what JMAP is: JMAP is an object synchronisation protocol. (And this is why JMAP so much more complex than the typical REST API. And why I prefer it so much.) I also think the JSON here is only for sending, not for receiving—I presume that you’ll receive the MIME message, because otherwise you’d be throwing away all kinds of essential information. All of this gets you basically nowhere along the path to JMAP, and achieving a JMAP endpoint would be a lot of effort. This project doesn’t look to be at all suitable as a base for such an endeavour. Things like sorting (e.g. newest first), querying (e.g. emails from so-and-so) and JMAP’s state management (so the server can tell you “something changed” and you can ask the server to tell you what changed since x, rather than needing to throw everything away and start again) don’t work well within the design of this system—you need to store lots of extra details along the way, maintaining indexes and other such things. For such an endeavour, I would instead recommend either wrapping an existing mail server in serverless voodoo (much of which I expect to be not too hard: you’re essentially just replacing ingress and egress and not running it as a daemon; but there will be architecturally difficult parts like getting push channels working probably), or starting new mail server software from scratch designed to be able to work serverless. (I work for Fastmail on our webmail. I have general knowledge of how mail servers work internally, but little specific knowledge; for example, I have no idea how amenable Cyrus, which we use and develop, would be to serverless packaging.)
- Boulth 7y ago
- theqult 7y ago>his day there's no easy way to have a full email server without the overhead of installing and configuring all servers needed to handle incoming and outgoing messages. https://mailinabox.email/ https://mailinabox.email/
- anonu 7y agoNow someone just needs to create a serverless (aka client side or browser only) Gmail like interface you can host on S3. And the shackles will be broken...
- arno1 7y agohttps://www.rainloop.net https://www.rainloop.net ? Anyway, what is the point in moving from one Giant to another Giant? :-) Unless it saves the cost, I don't see the benefit of such hassle.
- Normal_gaussian 7y agoMost serverless offerings are somewhat compatible with a pitcher of greasing. It would be a doable exercise to duplicate this codebase for a few other platforms.
- eeZah7Ux 7y ago> shackles will be broken By tying your entire email system to a single cloud provider? This is lock-in on steroids. (Oh, and zero privacy)
- insomniacity 7y agoI'm missing something - how are people reading this in an email client if it doesn't have IMAP support?
- geek_at 7y agoI think the bigger problem is that you can up their bill by spamming them
- arkanciscan 7y agoIt seems that you are expected to read email by viewing the contents of the S3 bucket. That's a pretty big caveat.
- TheSpiciestDev 7y agoMy take away is that you'd be able to receive your emails and customize the handling of every email. i.e. emails are received and put into specific buckets/folders and then, per message, a process is triggered to do something unique (put into database, forward to another IMAP'ed box, etc.)
- giu 7y agoJust a friendly reminder, since I've worked with SES in the past: Don't forget about bounces when using SES [0]. From [0]: > If your bounce rate is 5% or greater, we'll place your account under review. To sum it up, try to keep track of bounced e-mails by using the SES notifications [1]. [0] https://docs.aws.amazon.com/ses/latest/DeveloperGuide/e-faq.html#e-faq-bn https://docs.aws.amazon.com/ses/latest/DeveloperGuide/e-faq.... [1] https://docs.aws.amazon.com/ses/latest/DeveloperGuide/monitor-sending-using-notifications.html https://docs.aws.amazon.com/ses/latest/DeveloperGuide/monito...
- statictype 7y agoWe accidentally had ses credentials set up on our QA server and quickly got banned for sending too many sdf@sdf.com emails. Took quite some time to get it unbanned. Since then we switched to Mailgun for email delivery but ses is still useful for processing incoming email via Lambda
- giu 7y agoVery good point about sending test e-mails, which also reminds me of the next friendly reminder: SES has a Mailbox Simulator [0] where you can send e-mails to specific e-mail addresses and check the notifications you receive, e.g., bounces. If you're using the SNS notifications [1], these notifications will be JSON objects [2]; you can then use a notification to extract the information needed, e.g. a bouncing e-mail address to be stored in a local registry in case of a bounce notification. [0] https://docs.aws.amazon.com/ses/latest/DeveloperGuide/mailbox-simulator.html https://docs.aws.amazon.com/ses/latest/DeveloperGuide/mailbo... [1] https://docs.aws.amazon.com/ses/latest/DeveloperGuide/notifications-via-sns.html https://docs.aws.amazon.com/ses/latest/DeveloperGuide/notifi... [2] https://docs.aws.amazon.com/ses/latest/DeveloperGuide/notification-contents.html https://docs.aws.amazon.com/ses/latest/DeveloperGuide/notifi...
- cyberferret 7y agoWe are careful to use throwaway email addresses like randomusername@mailinator.com on our dev and staging servers so they still get delivered, but we can just forget about them. Really interested to learn about the SES simulator address though (posted as a reply on this thread) - don't know how we missed that, and it would have really helped with early testing when we were developing the email queueing system on our app.
- Cyph0n 7y agoI’ve been working on a small side project that involves processing incoming email. In particular, it’s an app that needs to do something for each email it receives from (hopefully paying!) users. I am not interested in storing user mail, so SES is just too costly, at least according to a quick worst-case calculation. That leaves me with two options: 1. Self-hosted Postfix 2. Mail service like Mailgun With (1), there is no need to worry about overages, but scaling the mail server might be challenging. The advantage of (2) over SES is that you are only charged a flat fee for each email, regardless of size. Emails are then automatically deleted after some period of time. Scaling up and down is easy. For now, I am using Mailgun, but I am writing the mail processing daemon in a way that will make it easy to transition to Postfix, if needed. Also, I decided to write the mail processing backend in Rust, so I’ve been learning the language as I go!
- wolco 7y agoMailgun would seem cheaper than this. I use Postfix/dovecot to self host.
- wiradikusuma 7y agoI thought SES is the cheapest of all since it's the lowest level? (Compared to Mailgun etc)
- Cyph0n 7y agoNo, especially if you’re expecting emails with large attachments. SES charges $0.09 per 1000 mail “chunks”, where a chunk is 256 Kb of data. This is on top of the base SES fee and S3 operation and storage fees.
- whatsmyusername 7y agoYou can get receive at any address on a domain forwarded to whatever email you want if you're registered with Monicker. I imagine most other registrars offer the same thing.
- coding123 7y agoSeems like a crazy amount of architecture. Does AWS keep all this stuff organized in some way, or will my personal experiments in Lamba accidentally break this because it's all merged together? Say I've installed this. I now want to write my own lamba service to handle contact form POSTs or something. Then I decide to delete it, but I accidentally delete one of these crazy email things. What happens?
- drwiggly 7y agoYou can make "new" sub accounts from your main account. If you wanted to segregate it completely.
- newman8r 7y agoIf you only need to read the emails from S3, take a look at this project https://github.com/mewa/s3abird https://github.com/mewa/s3abird
- raoulbhatia 7y ago... and I thought about a similar thing (Email server using Lambdas) just yesterday ... ^^
- eivindga 7y agoCool project! I'll make sure to test it someday. Thanks for sharing!
- bsder 7y agoPlease don't use '+' for special purposes in email addresses without making it changeable (I recommend '_' instead). Yes, it is "nominally" accepted--in reality there are too many website that "validate" email addresses and barf on '+'.
- glandium 7y agoNote that SES only retries delivery for a fixed 840 minutes (not configurable), which is an annoyingly too short amount of time.