Mailcow-dockerized: All IPv6 connections are whitelisted

Created on 8 Jun 2020  路  14Comments  路  Source: mailcow/mailcow-dockerized

Prior to placing the issue, please check following: (fill out each checkbox with an X once done)

  • [x] I understand, that not following or deleting the below instructions, will result in immediate closing and deletion of my issue.
  • [x] I have understood that answers are voluntary and community-driven, and not commercial support.
  • [x] I have verified that my issue has not been already answered in the past. I also checked previous issues.

Description of the bug:
This morning my mailcow installation has started sending out spam mails. In the postfix log, I found that mails were coming from client=unknown[172.22.1.1] which is the IPv4 address of the mailcow bridge. Since this address is whitelisted by default, all mail was accepted.

Apparently all incoming IPv6 connections are translated to this source address. I know this looks like a misconfiguration on my part since most people probably don't see this behaviour. However, since I only just now modified the firewall configuration and followed the documentation, I believe this might be a bug in mailcow-dockerized.

Docker container logs of affected containers:
Well, I assume this would be ipv6nat:

$ docker logs -f mailcowdockerized_ipv6nat-mailcow_1   
# Warning: iptables-legacy tables present, use iptables-legacy to see them
# Warning: iptables-legacy tables present, use iptables-legacy to see them
# Warning: iptables-legacy tables present, use iptables-legacy to see them

Reproduction of said bug:

Restarting the server has not changed the behaviour so I guess I'm able to reproduce this.

System information:

| Question | Answer |
| --- | --- |
| My operating system | Ubuntu 18.04 |
| Is Apparmor, SELinux or similar active? | No |
| Virtualization technlogy (KVM, VMware, Xen, etc - LXC and OpenVZ are not supported | KVM |
| Server/VM specifications (Memory, CPU Cores) | 8GB RAM, 4 cores |
| Docker Version (docker version) | 19.03.8 |
| Docker-Compose Version (docker-compose version) | 1.25.5 |
| Reverse proxy (custom solution) | No |

* Further information *:

No changes to mailcow-dockerized:

$ git status
On branch master
Your branch is ahead of 'origin/master' by 12 commits.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean

I'm on commit dcb1ee9670233481be2f6423f5fc04fe51b1b09d.

iptables rules:

$ iptables -L -vn
Chain INPUT (policy ACCEPT 13716 packets, 2757K bytes)
pkts bytes target     prot opt in     out     source               destination
1338K  313M MAILCOW    all  --  *      *       0.0.0.0/0            0.0.0.0/0

Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target     prot opt in     out     source               destination
100M   17G MAILCOW    all  --  *      *       0.0.0.0/0            0.0.0.0/0
100M   17G DOCKER-USER  all  --  *      *       0.0.0.0/0            0.0.0.0/0
100M   17G DOCKER-ISOLATION-STAGE-1  all  --  *      *       0.0.0.0/0            0.0.0.0/0
    0     0 ACCEPT     all  --  *      docker0  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
    0     0 DOCKER     all  --  *      docker0  0.0.0.0/0            0.0.0.0/0
    0     0 ACCEPT     all  --  docker0 !docker0  0.0.0.0/0            0.0.0.0/0
    0     0 ACCEPT     all  --  docker0 docker0  0.0.0.0/0            0.0.0.0/0
116M   46G ACCEPT     all  --  *      br-mailcow  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
5908K  430M DOCKER     all  --  *      br-mailcow  0.0.0.0/0            0.0.0.0/0
22M 3451M ACCEPT     all  --  br-mailcow !br-mailcow  0.0.0.0/0            0.0.0.0/0
5674K  419M ACCEPT     all  --  br-mailcow br-mailcow  0.0.0.0/0            0.0.0.0/0

Chain OUTPUT (policy ACCEPT 15061 packets, 3119K bytes)
pkts bytes target     prot opt in     out     source               destination

Chain DOCKER (2 references)
pkts bytes target     prot opt in     out     source               destination
    0     0 ACCEPT     tcp  --  !br-mailcow br-mailcow  0.0.0.0/0            172.22.1.250         tcp dpt:12345
    0     0 ACCEPT     tcp  --  !br-mailcow br-mailcow  0.0.0.0/0            172.22.1.250         tcp dpt:4190
41  2120 ACCEPT     tcp  --  !br-mailcow br-mailcow  0.0.0.0/0            172.22.1.250         tcp dpt:995
50  2588 ACCEPT     tcp  --  !br-mailcow br-mailcow  0.0.0.0/0            172.22.1.250         tcp dpt:993
13   664 ACCEPT     tcp  --  !br-mailcow br-mailcow  0.0.0.0/0            172.22.1.250         tcp dpt:143
13   672 ACCEPT     tcp  --  !br-mailcow br-mailcow  0.0.0.0/0            172.22.1.250         tcp dpt:110
    1    60 ACCEPT     tcp  --  !br-mailcow br-mailcow  0.0.0.0/0            172.22.1.6           tcp dpt:587
    1    60 ACCEPT     tcp  --  !br-mailcow br-mailcow  0.0.0.0/0            172.22.1.6           tcp dpt:465
15   900 ACCEPT     tcp  --  !br-mailcow br-mailcow  0.0.0.0/0            172.22.1.6           tcp dpt:25

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
pkts bytes target     prot opt in     out     source               destination
    0     0 DOCKER-ISOLATION-STAGE-2  all  --  docker0 !docker0  0.0.0.0/0            0.0.0.0/0
16M 2585M DOCKER-ISOLATION-STAGE-2  all  --  br-mailcow !br-mailcow  0.0.0.0/0            0.0.0.0/0
100M   17G RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0

Chain DOCKER-ISOLATION-STAGE-2 (2 references)
pkts bytes target     prot opt in     out     source               destination
    0     0 DROP       all  --  *      docker0  0.0.0.0/0            0.0.0.0/0
    0     0 DROP       all  --  *      br-mailcow  0.0.0.0/0            0.0.0.0/0
16M 2585M RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0

Chain DOCKER-USER (1 references)
pkts bytes target     prot opt in     out     source               destination
368M  186G RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0

Chain MAILCOW (2 references)
pkts bytes target     prot opt in     out     source               destination


$ ip6tables -L -vn
Chain INPUT (policy ACCEPT 81 packets, 5312 bytes)
pkts bytes target     prot opt in     out     source               destination
28439 1917K MAILCOW    all      *      *       ::/0                 ::/0
    7   560 DROP       tcp      *      *       ::/0                 ::/0                 tcp dpt:25
    0     0 DROP       tcp      *      *       ::/0                 ::/0                 tcp dpt:587
    0     0 DROP       tcp      *      *       ::/0                 ::/0                 tcp dpt:456
    0     0 DROP       tcp      *      *       ::/0                 ::/0                 tcp dpt:465
    0     0 DROP       tcp      *      *       ::/0                 ::/0                 tcp dpt:2525

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target     prot opt in     out     source               destination
1313K 1284M DOCKER-USER  all      *      *       ::/0                 ::/0
1940K 2062M MAILCOW    all      *      *       ::/0                 ::/0
53M   64G DOCKER     all      *      br-mailcow  ::/0                 ::/0
44M   64G ACCEPT     all      *      br-mailcow  ::/0                 ::/0                 ctstate RELATED,ESTABLISHED
4576K  425M ACCEPT     all      br-mailcow !br-mailcow  ::/0                 ::/0
8839K  618M ACCEPT     all      br-mailcow br-mailcow  ::/0                 ::/0
1254 96611 DOCKER-ISOLATION-STAGE-1  all      *      *       ::/0                 ::/0

Chain OUTPUT (policy ACCEPT 71 packets, 4984 bytes)
pkts bytes target     prot opt in     out     source               destination

Chain DOCKER (1 references)
pkts bytes target     prot opt in     out     source               destination

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
pkts bytes target     prot opt in     out     source               destination
    0     0 DOCKER-ISOLATION-STAGE-2  all      br-mailcow !br-mailcow  ::/0                 ::/0
94  5640 RETURN     all      *      *       ::/0                 ::/0

Chain DOCKER-ISOLATION-STAGE-2 (1 references)
pkts bytes target     prot opt in     out     source               destination
    0     0 DROP       all      *      br-mailcow  ::/0                 ::/0
    0     0 RETURN     all      *      *       ::/0                 ::/0

Chain DOCKER-USER (1 references)
pkts bytes target     prot opt in     out     source               destination
58M   65G RETURN     all      *      *       ::/0                 ::/0

Chain MAILCOW (2 references)
pkts bytes target     prot opt in     out     source               destination


$ iptables -L -vn -t nat
Chain PREROUTING (policy ACCEPT 8970 packets, 606K bytes)
pkts bytes target     prot opt in     out     source               destination
99522 5390K DOCKER     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL

Chain INPUT (policy ACCEPT 2069 packets, 115K bytes)
pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 734 packets, 44141 bytes)
pkts bytes target     prot opt in     out     source               destination
    0     0 DOCKER     all  --  *      *       0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCAL

Chain POSTROUTING (policy ACCEPT 4227 packets, 287K bytes)
pkts bytes target     prot opt in     out     source               destination
    0     0 MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0
5464K  401M MASQUERADE  all  --  *      !br-mailcow  172.22.1.0/24        0.0.0.0/0
    0     0 MASQUERADE  tcp  --  *      *       172.22.1.7           172.22.1.7           tcp dpt:8983
    0     0 MASQUERADE  tcp  --  *      *       172.22.1.249         172.22.1.249         tcp dpt:6379
    0     0 MASQUERADE  tcp  --  *      *       172.22.1.10          172.22.1.10          tcp dpt:443
    0     0 MASQUERADE  tcp  --  *      *       172.22.1.10          172.22.1.10          tcp dpt:80
    0     0 MASQUERADE  tcp  --  *      *       172.22.1.250         172.22.1.250         tcp dpt:12345
    0     0 MASQUERADE  tcp  --  *      *       172.22.1.250         172.22.1.250         tcp dpt:4190
    0     0 MASQUERADE  tcp  --  *      *       172.22.1.250         172.22.1.250         tcp dpt:995
    0     0 MASQUERADE  tcp  --  *      *       172.22.1.250         172.22.1.250         tcp dpt:993
    0     0 MASQUERADE  tcp  --  *      *       172.22.1.250         172.22.1.250         tcp dpt:143
    0     0 MASQUERADE  tcp  --  *      *       172.22.1.250         172.22.1.250         tcp dpt:110
    0     0 MASQUERADE  tcp  --  *      *       172.22.1.6           172.22.1.6           tcp dpt:587
    0     0 MASQUERADE  tcp  --  *      *       172.22.1.6           172.22.1.6           tcp dpt:465
    0     0 MASQUERADE  tcp  --  *      *       172.22.1.6           172.22.1.6           tcp dpt:25

Chain DOCKER (2 references)
pkts bytes target     prot opt in     out     source               destination
    0     0 RETURN     all  --  docker0 *       0.0.0.0/0            0.0.0.0/0
45  6299 RETURN     all  --  br-mailcow *       0.0.0.0/0            0.0.0.0/0
    0     0 DNAT       tcp  --  !br-mailcow *       0.0.0.0/0            127.0.0.1            tcp dpt:19991 to:172.22.1.250:12345
    0     0 DNAT       tcp  --  !br-mailcow *       0.0.0.0/0            0.0.0.0/0            tcp dpt:4190 to:172.22.1.250:4190
41  2120 DNAT       tcp  --  !br-mailcow *       0.0.0.0/0            0.0.0.0/0            tcp dpt:995 to:172.22.1.250:995
50  2588 DNAT       tcp  --  !br-mailcow *       0.0.0.0/0            0.0.0.0/0            tcp dpt:993 to:172.22.1.250:993
13   664 DNAT       tcp  --  !br-mailcow *       0.0.0.0/0            0.0.0.0/0            tcp dpt:143 to:172.22.1.250:143
13   672 DNAT       tcp  --  !br-mailcow *       0.0.0.0/0            0.0.0.0/0            tcp dpt:110 to:172.22.1.250:110
    1    60 DNAT       tcp  --  !br-mailcow *       0.0.0.0/0            0.0.0.0/0            tcp dpt:587 to:172.22.1.6:587
    1    60 DNAT       tcp  --  !br-mailcow *       0.0.0.0/0            0.0.0.0/0            tcp dpt:465 to:172.22.1.6:465
15   900 DNAT       tcp  --  !br-mailcow *       0.0.0.0/0            0.0.0.0/0            tcp dpt:25 to:172.22.1.6:25

$ ip6tables -L -vn -t nat
Chain PREROUTING (policy ACCEPT 319K packets, 28M bytes)
pkts bytes target     prot opt in     out     source               destination
95  6783 DOCKER     all      *      *       ::/0                 ::/0                 ADDRTYPE match dst-type LOCAL

Chain INPUT (policy ACCEPT 19 packets, 1260 bytes)
pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 23 packets, 1840 bytes)
pkts bytes target     prot opt in     out     source               destination
    0     0 DOCKER     all      *      *       ::/0                !::1                  ADDRTYPE match dst-type LOCAL

Chain POSTROUTING (policy ACCEPT 19547 packets, 1558K bytes)
pkts bytes target     prot opt in     out     source               destination
    0     0 MASQUERADE  all      *      br-mailcow  ::/0                 ::/0                 ADDRTYPE match dst-type LOCAL
4024K  380M MASQUERADE  all      *      !br-mailcow  fd4d:6169:6c63:6f77::/64  ::/0
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::e  fd4d:6169:6c63:6f77::e  tcp dpt:25
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::e  fd4d:6169:6c63:6f77::e  tcp dpt:465
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::8  fd4d:6169:6c63:6f77::8  tcp dpt:587
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::8  fd4d:6169:6c63:6f77::8  tcp dpt:25
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::8  fd4d:6169:6c63:6f77::8  tcp dpt:465
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::e  fd4d:6169:6c63:6f77::e  tcp dpt:587
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::d  fd4d:6169:6c63:6f77::d  tcp dpt:443
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::d  fd4d:6169:6c63:6f77::d  tcp dpt:80
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::c  fd4d:6169:6c63:6f77::c  tcp dpt:443
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::c  fd4d:6169:6c63:6f77::c  tcp dpt:80
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::10  fd4d:6169:6c63:6f77::10  tcp dpt:25
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::10  fd4d:6169:6c63:6f77::10  tcp dpt:465
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::10  fd4d:6169:6c63:6f77::10  tcp dpt:587
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::f  fd4d:6169:6c63:6f77::f  tcp dpt:443
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::f  fd4d:6169:6c63:6f77::f  tcp dpt:80
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::d  fd4d:6169:6c63:6f77::d  tcp dpt:110
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::d  fd4d:6169:6c63:6f77::d  tcp dpt:143
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::d  fd4d:6169:6c63:6f77::d  tcp dpt:4190
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::d  fd4d:6169:6c63:6f77::d  tcp dpt:993
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::d  fd4d:6169:6c63:6f77::d  tcp dpt:995
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::c  fd4d:6169:6c63:6f77::c  tcp dpt:465
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::c  fd4d:6169:6c63:6f77::c  tcp dpt:587
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::c  fd4d:6169:6c63:6f77::c  tcp dpt:25
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::7  fd4d:6169:6c63:6f77::7  tcp dpt:443
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::7  fd4d:6169:6c63:6f77::7  tcp dpt:80
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::10  fd4d:6169:6c63:6f77::10  tcp dpt:995
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::10  fd4d:6169:6c63:6f77::10  tcp dpt:110
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::10  fd4d:6169:6c63:6f77::10  tcp dpt:143
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::10  fd4d:6169:6c63:6f77::10  tcp dpt:4190
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::10  fd4d:6169:6c63:6f77::10  tcp dpt:993
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::11  fd4d:6169:6c63:6f77::11  tcp dpt:25
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::11  fd4d:6169:6c63:6f77::11  tcp dpt:465
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::11  fd4d:6169:6c63:6f77::11  tcp dpt:587

Chain DOCKER (2 references)
pkts bytes target     prot opt in     out     source               destination
    0     0 RETURN     all      br-mailcow *       ::/0                 ::/0

Please note that the ip6tables DROP rules were added by me to prevent further spam from being sent. If you need any more information, please let me know.

Most helpful comment

Many people use mailcow, many people can do different things wrong at the same time with the same result. I see many people masquerading their primary interface because of VPN servers for example. Different scenario, same result.

ufw DOES do fancy things. It does a LOT of things. It is by far not a fire and forget. It is not that it inserts an INPUT filter rule and that's it (again: it is useless to filter on INPUT for Docker). It adds a lot of chains and manages the networking (nat, forwarding, input, output, bla). If it reloads and rebuilds with old/wrong rules, it can totally mess up Dockers rulesets. That's when bad things happen.

Since I support and manage many, many mailcows and monitor them for being open relays, I can assure you this is nothing we can/should fix on our side. I do not want to give out free remote hands to check foreign setups anymore. You should monitor your setup and watch the iptables ruleset for changes. Check why you seem to randomly lose important rules.

If you want to use ufw and ignore the fact it is not supported (important side-node), you are on your own. You need to monitor your rules by yourself. I don't want to provide free firewall support with every installation. It can work fine with ufw (!), but make sure it does not do fancy things like reloading and changing rule positions etc. - ufw DOES do that. Docker and ufw will fight to be authoritative for some chains and positions.

Check this: https://unrouted.io/2017/08/15/docker-firewall/ - that's a great way to filter and not becoming an open relay.

Btw. - you can always check our commits and find our changes. Nothing would ever randomly remove rules from your chains or rebuild incorrectly. We don't even touch them.

All 14 comments

client=unknown[172.22.1.1] means that the IPv6 connections are handled by the Docker userland proxy and are not address-translated by the kernel. The userland proxy cannot preserve source IP addresses, which is why you end up with an open relay over IPv6.

This is what ip6tables should look like (or at least do on my server, which is behaving correctly):

$ ip6tables -L -vn
Chain INPUT (policy ACCEPT 511K packets, 41M bytes)
 pkts bytes target     prot opt in     out     source               destination         
 511K   41M MAILCOW    all      *      *       ::/0                 ::/0                

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
2305K 1512M MAILCOW    all      *      *       ::/0                 ::/0                
2438K 1587M DOCKER-USER  all      *      *       ::/0                 ::/0                
9162K 5449M DOCKER-ISOLATION-STAGE-1  all      *      *       ::/0                 ::/0                
7820K 5004M DOCKER     all      *      br-mailcow  ::/0                 ::/0                
6235K 4836M ACCEPT     all      *      br-mailcow  ::/0                 ::/0                 ctstate RELATED,ESTABLISHED
1342K  445M ACCEPT     all      br-mailcow !br-mailcow  ::/0                 ::/0                
1113K   79M ACCEPT     all      br-mailcow br-mailcow  ::/0                 ::/0                

Chain OUTPUT (policy ACCEPT 50581 packets, 5426K bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain DOCKER (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     tcp      !br-mailcow br-mailcow  ::/0                 fd4d:6169:6c63:6f77::d  tcp dpt:110
31340 3936K ACCEPT     tcp      !br-mailcow br-mailcow  ::/0                 fd4d:6169:6c63:6f77::d  tcp dpt:143
    0     0 ACCEPT     tcp      !br-mailcow br-mailcow  ::/0                 fd4d:6169:6c63:6f77::d  tcp dpt:4190
48563 4748K ACCEPT     tcp      !br-mailcow br-mailcow  ::/0                 fd4d:6169:6c63:6f77::d  tcp dpt:993
    0     0 ACCEPT     tcp      !br-mailcow br-mailcow  ::/0                 fd4d:6169:6c63:6f77::d  tcp dpt:995
 4234 6673K ACCEPT     tcp      !br-mailcow br-mailcow  ::/0                 fd4d:6169:6c63:6f77::e  tcp dpt:587
 1412 1727K ACCEPT     tcp      !br-mailcow br-mailcow  ::/0                 fd4d:6169:6c63:6f77::e  tcp dpt:25
 3134 4188K ACCEPT     tcp      !br-mailcow br-mailcow  ::/0                 fd4d:6169:6c63:6f77::e  tcp dpt:465

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
 pkts bytes target     prot opt in     out     source               destination         
 316K   86M DOCKER-ISOLATION-STAGE-2  all      br-mailcow !br-mailcow  ::/0                 ::/0                
2438K 1587M RETURN     all      *      *       ::/0                 ::/0                

Chain DOCKER-ISOLATION-STAGE-2 (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all      *      br-mailcow  ::/0                 ::/0                
 316K   86M RETURN     all      *      *       ::/0                 ::/0                

Chain DOCKER-USER (1 references)
 pkts bytes target     prot opt in     out     source               destination         
9162K 5449M RETURN     all      *      *       ::/0                 ::/0                

Chain MAILCOW (2 references)
 pkts bytes target     prot opt in     out     source               destination         
$ ip6tables -L -vn -t nat
Chain PREROUTING (policy ACCEPT 331K packets, 30M bytes)
 pkts bytes target     prot opt in     out     source               destination         
14130 1224K DOCKER     all      *      *       ::/0                 ::/0                 ADDRTYPE match dst-type LOCAL

Chain INPUT (policy ACCEPT 994 packets, 84752 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 32 packets, 2560 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    6   480 DOCKER     all      *      *       ::/0                !::1                  ADDRTYPE match dst-type LOCAL

Chain POSTROUTING (policy ACCEPT 107K packets, 8593K bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 MASQUERADE  all      *      br-mailcow  ::/0                 ::/0                 ADDRTYPE match dst-type LOCAL
 841K   81M MASQUERADE  all      *      !br-mailcow  fd4d:6169:6c63:6f77::/64  ::/0                
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::d  fd4d:6169:6c63:6f77::d  tcp dpt:25
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::d  fd4d:6169:6c63:6f77::d  tcp dpt:465
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::d  fd4d:6169:6c63:6f77::d  tcp dpt:587
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::e  fd4d:6169:6c63:6f77::e  tcp dpt:995
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::e  fd4d:6169:6c63:6f77::e  tcp dpt:110
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::f  fd4d:6169:6c63:6f77::f  tcp dpt:25
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::f  fd4d:6169:6c63:6f77::f  tcp dpt:465
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::f  fd4d:6169:6c63:6f77::f  tcp dpt:587
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::e  fd4d:6169:6c63:6f77::e  tcp dpt:143
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::e  fd4d:6169:6c63:6f77::e  tcp dpt:4190
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::e  fd4d:6169:6c63:6f77::e  tcp dpt:993
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::e  fd4d:6169:6c63:6f77::e  tcp dpt:25
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::e  fd4d:6169:6c63:6f77::e  tcp dpt:465
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::e  fd4d:6169:6c63:6f77::e  tcp dpt:587
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::d  fd4d:6169:6c63:6f77::d  tcp dpt:995
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::d  fd4d:6169:6c63:6f77::d  tcp dpt:110
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::d  fd4d:6169:6c63:6f77::d  tcp dpt:143
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::d  fd4d:6169:6c63:6f77::d  tcp dpt:4190
    0     0 MASQUERADE  tcp      *      *       fd4d:6169:6c63:6f77::d  fd4d:6169:6c63:6f77::d  tcp dpt:993

Chain DOCKER (2 references)
 pkts bytes target     prot opt in     out     source               destination         
   28  2240 RETURN     all      br-mailcow *       ::/0                 ::/0                
    0     0 DNAT       tcp      !br-mailcow *       ::/0                 ::/0                 tcp dpt:110 to:[fd4d:6169:6c63:6f77::d]:110
  980 87849 DNAT       tcp      !br-mailcow *       ::/0                 ::/0                 tcp dpt:143 to:[fd4d:6169:6c63:6f77::d]:143
    0     0 DNAT       tcp      !br-mailcow *       ::/0                 ::/0                 tcp dpt:4190 to:[fd4d:6169:6c63:6f77::d]:4190
 1010 85621 DNAT       tcp      !br-mailcow *       ::/0                 ::/0                 tcp dpt:993 to:[fd4d:6169:6c63:6f77::d]:993
    0     0 DNAT       tcp      !br-mailcow *       ::/0                 ::/0                 tcp dpt:995 to:[fd4d:6169:6c63:6f77::d]:995
    7   588 DNAT       tcp      !br-mailcow *       ::/0                 ::/0                 tcp dpt:587 to:[fd4d:6169:6c63:6f77::e]:587
   32  2544 DNAT       tcp      !br-mailcow *       ::/0                 ::/0                 tcp dpt:25 to:[fd4d:6169:6c63:6f77::e]:25
   24  1964 DNAT       tcp      !br-mailcow *       ::/0                 ::/0                 tcp dpt:465 to:[fd4d:6169:6c63:6f77::e]:465

I can see that your DOCKER chain is missing the port mapping rules. That explains why it falls back to the proxy. Those rules should be added by the ipv6nat container. Details on that are at https://github.com/robbertkl/docker-ipv6nat. I think it also has a debug mode where it prints rules to the log while adding them, which could be helpful in determining why they didn't get added for you.

Furthermore there is no documentation to modify the firewall on our side. I don't know what you changed, but you did it wrong. :( Better don't mess with Dockers iptables, if you are not absolutly sure, what you do.

Yes, that is correct and I did not change the firewall (other than blocking IPv6 connections to prevent further spam).

Something changed the ruleset then, I guess. I don't know what happened, but it does not happen on its own.
I have no mailcow in support or managed where this ever happened.

Of course, I did not suggest that this is the intended behaviour. Clearly this is not a widespread problem either. I'm not here to complain about your software, my apologies if it sounded like I was blaming you for this issue!

I'm not really sure about the specifics of this problem but a docker upgrade seems to have helped. Before that I was able to reproduce the behaviour shown above (docker-compose down && docker-compose up yielded the same result). Now the rules shown by mkuron are in place and connecting works as intended.

Would it be possible to implement a safeguard for cases like this in the future? I assume just removing 172.22.1.1 from the whitelist would break some setups.

Came here to report the same issue, then found this thread. I also had two cows suddenly start accepting outside connections and start sending lots of spam. I have no clue how this happened, as I don't modify any mailcow sources. The hosts are pure Ubuntu 18.04 machines. It happened on one of my cows two weeks ago and again yesterday. I reinstalled the whole machine which (seemingly) fixed the issue.

Anyone else ever noticed such a behavior?

I notice it when you mess with the ruleset. I have many cows in support and managed, there is not a single one - no matter the OS - with this error. CentOS 8 will result in an open relay, but besides that...

Every single time someone contacted me with this, it was due to VPN on the same machine (sigh), broken ufw, firewalld or some other experiments.

mailcow will _never_ be an open relay without a reason.
If you have a SAL, you can enable the open relay check and be alerted.
If you still struggle with it, contact me.

I never stated that mailcow is an open relay without a reason ;-) and I have neither vpn nor other experiments on those machines. Just your basic Ubuntu installation with ufw allowing all the ports that are required by mailcow (ufw allow xxx/tcp) and mailcow installed following the docs. Those cows are used by good friends of mine for their personal use, no way I鈥檓 going to play with those setups.

I did not mess with any rulesets. Why would I? The only reason to use mailcow instead of a manual setup is simplicity, so why take that away by changing application code/settings?

The only thing I did on those machines is to update Ubuntu and mailcow on a regular basis (through their official channels, apt update/upgrade and ./update.sh). I did updates to both machines before that happened, so maybe that could have caused it?

Unfortunately I did not save any files besides mail data before scrubbing the machines, I will do so next time it happens to make debugging simpler. Just wanted to add my own experiences to the error described above, hoping it might help :-/

with ufw allowing all the ports that are required by mailcow

If you're only running Mailcow on these machines, you might as well disable ufw. There are no services that need to be blocked by the firewall, and running anything that modifies iptables while Docker is running can be dangerous.

Thanks for suggesting, but I won't do that. I can't see how ufw would be the problem, as there are no other rules than your basic "ufw allow 25/tcp", "ufw limit 22/tcp" etc. in place. No way there is any translation going on. Mailcow has been running without issues for a long time, when suddenly the problem happened shortly after updating.

Does Mailcow really expect to be run on a machine without a firewall?? Isn't that against common sense in terms of securely hosting a public service?

No, it is not unsecure.
It's unsecure to work with a firewall without understanding all consequences.

As described above: So far there have been no cases where Mailcow acted as an open relay due to an error in the package/distribution.
All cases so far were issue with other containers on the same host, manual network-tweaks or manually modified docker-bridges.
Or Firewall-Misconfigurations of all sorts (i.e. external ipfire).

If mailcow can not see the real source ip of incoming mail but just some kind of local network, which is whitelisted: then the person who did that shot himself in the foot.

Yep. Furthermore it works fine with a firewall. It is simply the fact you need to know what you are doing. "ufw allow 25" - for example - has no effect on the forwarding chain. That's where "you need to know what you are doing" begins. There is more to it then opening a port in the input chain.

If you play with your iptables, you are on your own. It will never break without a reason or randomly remove important rules from a chain. That's nothing we implemented with an update. :P

Ok, now you are putting words in my mouth which I never said. Mailcow can see the real source ip perfectly fine if you place it behind ufw. It can do so on the newly installed machines, I did NOTHING differently in terms of machine setup. I also didn't "play with my iptables", I simply opened ports. Nothing more, nothing less. The beauty of ufw is that it doesn't do anything fancy by default.

Instead of blaming it on the user(s), maybe there should be some investigating on why this happened to two different people at roughly the same time?

Many people use mailcow, many people can do different things wrong at the same time with the same result. I see many people masquerading their primary interface because of VPN servers for example. Different scenario, same result.

ufw DOES do fancy things. It does a LOT of things. It is by far not a fire and forget. It is not that it inserts an INPUT filter rule and that's it (again: it is useless to filter on INPUT for Docker). It adds a lot of chains and manages the networking (nat, forwarding, input, output, bla). If it reloads and rebuilds with old/wrong rules, it can totally mess up Dockers rulesets. That's when bad things happen.

Since I support and manage many, many mailcows and monitor them for being open relays, I can assure you this is nothing we can/should fix on our side. I do not want to give out free remote hands to check foreign setups anymore. You should monitor your setup and watch the iptables ruleset for changes. Check why you seem to randomly lose important rules.

If you want to use ufw and ignore the fact it is not supported (important side-node), you are on your own. You need to monitor your rules by yourself. I don't want to provide free firewall support with every installation. It can work fine with ufw (!), but make sure it does not do fancy things like reloading and changing rule positions etc. - ufw DOES do that. Docker and ufw will fight to be authoritative for some chains and positions.

Check this: https://unrouted.io/2017/08/15/docker-firewall/ - that's a great way to filter and not becoming an open relay.

Btw. - you can always check our commits and find our changes. Nothing would ever randomly remove rules from your chains or rebuild incorrectly. We don't even touch them.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

pgollor picture pgollor  路  3Comments

K2rool picture K2rool  路  3Comments

mritzmann picture mritzmann  路  3Comments

lgleim picture lgleim  路  3Comments

RogerSik picture RogerSik  路  3Comments