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

[Feature]: Ability to change firewalld zone #573

Open
ivanov17 opened this issue Jan 30, 2023 · 11 comments
Open

[Feature]: Ability to change firewalld zone #573

ivanov17 opened this issue Jan 30, 2023 · 11 comments

Comments

@ivanov17
Copy link

ivanov17 commented Jan 30, 2023

Feature request description

I suggest you consider adding the ability to change zone when using a firewalld backend.

Currently, podman automatically adds containers to the trusted zone. It means that a pod or container that binds to all interfaces always has ports open for outside connections. But in many cases, services need to be available on any interface, but not outside. In addition, administrator must be able to open ports explicitly. Traditionally, firewall rules are used for this, but docker and podman de facto ignore the presence of a firewall.

Suggest potential solution

This can be implemented as a configuration option in the containers.conf file for global setting and as a command line option for networks, pods and containers.

Have you considered any alternatives?

  • Firewalld Rich Language. This requires exploring the rules generated by podman and then writing an own rule with a specific syntax. When we have zones, it seems like overcomplication.
  • Setting up a container with a proxy server that can reject traffic from untrusted networks. It seems very dirty because we have open external port but all traffic is rejected. When we have a firewall, we can choose not to open this port at all.
  • Allow requests only from trusted networks in the service settings. Of course, but I would like no one to know that I have this service, because it is internal.

Additional context

Using of zones with firewalld seems as non-breaking and elegant solution. When using iptables or nftables directly, administrator can add the necessary firewall rules to block the ports. Special option for firewalld will not affect them.

With a zone-based firewall zones should be used. Of course, zones are currently in use by podman, but the zone cannot be changed. This can be fixed. Default zone for podman will be trusted, as it is now.

@Luap99
Copy link
Member

Luap99 commented Jan 30, 2023

Do you use netavark as network backend? If anything it would be implemented there. We will not add new features to CNI.

@mheon WDYT? What is the state of your firewalld backend code?

@Luap99 Luap99 added the network label Jan 30, 2023
@rhatdan
Copy link
Member

rhatdan commented Jan 30, 2023

@ivanov17 Interested in working on this?
I kind of like the idea.

@mheon
Copy link
Member

mheon commented Jan 30, 2023

Firewalld backend needs some work for port-forwarding (specifically, a bit of code needs to be written to use rich rules to handle port forwards from only a single host IP), but is otherwise finished. It completely eliminates the use of the 'trusted' zone and adds a separate zone specifically for Podman-created interfaces.

@Luap99 Luap99 transferred this issue from containers/podman Jan 30, 2023
@Luap99
Copy link
Member

Luap99 commented Jan 30, 2023

Moved to netavark repo because it would need to implemented here first.

@justinjereza
Copy link

@mheon Does the work you're doing also cover a routed rather than NAT use case?

Given the following:

foo --- gateway --- bar --- container

foo, gateway, and bar are on 192.168.0.0/24. container is on 10.88.0.0/16.

On EL9 with the default podman network, foo cannot reach the container with 10.88.0.0/16 as a source in the trusted zone. If the trusted zone is removed and 10.88.0.0/16 is added as a source instead to the zone used by bar's network interface to gateway (in my case, the home zone), it becomes reachable.

The following seems to be the cause of the problem:

        chain filter_FORWARD_ZONES {
                ip saddr 10.88.0.0/16 goto filter_FWD_trusted
                iifname "wlp0s20f3" goto filter_FWD_home
                goto filter_FWD_public
        }

        chain filter_FWD_trusted_allow {
                ip daddr 10.88.0.0/16 accept
        }

Only traffic within the trusted zone is accepted as opposed to when the subnet is a source in the home zone:

        chain filter_FORWARD_ZONES {
                ip saddr 10.88.0.0/16 goto filter_FWD_home
                iifname "wlp0s20f3" goto filter_FWD_home
                goto filter_FWD_public
        }

        chain filter_FWD_home_allow {
                oifname "wlp0s20f3" accept
                ip daddr 10.88.0.0/16 accept
        }

The source address doesn't match but the interface does after which the destination address matches and is accepted.

Maybe it would be nice if the user is able to select between a routed and NAT scenario as well as to just disable podman's handling of firewalld?

@mheon
Copy link
Member

mheon commented Apr 13, 2023

No, we're not covering routed usage with Netavark at all, generally speaking. That sounds like a separate feature request. I think it would add a moderate amount of complexity to iptables/firewalld rules generation, in that there would be fewer rules but the structure would be sufficiently different that I doubt we could re-use existing NAT rules.

@Sydius
Copy link

Sydius commented Jun 8, 2023

I noticed a comment in the code:

    // Until firewalld 1.1.0 with support for self-port forwarding lands:
    // Just use iptables

I'm not sure of how to check whether what is needed is implemented in firewalld or not, but I do notice firewalld is up to v1.3.2. I don't suppose this is unblocked?

I also wonder if it will work / anything bad will happen if I were to set the NETAVARK_FW environment variable to firewalld in the meantime.

@Sydius
Copy link

Sydius commented Jun 8, 2023

The good news: setting the environment variable NETAVARK_FW to firewalld results in a working setup without containers going into trusted! 🎉 Doing this puts the containers in the netavark_zone instead of trusted, which seems like an improvement, and creates a policy for forwarding the traffic on the ports. Everything works well (with the minor exception that the HOST can no longer reach these ports, since I don't believe ANY used in the policy includes HOST).

The bad news: I can't for the life of me figure out how to filter that traffic before it is forwarded. I thought that if I set the priority of the policy created by podman to a positive number that it would first reject the traffic if not explicitly opened in the public zone, but this doesn't seem to be the case. I was hoping to arrive at a solution that default-blocked the ports until explicitly opened in the firewall (ideally by simply adding the service to public), but nothing I've tried works.

@maxxberg
Copy link

I'm in the same situation as @Sydius. Containers are in the netavark_zone and ports 80 & 443 are forwarded.
Now I want to use Fail2Ban to block certain addresses who act malicious. But I can't find any way to configure firewalld to block these addresses before getting port-forwarded.

This is a huge problem as it seems to be impossible to filter external traffic before reaching the designated container.

@roozbehk
Copy link

Any solution for this?

@ne20002
Copy link

ne20002 commented Jun 21, 2024

I'm also on the problem with fail2ban. It seems it needs to disable the firewall plugin and do it manually (which is OK). I found a few articles but I'm still looking how to do this with rootless containers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants