LXD Security Best Practices

Greetings, all. First and foremost thank you for providing this forum; it is an invaluable service.

My post is about best practices to secure LXD. I have the following questions:

  1. Are LXD containers by default unprivileged (assuming I run LXD as a non-root user on the host. the non-root user has sudo privileges)
  2. Normally when I want to execute within in a container I will use “lxc exec – /bin/bash”. This will initiate a session as root. Is this inherently insecure? Should I be initiating sessions as a non-root user w/ sudo privileges?

Any other suggestions to make my LXD use more secure? 99% of my containers are services that run in the background (nextcloud, airsonic, plexmediaserver, HAProxy, etc.) but I do run Firefox in a LXD container.

Hi!

By default, when you create an LXD container, the container is an unprivileged container.
If you were to create a privileged container, you would have to launch it as below:

lxc launch ubuntu: mycontainer -c security.privileged=true

Therefore, most likely all your containers are unprivileged.

When you get a shell into a container, it looks like this. What’s going on? We are root in the container?

$ lxc launch ubuntu: mycontainer
Creating mycontainer
Starting mycontainer
$ lxc exec mycontainer -- /bin/bash
root@mycontainer:~# id
uid=0(root) gid=0(root) groups=0(root)
root@mycontainer:~# 

Well, it appears to be root according to the container, but the process does not have ID=0 according to the host. Let’s check. Run the following command. This command is just an example of a command that will wait there, and does not consume resources. You can later interrupt it with Ctrl+C.

root@mycontainer:~# cat | tee /tmp/MYFILE.txt

Then, run on the host the following command to view this tee /tmp/MYFILE.txt process. The user-id (UID) is 1000000 on the host, and not 0. Therefore, the root in the container is actually UID 1000000 on the host. Therefore, the container is unprivileged.

$ ps aux  | grep MYFILE
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
1000000  28257  0.0  0.0   7924   608 ?        S+   18:40   0:00 tee /tmp/MYFILE.txt
1 Like

While it is not directly insecure to run something as root in container (as simos already explained), you can still also create users inside the container and run things as user, for example with:
lxc exec containername -- su --login username -c program/command

Some tips:

  • never run insecure or untrusted software (also not in containers)
  • use firewalls (inside container and on host)
  • don’t use X-forward methods (as this will use your hosts X-Server and thus software in container can now see everything on your X-Server (what you type, see (on your host) etc.))
    • instead you should run a seperate X- or Wayland-Server inside the Container and then access it via ssh or something else
  • You can further limit a containers use of your hosts ressources: incus/doc/instances.md at main · lxc/incus · GitHub - search for limit
  • set: security.idmap.isolated=true - this will give each container their own set of UIDs/GIDs
    More info here: incus/doc/instances.md at main · lxc/incus · GitHub

Also see:

Simos:

Thank you for not only answering my question by socratically explaining the answer! Thank you!

thank you for the suggestions, Toby!

1 Like

What is the point of containers then? If we could trust everything what would we need isolation for?

Do you have some concrete examples?

Well, I guess it comes down to two things:

  1. There are other reasons: You can easily divide the system into “units” (so you can have different configurations, software-versions, distributions, non-interference of different software etc.) and you have easier distribution of software/systems etc.
  2. It depends on the interpretation of untrusted.
    For example: I use LXD for most proprietary software, because I somehow trust it (and I use it), but I don’t trust it 100%.

The most important thing you should remember is, containers might not be perfectly safe, so you shouldn’t run viruses in it.

You can use tools like ufw or firewalld, this makes using firewalls easier than using nftables or iptables directly.

If I want absolute max security I usually fall back to using good old VM’s, then will usually run LXD in the VM or docker (or both).