Why is firewalld allowing public traffic to my non-public ports, bound to Docker containers?
Solution 1:
Well, it turns out that the problem stems from the fact that I'm using Docker for my internal ports. In order to simplify the process of getting containers to talk to the world and each other, Docker made the choice to take a large amount of control over your firewalls/networking. This means that if you don't want your containers to be publicly accessible AND you need to control public access via the firewall on the same machine as your Docker daemon, you need to configure your firewalls slightly differently. Docker has some official documentation on how to do this. Basically, you have the following options:
- Set up a separate machine just for your firewall. This would probably be the easiest, since Docker and your firewall wouldn't have to share resources.
- Add your
iptables
rules to theDOCKER-USER
chain (this is more of an answer foriptables
users; I'm not sure how to getfirewalld
to replicate this approach) - Disable the whole thing by setting
iptables=false
in your Docker service config. (this blog post discusses this option)
I also found a post that I thought was a nice variation on the DOCKER-USER
chain option. Basically, you create an iptables.conf
file that you can load without a flush using iptables-restore -n
. Unfortunately, it's an iptables
solution, not a firewalld
solution.
One of the hard parts of diagnosing this issue was that I would run a script to modify the firewall to match what I wanted, and that would work until I restarted the machine or started up the Docker daemon. Docker overwrites the iptables
config when it starts up.