Incus Container Security

Hi-
This is an easy one for the Incus expects. I know you should run containers in unprivileged mode, but when you install applications/services (such as a proxy like Traefik) would you install the service under a separate Traefik user or the just run under container root. I guess container root is not really root on the host.

Interested in thoughts here and other security tips you may have.

thanks

In unprivileged mode uids are mapped, so uid 0 (root) inside the container is 1000000 on the host, uid 112 inside the container is 1000112 on the host, and so on.

So from the point of view of the host, they’re both regular users with no special permissions.

From the point of view of the container, the root user has more permissions for modifying things on the container’s filesystem, killing processes inside the container etc. So someone who finds a hole in Traefik and breaks in, would be able to do more damage within the container as the “root” user than the “traefik” user; but they still wouldn’t have any privileges on the host. And to be honest you’re toast pretty much either way.

Since you manage incus containers just like normal systems, usually the package manager will create a service user for you when you do “apt-get install traefik” or “apt-get install apache2” or whatever, and you might as well use it.

However, it’s something people tend not to worry about too much. At least, I’ve seen many docker containers which run applications as the root user within the container.

I think @candlerb covered this. I also think that you need several people covering the same issue in their own way so that you get more confidence in all this.

In the beginning there were virtual machines (VMs), where you would install services on the same actual physical server. It was a big improvement from having several physical servers with one service per server (a real waste). Those virtual machines require certain hardware support from the physical server (CPU, etc) and need lots of memory and disk-space. Then, some workloads did not justify a separate virtual machine because it was taking too many resources. Would it be possible to have some sort of software-only virtual machines? Yep, and those are the containers.

The Linux kernel provides certain generic functionality (primitives) that can be used together to enable Linux containers. This functionality includes namespaces and cgroups. They provide container isolation and resource management. A container is a process tree, that is launch from the host, and as soon it is launched, it becomes isolated from the rest of the system (it’s configurable). The container cannot revert this isolation from within. That is, if your container is compromised, it cannot revert back to a non-isolated state.

The best containers are the unprivileged containers. In the following setup, when you create an unprivileged container, UID 0 (from within the container) is mapped to UID 100000 from the point of view of the host. In the container you would think you are running as root, but in reality, it’s just some non-root account with UID 100000. Then, your non-root account ubuntu in the container with UID 1000, has a real UID 100000+1000 = 101000 on the host.

$ cat /etc/subuid
root:100000:65536
$ 

When creating unprivileged containers, you are giving back some privileges to make them useful. It’s up to you to decide what is really needed. For example, you may share a directory from the host to the container. If you do so, then you are opening up a bit your attack surface and give the opportunity to a possibly compromised container to add some file in the shared directory and hopefully get some user from the host to execute.

To get back to your Traefik question, you would install the service in the way it requires (from the packaging) in an unprivileged container. A root in an unprivileged container is a non-root user on the host. Your concern might be about network access of that container. Can that container network access the host (by default it does), or all other containers (it also does). Does Traefik actually need network access to all these? Most likely not. This is an area that you could look into. In most cases it is not a first priority. If you want to go deeper into this, start a new thread about something like Network isolation of containers.

Thanks Brian & Simos for your responses. I appreciate the information. Since I may expose my Traefik instance to the internet some day I am thinking the following at this point.

I will probably install Traefik in a normal container instead of via an OCI container. I will install via a package manager in either unbuntu or debian. I installed manually for testing under root, but for production it will probably make more sense via package manager so it will run under the normal Traefik user. Also with this approach, I can keep both the traefik and container updated daily for any security updates by doing automatic updates. I think this is a significant benefit over running the OCI container version of Traefik where you are depending on the container maintainer for updates.

Also I have been mapping the container’s etc directory to a folder on the host which is very nice to get a backup of the configuration files. Maybe for this container I will not do that.

Do you think my logic makes sense?

Do you have any other suggestions?

I am not sure of the whole network isolation question you raised, but most my containers with be reachable on the lxdbro bridge and the host. I am not sure if I can revoke some network privileges.

Also, I am thinking you need to be careful on putting all your internal and external reachable containers in the same Traefik instance. Maybe this should be broken into an internal and external instance.

All of this is probably overkill for a little home setup, but why not learn from the experts.