I said that in this third part of the series I would talk about making the 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, I will need to create a listing for my SMTP server so that other SMTP servers know where to look when they have email for my domain (the MX host setting). Secondly, I will set up my router/firewall so that my SMTP server can communicate with the outside world. Finally I will of course have to adjust my Postfix configuration.
Setting your MX host means telling the world what the address of the SMTP server is for mail for your domain. This can take the form of saying that the MX host address for the domain acorp.com is simpy acorp.com
Why is this necessary then? A couple of reasons. First, if ACORP 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.acorp.com, mail2.acorp.com, etc. These can be given priorities so that an SMTP server trying to deliver mail to a acorp.com account will try them in order. Or maybe acorp.com don’t want the hassle of email management and have outsourced the job to BCORP. Then they would need to tell the world that email destined for acorp.com should be directed to the SMTP server at bcorp.com (which is hopefully configured to accept mail for that destination).
Most guides to selfhosted email will instruct you to set the MX host to the mail subdomain, e.g. mail.acorp.com. If you don’t use a separate machine for mail, there’s absolutely no need for this (2020 note: This is technically true – a mail subdomain doesn’t help in any way shape or form, it’s just a convention. 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.
MX settings are likely found at the domain name registrar (e.g. namecheap, godaddy, etc.) 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. 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.
If my mail server is running on a VPS, all I need to do is to make sure that port 25 is not blocked. If in a container as well, that the container’s port 25 is mapped to the same port on the host.
If however, I am setting up Postfix to run on a host in my network, I need to forward the port on the router to the host in question. 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 my case I want requests at the router’s port 25 (WAN side), the standard SMTP port, to go to the machine I 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. There’s a decent tutorial here.
Okay, so now foreign SMTP servers should be able to find my Postfix instance. Now I need to make Postfix accept email addressed to us on my internet domain as opposed to the kind of in-house mail that I 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. I don’t have that. I have a single machine. That is my host and my domain. This is how that translates to my
my* settings in
# domains myorigin = $mydomain myhostname = $mydomain mydomain = acorp.com mydestination = $mydomain, localhost, localhost.localdomain
mydomain is of course the domain name that I am trying to set up. Postfix uses the value of
$myhostname to greet foreign SMTP servers and in interactions with certain other programs but when I am not using it to address local mail, I can call it pretty much what I like.
myorigin should be
$mydomain so that mail addressed to alice gets sent to email@example.com. Postfix should still consider itself the destination for my domain and locally addressed email. I 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. I 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, I go to a webmail provider and send an email to a user (or alias) on my machine, addressing the account by way of the internet domain, e.g. firstname.lastname@example.org. I then 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 ACORP postfix/local: 7819AD432A1: to=<email@example.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) I address the email to a user on an internet domain and b) the log shows me that it is delivered to a local (i.e. system) user (
Be aware though, that it can take several hours before MX host settings have propagated throughout the world and everybody’s aware of them.
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 me 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 I setup postfix with the
mydomain of acorp.com but add bcorp.com to my
mydestination list (alongside
$mydomain and others). First I assign the same MX host to bcorp.com as I did to acorp.com, that is acorp.com with a priority of 1. Then I address an email to firstname.lastname@example.org and another to email@example.com from some outside source. The outside source looks for MX hosts for acorp.com and bcorp.com and find in each case that the top (and only) MX host is acorp.com. After a quick DNS lookup it finds my SMTP server. Given that Postfix considers itself the destination for both acorp.com and bcor.com, it will accept both emails. Once inside the door 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 I could make the two emails go to different inboxes. However, I think this is where I have to accept that a local setup is not really what I want. firstname.lastname@example.org and email@example.com are not the same user, masquerading behind different doors, it’s two different email addresses for two different purposes. Logically, therefore I need to move on to a virtual setup, where accounts are divorced from shell users.
Now that I have opened up to the outside world I will be getting attempts to use my server for relay. In other words, spammers. Postfix’s default settings make sure that it will not relay anything except email from within my network. So unless they’re in my wifi or on my box, I should be safe. Again, though, as always, I stop the
postfix.service when I am 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.