Code Monkey home page Code Monkey logo

podman-rootful-network's Introduction

Rootful networking with rootless podman containers

As presented at devconf.cz 2023.

This python tool allows attaching network interfaces to initialized, but not running, rootless podman containers. It uses netavark, which is the same tool podman uses to do this. There are some known limitations:

  • podman inspect won't know about the network. From podman's point of view, the container doesn'thave networking.
  • podman run --sdnotify=conmon won't work; systemd receives but rejects the notification with a message similar to [email protected]: Got notification message from PID 7687, but reception only permitted for main PID 3201

If you are using podman >= 4.5, using

podman run \
    --uidmap="0:$(id -u user):1" \
    --uidmap="1:$(grep -Po '(?<=^user:).*$' /etc/subuid | head -1)"

also gives you containers without a mapped root UID without external tooling. You may want to use that, as it's a lot simpler.

Dependencies

  • python3
  • python3-podman
  • container-selinux
  • dbus-x11 for dbus-launch, which is called somewhere in the setup by podman or systemd

Running

To see this in action manually, open one shell as root and one as the unprivileged user you want to use to run your container. In the example below, this user is test with a UID of 1000.

Initial setup (run once)

As root:

# Create a secret that will be used to make the IP addresses (which are
# calculated from the container name) unpredictable
touch /etc/rootful_network_secret \
    && chmod 600 /etc/rootful_network_secret \
    && dd if=/dev/urandom of=/etc/rootful_network_secret bs=1 count=32

# lingering is required for the unprivileged user
loginctl enable-linger test

# clone and install required scripts
git clone https://github.com/neverpanic/podman-rootful-network
install -m0755 \
    podman-rootful-network/rootful_network.py \
    /usr/local/sbin/rootful_network

# enable the podman socket for root
systemctl enable --now podman.socket

# create the podman network you want to use; rootless_network.py expects to
# have exclusive control over this network, so do not use it for any other
# containers
podman network create [--ipv6] "$networkname"

As user:

# enable the podman socket for the user
systemctl --user enable --now podman.socket

For each container

As user:

# create the runtime directory that will contain state information
runtimedir="/run/user/$(id -u)/container/$containername"
mkdir -p "$runtimedir"
# create the container, but do not start it
# the --cidfile will be used by rootful_network.py
podman create \
    --cidfile="$runtimedir/ctr-id" \
    --network=none \
    --name "$containername" \
    "$image:$tag"

# initialize the container namespaces, but do not start it
podman container init rootless

As root:

runtimedir="/run/user/1000/container/$containername"

rootful_network \
    "$runtimedir" \
    setup \
    "$name_used_to_generate_ip" \
    /etc/rootful_network_secret \
    "$unprivileged_user" \
    --network "$networkname" \
    [--publish [[ip:][hostPort]:]containerPort[/protocol]] \
    [--network-alias "$alias"]

As user:

podman start "$containername"

Stopping containers

As user:

podman stop "$containername"

As root:

runtimedir="/run/user/1000/container/$containername"

rootful_network \
    "$runtimedir" \
    teardown

As user:

podman rm "$containername"

If you start containers with --rm rootful_network.py won't be able to determine the container ID during teardown and cleanup will fail.

The example systemd service file rootless-example.service shows these commands in a systemd service that can start and stop a container after the initial setup steps.

Credits

Without the help of the following people and their posts and presentations, this would not have been possible:

License

This code is licensed under the BSD-2-Clause license. The SPDX identifier is BSD-2-Clause.

podman-rootful-network's People

Contributors

ben7on avatar neverpanic avatar sujaldev avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.