Preface

Mailcow is an awesome self-hosted, container-based email solution.

SRS (Sender Rewriting Framework) (from Wikipedia):

For a mail transfer agent (MTA), the Sender Rewriting Scheme (SRS) is a scheme for rewriting the envelope sender address of an email message, in view of remailing it. In this context, remailing is a kind of email forwarding. SRS was devised in order to forward email without breaking the Sender Policy Framework (SPF), in 2003.

Mailcow does not include support for SRS which causes problems with email aliases that point to external email addresses.

This article show how I have ‘hacked’ SRS into Mailcow using postsrsd. Most of the Postfix configuration was taking from this postsrsd issue.

Container

I have created a container with postsrsd.

First, add a new container to docker-compose.override.yml

    postsrsd-mailcow:
            image: ajoergensen/postsrsd:latest
            restart: always
            environment:
                    - SRS_DOMAIN=mydomain.dom
                    - SRS_SECRET=<secret>
            networks:
                    mailcow-network:
                            ipv4_address: ${IPV4_NETWORK:-172.22.1}.42

SRS_DOMAIN is the domain to be used as sender domain for the rewritten emails.

SRS_SECRET is the key used to generate the hashed rewritten sender addresses.
This should be treated with same care as a password as knowledge of this secret would allow someone to use your mailserver as an open relay. It is generated using this command:

dd if=/dev/random bs=18 count=1 | base64

After adding the container, start it:

docker-compose up -d postsrsd-mailcow

The container’s configuration is documented on Docker Hub.

Postfix configuration

In the file data/conf/postfix/extra.cf (relative to where the Mailcow git repository is checked out), add these lines:

sender_canonical_classes = envelope_sender
recipient_canonical_maps = tcp:172.22.1.42:10002, proxy:mysql:/opt/postfix/conf/sql/mysql_recipient_canonical_maps.cf
recipient_canonical_classes = envelope_recipient, header_recipient

In the file data/conf/postfix/master.cf, add these lines:

# SRS config
cleanup-srs unix  n       -       -       -       0       cleanup
      -o sender_canonical_maps=tcp:172.22.1.42:10001
      -o sender_canonical_classes=envelope_sender
      -o recipient_canonical_maps=regexp:/opt/postfix/conf/regex_sender_canonical_srs

127.0.0.1:10029 inet    n       -       -       -       -       smtpd
        -o cleanup_service_name=cleanup-srs
        -o smtpd_tls_security_level=none
        -o content_filter=smtp:
        -o smtpd_recipient_restrictions=permit_mynetworks,reject
        -o smtpd_milters=

In the file data/conf/postfix/regex_sender_canonical_srs, add this line:

/^srs=(.*)@(.*)$/ ${1}@${2}

In the file data/conf/postfix/custom_transport.pcre, add this line:

/^srs=.*@.*$/ smtp:127.0.0.1:10029

Finally, restart the Postfix container:

docker-compose restart postfix-mailcow

Add external aliases

Any external email address must be prefixed with “srs=” in order for it to be routed through postsrsd:

Add new alias

And do not worry, the srs= part is stripped before the email leaves the server.