Skip to content

hallyn/uidmapviz

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

uidmapviz

A little program to visualize uid mappings

Building

Build in the usual new-style golang way:

git clone https://github.com/hallyn/uidmapviz
cd uidmapviz
go get ./...
go build

Running

You can run uidmap with no arguments to show the default uid mapping (i.e. your first full map entry).

If you provide a filename as an argument, it should represent a set of uid mappings for containers. For instance

c1 0:100000:200000 c1/c2 0:100000:65536

represents two containers, one nested inside the other. Running uidmapviz agains tthis gives you

+-----------+--------------+------------+-----------------+---------------+------------+----------+
| CONTAINER | PARENT START | PARENT END | CONTAINER START | CONTAINER END | HOST START | HOST END |
+-----------+--------------+------------+-----------------+---------------+------------+----------+
| c1/c2     |       100000 |     165536 | 0               |         65536 |     200000 |   265536 |
| c1        |       100000 |     300000 | 0               |        200000 |     100000 |   300000 |
+-----------+--------------+------------+-----------------+---------------+------------+----------+

A child container must come after the parent definition. If a child container's mapping is not contained within the parent's available range, then uidmapviz will warn you.

More details

ubuntu@lxd1:~$ uidmapviz
Your current default allocation is:
host uid 100000 - 165535 mapping to 0 - 65535 in container
host gid 100000 - 165535 mapping to 0 - 65535 in container

We'll create a little file showing the uid mappings we'd like to use:

cat > containers << EOF
c1 0:100000:65536
c1/c2 0:100000:65536
c1/c2/c3 0:200000:65536
EOF

Here the first field is a container name. If the name contains slashes, then it is read as grandparent/parent/child. The second field is the range, in the same format as /etc/subuid: the first id in the container, the first id in the parent container, and the range of the mapping. For each container we are mapping 65536 uids, starting at 0 in the container, to the range starting at 100000 in the parent.

Let's see what uidmapviz says about this:

ubuntu@lxd1:~$ uidmapviz containers Error opening file containers: "Mapping for c1/c2 exceeds its parent's, parentids should be between 0 - 65535"

c1's uid range is too narrow, as we should have known. When we provide a container with a mapping for uids 0-20, then only those uids exist in the container. It cannot delegate uids which do not exist. If we want to hand 20 uids to a child container while reserving 20 for ourselves, then we'll need 40 uids in total.

So let's give our first container 3*65k, or 196608 uids, and hand 65536-196604 to the second container. Then we'll hand the top half of c2's uids to c3.

cat > containers2 << EOF
c1 0:100000:196605
c1/c2 0:65536:131072
c1/c2/c3 0:65536:65536
EOF

ubuntu@lxd1:~$ uidmapviz containers2
Looking at c1
Looking at c1/c2
Looking at c1/c2/c3
+-----------+--------------+------------+-----------------+---------------+------------+----------+
| CONTAINER | PARENT START | PARENT END | CONTAINER START | CONTAINER END | HOST START | HOST END |
+-----------+--------------+------------+-----------------+---------------+------------+----------+
| c1        |       100000 |     296605 | 0               |        196605 |     100000 |   296605 |
| c1/c2     |        65536 |     196608 | 0               |        131072 |     165536 |   296608 |
| c1/c2/c3  |        65536 |     131072 | 0               |         65536 |     231072 |   296608 |
+-----------+--------------+------------+-----------------+---------------+------------+----------+

(Usually I use wider and easier to read allocations, i.e. b:100000:200000) Perfect. Now we need to make sure that the root user on the host is allowed to delegate the the range required by c1. We do this using /etc/subuid and /etc/subgid:

root:100000:196605

Restart lxd so the deamon will re-read its idmap.

We'll now create container c1. In order for it to be able to run nested containers, we'll set the 'security.nesting' flag to true:

lxc launch wily c1 --config security.nesting=true

Per-tenant idmaps are a future todo, for now the container will receive the full default id mapping allocated to the root user. So now we can log into the c1 container

lxc exec c1 bash

and install and setup lxd. This time we'll allocate the root user the mapping we wanted for c2:

root:65536:196605

That should be it. now you can

lxc launch wily c2

for an unprivileged container inside an unprivileged container. Configuring c3 is left as an exercise for the reader.

About

User namespace uid mapping visualization

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages