Skip to content

[socketVMNet] Disable symlink detection for the socketVMNet directory #1437

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
mritd opened this issue Mar 27, 2023 · 11 comments
Closed

[socketVMNet] Disable symlink detection for the socketVMNet directory #1437

mritd opened this issue Mar 27, 2023 · 11 comments

Comments

@mritd
Copy link

mritd commented Mar 27, 2023

Description

Currently, when Lima is installed for the first time on macOS, it will automatically create a ~/.lima/_config/networks.yaml configuration file, in which socketVMNet is automatically filled with a non-symlink directory.

But when we update socketVMNet through brew command, the old version directory may be deleted, which will cause Lima to fail to start.

If we set the socketVMNet directory to /opt/homebrew/opt/socket_vmnet/bin/socket_vmnet(this directory is a symlink maintained by brew.), it will also cause startup failure due to internal detection mechanism.

Can we use some compatible code to allow the socketVMNet directory to use symlink?

@AkihiroSuda
Copy link
Member

@lima-vm/maintainers Can we just trust the symlink when it is owned by the admin group?

@jandubois
Copy link
Member

@lima-vm/maintainers Can we just trust the symlink when it is owned by the admin group?

We would also need to check the target where the symlink points to, and all parent directories of the target, to make sure all of them are only writable by admin users. And do this recursively if any of those directories turn out to be symlinks.

@avoidik
Copy link

avoidik commented Sep 27, 2024

do you think that the socket_vmnet verification should be really strict as it is now? could it be relaxed?

#2662

@jandubois
Copy link
Member

jandubois commented Sep 27, 2024

do you think that the socket_vmnet verification should be really strict as it is now? could it be relaxed?

It has already been relaxed in #1220 to make it easier for Homebrew users. I feel uneasy about that already because it is not different from allowing password-less sudo access for the admin user. Which maybe is acceptable, but it should be something the user explicitly configures, and not a side-effect of the configuration of socket_vmnet.

So if anything, I think the verification should be stricter.

You should be able to delete the sudoers line from ~/.lima/_config/networks.yaml and allow password-less sudo, and the verification should be disabled already.

Just paste something like %admin ALL=(ALL) NOPASSWD:ALL into /etc/sudoers.d/nopasswd.

@avoidik
Copy link

avoidik commented Sep 28, 2024

as stated in the #2662 (comment) this will work if only my user is a member of the admin group, for example, if my primary group is "staff", it won't work even if my user name is in the sudoers file, due to:

adminGroup, err := user.LookupGroup("admin")

@jandubois
Copy link
Member

I believe loosening the restrictions to allow ownership by admin instead of only root was a mistake, and will lobby to tighten them again.

There are ways to install/run the daemon securely as an unmanaged launchdaemon.

For convenience Lima allows you to create sudoers rules to run just the commands needed to start/stop the daemon as root. This is only secure if the files are owned by root. Otherwise this becomes a backdoor that allows an attacker to run any command on the system as root.

If this is not a concern, then you can enable password-less sudo and Lima will skip all file ownership checks. You don't even need the sudoers file. I've just tested it myself:

$ limactl create --tty=false template://vmnet

INFO[0000] Run `limactl start vmnet` to start the instance.

$ limactl start vmnet
INFO[0000] Using the existing instance "vmnet"
FATA[0000] can't read "/private/etc/sudoers.d/lima": failed to run [sudo --user root --group wheel --non-interactive true]: exit status 1: (Hint: run `limactl sudoers >etc_sudoers.d_lima && sudo install -o root etc_sudoers.d_lima "/private/etc/sudo

$ yq -i 'del(.paths.sudoers)' ~/.lima/_config/networks.yaml

$ echo "%admin ALL=(ALL) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/nopasswd >/dev/null
Password:

$ limactl start vmnet
INFO[0000] Using the existing instance "vmnet"
INFO[0000] Starting socket_vmnet daemon for "shared" network
INFO[0000] Starting the instance "vmnet" with VM driver "qemu"

@avoidik
Copy link

avoidik commented Sep 28, 2024

This is all valid if a user is a member of the admin group (%admin).

My user is not a member of the admin group for the sake of said security, however is added in the sudoers list as user.name ALL=(ALL) NOPASSWD:ALL. In this case it's failing.

@jandubois
Copy link
Member

In this case it's failing.

Can you provide the output?

Also, what happens when you run sudo -k -n --user root --group wheel true?

@jandubois
Copy link
Member

jandubois commented Sep 28, 2024

however is added in the sudoers list as user.name ALL=(ALL) NOPASSWD:ALL. In this case it's failing.

I just realized that you have a . in your username. That is not going to work with sudoers. As a workaround you can create a group for this, add yourself to the group, and give the group password-less sudo.


EDIT: Actually, I'm not sure if the user.name itself is an issue; maybe it is creating /etc/sudoers.d/user.name that doesn't work, if that is what you are doing.

Anyways, seeing the actual error message might help.

@avoidik
Copy link

avoidik commented Sep 30, 2024

@jandubois I assume you're referring to a caveat when a sudoers file has a dot somewhere in its file name, in this case my sudoers file name has no dots in it

the output of the sudo -k -n --user root --group wheel true is 0, which is expected in the root user's context, however I do not run limactl as a root user (and it's actually impossible to run it as root):

the socket_vmnet is running as root:

$ sudo brew services list --json | jq -r '.[] | select(.name == "socket_vmnet")'
{
  "name": "socket_vmnet",
  "status": "started",
  "user": "root",
  "file": "/Library/LaunchDaemons/homebrew.mxcl.socket_vmnet.plist",
  "exit_code": 0
}

my sudoers config allows me to use password-less sudo:

$ tail /etc/sudoers.d/*
==> /etc/sudoers.d/lima <==

%everyone ALL=(root:wheel) NOPASSWD:NOSETENV: \
    /opt/homebrew/Cellar/socket_vmnet/1.1.4/bin/socket_vmnet --pidfile=/private/var/run/lima/host_socket_vmnet.pid --socket-group=everyone --vmnet-mode=host --vmnet-gateway=192.168.106.1 --vmnet-dhcp-end=192.168.106.254 --vmnet-mask=255.255.255.0 /private/var/run/lima/socket_vmnet.host, \
    /usr/bin/pkill -F /private/var/run/lima/host_socket_vmnet.pid

# Manage "shared" network daemons

%everyone ALL=(root:wheel) NOPASSWD:NOSETENV: \
    /opt/homebrew/Cellar/socket_vmnet/1.1.4/bin/socket_vmnet --pidfile=/private/var/run/lima/shared_socket_vmnet.pid --socket-group=everyone --vmnet-mode=shared --vmnet-gateway=192.168.105.1 --vmnet-dhcp-end=192.168.105.254 --vmnet-mask=255.255.255.0 /private/var/run/lima/socket_vmnet.shared, \
    /usr/bin/pkill -F /private/var/run/lima/shared_socket_vmnet.pid

==> /etc/sudoers.d/user <==
user.name ALL=(ALL) NOPASSWD: ALL

I'm able to create a new limactl VM:

$ limactl create --tty=false template://vmnet
INFO[0000] Terminal is not available, proceeding without opening an editor
INFO[0000] Attempting to download the image              arch=aarch64 digest="sha256:5ecac6447be66a164626744a87a27fd4e6c6606dc683e0a233870af63df4276a" location="https://cloud-images.ubuntu.com/releases/24.04/release-20240821/ubuntu-24.04-server-cloudimg-arm64.img"
INFO[0000] Using cache "/Users/user.name/Library/Caches/lima/download/by-url-sha256/346ee1ff9e381b78ba08e2a29445960b5cd31c51f896fc346b82e26e345a5b9a/data"
INFO[0000] Attempting to download the nerdctl archive    arch=aarch64 digest="sha256:77c747f09853ee3d229d77e8de0dd3c85622537d82be57433dc1fca4493bab95" location="https://github.com/containerd/nerdctl/releases/download/v1.7.6/nerdctl-full-1.7.6-linux-arm64.tar.gz"
INFO[0000] Using cache "/Users/user.name/Library/Caches/lima/download/by-url-sha256/21cc8dfa548ea8a678135bd6984c9feb9f8a01901d10b11bb491f6f4e7537158/data"
INFO[0000] Run `limactl start vmnet` to start the instance.

but I cannot start it:

$ limactl start vmnet
INFO[0000] Using the existing instance "vmnet"
FATA[0000] networks.yaml field `paths.socketVMNet` error: dir "/opt/homebrew/Cellar/socket_vmnet/1.1.4" owner XXXis not an admin
$ ls -ld /opt/homebrew/Cellar/socket_vmnet/1.1.4
drwxr-xr-x@ 11 user.name  admin  352 Sep 28 15:07 /opt/homebrew/Cellar/socket_vmnet/1.1.4

as you may see, the socket_vmnet directory is owned by the user.name:admin, and for some reason limactl assumes the user.name is also a member of the admin group, which is not the case:

$ id -n -g
staff

@avoidik
Copy link

avoidik commented Nov 13, 2024

The issue I have had reported before is now fixed 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants