And so it ends. My migration off of Google is now complete (at least, for the Bandlem e-mails; my gmail address is still much alive and subscribed to many open-source mailing lists). What started a transition in 2009 off of Yahoo! mail onto Google Mail has now happened from Google Mail. In both cases, I got what I paid for but the recent kerfuffle with Google was the tipping point for me.
On a side note, I’ll be glad to get rid of the ever-present ‘All Mail’ that lined my Google IMAP folders, resulting me in marking (on average) ever e-mail as read twice.
For those of you who are interested, here’s what I moved off onto. I
now use OSX Server (you may have expected this), which includes
for mail and
dovecot for IMAP connections. Fortunately, an out-of-the-box
setup is almost trivial, but if you want to support IPv6 then you have to
do some additional work to get going.
Firstly, you have to have IPv6 support, such as a router with native IPv6 or a tunnel (I use SixXS for this purpose). Getting IPv6 up and running is relatively easy, but OSX Server makes it much more difficult than it needs to be (at least, on 10.6).
The OSX Server firewall only configures IPv4 routes, and by default effectively disables IPv6 traffic outside the local network. Whilst this is a sane choice for a default install, it needs some tweaking to work properly if you want to run with a decent stack.
Note that the firewall GUI will blow away your settings each time you update it, so the choice comes down to either (a) not using the OSX firewall app, or (b) setting up something to monitor the changes and run your script on demand. You can also throw away whatever the OSX firewall says it should use, and instead create a startup script that monitors the state of changes, and re-applies the firewall for you.
Apple makes the information in a random help document but doesn’t exactly make it clear. In essence, there is a magic setting which stops the OSX app firewall from blowing the IPv6 rules away:
1 2 3 4
true says to synchronize the Firewall with
ipfw so that when the
IPv4 firewall stops and starts, so does the
ip6fw as well.
NoRules basically means ‘get off my lawn’. It won’t do anything with
ip6fw executable, but will start and stop it. As a result, you’ll
need to configure the firewall in an appropriate script or launch daemon.
Although there’s no good way of calling the configuration at startup,
you can watch the
/etc/ipfilter/ipfilter.conf.apple which will get
re-generated whenever Firewall re-generates the rules, and then use
that to manually update the content:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
If you load this script (either by rebooting, or by doing
sudo launchctl load /Library/LaunchDaemons/com.bandlem.ip6fw.plist)
then it should start a monitoring thread on both of those files. If you change
ip6fw.conf one, it will automatically reload the file (just be sure
that you know what you’re doing!) and if the Apple Firewall manager updates
the Apple file, then the corresponding
ip6fw will get reloaded as well.
There are some incompatibilities between the two files (other than the obvious
10.0.0.0/24) – for example,
understand about either
dst-port as a keyword (the values
are next to the addresses), and nor does it understand about
So it’s not possible (in general) to drive the other.
(As a side note; the omission of
keep-state appears to block the ability
for running a DNS server over IPv6 behind the firewall, since responses
come back on UDP packets that aren’t associated with port 53. I haven’t figured
out how to solve this yet, so if you know, drop me a line via
Generally, a set of defaults for IPv6 might look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
Note the TCP ‘setup’ commands, which essentially allow inbound connections only when the TCP connection is initiated. Thereafter, any connections in the ‘established’ state (rule 12300) are permitted. The only other rule pertains to DNS on port 53, but you can add others as well.
More information about the rules are listed in the
ip6fw man page.
Since postfix comes with compiled-in support for IPv6, setting the value isn’t too difficult. However, the Apple Mail server only supports setting values in IPv4 (dotted decimal) form, which somewhat limits the use for setting the values.
The two changes toy need to make are:
1 2 3
inet_protocols = all configures it for both IPv6 and IPv4.
Note that since the IPv6 address has
:: characters in it, they need to
be surrounded by the double quotes. Also, the netmask is larger – typically
/64 subnet – but obviously configure to taste.
Dovecot provides the IMAP functionality in OSX server, and also comes with compiled support for IPv6. However, it doesn’t listen on any IPv6 addresses by default which means it’s a no-go for IPv6 mail clients.
1 2 3 4 5 6
listen keyword isn’t present by default, but the
part is. I put the listen at the top and with a comment with
# in to
remind me (plus, useful for showing in
git diffs when you have
stored in a Git repository).
The OSX DNS server supports IPv6 records (AAAA) but unfortunately, doesn’t have a way to set any of them. This presents a bit of a problem when it comes to both forward and reverse domain name lookups.
Fortunately, it is possible to do. The way that OSX stores its records for
the DNS service is with
/etc/named.conf pointing to an include of
/etc/dns/publicView.conf.apple file, which in turn defines a list
of zones at
/var/named/ – although the OSX managed data is in
/var/named/ zone file contains an include for
/var/named/zones/ corresponding file name as an include, which provides the
SOA record. Fortunately, this means we can inject additional entries in the
/var/named/ zone after the OSX include line:
1 2 3 4
Thus Server Admin manages the IPv4 addresses whilst we can add additional IPv6 addresses manually to this list. But what about reverse lookups?
Reverse IPv6 lookups use the
ip6.arpa space, in much the same way that
reverse IPv4 lookups use the
in-addr.arpa space. And in the same way
that IPv4 addresses are reversed (a lookup of
220.127.116.11 results in a PTR
18.104.22.168.in-addr.arpa), the same is true with IPv6 as well.
However, instead of using the colon separated addresses (including the
:: variable zeros), IPv6 expands the address an byte at a time. Thus,
a lookup of
2001:0db8:85a3::c3b0 resuts in a PTR lookup of
This might seem excessive, but it is the only way to ensure that leading
zeros are represented, and furthermore allows the records to be broken
down by TLD. All example records will start with 2001, so a top-level
authority will look up a record
22.214.171.124.ip6.arpa which then gives an
NS of the
8.b.d.0 record, and so the recursion continues.
Ultimately you will probably have the reverse domain requirements of a
/64 or /48 and as such, you can create a zone which represents that
reverse lookkup, such as
although this looks like a weird zone, we can create this zone in Server
Manager – although it doesn’t match the built-in regexp so treats it as
a forward list rather than a reverse list. But it does give us this file:
1 2 3 4
So whilst we can’t edit the file in any meaningful sense in Server Admin, we can use it to wire in the zone as a master for the server and set up any additional options, such as transfers and the like. I’ve found adding zones this way to be much more preferable than trying to add an additional view in the bind configuration; for some reason, the views never seem to work out when I tried the various permutations.
These notes aren’t IPv6 specific, but are things that I had to do when setting up OSX as a server. However, they’re related so I leave them here for anyone else who is interested in setting them up.
Postfix and Greylisting
The postfix server in OSX sets up an automatic greylisting process, whereby each MTA that connects to the server is immediately told to go away with a 450 code. This is intended to be a transient condition in the SMTP server, such that any MTA should re-try after a certain time-out.
This works when the sending MTA is not a one-off spambot (which typically doesn’t bother) and when there is a single sending MTA (small organisations). The IP address of the attempt gets recorded, which then unlocks the IP address for the re-delivery of the message, provided that it arrives within the appropriate window.
Where this doesn’t work is when someone is sending you a mail from Yahoo or GMail. These have SMTP farms which take it in turns to throw your message at the MTA, each with its own IP address. It likely also records the number of failures, so after cycling through a few of the zombie net it is fairly likely ultimately to mark the address as a failure and give up (and maybe even flag it up for future unavailability).
You can fix this in one of two ways:
- Remove the greylisting checks
- Implement sender address checks
The first is easiest, but also opens your door to more drive-by spam from
fake MTAs. In the
main.cf there’s a property
which lists what the checks are.
check_policy_service unix:private/policy implements the greylisting
policy. Removing these two words will disable the greylisting from happening.
You can also leave this in, and add a sender access which allows some common
domains. To do this,
main.cf as follows:
1 2 3 4 5 6 7 8 9 10
We also need to create a file
/etc/postfix/sender_access as follows:
1 2 3
Whenever you change this file, you need to tell
postfix about it; the
way you do that is to invoke the shell commands:
Of course, keeping the sender access list up-to-date and monitoring the logs is the only way to tell if everything is OK.
SSL and Mail
OSX Server Admin allows you to define SSL access for mail hosts. There is an option to use SSL for SMTP as well as IMAP. The options are:
- Don’t use
The don’t use is not recommended, and means that all communication is unencrypted. Of course, once mail goes to the outside world then it will be unecrypted anyway; but for local-to-local messages it can still make sense.
The require option sounds like a good choice. However, if you enable SSL with require, it forces all clients to switch via StartTLS. This confuses Yahoo! Mail! badly because it tries to send messages via port 587 and then refusing to switch to SSL mode – though that may be an artefact of the self-signed certificate I’m currently using.
The only option that makes sense – unless you’re going to blacklist Yahoo! Mail! – is to use the Use option, and ensure that clients that you care about always switch to SSL when they need to.
Moving off of Google Mail was a technical challenge, from setting up my own server to configuring all the nuances of IPv6 support. An unrelated part is how I moved over all the GMail from Google to my servers; this basically involved deleting huge quantities of old mail, and then moving the rest via a Mail.app configured to point to both IMAP servers. Once that had been done, it was a case of switching over the MX records and letting the spam begin!