rootless-containers / slirp4netns

User-mode networking for unprivileged network namespaces
GNU General Public License v2.0
729 stars 82 forks source link

rootless routing issue in pod with ip rule "uidrange" #272

Closed ValHeimer closed 3 years ago

ValHeimer commented 3 years ago

repost of this issue https://github.com/containers/podman/issues/10923 as it seems to seem a slirp4netns bug

Is this a BUG REPORT or FEATURE REQUEST? (leave only one on its own line)

/kind bug

Description

In a rootless pod, the ip rule "uidrange" does not seem to work properly.

Steps to reproduce the issue:

  1. In the pod, I have 2 containers:

    • One with user root, which will add the routes
    • Another with user uid 50000
  2. Add routing rules (from inside the pod, in the container with user root)

    
    # add a rule to route request from uid 50000 to table 555
    ip rule add uidrange 50000-50000 table 555
    # add a default route to tap0 in table 555, which have internet connection
    ip route add default via <IP1> dev tap0 table 555

add a rule AFTER the uidrange rule whish should not be catch in our test

ip rule add to 1.1.1.1/24 table 666

then add a route in table 666 which can't resolve 1.1.1.1, this is only to "nullroute" the request if matched


3. Run `ip route get 1.1.1.1` (from inside the pod, in the container with user uid 50000)
You can see `1.1.1.1 via <IP1> dev tap0 src <myip>`
So the (output) request goes through the good routing table 555, as we can see `<IP1>`.
But...

4. Run `curl 1.1.1.1`, it times out... (from inside the pod, in the container with user uid 50000)
If I add (from container root) a rule to match uid 0 (idk why), now it works fine (rules order is important). Note the it needs both `8` and `9` rules, or it won't work)
```bash
ip rule add uidrange 0-0 table 555

$ip rule

0: from all lookup local
8: from all uidrange 0-0 lookup 555
9: from all uidrange 50000-50000 lookup 555
10: from all to 1.1.1.1/24 lookup 666
...

$id

uid=50000(user) gid=65533(nogroup)

Describe the results you received: The curl request to 1.1.1.1 times out (idk why, maybe because the routing rule didn't make the match with the uidrange for the response, it seems that the corresponding response is seen as user uid 0 (it works )

Describe the results you expected: The curl request should succeed (the corresponding response should be seen as user uid 50000)

Output of podman version:

Version: 3.1.0-dev
API Version: 3.1.0-dev
Go Version: go1.16.1
Built Fri Mar 26 19:32:03 2021
OS/Arch: linux/amd64

Output of podman info --debug:

host:
  arch: amd64
  buildahVersion: 1.19.8
  cgroupManager: cgroupfs
  cgroupVersion: v1
  conmon:
    package: conmon-2.0.27-1.module_el8.5.0+733+9bb5dffa.x86_64
    path: /usr/bin/conmon
    version: 'conmon version 2.0.27, commit: dc08a6edf03cc2dadfe803eac14b896b44cc4721'
  cpus: 4
  distribution:
    distribution: '"centos"'
    version: "8"
  eventLogger: file
  hostname: <REDACTED> 
  idMappings:
    gidmap:
    - container_id: 0
      host_id: 1001
      size: 1
    - container_id: 1
      host_id: 165536
      size: 65536
    uidmap:
    - container_id: 0
      host_id: 1001
      size: 1
    - container_id: 1
      host_id: 165536
      size: 65536
  kernel: 4.18.0-315.el8.x86_64
  linkmode: dynamic
  memFree: 2015375360
  memTotal: 3890102272
  ociRuntime:
    name: runc
    package: runc-1.0.0-70.rc92.module_el8.5.0+733+9bb5dffa.x86_64
    path: /usr/bin/runc
    version: 'runc version spec: 1.0.2-dev'
  os: linux
  remoteSocket:
    path: /run/user/1001/podman/podman.sock
  security:
    apparmorEnabled: false
    capabilities: CAP_NET_RAW,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: true
    seccompEnabled: true
    selinuxEnabled: true
  slirp4netns:
    executable: /usr/bin/slirp4netns
    package: slirp4netns-1.1.8-1.module_el8.5.0+733+9bb5dffa.x86_64
    version: |-
      slirp4netns version 1.1.8
      commit: d361001f495417b880f20329121e3aa431a8f90f
      libslirp: 4.3.1
      SLIRP_CONFIG_VERSION_MAX: 3
      libseccomp: 2.5.1
  swapFree: 536866816
  swapTotal: 536866816
  uptime: 21h 41m 51.93s (Approximately 0.88 days)
registries:
  search:
  - registry.access.redhat.com
  - registry.redhat.io
  - docker.io
store:
  configFile: /home/user/.config/containers/storage.conf
  containerStore:
    number: 7
    paused: 0
    running: 4
    stopped: 3
  graphDriverName: overlay
  graphOptions:
    overlay.mount_program:
      Executable: /usr/bin/fuse-overlayfs
      Package: fuse-overlayfs-1.5.0-1.module_el8.5.0+733+9bb5dffa.x86_64
      Version: |-
        fusermount3 version: 3.2.1
        fuse-overlayfs: version 1.5
        FUSE library version 3.2.1
        using FUSE kernel interface version 7.26
  graphRoot: /home/user/.local/share/containers/storage
  graphStatus:
    Backing Filesystem: xfs
    Native Overlay Diff: "false"
    Supports d_type: "true"
    Using metacopy: "false"
  imageStore:
    number: 31
  runRoot: /run/user/1001/containers
  volumePath: /home/user/.local/share/containers/storage/volumes
version:
  APIVersion: 3.1.0-dev
  Built: 1616783523
  BuiltTime: Fri Mar 26 19:32:03 2021
  GitCommit: ""
  GoVersion: go1.16.1
  OsArch: linux/amd64
  Version: 3.1.0-dev

Package info (e.g. output of rpm -q podman or apt list podman):

podman-3.1.0-0.13.module_el8.5.0+733+9bb5dffa.x86_64

Additional environment details (AWS, VirtualBox, physical, etc.):

VMware

ValHeimer commented 3 years ago

Does anyone know if it is indeed a slirp4netns issue or if I should open an issue somewhere else ? (@AkihiroSuda ?) Thank you!

ValHeimer commented 3 years ago

It was an error in my host config........

I just had to run

sudo sysctl net.ipv4.conf.all.rp_filter=2

recreate the pod, and it works

sorry about that