Does default masquarade config block connection to forwarded public port?

Hello,
I use LXD v2.10.1 and I have lxdbr0 network - 10.0.4.0/24
I forward port 10450 on public IP address to a container 10.0.4.104:5000 using iptables:
-A PREROUTING -p tcp -m tcp --dport 10450 -j DNAT --to-destination 10.0.4.104:5000

From my laptop I successfully connect to 10450 port on public IP address - the forwarding works.
However, when I try to connect from another container (in network 10.0.4.0/24) using public IP address and port 10450 - connection fails.
I realized that default lxdbr0 iptables config blocks such connection:
-A POSTROUTING -s 10.0.4.0/24 ! -d 10.0.4.0/24 -m comment --comment “generated for LXD network lxdbr0” -j MASQUERADE

When I add a new rule:
-A POSTROUTING -s 10.0.4.0/24 -j MASQUERADE
I can successfully connect to port 10450 on public IP address from the container inside the network.

Could you explain me why ! -d 10.0.4.0/24 has been added in auto generated rule for lxdbr0 network?
Maybe I do something wrong?

Thanks

This rule is there because you pretty much never want to machines that are on the same L2 network to have their source addresses rewritten through NAT.

So in your case you have all addresses on your host redirecting to 10.0.4.104:5000 when hit on port 10450.

When connecting from inside a container, the host processes the prerouting rule, replacing the destination with the right container ip and port and sends the traffic through. The container then attempts to directly reply to the source without going through the host, which causes the packets to be dropped.

You are correct that the only real way to avoid the issue is to also SNAT that traffic, though rather than doing it for all container traffic, which as I mentioned isn’t a good idea to do in the middle of a subnet, you could just do a specific rule to MASQUERADE just that one port.

Something like:

iptables -t nat -A POSTROUTING -p tcp -d 10.0.4.104 --dport 5000 -j SNAT --to 10.0.4.1

Thank you for the reply. I will try your rule.

Hello,
I added your rule, but I still can not connect to 10450 port on public IP
address from another container.
Now I have two rules:

-A PREROUTING -p tcp -m tcp -i eth0 --dport 10450 -j DNAT --to-destination
10.0.4.104:5000
-A POSTROUTING -p tcp -d 10.0.4.104 --dport 5000 -j SNAT --to 10.0.4.1

Nevertheless, I can not connect from a container to :10450.
Do you have any idea how to fix it?
Thanks

I also added

-A PREROUTING -p tcp -m tcp -d <public-ip> --dport 10450 -j DNAT
--to-destination 10.0.4.104:5000