Recently I decided to rebuild our main Debian Squeeze host as a 64-bit Debian Wheezy (7.0; I believe the template is 7.3 as of the time of this writing) VPS. This box runs web hosting, email, internal IRC, shell access and basically any other services that one of our beloved sudoers would like to try. Both of these hosts live in Linode’s Newark datacenter.
Linode will pro-rate your account if you cancel a server in the middle of a month, so both instances (old and new) are currently running for a minimal net cost. You can also assign private IPs to each host and SCP data or mount NFS between servers without cutting into your bandwidth quota, as well as attain a slight transfer speed improvement. This gives us plenty of time to move finicky services and make sure that the new configuration is working as intended. We’ve been cutting over individual user websites and mail services one by one to lessen the impact.
One of the problems I ran into that did not exist on the old host was email forwarding. We use the Linode Library: Email with Postfix, Dovecot, and MySQL article as a basis for a mail server that supports multiple domains, IMAP mailboxes and aliases that forward to multiple accounts. Most of our traffic is forwarding operations, typically to multiple users at once as sort of a poor-man’s distribution list. The main forwarder is an internal alias for Slightly Sauced group discussions, which sends messages out to everyone’s preferred mail provider.
Initially there didn’t seem to be any problems with the mail setup. I use Exchange Online for my personal email and messages were coming and going properly to me. When I went to reply to an existing thread, I soon got a bounceback message from for only a few email recipients the list. Checking
/var/log/mail.log, I found the following lines (truncated for brevity and sanitized to not mention any specific email addresses):
Feb 26 21:58:24 services02 postfix/qmgr: 2F6FA6AB68: from=<email@example.com>, size=31176, nrcpt=9 (queue active)
Feb 26 21:58:24 services02 postfix/smtp: 2F6FA6AB68: to=<firstname.lastname@example.org>, orig_to=<email@example.com>, relay=ASPMX.L.GOOGLE.com[2607:f8b0:400d:c04::1b]:25, delay=8.6, delays=8/0.01/0.13/0.46, dsn=2.0.0, status=sent (250 2.0.0 OK 1393451904 g88si838453qgf.126 - gsmtp)
Feb 26 21:58:24 services02 postfix/smtp: 2F6FA6AB68: to=<firstname.lastname@example.org>, orig_to=<email@example.com>, relay=mx1.sub4.homie.mail.dreamhost.com[184.108.40.206]:25, delay=8.7, delays=8/0.02/0.24/0.39, dsn=2.0.0, status=sent (250 2.0.0 Ok: queued as 84D4B76807B)
Feb 26 21:58:24 services02 postfix/smtp: 2F6FA6AB68: to=<firstname.lastname@example.org>, orig_to=<email@example.com>, relay=gmail-smtp-in.l.google.com[2607:f8b0:400d:c00::1a]:25, delay=8.7, delays=8/0.01/0.06/0.58, dsn=5.7.1, status=bounced (host gmail-smtp-in.l.google.com[2607:f8b0:400d:c00::1a] said: 550-5.7.1 [2600:3c03::f03c:91ff:fe6e:423f 12] Our system has detected that 550-5.7.1 this message is likely unsolicited mail. To reduce the amount of spam 550-5.7.1 sent to Gmail, this message has been blocked. Please visit 550-5.7.1 http://support.google.com/mail/bin/answer.py?hl=en&answer=188131 for 550 5.7.1 more information. r6si610718qcl.69 - gsmtp (in reply to end of DATA command))
Feb 26 21:58:26 services02 postfix/smtp: 2F6FA6AB68: to=<firstname.lastname@example.org>, orig_to=<email@example.com>, relay=example-com.mail.protection.outlook.com[220.127.116.11]:25, delay=11, delays=8/0.02/0.34/2.3, dsn=2.6.0, status=sent (250 2.6.0 <72c119e2692a422cbc733234ced8599a@SN2PR03MB046.namprd03.prod.outlook.com> [InternalId=49989124371267, Hostname=BY2PR03MB041.namprd03.prod.outlook.com] Queued mail for delivery)
Feb 26 21:58:26 services02 postfix/bounce: 2F6FA6AB68: sender non-delivery notification: D6C4C6AB90
The first thing I noticed is that the users on Dreamhost IMAP, Exchange Online, and Google Apps / Google Hosted accounts did not have the forwarded message rejected. Forwards going to straight @gmail.com addresses were immediately rejected. I reviewed the Google Support document without much luck, and then stumbled across some documentation from Tanguy Ortolo about Google’s IPv6-related email restrictions. While Tanguy’s workaround was a good one (force IPv4 connections to Google mail servers), I tried to solve the problem while maintaining IPv6 connectivity. Linode does let you set reverse DNS (PTR) records for both IPv4 and IPv6 addresses, as long as they forward-resolve correctly.
- In the Linode control panel or your own DNS management system, establish A and AAAA records for the server that is transmitting email. (eg: mailserver01.example.com.) Wait for the records to be resolvable and check with the dig a $hostname; dig aaaa $hostname commands on an IPv6 enabled system.
- In the Linode control panel, find the individual VPS and access Remote Access. In the Public IPs section, click Reverse DNS.
- On the Reverse DNS page, look up the domain name (mailserver01.example.com) with the provided tool. If your A and AAAA records are present and functional, Linode will ask whether you would like to use mailserver01.example.com as the reverse DNS entry for both your IPv4 and IPv6 addresses. Click Yes to both options.
Within 24 hours, forwarded mail flow to Gmail accounts should begin working properly.
I also took this opportunity to update my SPF records as Exchange Online was fairly restrictive about certain types of messages that I sent through this server. I had to update my SPF record to:
v=spf1 a mx include:spf.protection.outlook.com include:example.com ~all, where example.com was the domain of our Debian mail server that had its own SPF record.
Update, June 29/14: You also want to ensure that your SPF record doesn’t have more than ten total DNS lookups, recursively including all ‘include:’ directives. Exchange Online adds quite a few. Use http://www.kitterman.com/spf/validate.html to confirm that the SPF entry passes with the pyspf checker.