I'm running a Mastodon instance using docker-compose
, which builds and runs several containers, that connect to each other through a Docker internal network (the relevant docker-compose.yml).
I'm running this on an up-to-date Debian 11 server. The issue is that with the default installation, the Docker containers cannot connect to each other ("No Route to Host"). One solution I found is to enable IP masquerade in the firewalld public zone: firewall-cmd --zone=public --add-masquerade
, which solves the issue and allows the containers to talk to each other.
Sadly, this solution has a downside that I cannot easily live with: The same server has a second IP address on the same network interface, that I need to use for outgoing SMTP traffic generated by postfix. To make this work, I've set smtp_bind_address
to the secondary IP address. This works perfectly fine until I enable IP masquerading with the above command. As soon as I do that, the source IP of all outgoing traffic from postfix gets changed to the primary IP, which breaks mail delivery.
A temporary fix I found is to reverse the address translation using a manual netfilter rule:
nft add chain nat postrouting { type nat hook postrouting priority 100 \; }
nft add rule nat postrouting oifname eth0 tcp dport 25 snat to <secondary ip>
Obviously, this is not a good idea if I'm using firewalld as well, also I assume this is not persisted in any way.
So, ideally there would be a way to make networking between the Docker containers possible without enabling masquerading (I don't understand why this is necessary anyway), so that I don't need to hack this "fix" into netfilter. If this is absolutely not possible, I'd also settle for a way to tell firewalld to add the equivalent of my manual netfilter rules. I assume there's a way to do that with direct rules, but I can't figure out the correct syntax for it.
Other firewall rules in place are mostly blocking and opening some ports to various services.