jmtd → log → podman rootless
Podman (an alternative to Docker) supports "rootless containers" since around 2019.
what are rootless containers?
- containers that created/run/managed by users w/o admin rights
- protect against engine/runtime/orchestrator compromise
drawbacks?
- slirp4netns (not needed?)
$HOME/.local/share/containers/storage vs /var/lib/containers
Questions
what does conmon do
do they use distinct user namespaces?
I'm running two user-namespace ikiwiki containers. what namespace do they use
├─conmon,2031027 --api-version 1 -c 3353fef59670f6f12de3cbb9094d009fe3cc78796376e28c5313013f777806fd -u... │ └─lighttpd,2031042 -Df /etc/lighttpd/lighttpd.conf ├─conmon,2031121 --api-version 1 -c 55abef9846fb0130ef094c6fe4012317816b4b251d1099dc06c3db2d066bdd23 -u... │ └─lighttpd,2031135 -Df /etc/lighttpd/lighttpd.conf
they seem to be mapped to the same uuid outside
100999 2031042 2031027 0 14:26 ? 00:00:00 /usr/sbin/lighttpd -Df /etc/lighttpd/lighttpd.conf 100999 2031135 2031121 0 14:26 ? 00:00:00 /usr/sbin/lighttpd -Df /etc/lighttpd/lighttpd.conf
the conmon instances are running as uid=jon
containers I am running:
container-calibreweb.service all running as root container-freshrss.service runs apache, cron, sensitive-log.sh as root container-graphite.service whole thing running as root container-navidrome.service
container-nextcloud.service container-paperless.service container-privwiki.service container-redis.service
does podman use a uidmap by default? Can I inspect it?
graphite: USER HUSER COMMAND root root entrypoint root root runsvdir root root runsv root root runsv root root runsv root root runsv root root runsv root root runsv root root runsv root root runsv root root runsv root root runsv root root runsv root root nginx root root crond root root gunicorn root root tee root root tee root root tee root root python3 root root statsd /opt/sta root root tee root root python3 nginx systemd-network nginx nginx systemd-network nginx nginx systemd-network nginx nginx systemd-network nginx root root gunicorn root root gunicorn root root gunicorn root root gunicorn navidrome: USER HUSER COMMAND 1000 jon navidrome freshrss: USER HUSER COMMAND root root apache2 root root cron root root sensitive-log.s root root sed www-data www-data apache2 www-data www-data apache2 www-data www-data apache2 www-data www-data apache2 www-data www-data apache2 www-data www-data apache2 redis: USER HUSER COMMAND redis systemd-coredump redis-server privwiki: USER HUSER COMMAND ikiwiki jon lighttpd paperless: USER HUSER COMMAND root root supervisord paperless jon gunicorn: maste paperless jon [celeryd: celer paperless jon [celery beat] - paperless jon python3 paperless jon gunicorn: worke paperless jon [celeryd: celer calibreweb: USER HUSER COMMAND root root s6-svscan root root s6-supervise root root s6-linux-init-s root root s6-supervise root root s6-supervise root root s6-supervise root root s6-supervise root root s6-ipcserverd abc 911 python3 root root bash root root sleep nextcloud: USER HUSER COMMAND root root apache2 www-data www-data apache2 www-data www-data apache2 www-data www-data apache2 www-data www-data apache2 www-data www-data apache2 www-data www-data apache2 www-data www-data apache2 www-data www-data apache2 www-data www-data apache2 www-data www-data apache2
no uidmapping argh
simplifying my investigations down to uid mapping and the like.
sudo podman top freshrss user,pid,huser,hpid USER PID HUSER HPID root 1 root 3632
sudo ls -l /proc/3632/ns
sudo lsns -t user
NS TYPE NPROCS PID USER COMMAND
4026531837 user 272 1 root /sbin/init
4026532989 user 1 223410 uuidd └─/usr/sbin/uuidd --socket-activation
there's only two user namespaces on the system, so podman is not using them yet.
what's uuidd? a local daemon, systemd has PrivateUsers=yes hence the namespace!
which container to experiment on? either privwiki or paperless, neither important
privwiki /var/lib/containers/storage/volumes/privwiki/_data
if I use --userns=auto, the container thinks its running as uid=1000 (can't be sure what is actually chosen) but it cannot read the volume (mapped to nobody)
using a fresh volume, it gets initialised to a big uid (2147484647), but is this consistent? can I rely on it?
second problem: /dev/stderr not writeable without -t, so lighttpd dies
== 2025-05-29 ==
the /dev/stderr thing, that's weird. is it a phobos specific issue? can I recreate it?
there's no root entry in /etc/subuid, but there is (now) a containers entry containers:2147483647:2147483648
podman run -d --replace --name privwiki --userns=auto quay.io/jdowland/opinionated-ikiwiki:latest bash -c 'date > /dev/stderr'
privwiki 9b610a64e032207eed690f18dd4ce59546fe8d810c694ccdd0f74ccdfb1225d0 root@phobos:~# podman logs 9b610a bash: line 1: /dev/stderr: Permission denied
reproduced locally:
- podman run -d --replace --name date --userns=auto date bash -c 'id -u; stat /proc/self/fd/2; date >> /proc/self/fd/2'
- 2e6fc313bb49d19222e45447a561942e79f1288baaecc50b765e562838351a40
- carbyne ▶;podman logs 2e6fc
- 1000
- File: /proc/self/fd/2 -> pipe:[24066627]
- Size: 64 Blocks: 0 IO Block: 1024 symbolic link
- Device: 0,111 Inode: 24070420 Links: 1
- Access: (0300/l-wx------) Uid: ( 1000/ jon) Gid: ( 0/ root)
- Access: 2025-05-29 13:47:31.763178125 +0000
- Modify: 2025-05-29 13:47:31.763178125 +0000
- Change: 2025-05-29 13:47:31.763178125 +0000
- Birth: -
- bash: line 1: /proc/self/fd/2: Permission denied
- carbyne ▶;podman run -d --replace --name date --userns=auto date bash -c 'id -u; stat /proc/self/fd/2; date >&2'
- 617daffb70ec0e4e1f314407530e72723f448d1de9fd7781b4013da545a80599
- carbyne ▶;podman logs 617daff 1000 File: /proc/self/fd/2 -> pipe:[24011709] Size: 64 Blocks: 0 IO Block: 1024 symbolic link Device: 0,110 Inode: 24071393 Links: 1 Access: (0300/l-wx------) Uid: ( 1000/ jon) Gid: ( 0/ root) Access: 2025-05-29 13:47:55.659164875 +0000 Modify: 2025-05-29 13:47:55.659164875 +0000 Change: 2025-05-29 13:47:55.659164875 +0000 Birth: - Thu May 29 13:47:55 UTC 2025
== 2025-05-30 ==
should a httpd container log to stderr/stdout by default?
apache: (SIGWINCH!) ErrorLog /proc/self/fd/2 CustomLog /proc/self/fd/1 common
yet seems to work as user with default usermapping stuff
;podman top apache huser user hpid pid comm HUSER USER HPID PID COMMAND 1000 root 2174688 1 httpd 100032 www-data 2174702 8 httpd 100032 www-data 2174703 9 httpd 100032 www-data 2174705 11 httpd
refuses to start with --userns=auto. with userns=host:
podman top apache huser user hpid pid comm HUSER USER HPID PID COMMAND 1000 root 2176081 1 httpd 100032 www-data 2176094 8 httpd 100032 www-data 2176095 9 httpd 100032 www-data 2176097 11 httpd 100999 1000 2176355 92 bash
how to interpret this: container user 0 is mapped to host user 1000, so the root process has my user privileges; my uid 1000 in container context is mapped to something 'safe'
is the issue mapping the default container-user (e.g. root) to not-host-me, so it hasn't permissions on /proc/dev/fd/2?
lighttpd:
== 2025-05-30 ==
need to take a step back. Given quadlet is around the corner, does it invoke containers as root? does it do user mapping?
I want to invoke as root (unless quadlet advises against) so stick to testing uid stuff invoked as root
podman quadlet doesn't do any --userns stuff by default you can put UserNS=, User= etc. into the .container (service) file
== 2025-05-30 ==
OK so root-invoked podman, userns=auto, lighttpd breaks: perms oin /dev/setderr. let's try and debug that
Comments