An email server in Lightsail: it’s harder than it sounds!
UPDATE as of 2021-09-18: A few details changed since the original was written. This has been updated to reflect those changes.
While it’s a little complicated, and takes fair bit of work, setting up your own email server with lightsail can be done. And it’s pretty cool to have your own email server.
There is a fair number of prerequisites that need to be done before this will have any chance of actually working. I’m not going to give documentation on all the parts, as most of the are documented pretty well, I will provide links to the documentation that you can follow to get the pieces set up.
For starters, you’ll need a Lightsail server. A small one is fine. A personal mail server should not use a lot of system resources. You’ll need a domain name, with DNS set up to be managed by Lightsail. You’ll need a few software bits: sendmail, awscli, alpine, dovecot-imapd, and dovecot-core. For the imap server to work, you’ll need to open up tcp/143 in Firewall section of the networking tab for your Lightsail server. If you are not going to add a DAV server you should probably remove http and https from the firewall config. But be sure to keep ssh!
I’m sure other mail servers can be used, but I know how get sendmail to do what I want it too, so I’m sticking with it and all the examples here will be using sendmail.
Once you have all those parts installed, then ..
Set up SES to send email following:
Then configure sendmail to send email:
Set up receive unencrypted mime files to an S3 bucket:
Set up the AWS command:
And then for use with S3:
And finally, for every To email address, either have an account on the system, or an entry in /etc/aliases.
Once all that is set up and working, we get to the fun part.
NOTE: Be sure to have you domain name ( mydomain.org ) in /etc/mail/local-host-names to ensure sendmail knows it’s suppose to deliver the mail locally.
Using the aws command, we want to get the mime files on the local Linux system so you can sendmail deliver it.
So, lets pretend your S3 bucket is email and the prefix is msg:
aws s3 ls s3://email/msg
If you have some messages, the output might look like:
# 2017-08-12 21:38:49 9943 4eothr4lcmjdkbv4cunbbj985v7avu8c8k29da01 # 2017-08-11 22:11:15 645 AMAZON_SES_SETUP_NOTIFICATION # 2017-08-12 09:51:41 3669 a9beedc4assu9a03sndvavfv3rvpthtqb2f0ocg1 # 2017-08-11 22:16:39 9938 q8pdd9j9e73mcts6mtnhrrbmaiqt93rupvrmamo1
Now, we need to through away the AMAZON_SES_SETUP_NOTIFICATION file:
aws s3 rm s3://email/msg/AMAZON_SES_SETUP_NOTIFICATION
Next, using the aws command, move the emails from the s3 bucket and use sendmail to deliver them:
mkdir /tmp/mail cd /tmp/mail aws s3 mv s3://email/msg/4eothr4lcmjdkbv4cunbbj985v7avu8c8k29da01 . aws s3 mv s3://email/msg/a9beedc4assu9a03sndvavfv3rvpthtqb2f0ocg1 . aws s3 mv s3://email/msg/q8pdd9j9e73mcts6mtnhrrbmaiqt93rupvrmamo1 . /usr/sbin/sendmail -i -t < 4eothr4lcmjdkbv4cunbbj985v7avu8c8k29da01 /usr/sbin/sendmail -i -t < a9beedc4assu9a03sndvavfv3rvpthtqb2f0ocg1 /usr/sbin/sendmail -i -t < q8pdd9j9e73mcts6mtnhrrbmaiqt93rupvrmamo1
If they were addressed to a local user, you can use Alpine to verify that the messages were delivered.
To get dovecote to work correctly, simply comment out this line in /etc/dovecoat/dovecoat.conf:
listen = *, ::
Then you can set up an imap client such as thunderbird. You’ll receive email from you server using login credentials on the local server, and send using your SMTP credentials and config for SES. Then to finish off, optionally add a DAV server such as Baïkal so you can have an address book and calendar that is synced with you email.
A complete script that does gets pulls the MIME files from S3, and sends them to sendmail for you can be found in the following Github repo:
Run this via a cron job once every min or 5 min for best results.
NOTE: You MUST set the “SES_BUCKET” variable as “bucket/prefix” for the script to work:
SES_BUCKET="email/msg" /usr/local/bin/deliver_ses_mail.sh > /tmp/deliver.$$.out 2>&1