This is a work-in-progress, and likely a somewhat slow one (maybe one edited post per day).

A few weeks ago, I set up my own email server. Despite everyone on the internet complaining that no one would work with it, that it was too much work, that there was too much risk, and other complaints, I somehow only put two weekends into the project. Since I had to remix a few tutorials to get something working, I'm documenting my work here. I will link to my sources when appropriate.

Obligatory Table of Contents for those who want to find a section quickly:


  1. Getting a Machine
  2. SMTP Server (Postfix)
  3. Link-Level Encryption (TLS)
  4. SMTP Authentication (SASL)
  5. IMAP/POP3 (Dovecot)
  6. amavisd
  7. Spam & Virus Filtering (SpamAssassin, ClamAV, Postgrey)
  8. Sender Authentication (SPF, DKIM)
  9. Final Testing, Maintenance, etc.


My choice was to use Ubuntu Server on AWS a domain maintained by Namecheap, and SSL Certificates from StartSSL. You can make your own choices on how things are setup, but as I can barely help others duplicate my setup, I'm not about to give advice on other setups (someone should slap me through the internet if I do).

There are some important things to note when deciding to setup an email server. Most important is that no one but you is responsible for how it is setup. If you decide to ignore my advice about when to unblock port 20, I will not sympathize with you when you discover that everyone has blocked your server because spammers found it before you could make sure it wasn't an open relay. If you are just getting your bearings on the internet, think twice, nay, thrice, before attempting this.

And, as always, Your Mileage May Vary.
My Choices vs. Yours
I used an Amazon Web Services micro instance for my computer. If you decide to use a physical machine, it is your responsibility to secure a colocation facility, pick an internet connection, do whatever negotiation with your ISP is necessary, and otherwise deal with nonsense.

I advise against setting up an email server on your home internet connection. Your downloading habits may disrupt email availability, your home ISP is likely to mistake your email server for a spam bot, and it's probably against your Terms of Service. But, ultimately, I am not going to stop you from making your life difficult; that's your life, not mine.

Domain
Getting a domain setup varies wildly with who you choose to host your domain with. The only thing I'm going to say here is (1) get a domain, and (2) Be ready to setup an A record for a subdomain (I recommend mail.your-domain.com).

Getting Going with Amazon Web Services
Maybe I'm just slow on the uptake, but I found that AWS had a dizzyingly diverse number of options everywhere, and that there was no quick-and-easy documentation. So, I'm documenting. Some of this will be obvious, some of it might not be. I don't have a source for this section.

Amazon Web Services ("AWS") provides a number of machine types, a plethora of network setup options, and a slew of services to make creating a web app easier. I did not need anything except a single EC2 instance. If you want to do anything fancier than just an email server in AWS, that's your call.

First step, if you haven't already, create an AWS account. They'll need quite a bit of contact info, and a credit card number. I also opted to use Multi-Factor Authentication. Once you receive your confirmation email, celebrate your free year of (some) AWS services!

OK, enough of that. Get to the EC2 management area, and click "Launch Instance" (or Instances > Launch Instance). Select Classic Wizard, click Next. I picked 64-bit Ubuntu. You will need to adapt these instructions heavily if you pick something non-ubuntu. On the next screen, make sure you pick a T1 - Micro instance. Nothing else matters until you get to the Storage Device Selection screen. I took that opportunity to make a 15GB data EBS volume for myself. Your free tier only includes 30GB of storage (as of when I did this).

Next screen. Create a new key pair, download it, and keep it safe. On the firewall selection screen, the default is to only allow port 22 to be open, but allow any connections. This is fine for getting started with, we'll edit it later. Note that once the machine is launched, it's a pain in the behind to change the security group, and each machine can only be on one security group. Click Next, then Finish.

Hop down to Elastic IPs, click Allocate New Address, select "EC2", finish. Select the address, click Associate Address. Select your EC2 instance, click "Yes, Associate". Remember that EIP address you just associated. Hop over to your domain's DNS management interface, create an A record for that EIP (example, an A record for mail.your-domain.com with value 127.0.0.1).

You have an SSH client, right? If not, go get one. I'm using the bog-standard SSH client all linux distros use. In the AWS Management Console, select your instance, Actions > Connect. "Standalone SSH Client" will give you the command you need (for Linux). Pro tip: If you wait for the DNS changes you made earlier to propagate, you can use the DNS name rather than the EIP when SSHing into your server.

Once you can login to your server via SSH, we're done in this section.
Before we get to postfix, let's get two other important things out of the way first.

Firewall
Make sure you only have port 22 open on your email server. Most particularly, block port 25. You should also block ports 110, 143, 465, 993, and 995, but you must block port 25. If you do not block port 25, and a spammer finds you before you get Postfix configured, you're an open relay, and you'll be playing email politics. Do yourself a favor, and block your ports.

For AWS users, go to the EC2 management section, and edit the security group your server is in.

Domain
Now is as good of a time as any to get the basic domain setup going. We won't be able to test it yet, but we will soon enough.

In addition to your A record for mail.your-domain.com, you should also set an MX record. It should look something like this:

Code:

Host Name          Mailserver              Type    Pref
your-domain.com    mail.your-domain.com    MX      10

How exactly you create an MX record depends on your particular registrar, so I leave the details as an exercise to the reader.

Postfix main source
This part isn't required, but I recommend it if you're following my instructions exactly.

On your email server:

Code:

sudo cp -r /etc/skel /etc/skel-eml
cd /etc/skel-eml
sudo mkdir cur new tmp .Drafts .Sent .Templates .Trash

Now make a bash alias for the following command:

Code:
sudo useradd -m -k /etc/skel-eml -s `which nologin` $1;

The server I setup doesn't support virtual users. That is, it must have a system login or an alias for each user that can use the server, and they must have a Maildir in their home directory. Adding an alias for the above command allows you to setup a user with an alternate home directory structure, and refuse such users shell access.

You should also make a Maildir with the same contents as /etc/skel-eml/Maildir now.

This part is required.

Code:
sudo apt-get install postfix
dpkg-reconfigure postfix

Yes, I'm that lame. I tried doing it the hard way, but that didn't work for me. Don't worry, we'll do a lot of hand-tweaking later.

Settings:
  • General type Internet Site
  • System Mail Name Same as whatever you setup in your DNS, mail.your-domain.com. My server's idea of its host name and its mail name are two very different things.
  • Root/Postmaster Recipient Leave blank for now.
  • Other destinations to accept mail.your-domain.com, your-domain.com, localhost.your-domain.com, localhost
  • Force synchronous mail queue No
  • Mailbox Size Limit Use 0 for unlimited. If you aren't comfortable with that, pick a number.
  • Everything else Use the default

We're going to do a lot more configuration later, but let's start with this and test it.

Testing
Make sure you're signed into your server. Then, telnet into localhost:25. You should get a 220 greeting with your mail host name. Type the following commands:

Code:
EHLO localhost
MAIL FROM: root@your-domain.com
RCPT TO: your-user@your-domain.com
DATA
asdf
asdf
.

After the EHLO, you should get a list of capabilities. After the MAIL FROM and RCPT TO commands, you should get a 250 OK message. The DATA command should yield a 354 End Data with <CR><LF>.<CR><LF> message, and the period should yield a message telling you your message was queued. Check the maildir for your user, and you should find your message was delivered.

If any of that didn't happen, double-check your configuration (including spelling), that your mail directories were created, and /var/log/mail.log and /var/log/mail.err for hints. You should make sure what you've got now works before I go making your life complicated.
Because I'm just insane like that, whenever SSL/TLS is involved with security, I insist on legitimate certificates, signed by a CA. Fortunately, despite what most people think, you can get an SSL certificate for free. It either comes with an insecure CA or some heavy stipulations (or both), but at least it'll keep warnings away from users, and keep the line secure.

For my cert, I used StartSSL's free offering. It's worthwhile to note that the CA hacking spree a while back hit StartSSL, but that it didn't seem to succeed against them. As always, though, you have to decide for yourself whether you trust the CA.

Getting a Certificate
First, we have to get some ducks in a row.

StartSSL "verifies" domain ownership by sending an email to an address associated with a domain. This will be postmaster@, webmaster@, or an address taken from your WHOIS info. I have namecheap's whoisguard turned on, so my WHOIS addresses all redirect to a gmail account, but appear to be email addresses in my domain. I can still receive email to that address, but the email server isn't setup yet.

So make sure your WHOIS info includes an email address that can get to you.

Before we get started with CAs, let's create a Certificate Signing Request. It can hang out on your server for a while, don't worry. SSH into your server, and make sure openSSL is installed. Create the folder /etc/postfix/ssl, and cd into it. Then, run the following:

Code:
# openssl genrsa -out domain.com.key 2048
# openssl req -new -key domain.com.key -out domain.com.csr
# chown root:root domain.com.key
# sudo chmod -wx domain.com.key
# sudo chmod o-r,g-r domain.key.com


First command generates a private key. Keep that guy under covers. Next command asks a few questions, and creates a Certificate Signing Request. StartSSL ignores most of the info in the CSR, but you still have to fill it out. The last three commands will make sure root owns the private key, that no one can write to it, and that only root can read it (executed in that order).

If you already have a StartSSL account, go get yourself a server certificate, and skip to the next section. Everyone else, go to www.startssl.com, click Control Panel, then Register. Once you do, do not switch computers, close the tab, or navigate away from their website. While the crypto demons won't eat you alive, bad things will happen, and you might have to start over with a different account.

The website will guide you through the registration process pretty well. At the end of it, you'll have a certificate in your browser that can be used to authenticate with websites (which no one supports, seemingly), encrypt or sign email via SMIME (supported by at least Thunderbird out of the box), and use StartSSL's OpenID and Web of Trust services. We don't care about most of those services.

Make sure you're in StartSSL's control panel, select Validations Wizard, and fire up the Domain Name validation wizard. Follow the steps as prompted. Once you've got a domain validated, you can hit up the Certificates Wizard, and get a Webserver SSL Certificate. Download the public key, and upload it to your server. I forget how I did the upload, but knowing me, it involved a text editor on the server, and copy/paste into the SSH session. If you do that, be careful the file formatting doesn't get screwed up.

Setting up Postfix to use TLS

I'll write this later...
This post is reserved for SASL.
This post is reserved for Dovecot.
This post is reserved for amavisd.
This post is reserved for SpamAssassin and ClamAV. I may end up not needing this post, but I'd rather reserve it and not need it than need it and not have it.
This post is reserved for DKIM and SPF.
This post is reserved for final testing, and other maintenance/reliability notes I might want to include.
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement