We have a linux root server which primarily just is a docker server. Hosting containers and a CI runner.

To protect this server the basic idea for now is to

  • block all traffic
  • except for one (or more) IP(s) that are allowed.

I added a rich rules yesterday with for ip4

  • blocking
  • explicitly allowing our static IP

This resulted in me being blocked from access. Docker container where still accessible. The containers generate a new interface, as far as I understand these interfaces should only be responsible for the communication from the host to the container. I hope at least, that the firewalld filters traffic before the traffic is forwarded from e.g. eth0 to dockerinterface1234.

My research so far suggests. Leaving out interface information in a zone makes the zone responsible for all traffic. However, my own test suggest that I either configured it wrong or my research was wrong.


Adopting from my tutorial on IP-based zones for firewalld:

Start by changing the default zone to drop:

firewallctl config set default-zone drop

The drop zone drops all incoming connections. You may want to consider the block zone which does the same except that it returns a blocked connection instead of just dropping it silently. Then create a new zone and bind it to a subnet of IP addresses (or a single address):

 firewallctl new --permanent zone --name "myzone"
 firewallctl zone "myzone" --permanent add source ""
 firewallctl zone "myzone" --permanent add source "2001:0DB8::/32"

(Remember to be IPv6-ready!) Check that your zones look okay:

 firewallctl info zones --active

At this point you start adding ports or services to myzone. These services will only be accessible from the zone/IP-subnet you add and not on the default drop/public zone.

| improve this answer | |

Wikipedia has a nice packet flow schematic at https://upload.wikimedia.org/wikipedia/commons/3/37/Netfilter-packet-flow.svg

Docker puts its port mapping rules in the 'mangle prerouting' stage. This stage runs before 'filter input' where most firewalls try to place their input filtering rules, but if you look at the schematic, you can see that packets will avoid that stage ('routing decision') if they are being forwarded. Which is probably what's happening for you.

Instead of fighting with Docker's rules you can completely preempt them using the 'raw' table. To drop all traffic from 'eth0' to port 12345

iptables -t raw -I PREROUTING -i eth0 -p tcp --dport 12345 -j LOG

Note that the 'raw' table also affects internal (Docker) traffic, so if you're going to drop based on source IP addresses, make sure you also whitelist localhost and docker's internal IP ranges

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.