Alex headshot

AlBlue’s Blog

Macs, Modularity and More

Migration off of Google

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.

Tech Details

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 postfix 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.


WORLD IPV6 DAY is 8 June 2011 – The Future is Forever

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:

```xml /etc/ipfilter/ip_address_groups.plist

IPv6Mode NoRules IPv6Control

The `true` says to synchronize the Firewall with `ipfw` so that when the
IPv4 firewall stops and starts, so does the `ip6fw` as well.

The `NoRules` basically means 'get off my lawn'. It won't do anything with
the `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/` which will get
re-generated whenever Firewall re-generates the rules, and then use
that to manually update the content:

```xml /Library/LaunchDaemon/com.bandlem.ip6fw.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "">
<plist version="1.0">

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 the 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 filters for fe80:/64 vs – for example, ip6fw doesn’t understand about either src-port or dst-port as a keyword (the values are next to the addresses), and nor does it understand about keep-state. 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 @alblue.)

Generally, a set of defaults for IPv6 might look like this:

```text /etc/ipfilter/ip6fw.conf

Get rid of any previous rules


For some reason the firewall defaults to ‘allow any to any’, so override that

add 65000 deny ipv6 from any to any

Ping etc.

add 01000 allow ipv6-icmp from any to any

Your local subnet

add 1200 allow all from 2001:0db8:85a3::/64 to 2001:0db8:85a3:/64

Allow established TCP connections

add 12300 allow tcp from any to any established

Allow any outbound requests

add 12301 allow tcp from any to any out add 12302 allow udp from any to any out

DNS support

add 12303 allow tcp from any to any 53 add 12303 allow tcp from any 53 to any add 12303 allow udp from any to any 53 add 12303 allow udp from any 53 to any

Fragmented UDP packets

add 12304 allow udp from any to any in frag

Allow inbound HTTP

add 12309 allow tcp from any to any 80 setup

Allow inbound SSH

add 12310 allow tcp from any to any 22 setup

Allow inbound HTTPS

add 12311 allow tcp from any to any 443 setup

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
<a href="">`ip6fw`</a> man page.

### Mail (Postfix/SMTP) ###

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:

```text /etc/postfix/
inet_protocols = all
smtp_bind_address6 = 2001:0db8:85a3::c3b0
mynetworks =,[::1]/128,[2001:0db8:85a3::]/64

The 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 a /64 subnet – but obviously configure to taste.

Mail (Dovecot/IMAP)

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.

```text /etc/dovecot/ protocol imap { … # Listen on both IPv4 (*) and IPv6 ([::]) addresses listen = *,[::] … }

The `listen` keyword isn't present by default, but the `protocol imap`
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 `/etc`
stored in a Git repository).

### DNS ###

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/` file, which in turn defines a list
of zones at `/var/named/` -- although the OSX managed data is in
`/var/named/zones/`. The `/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:

```text /var/named/
$INCLUDE /var/named/zones/ IN AAAA 2001:0db8:85a3::c3b0

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 space, in much the same way that reverse IPv4 lookups use the space. And in the same way that IPv4 addresses are reversed (a lookup of results in a PTR lookup of, 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 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 Fortunately, 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:


0.b.3.c. PTR

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.

### Other config ###

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 <abbr title="Mail Transfer Agent">MTA</abbr> 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

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:

1. Remove the greylisting checks
2. Implement sender address checks

The first is easiest, but also opens your door to more drive-by spam from
fake MTAs. In the `` there's a property `smtpd_recipient_restrictions`
which lists what the checks are.

The `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, `check_sender_access hash:/etc/postfix/sender_access`
into the `` as follows:

```text /etc/postfix/
# Place the following on one line
smtpd_recipient_restrictions =
 check_sender_access hash:/etc/postfix/sender_access
 check_policy_service unix:private/policy

We also need to create a file /etc/postfix/sender_access as follows:

```text /etc/postfix/sender_access OK OK …

Whenever you change this file, you need to tell `postfix` about it; the
way you do that is to invoke the shell commands:

$ sudo postmap /etc/postfix/sender_access
$ sudo postfix reload

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
  • Use
  • Require

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 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!