Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FirewallD doesn't go well with Docker #461

Closed
maverick85 opened this issue Feb 14, 2019 · 14 comments
Closed

FirewallD doesn't go well with Docker #461

maverick85 opened this issue Feb 14, 2019 · 14 comments

Comments

@maverick85
Copy link

@maverick85 maverick85 commented Feb 14, 2019

Hi everybody,

I am an avid user of CentOS which ships firewalld since long.

So I've been using Docker fairly recently and yesterday I noticed firewalld rules are completely ignored by docker/docker containers. I found this funny cause on your Home page you read:

Applications and libraries which support firewalld as a firewall management tool include:

  • NetworkManager
  • libvirt
  • docker
  • fail2ban

So basically I was setting up a server whose sole purpose is to run docker containers.
After setting things running, as I had a DB container running, I did the following:

firewall-cmd --permanent --new-zone=test-from-home && firewall-cmd --reload
firewall-cmd --permanent --zone=test-from-home --add-service=mysql
firewall-cmd --permanent --zone=test-from-home --add-source=XX.XX.XX.XX/32
firewall-cmd --reload

So then I went to testing, and I connected just fine. But then I logged in to another remote server, and I accessed the same when I totally should not.

These are outputs of my firewalld:

firewall-cmd --zone=test-from-home --list-all
test-from-home (active)
  target: default
  icmp-block-inversion: no
  interfaces: 
  sources: XX.XX.XX.XX/32
  services: mysql
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 
firewall-cmd --zone=public --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0
  sources: 
  services: ssh dhcpv6-client
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules:
[root@nd01 latest]# firewall-cmd --get-active-zones
test-from-home
  sources: XX.XX.XX.XX/32
public
  interfaces: eth0

Also, I asked a friend to test using netcat, from yet another random location, and he manages to connect too...

FirewallD doesn't play nice with Docker (or vice-versa)

Meanwhile I came across the fact that FirewallD and Docker do not play along.
According to the Docker documentation, the way to circumvent this is by disabling IPTables:

As it says from the very first stance:

On Linux, Docker manipulates iptables rules to provide network isolation. This is an implementation detail, and you should not modify the rules Docker inserts into your iptables policies.

Which wouldn't be my first resort as adviced against.

So I don't get how we go from this to firewalld friendly, but I would enjoy learning.
Anyway, this page goes on about how to fix it, and I actually took a few ideas from another blog post I came across Docker meets firewall - finally an answer and set it up.

But as firewalld gets more and more audience, I think it would be useful if someone:

a) fix where it says firewalld works with docker...
b) make firewalld play nice with docker?
maybe by adding a plugin for docker that would allow to move on the DOCKER-USER chain?

CentOS 7 minimal-install;
Docker version 18.09.2, build 6247962
@erig0
Copy link
Collaborator

@erig0 erig0 commented Feb 19, 2019

Applications and libraries which support firewalld as a firewall management tool include

IIRC, in the case of docker this means docker will see that firewalld is in use and add it's rules through firewalld's direct interface. It's not full support, but it is some support.

maybe by adding a plugin for docker that would allow to move on the DOCKER-USER chain?

This can be done already.

# firewall-cmd --permanent --direct --add-chain ipv4 filter DOCKER-USER
# firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER <priority> ...

I'm not sure what you're looking for. "play nice with docker" is a very vague request - especially as some level of "playing" already exists.

@erig0 erig0 added the needinfo label Feb 19, 2019
@jackhill
Copy link

@jackhill jackhill commented Apr 25, 2019

I'm not sure what @maverick85 means by "play nice with docker", but for me that means that traffic to the ports that are published by docker are subject to the same filtering rules as if a service was running on a port without the docker isolation.

For example, suppose I only enable the https service in firewalld for the work zone. If I run a "native" webserver on 443, connections not associated with the work zone would be denied. However, as it stands now, if I run a webserver in docker, with -p 443:8443 to set up the port forwarding, any connection will be allowed. What I would like to happen is that only connection that would have been associated with the work zone be allowed.

From @erig0's comment and others on the Internet, it seems there is a work-around by setting up rules in the DOCKER-USER chain, but a major downside to me, is that firewalld's concept of zones is not available in the DOCKER-USER chain.

@zyv
Copy link

@zyv zyv commented Apr 29, 2019

I've just stumbled upon this problem and second the comments of @jackhill and @maverick85.

On a freshly installed CentOS 7 system with firewalld and docker from system repositories, and my expectation is that the firewall rules from the public zone which are locked down by default have exactly the same effect on ports opened and forwarded from Docker containers, but with great (and unpleasant) surprise I have found out that my Jenkins instance running inside a Docker container is public instead, and now I know why.

Is there a cleaner way to solve this problem with making zone settings apply to Docker or the only way is to hack around with DOCKER-USER chain? Can one implement something suitable with Ansible firewalld module, or one is bound to firewalld CLI commands?

@patrakov
Copy link

@patrakov patrakov commented Dec 24, 2019

I think that for the end user there should be no difference whether the service to be firewalled is provided by a local process or by a process in a container. Therefore I think that firewalld should duplicate all rules that it normally places in the INPUT chain with equivalent rules in the FORWARD chain (ok, a configurable chain, because Docker) that check for DNATed packets and match the destination port using -m conntrack --ctorigdstport ....

@zyv
Copy link

@zyv zyv commented Dec 30, 2019

I ended up removing firewalld altogether and reverting to plain iptables :( I only need a very simple static set of rules, and getting stuff to work cleanly according to the linked blog post felt way too complicated.

@grk-pancham
Copy link

@grk-pancham grk-pancham commented Jan 16, 2020

I have the same issue. None of the fixes mentioned above worked for me. only option now is to disable firewall and use iptables to apply rules.

@erig0 erig0 removed the needinfo label Jan 17, 2020
@erig0
Copy link
Collaborator

@erig0 erig0 commented Jan 17, 2020

See also #556. That seems to be the root cause of what many of you are reporting.

@vlastoun
Copy link

@vlastoun vlastoun commented May 5, 2020

Fresh Fedora 32 with docker. After creating containers by docker-compose it starts:
journalctl -f -u NetworkManager

<info>  [1588698130.7231] device (veth5be8560): carrier: link connected
<info>  [1588698141.8261] manager: (veth32a28d9): new Veth device (/org/freedesktop/NetworkManager/Devices/156)
<info>  [1588698141.8595] device (veth5be8560): released from master device br-4ce2170a9240
<info>  [1588698141.9009] manager: (veth4562d1f): new Veth device (/org/freedesktop/NetworkManager/Devices/157)
<info>  [1588698141.9023] manager: (veth83cbbf0): new Veth device (/org/freedesktop/NetworkManager/Devices/158)
<info>  [1588698142.1627] device (veth83cbbf0): carrier: link connected

I have chrome disconnects and network errors.
When I disable firewalld service everything is OK.

@erig0
Copy link
Collaborator

@erig0 erig0 commented May 5, 2020

@ethindp
Copy link

@ethindp ethindp commented May 23, 2021

Any update on this? I'm considering running a mail server in docker containers, and I'd prefer to manage only one firewall.

@fcelda
Copy link

@fcelda fcelda commented May 23, 2021

Docker 20 has firewalld support and it works great for me. This is no longer an issue. I'm running Fedora 34.

@Jojonintendo
Copy link

@Jojonintendo Jojonintendo commented Aug 24, 2021

Latest firewalld 1.0.0-1.1 seems to break inter-container connectivity. At least in some cases like Mastodon's docker-compose.yml.

For instance the mastodon_streaming_1 container shows these errors repeatedly trying to connect to the redis container:

WARN Starting worker 50 
WARN Worker 50 now listening on 0.0.0.0:4000 
ERR! Error: Redis connection to mastodon_redis_1:6379 failed - connect EHOSTUNREACH 172.24.0.3:6379 
WARN Worker 50 exiting

It doesn't seem to happen with other projects though. Reverting to firewalld 0.9.3-3.3 (openSUSE Tumbleweed) fixes the issue.

@erig0
Copy link
Collaborator

@erig0 erig0 commented Aug 24, 2021

@Jojonintendo, please open a new issue (assuming you're on docker 20+). As noted by @fcelda this general issue has been addressed by docker 20 which added native firewalld support.

@erig0
Copy link
Collaborator

@erig0 erig0 commented Aug 24, 2021

I'm closing and locking this issue. Docker 20.10 added native firewalld support which addresses the issues raised here.

@erig0 erig0 closed this Aug 24, 2021
@firewalld firewalld locked as resolved and limited conversation to collaborators Aug 24, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
10 participants