AK // SYS LOG

A technical blog covering systems administration, IT infrastructure, site reliability engineering, homelab architecture, self-hosting, automation, and practical security workflows.

View on GitHub
2 September 2017 · Updated 13 June 2026

Mail forwarding with Postfix and OpenLDAP

·

Mail forwarding was never the primary way I handled redirection in this environment. With Sieve and ManageSieve already in place, users could create their own redirects without me touching the mail server. That covered most normal cases.

What I still wanted was directory-driven forwarding. In other words, the ability to say at the LDAP layer that a mailbox or alias should forward somewhere else, and have Postfix resolve that directly.

That meant extending the schema. I pushed a commit for postfix-book.schema to include a mailForwardingAddress attribute. The PostfixBookMailForward objectClass is what carries that field.

Forwarding

Once the schema is loaded, Postfix needs a lookup table for forwarding. I created ldap-forward.cf in /etc/postfix/ldap with this:

server_host = ldap://ldap.example.com/
search_base = ou=Mail,dc=example,dc=com
version = 3
bind = no
query_filter = (&(|(mailAlias=%s)(mail=%s))(objectClass=PostfixBookMailForward))
result_attribute = mailForwardingAddress

The query_filter will match a user’s primary mail address or any mail aliases while the result_attribute is the forwarded email address.

That filter is doing exactly what it should:

That way forwarding works whether the message was addressed to the main mailbox or to one of its aliases.

Then main.cf needs the new table in virtual_alias_maps, typically through the proxied LDAP lookup form:

virtual_alias_maps = ldap:/etc/postfix/ldap/ldap-aliases.cf,ldap:/etc/postfix/ldap/ldap-groups.cf proxy:ldap:/etc/postfix/ldap/ldap-forward.cf

I liked putting it after the normal aliases and groups lookups so the mail routing flow stayed predictable.

Testing the lookup

To verify forwarding, query the table directly:

postmap -q me@example ldap:/etc/postfix/ldap/ldap-forward.cf
forwarduser@somewhere

If that address comes back, Postfix has what it needs.

If it returns nothing, check:

Why I bothered with this

The real value here was policy at the directory layer. Instead of telling users to manage forwarding only through Sieve, I could also define forwarding behavior centrally from LDAP when needed.

That made sense for administrative accounts, utility mailboxes, and addresses that existed more as routing endpoints than as real inboxes.

Where this fits now

The pattern still makes sense if you are already running the old Postfix + OpenLDAP schema. But if I were building from scratch today, I would be honest about the tradeoff: every new schema extension buys capability at the cost of more directory complexity.

This is one of those designs that feels elegant when you are deep in the mail stack and increasingly questionable when you step back and ask whether you still want to be the person maintaining all of it.

Comments

Questions, corrections, and follow-ups live in GitHub Discussions.

tags: postfix - ldap - linux - openldap - self-hosted-email - mail-forwarding - mail-server - email-routing - virtual-mailboxes - virtual-aliases - postfix-book-schema - mail-schema - homelab - sysadmin - mail-infrastructure