containers / containers/netavark

Firewalld backend forward port even for non-local-targeting traffic

Open
#904 8 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
794
Forks
161
Avg merge
8d 17h
Merged PRs (30d)
3

Description

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 https://github.com/containers/netavark/issues/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.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.