My VPS provider (Ionos) recently changed to no longer support IPv6 Reverse DNS, and this causes problems with sending mails to services like Gmail. I set about disabling IPv6 in my Mailcow setup per the instructions docs.mailcow.email Icon here

, and all seemed fine.

However today I found a bunch of emails had been routed through my server somehow, sending spam using one of my domains which doesn’t have any mailboxes, just a couple of aliases, and the From address being used in the spam messages didn’t correspond to any of those addresses.

Digging through my logs, it appeared that these messages were being submitted from 172.22.1.1 which is the default gateway on the docker network for mailcow, using a high numbered port on the client end. This had me stumped for a while on how this could happen, but I think this is probably because the external IPv6 address is still available for my server, and Docker is routing IPv6 traffic to the internal IPv4 mailcow network via the default gateway. Since it looks like Mailcow automatically whitelists traffic from the gateway address, it looks like this effectively creates an open relay, or at least a relay for messages appearing to come from any of the hosted domains.

Does this analysis seem reasonable, or am I misinterpreting what’s happening here?

For now I have changed my configuration and re-enabled IPv6 support, and I think I have found the “proper” way to limit postfix to send mails out only via IPv4.

As per the postfix documentation here

:

The setting “smtp_address_preference = ipv4” is not a solution for remote servers that flag email received over IPv6 as more ‘spammy’ (the client IPv6 address has a bad or missing PTR or AAAA record, bad network neighbors, etc.). Instead, configure Postfix to receive mail over both IPv4 and IPv6, and to deliver mail over only IPv4.

/etc/postfix/main.cf:
inet_protocols = all
/etc/postfix/master.cf
smtp …other fields… smtp -o inet_protocols=ipv4

Mailcow already uses inet_protocols = all so I amended data/conf/postfix/master.cf to add the relevant option to sections which use the smtp service, specifically:

  • smtp_enforced_tls
  • smtp_via_transport_maps
  • smtp
  • relay

Snippets from master.cf:

# enforced smtp connector
smtp_enforced_tls      unix  -       -       n       -       -       smtp
  -o smtp_tls_security_level=encrypt
  -o syslog_name=enforced-tls-smtp
  -o smtp_delivery_status_filter=pcre:/opt/postfix/conf/smtp_dsn_filter
  -o inet_protocols=ipv4
# Send over IPv4 only since Ionos no longer supports reverse DNS for IPv6

# smtp connector used, when a transport map matched
# this helps to have different sasl maps than we have with sender dependent transport maps
smtp_via_transport_maps      unix  -       -       n       -       -       smtp
  -o smtp_sasl_password_maps=proxy:mysql:/opt/postfix/conf/sql/mysql_sasl_passwd_maps_transport_maps.cf
  -o inet_protocols=ipv4
# Send over IPv4 only since Ionos no longer supports reverse DNS for IPv6

smtp       unix  -       -       n       -       -       smtp
  -o inet_protocols=ipv4
# Send over IPv4 only since Ionos no longer supports reverse DNS for IPv6

relay      unix  -       -       n       -       -       smtp
  -o inet_protocols=ipv4
# Send over IPv4 only since Ionos no longer supports reverse DNS for IPv6

I believe I’ll need to re-apply these changes manually after each upgrade of mailcow since master.cf will be replaced during the upgrade, and I can’t set this configuration via extra.cf.

So far this configuration to send only via IPv4 seems to be working.

Looking into it a bit more, postfix is configured to relay mail coming from machines on the local subnet, due to the mynetworks_style = subnet setting combined with permit_mynetworks being set for smtpd_relay_restrictions, postscreen_access_list, smtpd_recipient_restrictions, and smtpd_sender_restrictions (all in main.cf), so I think this will actually create a full open relay if the incoming connection appears to come from the internal network.

I think my diagnosis is correct about the IPv6 external client address being mapped to the mailcow network’s IPv4 default gateway address, based on this page on IPv6 support for docker-mailserver.

If your host system supports IPv6 and an AAAA DNS record exists to direct IPv6 traffic to DMS, you may experience issues when an IPv6 connection is made:

  • The original client IP is replaced with the gateway IP of a docker network.

It looks like docker-mailserver does not have IPv6 enabled by default in its container(s), so this would be analogous to the scenario for Mailcow with IPv6 disabled.

So I think this is a scenario to watch out for when disabling IPv6 in the mailcow setup, but continuing to have an external IPv6 address on your host, since this will create an open relay for IPv6 external clients!

I think my diagnosis is correct about the IPv6 external client address being mapped to the mailcow network’s IPv4 default gateway address, based on this page on IPv6 support for docker-mailserver.

If your host system supports IPv6 and an AAAA DNS record exists to direct IPv6 traffic to DMS, you may experience issues when an IPv6 connection is made:

  • The original client IP is replaced with the gateway IP of a docker network.

It looks like docker-mailserver does not have IPv6 enabled by default in its container(s), so this would be analogous to the scenario for Mailcow with IPv6 disabled.

So I think this is a scenario to watch out for when disabling IPv6 in the mailcow setup, but continuing to have an external IPv6 address on your host, since this will create an open relay for IPv6 external clients!

Have something to say?

Join the community by quickly registering to participate in this discussion. We'd like to see you joining our great moo-community!

2 months later

Looks like my changes to master.cf to only use IPv4 for smtp services were preserved during the latest mailcow update process, but definitely something I’ll keep an eye on with each update.

a year later

Apparently this is still an issue and if you ask me a pretty significant security issue! I freshly installed mailcow and followed the instructions to disable ipv6 and soon enough was seeing spam sent to [randomnumber]@qq.com

here are the logs from postfix:

postfix/smtpd[7060]: B5F5321A0F04: client=unknown[172.22.1.1]
postfix/cleanup[7062]: B5F5321A0F04: message-id=<randomname@domain.com>
postfix/qmgr[377]: B5F5321A0F04: from=<randomname@domain.com>, size=3256, nrcpt=1 (queue active)
postfix/smtpd[7060]: disconnect from unknown[172.22.1.1] ehlo=1 mail=1 rcpt=1 data=1 quit=1 commands=5
postfix/smtp[7054]: Trusted TLS connection established to mx3.qq.com[203.205.219.57]:25: TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)
postfix/smtp[7054]: B5F5321A0F04: to=<randomnumber@qq.com>, relay=mx3.qq.com[203.205.219.57]:25, delay=7.3, delays=4.8/0/1.4/1.2, dsn=2.0.0, status=sent (250 OK: queued as.)
postfix/qmgr[377]: B5F5321A0F04: removed
  • esackbauer

    • Community Hero
    Moolevel 437
  • Edited

mailcow/mailcow-dockerized5242
Seemed like a docker issue on Arch Linux (which is not supported), but others had this as well, userland-proxy setting seems to fix it.

Perhaps I’m completely off track here (I’m no IPv6 expert), but if you don’t assign a public IPv6 address to your server, there’s really no need to disable IPv6 at the system level, since it then only has non-routable fe80:: addresses anyway. So I don’t believe it’s possible to create an open relay just by misconfiguring IPv6 settings in Mailcow, if your server doesn’t have a public IPv6 address assigned.

That said, Mailcow might still not work properly if it expects a public IPv6 address because IPv6 is enabled at some places..

Based on my experience, it’s best to follow the Postfix and Dovecot steps in the “Disable IPv6” section of the documentation to avoid potential issues. However, I’d say the Docker Compose override part is unnecessary if your server doesn’t even have a public IPv6 address assigned. In my case, that override never survived updates anyway.

  • cjwalsh

      Moolevel 2
    • Edited

    Just to clarify my own setup, I do still have a public IPv6 address for my server (the docker host) so traffic can attempt to be routed to my mailcow container via that address. What prompted me to look to disable IPv6 for mailcow was my hosting provider no longer supporting reverse DNS PTR records for IPv6 addresses. I have other services on this host which I’m happy to provide access over the IPv6 address.

    [unknown] What are the (other) implications of setting userland-proxy = false in the docker daemon configuration?

    [unknown] What are the (other) implications of setting userland-proxy = false in the docker daemon configuration?

      cjwalsh I have other services on this host which I’m happy to provide access over the IPv6 address.

      Ah, OK. That’s something I’ve never considered doing because I think email is too important to expose it to more attack vectors than it already faces by design. 😉

      But yeah, then I’m not sure. I’m not much of an IPv6 or Docker expert, which is why I treat Mailcow strictly as an appliance (which it technically is) and don’t run anything else on the same server/VPS.

      Even without any other services my setup allows for incoming connections over IPv6, but limits outgoing mail sending to IPv4 only to preserve the server’s reputation and avoid getting down-ranked due to lack of PTR record for the IPv6 address.

      I need to understand more about the userland-proxy setting however, seems like lots of recommendations from security perspective to disable it to reduce attack surface area. All my web services are behind a reverse proxy with a shared docker network which is referenced as an external network in their compose files but not exposed to the internet, but I am still exposing the non-web traffic mailcow ports directly.

      No one is typing