- Edited
You may have noticed that docker configures iptables in such a way that adding firewall rules (e.g. via ufw) has no effect. If you’re running dockerized-mailcow and have been using ufw/iptables incorrectly to add rules intended to help filter traffic from bad sources, they won’t work:
If you’re running Docker on a host that is exposed to the Internet, you will probably want to have iptables policies in place that prevent unauthorized access to containers or other services running on your host.
First off, make use of pflogsumm to see what’s been happening within your mail server. In my example below, we’ll see some rejected messages:
Special note: You can remove the “–since 24h” if you want to enumerate the statistics for the entire time period available from the postfix-mailcow container.
message reject detail
RCPT
blocked using b.barracudacentral.org (total: 1)
1 45.134.23.234
blocked using hostkarma.junkemailfilter.com (total: 1)
1 31.210.22.179
blocked using zen.spamhaus.org (total: 3)
2 31.210.22.179
1 185.216.71.7
Notice from the above, an IP attempted to deliver multiple messages (31.210.22.179 tried 2 times.) Repeated offenders should be higher priority for you to block.
These rejects were done by Rspamd’s RBLs. There are several RBLs enabled by default, and some additional ones added by Mailcow:
But the offender was still allowed to connect to your machine. Also these statistics will show warnings that could include deliberate attempts to execute HTTP command via SMTP, which should also be blocked:
Warnings
1 non-SMTP command from unknown[205.210.31.46]: GET / HTTP/1.1
1 non-SMTP command from unknown[138.68.91.83]: GET /c/version.js …
1 non-SMTP command from unknown[69.57.160.94]: GET /remote/fgt_la…
Going back to the docker documentation I linked above…
By default, all external source IPs are allowed to connect to the Docker host.
Docker installs two custom iptables chains named DOCKER-USER and DOCKER, and it ensures that incoming packets are always checked by these two chains first.
If you need to add rules which load before Docker’s rules, add them to the DOCKER-USER chain.
So if you want to start blocking offending IPs to prevent them from attempting anything against mailcow (which can have vulnerabilities), use the following command:
iptables -I DOCKER-USER -s <IP ADDRESS> -j DROP
This will block a single IP address by adding it to the DOCKER-USER iptables chain. You could use ‘whois <IP ADDRESS>’ to obtain the associated CIDR block of IPs associated with the offender, but that may be overkill and increases the risk of rejecting valid emails.
After you add an entry, you can verify it via the following command:
iptables -L DOCKER-USER
If you wish to log the activity from DOCKER-USER chain (to verify drops in the future)
iptables -A DOCKER-USER -j LOG
Keep in mind that doing this means you’ll never see connection attempts from that IP again. If the IP gets itself removed from RBLs, then you’ll be disconnected from this change. As such, I recommend only blocking repeat offenders, and periodically checking the RBLs to see if they’ve been removed, suggesting the owner fixed their problems.
Hope this is helpful!