I am using puppet to manage my containers. This might have some disadvantages in form of speed but the advantage is that it is

only the puppet service that needs to be secured, not an lxd or some other service. So what…

lets see how that works, the following hiera stencil defines me a virtual machine, this time without an

ip addess, but it can come with one at all:

lxc::vm::sandbox::networks:

- ethSand

lxc::vm::sandbox::network::ethSand:

lxc.network.link: brsandbox

```
```lxc::vm::sandbox::puppet: True

lxc::vm::sandbox::autostart: True

`lxc::vm::sandbox::rawconfig: |`

# this is the tun tap device

lxc.cgroup.devices.allow = c 10:200 rwm

lxc.mount.entry = /dev/net/tun dev/net/tun none bind,create=file 0 0

as soon as I enable

classes:

- lxc

and

lxc::vms:

. sandbox

the machinery starts its work: it checks for any lxc maintainace scripts and a logindefs class to set subuids, as soon as all prereqs are there it

- creates a user
- creates subuid and subgid ranges in lxc configuration
- creates network permissions
- installs a local debian os template with puppet node
- configures puppet and hostname
- modifies permissions so that no one exept root and the vm user can access vm data
- configures container backup via duplicity
- starts the container

It may not that easy to actualy move containers, but creation really is that easy… it also has a mode where it can automatically migrate a priviledged container into an unpriviledged one…

by the way, one short notice, if one sees manuals pointing that you should write: *your-username veth lxcbr0 10* I am not really happy with that example, because I cant think of any user who needs more than 1 simultaniously connected ethernet devices for his unpriviledged containers. so you may want to write 1 here. because if you really want to seperate your containers you might consider having one user that holds exactly one container, running with one specific range of subuids.

so far….

Sometimes it takes a while to come to the obvious solutions, however I did learn a lot about namespaces ans stuff, but conclusions first, if you want to have somethink like fakeroot but for lxc to create backups without knowing about mapped userids or if you want to untar a priviledged installation, you may want to use *lxc-usernsexec*

`cd ~/.local/lxc/yourvm/rootfs ; lxc-usernsexec -- tar xvfz somearchive.tar`

You can easily map to different maps or map as root by using *-m (u|g|b):0:startid:range* for example *-m b:0:1738400:65535*. lxc-usernsexec does not do a changeroot. so you can use all the tools and data from the base system. However, keep in mind that all the files which are not in your mapped range including the data of the own user, are owned by user nobody and nogroup, that means that ssh private keys and gpg data is not accessable, except if you set the permissions accordingly.

**Now a bit Theory:**

The namespace change is done by cloning a process with the clone() C system call this one is the basic system call from which fork() exec() and all the others are derived from. but with clone() you can decide that the cloned system process has his own namespace. The Manpage *user_namespaces* provides you with some piece of C code doing exactly that. If you look at the code you might find a few confusing parts.

- The uid and gid Mappings can only be made by the root user
- The uid and gid mappings can not be made by the cloned process, even if it is a root process.
- The uid and gid mappings can not be preset during clone()

This means clone() creates a new process with a new user namespace, which then has to wait for the parent or a setuid root process to set the mappings, and once this is done, it can continue with its work by, for example executing the process that really does the work. In the example from the user_namespaces manpace this waiting is done by waiting for a pipe to be closed by the parent.

close(args->pipe_fd[1]); /* Close our descriptor for the write

end of the pipe so that we see EOF

when parent closes its descriptor */

if (read(args->pipe_fd[0], &ch, 1) != 0) {

fprintf(stderr,

"Failure in child: read from pipe returned != 0\n");

exit(EXIT_FAILURE);

}

Because the experimental tool in the user_namespaces manpage only does a write to /proc/*newuidmap* and *newgidmap* these are also running setuid root, so they have to check if the user is allowed to do the mapping before they actually set it. You may have to keep that in mind before actually implement your own code, that it may be better to call these tools.

you may also need to know that there is *nsenter* which is a tool that just enters the exact same namespace of a process if the calling process is allowed to do that.

You can find additional information in secondary literature and other blog posts. regards

I started to change the rear member of my defender, unfortunately i discovered later in that repair, that my extensions are gone as well, so i ordered long extensions and will go for another try next week…

I build that one recently and made a small video:

So I hope it will not overcrowd my blog and I also hope that my readers are aware that not every link they click on is actually good for them. ðŸ˜‰

A few years ago I decided to stop using wordpress and to start using blogofile, a static website and blog generator. It was mainly the spam maintanance in my wordpress instance which forced me to do that.

Unfortunately as of today it seems that I have to fork a complete virtual environment for blogofile which breaks down whenever I try to write a post due to system upgrades.

So I decided to switch back to wordpress and here I am.

I hope that I can provide you with stuff more frequently, in the future. So don’t forget to add be to your rss feed, and also to follow me on Twitter and Youtube.

regards

2 more wtfs, this time in keyctl pse have a look:

$ keyctl list @u

1 key in keyring:

175445478: –alswrv 0 0 user: d395309aaad4de06

$ keyctl list 175445478

185 keys in keyring:

4: key inaccessible (Required key not available)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

0: key inaccessible (Invalid argument)

10: key inaccessible (Required key not available)

0: key inaccessible (Invalid argument)

64: key inaccessible (Required key not available)

2: key inaccessible (Required key not available)

90575192: key inaccessible (Required key not available)

-1289718489: key inaccessible (Invalid argument)

1226118138: key inaccessible (Required key not available)

1367941247: key inaccessible (Required key not available)

185619277: key inaccessible (Required key not available)

-395441912: key inaccessible (Invalid argument)

745876651: key inaccessible (Required key not available)

2130504598: key inaccessible (Required key not available)

-837867635: key inaccessible (Invalid argument)

-1322709961: key inaccessible (Invalid argument)

-405937745: key inaccessible (Invalid argument)

-1943943650: key inaccessible (Invalid argument)

1965794927: key inaccessible (Required key not available)

1320268544: key inaccessible (Required key not available)

-172599692: key inaccessible (Invalid argument)

-2138721474: key inaccessible (Invalid argument)

892941156: key inaccessible (Required key not available)

1631137843: key inaccessible (Required key not available)

878993761: key inaccessible (Required key not available)

909141348: key inaccessible (Required key not available)

571539456: key inaccessible (Required key not available)

1716864051: key inaccessible (Required key not available)

119: key inaccessible (Required key not available)

$

The kernel documentation makes it clear:

$$code

Each key is issued a serial number of type key_serial_t that is unique for

the lifetime of that key. All serial numbers are positive non-zero 32-bit

integers.

```
Userspace programs can use a key's serial numbers as a way to gain access
to it, subject to permission checking.
```

$$/code

So first, if I am not wrong I would have guessed that it should show the key

with the ID 175445478 not all the others. And secondly it looks like the output

accidently uses int instead of unsigned int.

But Wait, there is more:

$$code(lang=shell)

$ keyctl show

Session Keyring

70665221 –alswrv 0 0 keyring: _ses

184578637 –alswrv 0 65534 _ keyring: _uid.0

175445478 –alswrv 0 0 _ user: d395309aaad4de06

tanja:~# man keyctl

tanja:~# keyctl add user foobar barfoo @u

545549103

$ keyctl show

Session Keyring

70665221 –alswrv 0 0 keyring: _ses

184578637 –alswrv 0 65534 _ keyring: _uid.0

175445478 –alswrv 0 0 _ user: d395309aaad4de06

545549103 –alswrv 0 0 _ user: foobar

$$/code

Every other tool I know tries to prevent key data from being shown in the process list by not passing cleartext passwords as commandline arguments, maybe for keyctl rules are different.

So far for this interesting experience. I still hope that I am wrong and everything is fine as soon as I dig deeper.