Let’s do Postfix slowly and properly – Part 3: Opening up to the outside

I promised that in this third part of the series we would finally get to make our SMTP server accessible from the outside, gettting a bit closer to something that actually  resembles a real mail server. I am going to make good on that promise.

There are three aspects to this change. First, we will need to set up our router so that our SMTP server can communicate with the outside world. Secondly, we will need to create a listing for our SMTP server so that other SMTP servers know where to look when they have email for our domain (the MX host setting). Finally we will of course have to adjust our Postfix configuration.

MX hosts

Setting your MX host means telling the world what the address of the SMTP server is for any given domain. This can take the form of saying that the MX host address for the domain stuffandstuff.com is simply stuffandstuff.com.

Why is this necessary then? A couple of reasons. First, if stuffandstuff has a ton of email, they might need more mail servers. One way to distribute the load is to set multiple hosts in the MX host setting: mail1.stuffandstuff.com, mail2.stuffandstuff.com, etc. These can be given priorities so that an SMTP server trying to deliver mail to a stuffandstuff.com account will try them in order. Or maybe stuffandstuff.com don’t want the hassle of email management and have outsourced the job to mailandstuff.com. Then they would need to tell the world that email destined for stuffandstuff.com should be directed to the SMTP server at mailandstuff.com (which is hopefully configured to accept mail for that destination).

You may have followed other guides instructing you to set the MX host to the mail subdomain, e.g. mail.stuffandstuff.com. If you don’t use a separate machine for mail, there’s absolutely no reason for this (2020 note: This is technically true – a mail subdomain doesn’t help in any way shape or form. But some advanced online services and protocols will likely find the lack of a mail subdomain objectionable much further down the line). Setting the MX host is about finding your SMTP server as simply as possible and the overall domain name will accomplish that just as well as intricate subdomains that may complicate matters once we start adding certificates. Keep it simple, stupid.

I cannot give precise instructions here as the details depend on how you got your domain. You will need to go to the settings in your account with whoever sold you the domain and enter the details there. Here’s a screenshot of my account with domainnameshop.com (who don’t pay me anything to say that I recommend their services as cheap and reliable):

The domain for which the setting is valid appears on the left and the address of the MX host is on the right. The host is given priority 1 (i.e. first priority) as there are no other hosts.

Once the MX host for a domain has been found, the next step is a DNS lookup to find the IP address for madsmi.de. Needless to say you will have had to configure this as well to point in the right direction. For my account at domainnameshop.com it is simply a matter of clicking the ‘DNS-pegere’ tab. No, I don’t really know why it’s in Norwegian, either. An SMTP server with mail for me will look up my MX host, then the domain name on a DNS server, find my IP address, and then finally arrive at my router’s door.

Port forwarding

If you have set anything else up on your server, apart from email, you already know about port forwarding. If not, port forwarding is telling your router that requests at a certain port should be redirected to a specfic host (and optionally on a different port) on the network. In our case we want requests at port 25, the standard SMTP port, to go to the machine we run Postfix on.

I am not going to go into detail here as port forwarding as a subject is beyond the scope of a Postfix setup guide. You can try a tutorial or two on port forwarding. Or just google ‘port forwarding tutorial‘.

Okay, so now foreign SMTP servers should be able to find our Postfix instance. Now we need to make Postfix accept email addressed to us on our internet domain as opposed to the kind of in-house mail that we have played with so far.

Master of my domain

I’m going to keep this simple. Postfix is engineered to manage a whole host of well, hosts. We don’t have that. We have a single machine. That is our host and our domain. This is how that translates to our my* settings in main.cf:

# domains
myorigin = $mydomain
myhostname = $mydomain
mydomain = stuffandstuff.com
mydestination = $mydomain, localhost, localhost.localdomain

mydomain is of course the domain name that we are trying to set up. Postfix uses the value of $myhostname to greet foreign SMTP servers and in interactions with certain other programs but when we aren’t using it to address local mail we can call it pretty much what we like. myorigin should be $mydomain so that mail addressed to alice gets sent to alice@stuffandstuff.com. Postfix should still consider itself the destination for our domain and locally addressed email. We could also keep the local name (e.g. BOBSSERVER1) for the machine in the list but there’s not much call for that now.

And that should really be all that’s necessary. Restart the postfix service and have at look at the logs to see if it complains about any of our new settings (journalctl -r -u postfix.service will give you the log in reverse order on a systemd system).

2019 update: On Debian 10 Buster I have noticed that although the postfix.service file is used to control starting and stopping the master process, the sub-processes that make up postfix report to a different service, labelled postfix@-.service that starts and stops with the main postfix.service unit. So if you wish to listen in, that is the service you should be targetting.

To test it go to your webmail provider of choice and send an email to a user (or alias) on your machine, addressing the account by way of the internet domain, e.g. alice@stuffandstuff.com. Check the log to see how it is received. If all goes well, Postfix accepts the email and delivers it to the user.

Oct 22 15:52:02 THEMINT postfix/local[25289]: 7819AD432A1: to=<alice@stuffandstuff.com>, relay=local, delay=1.1, delays=1.1/0/0/0.01, dsn=2.0.0, status=sent (delivered to command: procmail -a "$EXTENSION")

The telling thing here is that a) we address the email to a user on an internet domain and b) the log shows us that it is delivered to a local (i.e. system) user ("relay=local").

Be aware though, that it can take several hours before your MX host settings have propagated throughout the world and everybody’s aware of them.

Multiple domains

In a local setting you cannot have multiple mydomain values. There is one and only one ‘real’ name for the machine and it’s domain. The mydestination setting however, allows us to accept mail destined for other domains than mydomain. Once Postfix has accepted it, all that remains is finding the user  and when setting up a local mail server, that means finding a local user with a matching username.

In other words, suppose we setup postfix with the mydomain of stuffandstuff.com but add stuffandstuff.net to our mydestination list (alongside $mydomain and others). First we assign the same MX host to stuffandstuff.net as we did to stuffandstuff.com, that is stuffandstuff.com with a priority of 1. Then we address an email to alice@stuffandstuff.com and another to alice@stuffandstuff.net from some outside source. The outside source looks for MX hosts for stuffandstuff.com and stuffandstuff.net and find in each case that the top (and only) MX host is stuffandstuff.com. After a quick DNS lookup it finds our SMTP server. Given that Postfix considers itself the destination for both stuffandstuff.com and stuffandstuff.net it will accept both emails. Once in though, all that matters is the username, i.e. alice in both cases. So both emails end up in local user alice’s inbox.

The limits of local

As mentioned in the last post, Postfix has a dizzying assortment of tools to rewrite and redirect email, so we could make the two emails go to different inboxes. However, I think this is where we have to accept that a local setup is not really what we want. mail@domain1.net and mail@domain2.net are not the same user, masquerading behind different doors, it’s two different email addresses for two different purposes. Logically, therefore we need to move on to a virtual setup, where accounts are divorced from shell users.

Now that we have opened up to the outside world we will be getting attempts to use our server for relay. In other words, spammers. Don’t worry: Postfix’s default settings make sure that it will not relay anything except email from within your network. So unless they’re in your wifi or on your box, you should be safe. If you want to be sure, though, as always, stop the postfix.service when not testing.

Next move will be to switch to a genuine virtual domain. This will a) make it easier to manage multiple domains without conflating usernames between domains and b) make it easier to create email accounts and not worry about homes and shells and all that.

Leave a Reply