vmware / open-vm-tools

Official repository of VMware open-vm-tools project
http://sourceforge.net/projects/open-vm-tools/
2.26k stars 427 forks source link

non-root user can change the VM's configuration by vmtoolsd --cmd #288

Closed sunshaoshuai01 closed 6 years ago

sunshaoshuai01 commented 6 years ago

I found even a non-root user can change the VM's configuration by vmtoolsd --cmd. If you reboot the VM after info-set, the setting will be updated to VMX file permanently. Is it a correct action? Can we disable the changing for non-root user(or for all users) by any setting?

` $ vmtoolsd --cmd 'info-get guestinfo.interface.1.ip.0.address' 10.67.254.132/24

$ vmtoolsd --cmd 'info-set guestinfo.interface.1.ip.0.address 10.67.254.232/24' $ vmtoolsd --cmd 'info-get guestinfo.interface.1.ip.0.address' 10.67.254.232/24

$ vmtoolsd --cmd 'info-set guestinfo.interface.1.ip.0.address 10.67.254.132/24' $ vmtoolsd --cmd 'info-get guestinfo.interface.1.ip.0.address' 10.67.254.132/24

$ cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core) $ uname -r 3.10.0-862.9.1.el7.x86_64 $ rpm -q open-vm-tools open-vm-tools-10.1.10-3.el7_5.1.x86_64 `

ravindravmw commented 6 years ago

These variables are called GuestVariables. GuestVariables were designed that way since long time, probably, security was not much of a concern then? :)

As GuestVariables allowed non-privileged access from beginning and also there could be applications in the guest that require non-privileged access to these varilables, we have not defaulted these to have privileged access intentionally to avoid breaking existing consumers. However, if you are on vSphere 6.0 or later, you can configure your VM to enforce privileged access to GuestVariables. Please note that doing so may break any applications that are running as non-root user and depend on GuestVariables. So, please make sure to do you own research about what applications are running in the guest and how are they using GueatVariables.

You could add following 2 lines to VM's vmx file to make "info-set" and "info-get" to be accessible to only privileged users in the guest:

guest_rpc.rpci.auth.cmd.info-set = "TRUE" guest_rpc.rpci.auth.cmd.info-get = "TRUE"

NOTE: You could add only the first line above, if you want to enforce privileged access to just "info-set". VM needs to be powered off to make these changes.

Here is an example session of your commands once above 2 settings are in effect in a VM:

[test@localhost ~]$ su Password: [root@localhost test]# id uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 [root@localhost test]# vmtoolsd --cmd 'info-get guestinfo.interface.1.ip.0.address' No value found [root@localhost test]# vmtoolsd --cmd 'info-set guestinfo.interface.1.ip.0.address 10.67.254.232/24'

[root@localhost test]# vmtoolsd --cmd 'info-get guestinfo.interface.1.ip.0.address' 10.67.254.232/24 [root@localhost test]# exit [test@localhost ~]$ id uid=1001(test) gid=1001(test) groups=1001(test) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 [test@localhost ~]$ vmtoolsd --cmd 'info-get guestinfo.interface.1.ip.0.address' Permission denied [test@localhost ~]$ vmtoolsd --cmd 'info-set guestinfo.interface.1.ip.0.address 10.67.254.232/24' Permission denied

sunshaoshuai01 commented 6 years ago

Hi ravindravmw

Thank you for the kind answer.

I'm using vSphere 6.0. I tried to add this setting "guest_rpc.rpci.auth.cmd.info-set = "TRUE"" to the VM by this way.

VM Options - Advanced - Edit Configuration

But I got this error message. I'm not sure why.

An error occurred while communicating with the remote host.

Any advice about this? Which version did you use in your test? Is there detailed document about GuestVariables?

This is my environment.

cat /etc/issue VMware vCenter Server Appliance 6.0.0.30501

esxcli system version get Product: VMware ESXi Version: 6.0.0 Build: Releasebuild-7967664 Update: 3 Patch: 84

Thanks.

ravindravmw commented 6 years ago

Any advice about this?

vSphere 6.0 and later will work for this. Let's first make sure you entered the value correctly. I'm not sure which client did you use, but please make sure to not specify double quotes around the key or the value.

Which version did you use in your test?

I used the latest 6.7. I also verified it with 6.0 the same build as yours. When you get to a 6.0 ESXi host's IP address, along with lots of other link you get following links:

o Download vSphere Client for Windows o Open the VMware Host Client

I clicked the second link and went to "Edit Settings" for the VM. Under "Edit Settings", I navigated through "VM Options" > "Advanced" > "Configuration Parameters" > "Edit Configuration" > "Add parameter". I could add the new key "guest_rpc.rpci.auth.cmd.info-set" (without quotes) and value "TRUE" (without quotes).

FYI, this configuration can be changed for a powered on VM too, but it will not take effect unless VM is powered off/on or suspended/resumed or vMotioned.

Is there detailed document about GuestVariables?

Unfortunately, there is not much up-to-date documentation. But, you can search the internet for "guest variables" or "guestinfo variables" and find some old documents. Please let us know if you still have any questions.

sunshaoshuai01 commented 6 years ago

Hi ravindravmw

Thanks for your clarification. I could set the "Configuration Parameters" by link "Open the VMware Host Client" from the ESXi host's IP page. Also, from VMware vSphere Client or vSphere HTML5 Web Client could set "Configuration Parameters". Only the traditional VMware vSphere Web Client couldn't set it(which I used at first).

I could add the new key "guest_rpc.rpci.auth.cmd.info-set" (without quotes) and value "TRUE" (without quotes). Then powered off/on the VM. Unfortunately, I still can change the value from the VM by the info-set command.

vmtoolsd --cmd 'info-set guestinfo.interface.1.ip.0.address 10.67.254.232/24'

Is there still something else I need to add/set? This is the VMX file I downloaded.

.encoding = "UTF-8"
config.version = "8"
virtualHW.version = "10"
vmci0.present = "TRUE"
floppy0.present = "FALSE"
memSize = "4096"
sched.cpu.units = "mhz"
powerType.suspend = "soft"
tools.upgrade.policy = "upgradeAtPowerCycle"
scsi0.virtualDev = "lsilogic"
scsi0.present = "TRUE"
ide0:0.startConnected = "FALSE"
ide0:0.deviceType = "cdrom-raw"
ide0:0.clientDevice = "TRUE"
ide0:0.fileName = "CD/DVD drive 0"
ide0:0.present = "TRUE"
scsi0:0.deviceType = "scsi-hardDisk"
scsi0:0.fileName = "test-vm-03.vmdk"
sched.scsi0:0.shares = "normal"
scsi0:0.present = "TRUE"
displayName = "test-vm-03"
guestOS = "centos-64"
toolScripts.afterPowerOn = "TRUE"
toolScripts.afterResume = "TRUE"
toolScripts.beforeSuspend = "TRUE"
toolScripts.beforePowerOff = "TRUE"
tools.syncTime = "FALSE"
messageBus.tunnelEnabled = "FALSE"
uuid.bios = "42 2c 8f c6 26 06 44 1f-62 34 24 40 14 5b 66 d2"
vc.uuid = "50 2c 09 68 84 a1 3b 8e-6c 4b 08 8d ba 5e 3b 45"
sched.cpu.min = "0"
sched.cpu.shares = "normal"
sched.mem.min = "0"
sched.mem.minSize = "0"
sched.mem.shares = "normal"
ethernet0.virtualDev = "vmxnet3"
ethernet0.dvs.switchId = "6d fc 2c 50 4e 72 d1 22-37 6f ab 9a 39 a4 a8 d8"
ethernet0.dvs.portId = "13795"
ethernet0.dvs.portgroupId = "dvportgroup-15"
ethernet0.dvs.connectionId = "1883433216"
ethernet0.addressType = "vpx"
ethernet0.generatedAddress = "00:50:56:ac:f7:37"
ethernet0.uptCompatibility = "TRUE"
ethernet0.present = "TRUE"
ethernet1.virtualDev = "vmxnet3"
ethernet1.dvs.switchId = "6d fc 2c 50 4e 72 d1 22-37 6f ab 9a 39 a4 a8 d8"
ethernet1.dvs.portId = "13802"
ethernet1.dvs.portgroupId = "dvportgroup-116"
ethernet1.dvs.connectionId = "1883440600"
ethernet1.addressType = "vpx"
ethernet1.generatedAddress = "00:50:56:ac:aa:7b"
ethernet1.uptCompatibility = "TRUE"
ethernet1.present = "TRUE"
uuid.location = "56 4d d9 94 13 38 0e e4-ed bf 4b 8b 4c c9 68 58"
vmci0.id = "341534418"
cleanShutdown = "TRUE"
sched.cpu.latencySensitivity = "normal"
sched.scsi0:0.throughputCap = "500"
tools.guest.desktop.autolock = "false"
nvram = "test-vm-03.nvram"
pciBridge0.present = "TRUE"
svga.present = "TRUE"
pciBridge4.present = "TRUE"
pciBridge4.virtualDev = "pcieRootPort"
pciBridge4.functions = "8"
pciBridge5.present = "TRUE"
pciBridge5.virtualDev = "pcieRootPort"
pciBridge5.functions = "8"
pciBridge6.present = "TRUE"
pciBridge6.virtualDev = "pcieRootPort"
pciBridge6.functions = "8"
pciBridge7.present = "TRUE"
pciBridge7.virtualDev = "pcieRootPort"
pciBridge7.functions = "8"
hpet0.present = "true"
scsi0.pciSlotNumber = "16"
vmci0.pciSlotNumber = "35"
time.synchronize.continue = "false"
time.synchronize.restore = "false"
time.synchronize.resume.disk = "false"
time.synchronize.resume.host = "false"
time.synchronize.shrink = "false"
time.synchronize.tools.enable = "false"
time.synchronize.tools.startup = "false"
migrate.hostLog = "test-vm-03-42b3b999.hlog"
guestinfo.hostname = "test-vm-03"
guestinfo.interface.0.state = "down"
guestinfo.interface.1.ip.0.address = "10.67.254.232/24"
guestinfo.interface.1.route.0.destination = "0.0.0.0/0"
guestinfo.interface.1.route.0.gateway = "10.67.254.254"
guestinfo.interface.1.state = "up"
mem.hotadd = "true"
vcpu.hotadd = "true"
ethernet0.pciSlotNumber = "160"
ethernet1.pciSlotNumber = "192"
monitor.phys_bits_used = "40"
pciBridge0.pciSlotNumber = "17"
pciBridge4.pciSlotNumber = "21"
pciBridge5.pciSlotNumber = "22"
pciBridge6.pciSlotNumber = "23"
pciBridge7.pciSlotNumber = "24"
replay.supported = "false"
sched.swap.derivedName = "/vmfs/volumes/5b67e551-f6b94192-ab61-246e96a836f8/test-vm-03/test-vm-03-7533723b.vswp"
softPowerOff = "FALSE"
virtualHW.productCompatibility = "hosted"
vmotion.checkpointFBSize = "4194304"
guest_rpc.rpci.auth.cmd.info-set = "TRUE"
replay.filename = ""
scsi0:0.redo = ""
config.readOnly = "FALSE"

Thanks

ravindravmw commented 6 years ago

I deployed same ESXi build 7967664 as yours and I could not reproduce the behavior you are seeing. I tried adding guest_rpc.rpci.auth.cmd.info-set = "TRUE" for a powered on VM, followed by powering it off and on. I also tried add guest_rpc.rpci.auth.cmd.info-set = "TRUE" for the powered off VM, followed by powering it on. In both cases I could see "Permission denied" error:

$ id uid=500(test) gid=500(test) groups=500(test) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 $ vmtoolsd --cmd 'info-get guestinfo.interface.1.ip.0.address' No value found $ vmtoolsd --cmd 'info-set guestinfo.interface.1.ip.0.address 10.67.254.232' Permission denied $ vmtoolsd --cmd 'info-get guestinfo.interface.1.ip.0.address' No value found

Could you please confirm following?

  1. Did you shutdown the guest and power on the VM or just rebooted the guest?
  2. The effective uid of the user you are running commad as? Probably, output of "id" command would do.
  3. Run your "vmtoolsd" command under "strace" and collect/share the output.
sunshaoshuai01 commented 6 years ago

Hi ravindravmw

Thank you so much for answering my questions patiently. I forgot change to a non-root user when did the check. I'm really sorry for my stupid mistake.

Add these settings definitely solved my problems.

guest_rpc.rpci.auth.cmd.info-set = TRUE
guest_rpc.rpci.auth.cmd.info-get = TRUE

Thanks again!

jirutka commented 4 years ago

You could add following 2 lines to VM's vmx file to make "info-set" and "info-get" to be accessible to only privileged users in the guest:

guest_rpc.rpci.auth.cmd.info-set = "TRUE" guest_rpc.rpci.auth.cmd.info-get = "TRUE"

This doesn’t work for me; when I enable the first one, not even root can set any variable. How does open-vm-tools identify “privileged users”?

My environment:

ravindravmw commented 3 years ago

Sorry to miss this earlier.

when I enable the first one, not even root can set any variable.

What error do you get for root? Could you please run "id" command and verify the effective user id?

How does open-vm-tools identify “privileged users”?

The verification is based on the usage of privileged port (< 1024) which is not allowed by the guest for non-privileged users.

akutz commented 3 months ago

@ravindravmw ,

The verification is based on the usage of privileged port (< 1024) which is not allowed by the guest for non-privileged users.

What about on Linux when CAP_NET_BIND_SERVICE is granted and a process started by a non-privileged can bind to a port <1024?