Skip to content

[IMP] Allow Podman's libpod API paths - #193

Open
junkerderprovinz wants to merge 1 commit into
Tecnativa:masterfrom
junkerderprovinz:feat/podman-libpod-paths
Open

junkerderprovinz wants to merge 1 commit into
Tecnativa:masterfrom
junkerderprovinz:feat/podman-libpod-paths

Conversation

@junkerderprovinz

Copy link
Copy Markdown

Supersedes #113 by @Alex-K37 (and #103). Thanks for the original work!

Fixes #104

Problem

The Podman client sends its requests to the native API under /v{version}/libpod/...,
starting with GET /v4.6.1/libpod/_ping. The rules in haproxy.cfg only accept
^(/v[\d\.]+)?/<endpoint>, so the proxy answers 403 to all of them and
podman --url tcp://... cannot connect.

Change

Every endpoint rule, and the use_backend docker-events rule, gets an optional
(/libpod)? segment after the version. A libpod path is allowed by the same variable as
its Docker counterpart, so /v5.0.0/libpod/containers/json needs CONTAINERS=1, the
same as /containers/json.

#113 used (/\w+)?, which accepts any word in that position. (/libpod)? only opens the
prefix Podman uses.

A few libpod routes can do more than the Docker endpoint behind the same variable. A
deny rule before the allow rules blocks them whatever the variables say:

  • secrets/{name}/json returns the secret in plain text with showsecret=true. Podman
    only honours that flag on libpod paths.
  • volumes/{name}/export streams a volume's contents, and volumes/{name}/import
    writes into it.
  • system/prune deletes unused data, and system/check can repair storage with
    repair_lossy.
  • images/scp/{name} copies an image to another host over the host's SSH.

Listing secrets and volumes, secrets/{name}/exists and system/df still work, and so
does the Docker style secrets/{name} inspect.

Libpod container subpaths that Docker lacks (mount, checkpoint, restore, init) fall
under the CONTAINERS prefix rule, the same way every /containers/... path does. With
POST=1 that rule already allows creating containers. containers/{name}/healthcheck
is a GET that runs the container's configured healthcheck; it stays under CONTAINERS
because it cannot run anything else.

I checked Podman's route registrations (pkg/api/server/register_*.go) and its client
(pkg/bindings/connection.go). By default the client builds
/v{major}.{minor}.{patch}/libpod/...; an API-Version header overrides the version.
Podman-only endpoints such as pods, manifests, kube, play, generate, artifacts, quadlets
and local/... have no variable here and stay blocked.

How tested

  • test_libpod_permissions: with CONTAINERS=1, the libpod paths for _ping,
    version and containers go through, while images, info, pods and
    /v4.6.1/other/containers/json get 403.
  • test_libpod_routes_beyond_docker_blocked: with IMAGES, SECRETS, SYSTEM and
    VOLUMES set, the libpod list routes and system/df go through, while secret
    inspect, volume export, system prune and image scp get 403. Without the deny rule this
    test fails on /v4.6.1/libpod/secrets/foo/json.
  • poetry run pytest --prebuild on Python 3.8 against Docker 29.9.2: 7 passed, both
    serial and with the default -n auto.
  • haproxy -c in the built image (HAProxy 3.4.2) accepts the config. Its only warning
    is the missing timeouts for docker-events, which master shows as well.
  • A Podman 5.8.9 service behind the proxy with CONTAINERS, IMAGES, SECRETS,
    SYSTEM, VOLUMES and POST set: ps, images, secret ls, secret create,
    volume ls, volume create and system df work. volume export, system prune and
    system check get 403, and so do secret inspect --showsecret and secret inspect,
    according to the proxy log.
  • pre-commit run passes on the changed files.

The last scheduled CI run on master failed with connection resets in three existing
tests, while the runs before it were green. If CI here fails the same way, a re-run
should show whether it is that.

The Podman client sends every request to /v{version}/libpod/..., so the
endpoint rules answered even _ping with 403 and podman --url could not
connect. Each rule now also matches with a /libpod segment, under the
same variable as its Docker counterpart. Podman-only sections such as
pods stay blocked, and so do the libpod routes that reach further than
the Docker endpoint behind the same variable: secret inspect, volume
export and import, system prune and check, and image scp.

Fixes Tecnativa#104

Co-authored-by: Alex-K37 <106149389+Alex-K37@users.noreply.github.com>
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

Successfully merging this pull request may close these issues.

podman failure due to strong regex filter (pull request attached)

1 participant