When running your own SMTP the real spam challenge is not to avoid getting targeted by spammers – it is is to avoid getting used by spammers.
Mind you, you don’t want spam in your inbox but a) that’s what filters are for and b) spammers (mostly) use confirmed lists of recipients, they don’t probe domains for addresses. When they do probe, they probe for access to relay, to use your server to distribute their junk. If they’re successful you’ll have far bigger problems than having to delete a couple emails a day (i.e. your IP and domain winding up on blacklists; also your ISP may disapprove). That is the reason I have saved relaying until now. Opening yourself up to receiving unwanted mail is at lot less problematic than opening yourself up to having your server hijacked by spammers. Postfix is by default set to be rather restrictive in who it lets send out mail so while we have been messing about with receiving mail, the mail sending settings have stayed default and safe.
This will be a short post, as we will only get to know how to relay mail based on the
mynetworks setting. ‘Relay’ is fairly synonynous with ‘sending’ but AFAICT it only refers to sending between SMTP servers. A user sends an email. An SMTP server relays it to another SMTP server. This post is about relaying from a local network.
Making it through the keyhole: Rules and restrictions
The first thing to know about mail relay is that there is no fundamental distinction between mail headed out or in. Email gets handed to the SMTP server and it tries to figure out where it should go and if it should be accepted. All mail, regardless of provenance, must pass a set of rules in order for it to be relayed by Postfix, whether to an account on our own server or somewhere else on the internet.
Here are the important terms to learn. You set six rules for mail to pass through to determine if Postfix will reject or accept it. That doesn’t sound like much but “rule” here, really means ‘stage’, each of which corresponds to a step in the SMTP transaction (steps such
MAIL FROM, and
RCPT TO that we went through in our first telnet session), and each of which can have any number of restrictions assigned to it. The default on my install (Ubuntu 15.04) is only to use one of these rules, the
smtpd_relay_restrictions. For this rule is used the default trio of restrictions. The
smtpd_relay_restrictions get into play on the RCPT TO-step when the client has told the server who the mail is from and to whom it is addressed. Let’s take a look:
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
Note that this long line can be broken up for easier reading. As long as the first character on a line is a space, Postfix reads that line as a continuation of the previous with no need for escape characters or the like.
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
When handling an email of whatever provenance – inside or outside of the local network, from the host machine itself – Postfix goes through these restrictions one by one in the order listed. Each restriction then evaluates to OK, REJECT or DUNNO. As soon as one of the restrictions says REJECT, Postfix quits evaluating not just the current rule but all rules. The email’s fate is sealed. If it gets an OK, it moves on to the next rule (that would be
smtpd_recipient_restrictions). Seeing as we only use the one rule (
smtpd_relay_restrictions) it basically boils down to whether the mail first hits an OK or a REJECT.
The default restrictions
So let’s try to understand what those three default restrictions actually test for.
permit_mynetworksissues an OK if the connecting client comes from any of the networks listed in the
mynetworkssetting. This is by default almost always just the local machine and some part of the local netowrk. A restriction that begins with “permit” therefore either results in an OK or a DUNNO, so anything from outside the local network just moves on to the next restriction. Connections that originate from within the local network are accepted, historically so that people working at very stationary desktops in an office building has free access to send within and out of the office. We will get more into how to configure the
mynetworkssetting later in the post.
permit_sasl_authenticatedallows a user who have authenticated using the Simple Authentication and Security Layer to send mail. We will get more into SASL in a later post but in this default setting this will always evaluate to DUNNO as we haven’t provided a way to authenticate using SASL.
defer_unauth_destinationis a variation of
reject_unauth_destination(defer sends out a slightly different rejection code) For our purposes it rejects any mail for which Postfix does not consider itself the final destination. If our Postfix install is the final destination for the email, it gets a DUNNO.
How does it work in practice then, say when somebody from the outside send us an email. Well,
permit_mynetworks is consulted first and responds with a shoulder shrugging DUNNO. The mail does not come from any of the networks listed in
mynetworks so it can’t give it an OK. Next up is
permit_sasl_authenticated which can’t give an OK either since foreign SMTP servers do not authenticate as accounts on our system. That’s another DUNNO. Since we haven’t got a REJECT yet, the mail limps on to the final restriction. Supposing that Postfix is the SMTP server for the domain addressed and the user addressee is a legitimate one, the mail does not get a REJECT from
defer_unauth_destination but yet another DUNNO. Remember, it’s not
permit_auth_destination. Huh, so three DUNNOs? Fortunately the default setting is to accept mail that has passed through all our restrictions without a REJECT, even if it has not explicitly been OK’ed.
You can try the same thought experiment for mail going the other way. Remember that for each rule, the evaluation ends as soon as we get either an OK or a REJECT (or get to the end with only DUNNOS which is the email equaivalent of a 0-0 tie). We aren’t going to change those defaults right now. At a later stage we will add a restriction that quickly rejects known spammers but for now we will content ourselves with looking at those
mynetworks that are by default allowed access.
Mynetworks: Relay access for mypeeps
The default setting for mynetworks on my setup was this:
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
That is three values divided by spaces. The first is in IPv4 notation, the last two are in IPv6. Now, you’ve probably heard about IP6 and how we need it because we are running out of IPv4 addresses. Well, seeing as this is purely a local network setup and I’m not running out of adddresses. I’m going to delete the IP6 addresses (my network isn’t set up for it anyway) and focus on the IPv4. Here’s the simple version. 127.0.0.0/8 denotes a network range, that is a number of IP addresses. The 8 after the slash tells you how many bits are ‘fixed’ and so allows you to see how many addresses are left to you. Let’s try to do the math and hopefully it will become clearer. If not there’s a decent explanation here. 8 bits is 10000000 in binary or 256 in decimal notation (28). That corresponds to the part of the address before the first point. The 8 tells you that this part of the address is locked, so your network range consists of all the variations on that beginning. That is the remaning part of the address, the three times 8 bits that are left or 256*256*256 or some 16 million addresses. Of course the 127.0.0.0/8 address range is probably only relevant for a single address, namely 127.0.0.1, which is the host machine itself. Now, sysadmins are interested in network ranges to see how many addresses they have. We are only interested in limiting who has access granted by the
mynetworks setting. I’m going to cut to the chase and present my mynetworks setting and explain it.
mynetworks = 127.0.0.0/8 !192.168.87.1 192.168.87.0/24
If we start with the last one. 192.168.87.0/24 is a network range in which 24 bits are fixed, meaning that there is only 8 bits left of ‘free’ addresses (32-24=8). This corresponds to the part of the address after the last point. So for any address to qualify it has to start with 192.168.87 (my ISP’s router is set to hand out addresses in this range). The second last value – the one beginning with an exclamation point – specifies a single IP address that is excepted from the allowed range (the ‘!’ means that this address is to be excluded). I have to put it before the general range because otherwise it would already have been accepted. Needless to say 192.168.87.1 is the router’s address. And the first value is the default setting we have already seen.
To test that the entire local network is now able to send, we set up a client on another machine on the network, e.g. a laptop. Anything, just not the server. For configuring our MUA for using our SMTP server, we use the local IP address of our server, port 25, and no encryption or ‘plaintext’. There is no need for authentication. Now, we fire off an email to a Gmail friend of ours. Here’s the kind of log we should get from Postfix.
Oct 25 12:08:21 THEMINT postfix/smtpd: connect from unknown[192.168.87.105] Oct 25 12:08:21 THEMINT postfix/smtpd: C3248D44826: client=unknown[192.168.87.105] Oct 25 12:08:21 THEMINT postfix/cleanup: C3248D44826: message-id=<email@example.com> Oct 25 12:08:21 THEMINT postfix/qmgr: C3248D44826: from=<firstname.lastname@example.org>, size=1061, nrcpt=1 (queue active) Oct 25 12:08:21 THEMINT postfix/smtpd: disconnect from unknown[192.168.87.105] Oct 25 12:08:22 THEMINT postfix/smtp: C3248D44826: to=<email@example.com>, relay=gmail-smtp-in.l.google.com[220.127.116.11]:25, delay=0.82, delays=0.15/0/0.34/0.3 Oct 25 12:08:22 THEMINT postfix/qmgr: C3248D44826: removed
What happens when we connect from outside
mynetworks? Change the client setup so that the SMTP server is our domain name. Write to the same Gmail address. Regardless of how we connect (using local wifi or phone network) we should get rejected because the addressing is not that of the local network but of the internet. Here’s me using my 3G network to access the server over the network and getting rejected.
Oct 25 12:19:06 THEMINT postfix/smtpd: connect from 80-62-116-127-mobile.dk.customer.tdc.net[18.104.22.168] Oct 25 12:19:07 THEMINT postfix/smtpd: NOQUEUE: reject: RCPT from 80-62-116-127-mobile.dk.customer.tdc.net[22.214.171.124]: 454 4.7.1 <firstname.lastname@example.org>: Relay access denied; from=<email@example.com> to=<firstname.lastname@example.org> proto=ESMTP helo=<[10.37.15.127]> Oct 25 12:19:07 THEMINT postfix/smtpd: disconnect from 80-62-116-127-mobile.dk.customer.tdc.net[126.96.36.199]
So now we can use our laptop to send mail – assuming we don’t leave the house. It’s not much but it’s a start. We’re getting there slowly and hopefully, properly.