Contribution guidelines
Checklist prior issue creation
Description
The netfilter container adds a blanket DROP tcp -- 0.0.0.0/0 0.0.0.0/0 /* mailcow isolation */ rule to the MAILCOW chain without any prior ACCEPT rules for mail ports (25, 465, 587, 993, 995, 143, 110, 4190). This effectively blocks all incoming TCP connections including legitimate SMTP traffic on port 25, even though DISABLE_NETFILTER_ISOLATION_RULE=y is set in mailcow.conf.
Additionally, the MAILCOW chain is not flushed before re-initialization, causing rules to accumulate in duplicate on every netfilter restart.
Observed MAILCOW chain in broken state:
Chain MAILCOW (4 references)
num target prot opt source destination
1 DROP tcp -- 0.0.0.0/0 0.0.0.0/0 /* mailcow isolation */
2 DROP tcp -- 0.0.0.0/0 0.0.0.0/0 /* mailcow isolation */
After multiple restarts the chain accumulates further (ban list rules + isolation DROP appearing at positions 60 and 120), still with no ACCEPT rules for mail ports in between.
The result: SYN packets arrive on eth0 (confirmed via tcpdump) but no SYN-ACK is sent — external mail servers including DockerHub notifications and OVH cannot connect.
Steps to reproduce:
- Deploy mailcow with default config (
DISABLE_NETFILTER_ISOLATION_RULE=n)
- Check the MAILCOW chain:
iptables -L MAILCOW -n --line-numbers
- Observe: only bare DROP rules, no ACCEPT rules for mail ports
- Try external connection:
telnet <mail-server> 25 → times out
- Confirm via
tcpdump -i any port 25 -n: SYN packets arrive but no SYN-ACK is sent
- Set
DISABLE_NETFILTER_ISOLATION_RULE=y in mailcow.conf
- Restart netfilter:
docker compose restart netfilter-mailcow
- Isolation DROP rule persists — chain must be manually flushed:
iptables -F MAILCOW
- After next automatic netfilter restart, the problem reappears
Workaround (must be re-applied after every netfilter restart):
iptables -F MAILCOW
docker compose restart netfilter-mailcow
Logs:
# Warning: table ip filter is managed by iptables-nft, do not touch!
# Warning: table ip nat is managed by iptables-nft, do not touch!
# Warning: table ip6 filter is managed by iptables-nft, do not touch!
# Warning: table ip6 nat is managed by iptables-nft, do not touch!
2026-06-09 17:00:42 INFO: Using NFTables backend
2026-06-09 17:00:42 INFO: Clearing all bans
2026-06-09 17:00:43 INFO: Initializing mailcow netfilter chain
2026-06-09 17:00:44 INFO: Setting MAILCOW isolation
2026-06-09 17:00:44 INFO: Watching Redis channel F2B_CHANNEL
No errors logged — netfilter initializes successfully but sets the isolation DROP without prior ACCEPT rules for mail ports.
Which branch are you using?
master (stable)
Which architecture are you using?
x86_64
Operating System:
Debian GNU/Linux 13 (trixie)
Server/VM specifications:
Netcup VPS 500 G12 NUE — 2 CPU Cores, 2 GB RAM
Is Apparmor, SELinux or similar active?
no
Virtualization technology:
KVM
Docker version:
29.5.3
docker-compose version or docker compose version:
v5.1.4
mailcow version:
2026-05c
Reverse proxy:
none
Logs of git diff:
Only changes are:
- `data/assets/ssl-example/cert.pem` and `key.pem` (replaced example cert with own self-signed cert)
- `data/conf/postfix/main.cf` (added postscreen DNSBL config and `myhostname` override in the user overrides section)
No changes to netfilter-related code.
Logs of iptables -L -vn:
Chain INPUT (policy ACCEPT 370K packets, 98M bytes)
pkts bytes target prot opt in out source destination
421K 102M MAILCOW all -- * * ::/0 ::/0 /* mailcow */
415K 102M MAILCOW all -- * * ::/0 ::/0 /* mailcow */
415K 102M MAILCOW all -- * * ::/0 ::/0 /* mailcow */
Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
1412K 441M MAILCOW all -- * * ::/0 ::/0 /* mailcow */
1411K 441M DOCKER-USER all -- * * ::/0 ::/0
1411K 441M DOCKER-FORWARD all -- * * ::/0 ::/0
0 0 MAILCOW all -- * * ::/0 ::/0 /* mailcow */
0 0 MAILCOW all -- * * ::/0 ::/0 /* mailcow */
Chain OUTPUT (policy ACCEPT 259K packets, 20M bytes)
pkts bytes target prot opt in out source destination
Chain MAILCOW (6 references)
pkts bytes target prot opt in out source destination
0 0 DROP all -- * * 2001:470::/32 ::/0
0 0 DROP all -- * * 2604:a880::/32 ::/0
[... ban list entries ...]
Logs of ip6tables -L -vn:
Chain INPUT (policy ACCEPT 370K packets, 98M bytes)
pkts bytes target prot opt in out source destination
421K 102M MAILCOW all -- * * ::/0 ::/0 /* mailcow */
415K 102M MAILCOW all -- * * ::/0 ::/0 /* mailcow */
415K 102M MAILCOW all -- * * ::/0 ::/0 /* mailcow */
Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
1412K 441M MAILCOW all -- * * ::/0 ::/0 /* mailcow */
1411K 441M DOCKER-USER all -- * * ::/0 ::/0
1411K 441M DOCKER-FORWARD all -- * * ::/0 ::/0
0 0 MAILCOW all -- * * ::/0 ::/0 /* mailcow */
0 0 MAILCOW all -- * * ::/0 ::/0 /* mailcow */
Chain OUTPUT (policy ACCEPT 259K packets, 20M bytes)
pkts bytes target prot opt in out source destination
Chain MAILCOW (6 references)
pkts bytes target prot opt in out source destination
0 0 DROP all -- * * 2001:470::/32 ::/0
0 0 DROP all -- * * 2604:a880::/32 ::/0
[... ban list entries ...]
## Logs of iptables -L -vn -t nat:
Chain PREROUTING (policy ACCEPT 2102K packets, 145M bytes)
pkts bytes target prot opt in out source destination
745K 40M DOCKER all -- * * 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT 3879 packets, 231K 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
1436K 109M MASQUERADE all -- * !br-mailcow 172.22.1.0/24 0.0.0.0/0
Chain DOCKER (2 references)
pkts bytes target prot opt in out source destination
1102 59112 DNAT tcp -- !br-mailcow * 0.0.0.0/0 0.0.0.0/0 tcp dpt:110 to:172.22.1.250:110
1118 59456 DNAT tcp -- !br-mailcow * 0.0.0.0/0 0.0.0.0/0 tcp dpt:143 to:172.22.1.250:143
1116 62736 DNAT tcp -- !br-mailcow * 0.0.0.0/0 0.0.0.0/0 tcp dpt:993 to:172.22.1.250:993
710 39336 DNAT tcp -- !br-mailcow * 0.0.0.0/0 0.0.0.0/0 tcp dpt:995 to:172.22.1.250:995
885 52072 DNAT tcp -- !br-mailcow * 0.0.0.0/0 0.0.0.0/0 tcp dpt:4190 to:172.22.1.250:4190
16698 947K DNAT tcp -- !br-mailcow * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 to:172.22.1.11:80
43963 2545K DNAT tcp -- !br-mailcow * 0.0.0.0/0 0.0.0.0/0 tcp dpt:443 to:172.22.1.11:443
10451 608K DNAT tcp -- !br-mailcow * 0.0.0.0/0 0.0.0.0/0 tcp dpt:25 to:172.22.1.253:25
1564 85436 DNAT tcp -- !br-mailcow * 0.0.0.0/0 0.0.0.0/0 tcp dpt:465 to:172.22.1.253:465
1630 93812 DNAT tcp -- !br-mailcow * 0.0.0.0/0 0.0.0.0/0 tcp dpt:587 to:172.22.1.253:587
Logs of iptables -L -vn -t nat:
Chain PREROUTING (policy ACCEPT 2102K packets, 145M bytes)
pkts bytes target prot opt in out source destination
745K 40M DOCKER all -- * * 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT 3879 packets, 231K 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
1436K 109M MASQUERADE all -- * !br-mailcow 172.22.1.0/24 0.0.0.0/0
Chain DOCKER (2 references)
pkts bytes target prot opt in out source destination
1102 59112 DNAT tcp -- !br-mailcow * 0.0.0.0/0 0.0.0.0/0 tcp dpt:110 to:172.22.1.250:110
1118 59456 DNAT tcp -- !br-mailcow * 0.0.0.0/0 0.0.0.0/0 tcp dpt:143 to:172.22.1.250:143
1116 62736 DNAT tcp -- !br-mailcow * 0.0.0.0/0 0.0.0.0/0 tcp dpt:993 to:172.22.1.250:993
710 39336 DNAT tcp -- !br-mailcow * 0.0.0.0/0 0.0.0.0/0 tcp dpt:995 to:172.22.1.250:995
885 52072 DNAT tcp -- !br-mailcow * 0.0.0.0/0 0.0.0.0/0 tcp dpt:4190 to:172.22.1.250:4190
16698 947K DNAT tcp -- !br-mailcow * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 to:172.22.1.11:80
43963 2545K DNAT tcp -- !br-mailcow * 0.0.0.0/0 0.0.0.0/0 tcp dpt:443 to:172.22.1.11:443
10451 608K DNAT tcp -- !br-mailcow * 0.0.0.0/0 0.0.0.0/0 tcp dpt:25 to:172.22.1.253:25
1564 85436 DNAT tcp -- !br-mailcow * 0.0.0.0/0 0.0.0.0/0 tcp dpt:465 to:172.22.1.253:465
1630 93812 DNAT tcp -- !br-mailcow * 0.0.0.0/0 0.0.0.0/0 tcp dpt:587 to:172.22.1.253:587
Logs of ip6tables -L -vn -t nat:
Chain PREROUTING (policy ACCEPT 286K packets, 26M bytes)
pkts bytes target prot opt in out source destination
32383 2625K DOCKER all -- * * ::/0 ::/0 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT 27477 packets, 2322K bytes)
pkts bytes target prot opt in out source destination
0 0 MASQUERADE all -- * !docker0 fdd0:91e9:ad79::/64 ::/0
280K 25M MASQUERADE all -- * !br-mailcow fd4d:6169:6c63:6f77::/64 ::/0
Chain DOCKER (2 references)
pkts bytes target prot opt in out source destination
61 4556 DNAT tcp -- !br-mailcow * !fe80::/10 ::/0 tcp dpt:110 to:[fd4d:6169:6c63:6f77::8]:110
230 18332 DNAT tcp -- !br-mailcow * !fe80::/10 ::/0 tcp dpt:143 to:[fd4d:6169:6c63:6f77::8]:143
402 32244 DNAT tcp -- !br-mailcow * !fe80::/10 ::/0 tcp dpt:993 to:[fd4d:6169:6c63:6f77::8]:993
18 1132 DNAT tcp -- !br-mailcow * !fe80::/10 ::/0 tcp dpt:995 to:[fd4d:6169:6c63:6f77::8]:995
129 9984 DNAT tcp -- !br-mailcow * !fe80::/10 ::/0 tcp dpt:25 to:[fd4d:6169:6c63:6f77::12]:25
219 16956 DNAT tcp -- !br-mailcow * !fe80::/10 ::/0 tcp dpt:80 to:[fd4d:6169:6c63:6f77::f]:80
24772 2087K DNAT tcp -- !br-mailcow * !fe80::/10 ::/0 tcp dpt:443 to:[fd4d:6169:6c63:6f77::f]:443
DNS check:
Contribution guidelines
Checklist prior issue creation
Description
The netfilter container adds a blanket
DROP tcp -- 0.0.0.0/0 0.0.0.0/0 /* mailcow isolation */rule to the MAILCOW chain without any prior ACCEPT rules for mail ports (25, 465, 587, 993, 995, 143, 110, 4190). This effectively blocks all incoming TCP connections including legitimate SMTP traffic on port 25, even thoughDISABLE_NETFILTER_ISOLATION_RULE=yis set inmailcow.conf.Additionally, the MAILCOW chain is not flushed before re-initialization, causing rules to accumulate in duplicate on every netfilter restart.
Observed MAILCOW chain in broken state:
After multiple restarts the chain accumulates further (ban list rules + isolation DROP appearing at positions 60 and 120), still with no ACCEPT rules for mail ports in between.
The result: SYN packets arrive on eth0 (confirmed via
tcpdump) but no SYN-ACK is sent — external mail servers including DockerHub notifications and OVH cannot connect.Steps to reproduce:
DISABLE_NETFILTER_ISOLATION_RULE=n)iptables -L MAILCOW -n --line-numberstelnet <mail-server> 25→ times outtcpdump -i any port 25 -n: SYN packets arrive but no SYN-ACK is sentDISABLE_NETFILTER_ISOLATION_RULE=yinmailcow.confdocker compose restart netfilter-mailcowiptables -F MAILCOWWorkaround (must be re-applied after every netfilter restart):
Logs:
Which branch are you using?
master (stable)
Which architecture are you using?
x86_64
Operating System:
Debian GNU/Linux 13 (trixie)
Server/VM specifications:
Netcup VPS 500 G12 NUE — 2 CPU Cores, 2 GB RAM
Is Apparmor, SELinux or similar active?
no
Virtualization technology:
KVM
Docker version:
29.5.3
docker-compose version or docker compose version:
v5.1.4
mailcow version:
2026-05c
Reverse proxy:
none
Logs of git diff:
Logs of iptables -L -vn:
Logs of ip6tables -L -vn:
Logs of iptables -L -vn -t nat:
Logs of ip6tables -L -vn -t nat:
DNS check: