Nspawn must be in /var/lib/machines for proper selinux?

Fedora instructions show that we create an nspawn container in /var/lib/machines, install a container there, and then have it selinux labeled.

Question - is it imperative to have your nspawn container machine be in the /var/lib/machines folder to have selinux labels of the container to be always properly maintained during container’s operation?

I’m still not sure how selinux works with nspawn exactly. It’s impossible to turn on selinux from within nspawn containers, even if they are booted. So selinux is applied from the host side? Using which policy? What are the requirements for the containers in this regard?


Hi there,
thirst, I’m not so familiar with nspawn.
Under Fedora I personally use Podman for using container.

You could do something like this and check if it works
chcon -Rv --reference=/var/lib/machines /your/path/you/want/to/use
This copies the SELinux permission of “/var/lib/machines” to the path you want to use.

Then you could try to check if there still are problems with commands like this:
As time marker, you can use one of:
[ now | recent | this-hour | boot | today | yesterday | this-week | week-ago | this-month | this-year ]

Oh, I labeled the container initially after setting up just fine. My question is: is that all I need to do? Do all newly created files within the container as a result of its inner operation propagate correct labels regardless of where the container is stored and what it does?

That’s a good question. Have you tested? This might be one way to find it out.
My personal guess is that it might work, since it already does work under the default path, right?

However, the solution above is not persistent.
If you execute a restorecon command, the SELinux permission might get reset to the default values.

So you would need to make it persistent using the semanage command.

First check out the original permissions using
ls -ahlZ /var/lib/machines/
then set it via (for example, please use the correct types)
semanage fcontext -a -t systemd_machined_var_lib_t '/your/custom/path(/.*)?'
Now it should be permanent. But this only applies for the SELinux part.
Set it by
restorecon -R -v /your/custom/path

Nspawn should set new files with correct permissions itself.
As far as I know SELinux does not set them automatically, it just verifies them, allows or disallows execution. (If your question was into this direction)


Thanks, this is sort of what I was wondering about. So I guess my key 100 million dollar question is that it matters if my containers are in a folder with the -t systemd_machined_var_lib_t for SELinux to secure them properly when systemd-nspawn is run on that container??

1 Like

`Example 2. Build and boot a minimal Fedora distribution in a

       # dnf -y --releasever=39 --installroot=/home/<User>/Containers/Contain \
             --repo=fedora --repo=updates --setopt=install_weak_deps=False install \
             passwd dnf fedora-release vim-minimal util-linux systemd systemd-networkd
       # systemd-nspawn -bD /home/<User>/Containers/Contain`

This is a flash back for me, Back in my day we installed it anywhere we wanted :slight_smile: :exclamation: Here is a video of how we used to do it 9yrs ago and is still relevant.
At 0:22 He goes into the install of the container in a different root. Ignore the use of yum here, dnf will do the trick for this.

Basically installing the root file system somewhere else and adding the new SELinux labels so as not to interfere with the host file system. At 2:35 Seth discusses the reasons why he has a rule set up for this.

edit: I reviewed some notes and the last time i used the SELinux sandbox commands I used sandbox_web_t if that is not already apparent.

This is how we used to install debian on fedora to run spotify back then. . . :laughing:

I hope this helps and does not take you off track.

1 Like

I’m still not 100% sure on this.

I have an nspawn container that has firefox and other execs with unconfined_u:object_r:bin_t:s0 SELinux context. The other execs that I assume were installed when this nspawn container was created have system_u:object_r:bin_t:s0.

This is wrong and insecure, right? firefox should have system_u?

So can someone help and explain WHEN things get SELinux labeled when installed from INSIDE the container (launched with systemd-nspawn without the -b parameter, for example)? Or it never happens and we must manually restorecon from outside of the container after anything gets installed from inside the container?


You need to relabel it. I used sandbox_web_t for my use case. container_t now exist among others.

It seems that placing containers into /var/lib/machines is required if you want to control your nspawn containers via machinectl command.

And this also should be added to Fedora’s documentation because it is not pointed out there in big bold bright red letters there. I know that page talks about setting up an nspawn container, but this will beat the whole point of containerization if people don’t know to relabel their containers on any dnf transaction?

This is in the the Docs, Maybe should include a relabel as an example?

No, that’s the initial labeling. No word about this needing be done again. Yes, a relabel example would be nice. Could you please post it here for reference for any folks who get here from search engines?

I’ll work on on the Documentation. I’ll try this next week as part of my project, it’s been a while since I did some systemd-nspawn container stuff anyway.

The Documentation might be correct and it’s just a different approach, or I simply relabled for the purpose of my usecase, which was sandboxing/container etc. Eitehr way it’s worth a revisit :party:

1 Like

For example, this might not be enough and you need to add -F switch to it? Or why would you not add -F to restorecon?

UPD: I guess -F would erase any custom labeling you would have done in your container, but if you don’t do any custom labeling of your own, you can just use restorecon with or without -F to the same effect?

Yes, I have tested, and you are patently wrong. If you follow what you suggest it will change SELinux labels to whatever physical folder your container will be in.

restorecon does not follow symlinks either.

So any and all containers MUST be physically in /var/lib/machines for everything to be relabeled correctly. Then you can move the container wherever. But SELinux relabeling must be done on the container physically placed in /var/lib/machines.

I think there’s something wrong here, but I can’t test right now. . .

What I prefer to do is to set the context property on the filesystem.

# zfs get context zfs0/san/vm-{00,01}
NAME            PROPERTY  VALUE                                     SOURCE
zfs0/san/vm-00  context   system_u:object_r:container_file_t:s0:c0  local
zfs0/san/vm-01  context   system_u:object_r:container_file_t:s0:c1  local

The context property will set the SELinux label for all files on that (sub)filesystem, including any new files that might be added to it at a later time. But that is a ZFS feature. It might be more complicated to do that with other filesystems.

I also override the Exec= for systemd-nspawn@<container-name>.service.d/override.conf and add --selinux-context="<whatever-selinux-context-i-want>" so I can isolate my systemd-nspawn containers with custom contexts and categories.

I do keep my containers mounted under /var/lib/machines so that I can access them with the machinectl command. (I could probably customize the mountpoint with a wrapper script around the machinectl command if I wanted to.)

1 Like

What I used to do was :

semanage fcontext -a -t sandbox_file_t "/home/USER/Contain/F27(/.*)?"

restorecon -R /home/USER/Contain/F27

systemd-nspawn -D /home/USER/Contain/F27

and was fine with it. I could be missing the OP’s point but again, I can’t test right now. . . and from the snippet it’s clearly been a while since I tried this :laughing:

1 Like

To delete custom made context use semanage fcontext --deleteall /custom/path.
This works to delete a custom rule. Thereafter you can assign a different one.

The restorecon -F option should not work in this case.
But I’m frankly I’m not entirely sure in which case this one is being used.
At least I never had a need to use it.