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 backend forward port even for non-local-targeting traffic #904

Open
karuboniru opened this issue Jan 27, 2024 · 2 comments
Open

Comments

@karuboniru
Copy link

karuboniru commented Jan 27, 2024

Reproduce of the problem:
Start a container with port forwarding using firewalld backend.

$ sudo NETAVARK_FW=firewalld podman run -p 12345:12345 --rm -it alpine
 ...
# ip a 
 ...
 ... 10.88.0.2/16 ...
 ...
# python3 -m http.server 12345
 ...

Firewalld state:

$ sudo firewall-cmd --info-policy=netavark_portfwd
netavark_portfwd (active)
  priority: -1
  target: CONTINUE
  ingress-zones: ANY
  egress-zones: ANY
  services: 
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
	port=12345:proto=tcp:toport=12345:toaddr=10.88.0.2
  source-ports: 
  icmp-blocks: 
  rich rules: 

In another container

$ sudo NETAVARK_FW=firewalld podman run --rm -it alpine
 ...
# curl 10.88.0.2:12345
 ... (reply from python, listing contents in /)
# curl 10.88.0.12:12345
 curl: (7) Failed to connect to 10.88.0.12 port 12345 after 3108 ms: Couldn't connect to server
# curl 1.1.1.1:12345
 ... (reply from python, listing contents in /)

It is unexpected to me that 1.1.1.1:12345 would be successful, as traffic to 1.1.1.1:12345 should be masqueraded to real 1.1.1.1 and result in Failed to connect as cloudflared should not have a python http.server running in /.


Reason:
Generated nft rule from firewalld:

	chain nat_PREROUTING {
		type nat hook prerouting priority dstnat + 10; policy accept;
		jump nat_PREROUTING_POLICIES
	}
	chain nat_PREROUTING_POLICIES {
...
		jump nat_PRE_policy_netavark_portfwd
...
	}
	chain nat_PRE_policy_netavark_portfwd {
...
		jump nat_PRE_policy_netavark_portfwd_allow
...
	}
	chain nat_PRE_policy_netavark_portfwd_allow {
		meta nfproto ipv4 tcp dport 12345 dnat ip to 10.88.0.2:12345
	}

This makes the dnat rule apply to every traffic that hit prerouting chain without checking fib information.

Consider the container is running with -p 443:443 and the machine running the container is a router, every traffic to anyip:443 would be forwarded to the container, which is bad. (This is the exact reason why #881 exist as I wanted to limit the address forwarded from, which did not work since the issue) I thought that forwarding even for non-local-targeting traffic is somewhat designed but after swiched back to iptables backend I realized that this might be a bug.


Behavior when iptables backend is used (rules are transleted by iptables-nft)

...
		fib daddr type local counter packets 50672 bytes 4178234 jump NETAVARK-HOSTPORT-DNAT
...

we have the fib daddr type local check here.


This might be hard to fix I guess, as I can't think of a way to match fib in firewalld rules for now, maybe some cooperation with firewalld is needed.

@karuboniru karuboniru changed the title Firewalld backend forward port even for non-local traffic Firewalld backend forward port even for non-local-targeting traffic Jan 27, 2024
@mheon
Copy link
Member

mheon commented Jan 27, 2024

Definitely a firewalld bug. I'm working through some bugs with the firewalld team as part of the process of getting #885 merged but have not noticed this one yet - I'll add it to the list.

Until #885 merges (which will be after the bugs are addressed enough that our tests start passing), I do not recommend using the firewalld driver.

@Luap99
Copy link
Member

Luap99 commented Jan 29, 2024

it was mentioned here: #859
Looks like I forgot to ping you there.

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

No branches or pull requests

3 participants