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

[Contribution] Tasket's Qubes-VM-hardening #2748

Open
andrewdavidwong opened this Issue Apr 16, 2017 · 10 comments

Comments

Projects
None yet
5 participants
@andrewdavidwong
Member

andrewdavidwong commented Apr 16, 2017

This is a tracking ticket for integrating @tasket's Qubes-VM-hardening as a package in Qubes-contrib.

Community-developed feature tracker entry:
https://www.qubes-os.org/qubes-issues/#qubes-vm-hardening

@andrewdavidwong andrewdavidwong added this to the Release 4.0 milestone Apr 16, 2017

andrewdavidwong added a commit that referenced this issue Apr 16, 2017

@tasket

This comment has been minimized.

Show comment
Hide comment
@tasket

tasket Apr 17, 2017

Thanks!

Protecting /home startup scripts helps prevent:

  • malware persistence on VM startup
  • use of shims (like alias sudo or mods to $PATH) to gain root privs

This assumes sudo/root protection like doc/vm-sudo, and also compliments VM kernel hardening.


Discussion:
https://groups.google.com/d/msgid/qubes-users/0eb0a2c6-5a42-19a4-0ebc-718606d1e245%40openmailbox.org

tasket commented Apr 17, 2017

Thanks!

Protecting /home startup scripts helps prevent:

  • malware persistence on VM startup
  • use of shims (like alias sudo or mods to $PATH) to gain root privs

This assumes sudo/root protection like doc/vm-sudo, and also compliments VM kernel hardening.


Discussion:
https://groups.google.com/d/msgid/qubes-users/0eb0a2c6-5a42-19a4-0ebc-718606d1e245%40openmailbox.org

@tasket

This comment has been minimized.

Show comment
Hide comment
@tasket

tasket Apr 17, 2017

Further idea about protecting template-based VM startup in case of priv escalation: De-activation /rw/config, etc. for VMs that don't need it:

https://groups.google.com/d/msgid/qubes-users/11957389-e9f1-3140-863b-87a6a9396d57%40openmailbox.org

https://groups.google.com/d/msgid/qubes-devel/33ef30da-f359-38d6-531c-8a4681e73fa5%40openmailbox.org

tasket commented Apr 17, 2017

Further idea about protecting template-based VM startup in case of priv escalation: De-activation /rw/config, etc. for VMs that don't need it:

https://groups.google.com/d/msgid/qubes-users/11957389-e9f1-3140-863b-87a6a9396d57%40openmailbox.org

https://groups.google.com/d/msgid/qubes-devel/33ef30da-f359-38d6-531c-8a4681e73fa5%40openmailbox.org

@evadogstar

This comment has been minimized.

Show comment
Hide comment
@evadogstar

evadogstar Apr 17, 2017

Before implement this will be good to add on Qubes Manager settings to give users possibility to select some auto start programs (and command lines like "gnome-terminal") to execute on boot and run by dom0 call on AppVM start.

Further idea about protecting template-based VM startup in case of priv escalation: De-activation /rw/config, etc. for VMs that don't need it:

Good idea and will be fine to see this as one click option on new QM

evadogstar commented Apr 17, 2017

Before implement this will be good to add on Qubes Manager settings to give users possibility to select some auto start programs (and command lines like "gnome-terminal") to execute on boot and run by dom0 call on AppVM start.

Further idea about protecting template-based VM startup in case of priv escalation: De-activation /rw/config, etc. for VMs that don't need it:

Good idea and will be fine to see this as one click option on new QM

@tasket

This comment has been minimized.

Show comment
Hide comment
@tasket

tasket Apr 24, 2017

@evadogstar Currently, the user must specify Qubes Service names to control the protection mode. This can be done in Qubes Manager settings dialog.

Its possible that another service ID can be used to make the VM boot with the immutable flags removed (in fact the script already removes them for a brief instant); in that case the user would also have to shut down the VM after making his/her modifications, then remove the 'unprotect' service ID.

tasket commented Apr 24, 2017

@evadogstar Currently, the user must specify Qubes Service names to control the protection mode. This can be done in Qubes Manager settings dialog.

Its possible that another service ID can be used to make the VM boot with the immutable flags removed (in fact the script already removes them for a brief instant); in that case the user would also have to shut down the VM after making his/her modifications, then remove the 'unprotect' service ID.

andrewdavidwong added a commit that referenced this issue Apr 28, 2017

@andrewdavidwong andrewdavidwong changed the title from Integrate Tasket's Qubes-VM-hardening to [Contribution] Tasket's Qubes-VM-hardening Apr 18, 2018

@andrewdavidwong

This comment has been minimized.

Show comment
Hide comment
@andrewdavidwong

andrewdavidwong Apr 18, 2018

Member

Assigning to @marmarek (who may reassign this to someone else) for review according to the package contribution procedure.

Member

andrewdavidwong commented Apr 18, 2018

Assigning to @marmarek (who may reassign this to someone else) for review according to the package contribution procedure.

@marmarek

This comment has been minimized.

Show comment
Hide comment
@marmarek

marmarek Apr 30, 2018

Member

@tasket for this to be included in yum/apt repositories, it needs to have rpm/deb packaging. Let me know if you need any help with this.

Member

marmarek commented Apr 30, 2018

@tasket for this to be included in yum/apt repositories, it needs to have rpm/deb packaging. Let me know if you need any help with this.

@marmarek

This comment has been minimized.

Show comment
Hide comment
@marmarek

marmarek Apr 30, 2018

Member

Also, I've briefly reviewed it as of tasket/Qubes-VM-hardening@7dc8b02. The vm-boot-protect.sh script looks fine. configure-sudo-prompt is quite hacky. On 4.0 the package should simply conflicts with qubes-core-agent-passwordless-root and provide just pam configuration for sudo prompt. On 3.2 unfortunately such hacky solution is needed :( But the script should distinguish those two cases.

Member

marmarek commented Apr 30, 2018

Also, I've briefly reviewed it as of tasket/Qubes-VM-hardening@7dc8b02. The vm-boot-protect.sh script looks fine. configure-sudo-prompt is quite hacky. On 4.0 the package should simply conflicts with qubes-core-agent-passwordless-root and provide just pam configuration for sudo prompt. On 3.2 unfortunately such hacky solution is needed :( But the script should distinguish those two cases.

@t4777sd

This comment has been minimized.

Show comment
Hide comment
@t4777sd

t4777sd Jul 22, 2018

My observations:

Configure-sudo script only works on debian. The default template in qubes is fedora, so only working on debian is a little pointless.

I recommend to change the code that rewrites pam.d to a variant of the following which has the benefits:

  • Works with fedora and debian
  • Does not erase everything in the file. Instead it deletes the "auth" lines and then appends new auth lines.
if [ -f /etc/pam.d/common-auth ]; then
	authFile="/etc/pam.d/common-auth"
fi

authFileBackup="${authFile}.bak"

sudo cp $authFile $authFileBackup
sudo sed -i '/^\s*auth.*/c\' $authFile

echo "" | sudo tee -a $authFile > /dev/null
echo "auth  [success=1 default=ignore]  pam_exec.so seteuid /usr/lib/qubes/qrexec-client-vm dom0 qubes.VMAuth /bin/grep -q ^1$" | sudo tee -a $authFile > /dev/null
echo "auth  requisite  pam_deny.so" | sudo tee -a $authFile > /dev/null
echo "auth  required   pam_permit.so" | sudo tee -a $authFile > /dev/null

t4777sd commented Jul 22, 2018

My observations:

Configure-sudo script only works on debian. The default template in qubes is fedora, so only working on debian is a little pointless.

I recommend to change the code that rewrites pam.d to a variant of the following which has the benefits:

  • Works with fedora and debian
  • Does not erase everything in the file. Instead it deletes the "auth" lines and then appends new auth lines.
if [ -f /etc/pam.d/common-auth ]; then
	authFile="/etc/pam.d/common-auth"
fi

authFileBackup="${authFile}.bak"

sudo cp $authFile $authFileBackup
sudo sed -i '/^\s*auth.*/c\' $authFile

echo "" | sudo tee -a $authFile > /dev/null
echo "auth  [success=1 default=ignore]  pam_exec.so seteuid /usr/lib/qubes/qrexec-client-vm dom0 qubes.VMAuth /bin/grep -q ^1$" | sudo tee -a $authFile > /dev/null
echo "auth  requisite  pam_deny.so" | sudo tee -a $authFile > /dev/null
echo "auth  required   pam_permit.so" | sudo tee -a $authFile > /dev/null
@t4777sd

This comment has been minimized.

Show comment
Hide comment
@t4777sd

t4777sd Jul 22, 2018

Also, I feel like a lot of the VM hardening code is run in the wrong place. It appears that basically all of it is running inside the VM itself. And, as a result, it depends on the VM not being compromised, which is why enabling sudo is so important.

Your solution requires trusting the VM to verify it's own state of health and seems to almost function like the anti-evil maid defense on the boot loader (check summing files, making sure they weren't changed, etc).

Proposal
I think a better way to do this would be run everything outside the VM inside of a management VM (whether dom0 or another and of course the management VM cannot monitor itself so it needs no net access, etc).

When a VM is called to start, then before it starts the disk is attached to the management VM which then analyzes the files for modificatons. If there has been modifications, then a prompt will come up in dom0 (via zenity or whatever) and ask the user if they want to continue with the startup. To me, this seems much more secure and it really is not much more work than what is being done now the only difference is what process monitors the VM (the VM itself or a management script).

This would add a slight increase in startup time for the VM probably as its disk is mounted to the management VM, inspected, unmounted, and finally it boots up as normal. A modified version would be check to the disk on shutdown as that does not interfere with the user experience.

t4777sd commented Jul 22, 2018

Also, I feel like a lot of the VM hardening code is run in the wrong place. It appears that basically all of it is running inside the VM itself. And, as a result, it depends on the VM not being compromised, which is why enabling sudo is so important.

Your solution requires trusting the VM to verify it's own state of health and seems to almost function like the anti-evil maid defense on the boot loader (check summing files, making sure they weren't changed, etc).

Proposal
I think a better way to do this would be run everything outside the VM inside of a management VM (whether dom0 or another and of course the management VM cannot monitor itself so it needs no net access, etc).

When a VM is called to start, then before it starts the disk is attached to the management VM which then analyzes the files for modificatons. If there has been modifications, then a prompt will come up in dom0 (via zenity or whatever) and ask the user if they want to continue with the startup. To me, this seems much more secure and it really is not much more work than what is being done now the only difference is what process monitors the VM (the VM itself or a management script).

This would add a slight increase in startup time for the VM probably as its disk is mounted to the management VM, inspected, unmounted, and finally it boots up as normal. A modified version would be check to the disk on shutdown as that does not interfere with the user experience.

@tasket

This comment has been minimized.

Show comment
Hide comment
@tasket

tasket Jul 23, 2018

Thanks for the code suggestion @t4777sd.

I didn't have the time to also cover fedora back when I posted it, and the configure-sudo-prompt script wasn't terribly satisfying to begin with... as Marek said the approach is 'hacky'. Also for most things I'm not partial to the 'fedora as default' idea... Qubes project wants it replaced and I couldn't agree more. Fedora's biggest sin is withholding repository manifest signatures which (intentionally!) damages its security profile. I think that matters when the goal is OS hardening... choose an OS that hasn't been weakened.

People can still config auth manually or just remove the passwordless package. So that's two options. But ultimately Marek's suggestion will be the way to go: Create new packages to supply the desired auth configs.


The concept for the qubes-boot-protect service is to bolster the guest OS' own defenses by closing some obvious loopholes affecting startup and shell integrity in a relatively simple manner. These issues are mostly endemic to Unix, but Qubes template architecture gives us special leverage in addressing them... It basically gives us two different VM environments for the price of one VM boot event. The first one is, of course, a pristine guest system during initial startup which is untouched by past user sessions; this pristine environment is where the boot-protect code launches and then effects a more controlled transition to the second environment with private storage present at its normally assigned /rw.

I don't know how this could be much less secure than using an additional VM (which could not be dom0, and would have to be rebooted each time the target VM boots). Under normal operation boot-protect performs simple tasks on the private fs like moving, copying, attribute setting and checksumming files. It intentionally doesn't rise to the level of risk that, say, anti-virus scanning does. Also note the simple measure of mounting the private volume isolated from its normal path helps ensure the private volume's files won't affect the boot-protect or other processes. IMHO, what qubes-boot-protect offers is pretty solid compared to what it takes.


As for having a checkpoint dialog during the boot process to provide affirmative feedback to the user, that could be a possible mode. Although I would avoid making it the default since a startup dialog for Qubes VMs seems obtrusive. Qubes RPC might have to be used which means dom0 dialogs would be displayed. Currently, using the -cli suffix on the service name can provide a makeshift checkpoint of sorts (in the service shell: unmount the bind at /rw/home then mount /dev/badxvdb, etc).

BTW, specific features are probably best addressed as issues in the project home Qubes-VM-hardening.

tasket commented Jul 23, 2018

Thanks for the code suggestion @t4777sd.

I didn't have the time to also cover fedora back when I posted it, and the configure-sudo-prompt script wasn't terribly satisfying to begin with... as Marek said the approach is 'hacky'. Also for most things I'm not partial to the 'fedora as default' idea... Qubes project wants it replaced and I couldn't agree more. Fedora's biggest sin is withholding repository manifest signatures which (intentionally!) damages its security profile. I think that matters when the goal is OS hardening... choose an OS that hasn't been weakened.

People can still config auth manually or just remove the passwordless package. So that's two options. But ultimately Marek's suggestion will be the way to go: Create new packages to supply the desired auth configs.


The concept for the qubes-boot-protect service is to bolster the guest OS' own defenses by closing some obvious loopholes affecting startup and shell integrity in a relatively simple manner. These issues are mostly endemic to Unix, but Qubes template architecture gives us special leverage in addressing them... It basically gives us two different VM environments for the price of one VM boot event. The first one is, of course, a pristine guest system during initial startup which is untouched by past user sessions; this pristine environment is where the boot-protect code launches and then effects a more controlled transition to the second environment with private storage present at its normally assigned /rw.

I don't know how this could be much less secure than using an additional VM (which could not be dom0, and would have to be rebooted each time the target VM boots). Under normal operation boot-protect performs simple tasks on the private fs like moving, copying, attribute setting and checksumming files. It intentionally doesn't rise to the level of risk that, say, anti-virus scanning does. Also note the simple measure of mounting the private volume isolated from its normal path helps ensure the private volume's files won't affect the boot-protect or other processes. IMHO, what qubes-boot-protect offers is pretty solid compared to what it takes.


As for having a checkpoint dialog during the boot process to provide affirmative feedback to the user, that could be a possible mode. Although I would avoid making it the default since a startup dialog for Qubes VMs seems obtrusive. Qubes RPC might have to be used which means dom0 dialogs would be displayed. Currently, using the -cli suffix on the service name can provide a makeshift checkpoint of sorts (in the service shell: unmount the bind at /rw/home then mount /dev/badxvdb, etc).

BTW, specific features are probably best addressed as issues in the project home Qubes-VM-hardening.

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