Users—real or virtual?
We need to make a configuration decision as we jump in, though: do you want your mailboxes to be tied to actual local user accounts on your mail server? This is the most traditional e-mail configuration—a local account named "bob" would have "email@example.com" as his e-mail account; another local account named "fred" would use "firstname.lastname@example.org," and so on. This configuration has the advantage of simplicity, but it's less than ideal if you don't want a bunch of user accounts on your mail server.
Instead, we're going to use virtual users for our mail server. This means that none of the mailboxes we're going to be creating will be tied to individual user accounts—rather, there will be a single (real) local service account that handles all mail, and you'll set up virtual mailboxes for as many individual user identities as you want. This way, you can give Bob and Fred their e-mail addresses without creating local accounts for them—you just need to set up an IMAP username and password and a virtual user path for them. Want to add someone to your mail server? Create a new virtual user, fast and easy.
We'll eventually create three "real" virtual users—one for you, one to use as a service robot/notifier kind of account (an address for your Web applications to send notices from, for example), and a "webmaster" e-mail account for official domain business-type stuff.
With that decision made, let's jump into Postfix's main config file.
Fix that post!
mail-stack-delivery package we installed in
part 1 has already done some basic preconfiguration tasks for us. One of
the primary things we gained without having to do the work was SASL authentication
between Postfix and Dovecot—that is, Postfix and Dovecot are already
preconfigured to be aware of each others' presence, and there's already a
Unix socket set up for Postfix to feed the e-mails it receives to
From Postfix's perspective, though, we still need to tell it some
more information about what domain it's going to be servicing and how we
want it to behave. We'll be doing this by directly editing Postfix's
main configuration file, which is called, appropriately enough,
main.cf. Let's open it up for editing and take a peek:
Right now, Postfix almost certainly isn't reachable from the Internet, because you've probably got all of its required TCP ports firewalled off (and if not, you should—at least until we're ready to use it). Even so, out of the box, Postfix is preconfigured in a relatively secure fashion. We're going to tweak it and make it better.
Staring at an application's config file for the first time can be a lot like looking at an airplane cockpit for the first time—it can project an overwhelming sense of complexity. However, just as with that cockpit's instruments and controls, the configuration file breaks down into logical groupings, and you can often ignore large parts of it once you understand what those parts do.
Here's what we want
main.cf to look like when we're
done. Note that some lines are commented out for now—we'll eventually
come back to them and uncomment them.
I've reorganized the file to keep the settings we're leaving alone at the beginning and the ones we want to change loosely organized by function below that. Note that if you're going to cut-and-paste this, remove the line breaks on the indented lines (I added them for readability and to prevent horizontal scrolling in the code window).
There are a lot of options to modify, and it's important that we don't just set them but also understand them—don't be a cargo cult sysadmin. We're going to address these configuration directives in broad strokes, because they're documented in detail in the official Postfix config file documentation. If you see a directive you'd like to look up in greater detail, definitely consult the manual.
You'll notice that several of these configuration directives refer to "maps" or hashes. Don't worry—right after we get done walking through the config file, we'll take care of getting these created.
We won't spend much time here, but there are a few things to look at. First is the
myorigin variable, which tells Postfix the name of the local server. There should be a file,
/etc/mailname, containing your mail server's hostname (mail.yourdomain.com). Make sure it's there.
You should also be aware of all the
SASL is the protocol that Dovecot uses to authenticate itself to
Postfix; remember that although we're using them as a single mail
solution, they're two different applications and they need to be able to
talk securely to each other. Our method of installation preconfigures
this communication, including setting up a unix socket within Postfix's
chroot jail (at
private/dovecot-auth) for the applications to use.
Mail server identity options
Next, we need to tell your mail server who and where it is. This is done with the three variables
Set each as appropriate—the first should be your server's fully
qualified name (mail.yourdomain.com), and the second should list the
same with some common alternate names (mail.yourdomain.com, localhost,
Finally, the last variable should include your local LAN network
segment in CIDR notation—if you're using 192.168.0.something for your
LAN, you'd include
192.168.0.0/24 in there. If you're on a
virtual host, then you might not have a local LAN segment to include—if
not, you can leave the setting at its default.
Customized smtpd parameters
Now we get to the meat: modifying options that directly affect how the mail server works ("smtpd" is the SMTP daemon—the process that sends mail).
Starting at the top, the
smtpd_banner option sets how
your server identifies itself to other servers that want to connect to
it and send mail. The default setting includes two variables,
$mail_name, along with the word "Ubuntu" in parenthesis; we want to trim this so that the whole line looks like this:
That's the minimum correct response required; wherever we have the choice to tell remote servers about ourselves, we want to do the bare minimum amount of identification. No sense in helping out attackers by revealing anything about our system that we don't have to reveal.
smtpd_helo_required = yes tells Postfix that
remote servers must identify themselves before you'll accept e-mail
commands from them. This is important because we can use the way
the remote server identifies itself as a basis for accepting or
rejecting mail from it—spammers often don't issue proper HELO responses.
In fact, the next line,
smtpd_helo_restrictions, sets up exactly what kind of responses we consider acceptable. We lead off with a
which means that clients on your LAN can generally say whatever they
want, but after that we get strict. The list of restrictions we're
applying is pretty self-explanatory (and you can consult the docs if you
want an in-depth explanation of each), but we're essentially telling
Postfix that unless a remote mail server properly identifies itself with
a verifiable, DNS-look-up-able name, we give it the middle finger and
drop the connection.
We keep the restrictions going on the next line,
smtpd_recipient_restrictions, which tells Postfix what kind of messages it will accept. Again, we have a
permit_mynetworks in the list so that mail from hosts in networks matching the
mynetworks variable is pretty unrestricted, but other than that, we have an entire slew of restrictions we're enforcing.
smtpd_sender_restrictions adds a few more
things we don't want Postfix doing, and then the last line in the
section about sender login maps tells Postfix who actually is
allowed to send e-mail on your server. As mentioned earlier, we'll get
to actually creating and populating the map files after we finish the