Docker opened firewall ports by default with special DOCKER-USER rule and steps to remove it (CentOS)

Background and how I discovered this

I discovered this when the independence security scanning emailed me saying my VM on cloud having port 27017 opened.

I have had a MongoDB docker image running on that VM and with the simple 27017:27017 port mapping, and I used to believe I haven’t open the port on VM firewall, but when I telnet, I confirmed I can access that port remotely, that is something I think I need to fix.


All credit goes to this git comment:

The quick idea is docker added a special firewall rule and expose all exposed ports.

The below solution is copied from the git comment directly with 1 added line indicating how to add more ports to open.

# Removing DOCKER-USER CHAIN (it won't exist at first)
firewall-cmd --permanent --direct --remove-chain ipv4 filter DOCKER-USER
# Flush rules from DOCKER-USER chain (again, these won't exist at first; firewalld seems to remember these even if the chain is gone)
firewall-cmd --permanent --direct --remove-rules ipv4 filter DOCKER-USER
# Add the DOCKER-USER chain to firewalld
firewall-cmd --permanent --direct --add-chain ipv4 filter DOCKER-USER
# Add rules (see comments for details)
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m comment --comment "This allows docker containers to connect to the outside world"
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -j RETURN -s -m comment --comment "allow internal docker communication"
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -p tcp -m multiport --dports https -s 123.456.7.89/32 -j ACCEPT -m comment --comment "my allowed ip address to http and https ports"
##### Here you can add more rules
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -p tcp --dport 8000 -j ACCEPT -m comment --comment "my allowed port - 8000, this is the exposed port instead of the redirected port"
#Add as many ip or other rules and then run this command to block all other traffic
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -j REJECT -m comment --comment "reject all other traffic"
# restart the services
systemctl stop docker
systemctl stop firewalld
systemctl start firewalld
systemctl start docker

Note that one would need to re-run the above when different rules need to be adjusted. (The above would flush all rules and re-add).