Greg,I don't know if this is exactly what you are looking for in SELinux but here is an example of deny vsock for privileged and unprivileged containers with cil:
``` # on terminal 1 nc --vsock -l 4000 # on terminal 2 podman run -it fedora:latest /bin/bash dnf install nmap-ncat nc --vsock 1 4000 # Type here "Hello" and should show up on terminal 1 ``` ``` cat > container_vsock.cil <<EOF(deny container_t self (vsock_socket (create read write bind connect getattr setattr ioctl getopt setopt shutdown sendto recvfrom accept listen)))
(deny spc_t self (vsock_socket (create read write bind connect getattr setattr ioctl getopt setopt shutdown sendto recvfrom accept listen)))
EOF semodule -i container_vsock.cil ```Now repeat the example before to validate that the container can't use vsock. You can remove the cil policy with `semodule -r container_vsock`.
This can be done for any selinux process context, not just container_t or spc_t.
Regards, Carlos R.F. On 1/2/26 5:48 PM, Greg Dahlman wrote:
Thanks for the reply, I have been busy trying to figure out what breaks with apparmor and other options. Obviously runc is similar to the pain points of dbus, where it is call anywhere with no ability to set defaults, but I think a combo of the below works pretty well. Container runtimes should still set reasonable defaults in the long run IMHO, but a combo of the below seems to work, but it will probably break kata containers etc... You can launch a vsock C2 container with runc as nobody with no issue and just a few env vars as an example. I am not sure if there are any hypervisor tools that are in flatpack/snap/bwrap etc... but pretty much everything that is given userns and unlabeled may need a apparmor.d/local file for users actually using vsock for critical use cases. This qualsys post from earlier this year applies: https://seclists.org/oss-sec/2025/q1/253 I am still trying to do more testing, but crun/runc/podman/buildah/chrome/chromium/firefox/etc. don't seem to break with a container only workload I have tested with the apparmor addition. Unfortunately putting it in globals would break things. Kernel boot string ================== Disables systemd sshd vsock listener, will not protect the L4 bridge. The official way to disable vsock sshd is through a kernel command line parameters or system credentials logic. [systemd-ssh-generator] systemd.ssh_auto=no Mask systemd socket =================== This will disable the systemd sshd vsock listener, but will not protect the L4 bridge. sudo systemctl mask sshd-vsock.socket Note: If another unit **explicitly** wants "sshd-vsock.socket" it may be started. AppArmor ======== This will remove access to the L4 bridge, which will also remove access to the systemd sshd vsock listener for targeted binaries. Add the following to "/etc/apparmor.d/local/<filename>" for each high risk command. audit deny network vsock, SElinux ======= TODO Seccomp ======= CRIs and sandbox commands should probably follow the methods containerd used when containerd blocked vsock [7442] [7442] https://github.com/containerd/containerd/issues/7442 On Fri, Jan 2, 2026 at 4:14 PM <[email protected]> wrote:I do not use Fedora, but I checked the update repo for f42. Neither openssh ¹, nor systemd ² have been updated for Fedora 42 in the last few weeks. Thus I have to guess that your method to setup/test the VM was different. Just in case, I have masked the vsock socket on all of my instances (no VMs though) and I will check on occasions if masking disappears. Nonetheless, I dug deeper into systemd and checked their source code ³. systemd-vmspawn uses another service: [email protected] ⁴ And there is also [email protected] ⁵ which might require another masking - same for [email protected] ⁶. Since I do not use VMs, it was rather an addition for this list, thus I won't dig deeper for now. busctl is unknown to me (yet). The "RestrictAddressFamilies" option for services might be another idea to restrict sshd - but I don't know if it affects the unix-socket/vsock sockets generated by systemd - and whether this also influences access to local sockets (e.g. to control systemd itself). I haven't understood the L4 bridge issue completely yet, so I would need to read more into it and test it. My guess on the L4 bridge problem: - Exposed vsocks are in global namespace. - VMs with enabled vsock feature (on hypervisor and inside VM) expose their services. - Containers (with unmitigated container runtimes) run on the hypervisor (not within VMs) are able to access the vsocks of VMs. That's a short description of my current understanding to it. 1 https://bodhi.fedoraproject.org/updates/FEDORA-2025-ad76584c00 2 https://bodhi.fedoraproject.org/updates/FEDORA-2025-61132a053f 3 https://github.com/systemd/systemd/ 4 https://github.com/systemd/systemd/blob/v259-stable/src/vmspawn/vmspawn.c#L2654 5 https://github.com/systemd/systemd/blob/v259-stable/src/ssh-generator/ssh-generator.c#L228 6 https://github.com/systemd/systemd/blob/v259-stable/src/ssh-generator/ssh-generator.c#L265 On 12/30/25 21:44, Greg Dahlman wrote:Thanks for the reply Alex, I didn't include that option because I ran into an issue that I couldn't find the root cause for. Specifically on Fedora, a `dnf upgrade` resulted in the mask disappearing. I could find some complaints with Fedoraversionupgrades, but couldn't find anything on package upgrade. As I don't have access to the RedHat support portal I decided to excludeitout of caution. It looked like there was nothing in /usr/lib/systemd/system-preset for sshd-vsock.socket that I found, and those should respect the mask for sshd-vsock.socket and wouldn't remove the /etc/systemd/system/sshd-vsock.socket symlink as I understand it. I think that because it doesn't show up in `busctl --activatable`, and no packages I can find "Wants" sshd-vsock.socket explicitly that would probably work. I just tried a fresh install of Fedora Linux 42 workstation and didn't experience the unintended unmasking with a dnf upgrade. That wasreliable afew weeks ago. Maybe I just was unlucky with a package that was fixed? Either way I think it is an option for people who use configuration management tools that can periodically check sshd-vsock.socket is still disabled. Also for normal *systemd* services that need isolation from the vsock bridge you can use: RestrictAddressFamilies=none # disable all af families RestrictAddressFamilies=AF_INET # only AF_INET RestrictAddressFamilies=~AF_VSOCK # not AF_VSOCK The L4 bridge problem will be harder for projects that use CRI's that are not containerd like the k8s/podman/crun/runc. If anyone on here is involved with them, or sandboxing tools like bubblewrap etc... Filtering address family 40 will still be required by default to have any real intra-container/pod/process network isolation on a node. Thanks, Greg On Tue, Dec 30, 2025 at 12:12 PM <[email protected]> wrote:I have searched for that - instead of blacklisting the vsock module, I did myself two measures: - systemctl mask --now sshd-unix-local.socket to kill and mask the sshd unix socket created by that generator, - systemctl mask sshd-vsock.socket to mask the sshd vsock created by that generator (use --now if the socket has started or use systemctl stop... ). Though, vsock untested but I found that source mentioning that socket. https://linux-audit.com/system-administration/commands/systemd-analyze/ Masking the sockets should stop them from starting again. The vsock kernel module should not be blacklisted if some hypervisor features are required: https://libvirt.org/ssh-proxy.html https://wiki.qemu.org/Features/VirtioVsock Greetings Alex On 12/29/25 05:11, Jacob Bachmeyer wrote:On 12/27/25 21:46, Greg Dahlman wrote:[...] **Systemd v256 change** - When the *openssh-server* package is installed on a VM with vsock support, systemd now automatically starts an *sshd* instance that listens on the **af_vsock** socketinthe **global network namespace** without any manual configuration.Obvious question: what manual configuration is required to kill that listener? -- Jacob
OpenPGP_signature.asc
Description: OpenPGP digital signature
