netavark icon indicating copy to clipboard operation
netavark copied to clipboard

Bridge network isolation blocks access to other containers published ports

Open PlqnK opened this issue 2 years ago • 7 comments

I'm opening a new issue to address the same thing as #679 which was closed by its author because I'm encountering the problem myself.

I have this problem on all of my homelab hosts, I reproduced the issue in a Vagrant environment with the following Vagrantfile:

Vagrant.configure("2") do |config|
  config.vm.box = "fedora/38-cloud-base"
  config.vm.provider "virtualbox" do |vb|
    vb.cpus = "2"
    vb.memory = "2048"
  end
end

Some network/firewall information about the environment:

[root@localhost ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 52:54:00:d6:6b:09 brd ff:ff:ff:ff:ff:ff
    altname enp0s3
    inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic noprefixroute eth0
       valid_lft 85667sec preferred_lft 85667sec
    inet6 fe80::5487:511f:600:c001/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
[root@localhost ~]# firewall-cmd --state
-bash: firewall-cmd: command not found
[root@localhost ~]# nft list ruleset
[root@localhost ~]#
[root@localhost ~]# iptables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N NETAVARK_FORWARD
-N NETAVARK_ISOLATION_1
-N NETAVARK_ISOLATION_2
-A FORWARD -m comment --comment "netavark firewall plugin rules" -j NETAVARK_FORWARD

Here, iptables is used, but I have the same problem on my "production" hosts running firewalld with nftables as a backend.

If I try to create a container with a published port in one isolated network, I can't access the published port from a container in another isolated network which is something that does work with docker where networks are isolated by default (all the commands are executed as root):

# Create 2 networks with isolate=true
podman network create -o isolate=true nginxnet
podman network create -o isolate=true curlnet

# Run NGINX on nginxnet and publish a port
podman run --rm -d --net nginxnet -p 80:80 docker.io/library/nginx:latest

# I can access the port from the host without problem
curl -I "http://10.0.2.15:80"
HTTP/1.1 200 OK
Server: nginx/1.25.0
Date: Fri, 02 Jun 2023 13:17:46 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 23 May 2023 15:08:20 GMT
Connection: keep-alive
ETag: "646cd6e4-267"
Accept-Ranges: bytes

# But I get a timeout from a curl container running in the curlnet network
podman run --rm --net curlnet docker.io/curlimages/curl:latest curl -I "http://10.0.2.15:80"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:--  0:05:32 --:--:--     0
curl: (28) Failed to connect to 10.0.2.15 port 80 after 332583 ms: Couldn't connect to server

Here's some info about podman and netavark in the environment: podman version

Client:       Podman Engine
Version:      4.5.0
API Version:  4.5.0
Go Version:   go1.20.2
Built:        Fri Apr 14 15:42:22 2023
OS/Arch:      linux/amd64

podman info

host:
  arch: amd64
  buildahVersion: 1.30.0
  cgroupControllers:
  - cpuset
  - cpu
  - io
  - memory
  - hugetlb
  - pids
  - rdma
  - misc
  cgroupManager: systemd
  cgroupVersion: v2
  conmon:
    package: conmon-2.1.7-2.fc38.x86_64
    path: /usr/bin/conmon
    version: 'conmon version 2.1.7, commit: '
  cpuUtilization:
    idlePercent: 99.34
    systemPercent: 0.35
    userPercent: 0.31
  cpus: 2
  databaseBackend: boltdb
  distribution:
    distribution: fedora
    variant: cloud
    version: "38"
  eventLogger: journald
  hostname: localhost.localdomain
  idMappings:
    gidmap: null
    uidmap: null
  kernel: 6.3.4-201.fc38.x86_64
  linkmode: dynamic
  logDriver: journald
  memFree: 1410572288
  memTotal: 2048602112
  networkBackend: netavark
  ociRuntime:
    name: crun
    package: crun-1.8.5-1.fc38.x86_64
    path: /usr/bin/crun
    version: |-
      crun version 1.8.5
      commit: b6f80f766c9a89eb7b1440c0a70ab287434b17ed
      rundir: /run/crun
      spec: 1.0.0
      +SYSTEMD +SELINUX +APPARMOR +CAP +SECCOMP +EBPF +CRIU +LIBKRUN +WASM:wasmedge +YAJL
  os: linux
  remoteSocket:
    path: /run/podman/podman.sock
  security:
    apparmorEnabled: false
    capabilities: CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_FOWNER,CAP_FSETID,CAP_KILL,CAP_NET_BIND_SERVICE,CAP_SETFCAP,CAP_SETGID,CAP_SETPCAP,CAP_SETUID,CAP_SYS_CHROOT
    rootless: false
    seccompEnabled: true
    seccompProfilePath: /usr/share/containers/seccomp.json
    selinuxEnabled: true
  serviceIsRemote: false
  slirp4netns:
    executable: /usr/bin/slirp4netns
    package: slirp4netns-1.2.0-12.fc38.x86_64
    version: |-
      slirp4netns version 1.2.0
      commit: 656041d45cfca7a4176f6b7eed9e4fe6c11e8383
      libslirp: 4.7.0
      SLIRP_CONFIG_VERSION_MAX: 4
      libseccomp: 2.5.3
  swapFree: 2047864832
  swapTotal: 2047864832
  uptime: 0h 54m 0.00s
plugins:
  authorization: null
  log:
  - k8s-file
  - none
  - passthrough
  - journald
  network:
  - bridge
  - macvlan
  - ipvlan
  volume:
  - local
registries:
  search:
  - registry.fedoraproject.org
  - registry.access.redhat.com
  - docker.io
  - quay.io
store:
  configFile: /usr/share/containers/storage.conf
  containerStore:
    number: 0
    paused: 0
    running: 0
    stopped: 0
  graphDriverName: overlay
  graphOptions:
    overlay.mountopt: nodev,metacopy=on
  graphRoot: /var/lib/containers/storage
  graphRootAllocated: 41788899328
  graphRootUsed: 990142464
  graphStatus:
    Backing Filesystem: btrfs
    Native Overlay Diff: "false"
    Supports d_type: "true"
    Using metacopy: "true"
  imageCopyTmpDir: /var/tmp
  imageStore:
    number: 2
  runRoot: /run/containers/storage
  transientStore: false
  volumePath: /var/lib/containers/storage/volumes
version:
  APIVersion: 4.5.0
  Built: 1681486942
  BuiltTime: Fri Apr 14 15:42:22 2023
  GitCommit: ""
  GoVersion: go1.20.2
  Os: linux
  OsArch: linux/amd64
  Version: 4.5.0

rpm -q podman

podman-4.5.0-1.fc38.x86_64

rpm -q netavark

netavark-1.6.0-2.fc38.x86_64

PlqnK avatar Jun 02 '23 13:06 PlqnK

I need to take a look how docker does it but I agree that should work, if the port is exposed on the host I see no reason why this should be restricted.

Luap99 avatar Jun 02 '23 16:06 Luap99

I have the same Problem. A container, which needs to communicate to another container on the same host using the public hostname, gets blocked by the NETAVARK_ISOLATION_2 rule. Netavark uses iptables-nft, which should be supported to my understanding.

I saw firewalld solving this by accepting DNAT packets using the conntrack module.

rpm -q podman

podman-4.8.1-1.fc39.aarch64

rpm -q netavark

netavark-1.9.0-1.fc39.aarch64

maxxberg avatar Dec 25 '23 22:12 maxxberg

@Luap99 are there any news?

I'm trying to run a Collabara CODE Container next to Nextcloud. But as CODE needs to connect via host IP to Nextcloud this is not possible as long as the bridge isolation blocks such traffic. Both containers are behind a reverse proxy.

If it helps I could provide the generated firewall rules and a nft trace.

maxxberg avatar Jan 16 '24 13:01 maxxberg

I don't have time to look into this, I guess we need extra rules to allow such traffic or need to switch some ordering.

Luap99 avatar Jan 22 '24 11:01 Luap99