Convert default qrexec policy to the new format

QubesOS/qubes-issues#4370
This commit is contained in:
Marek Marczykowski-Górecki 2020-05-12 05:01:36 +02:00
parent c7d3635972
commit 9cc6050e7c
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724
9 changed files with 192 additions and 96 deletions

View File

@ -170,31 +170,11 @@ ifeq ($(BACKEND_VMM),xen)
# Currently supported only on xen # Currently supported only on xen
cp etc/qmemman.conf $(DESTDIR)/etc/qubes/ cp etc/qmemman.conf $(DESTDIR)/etc/qubes/
endif endif
mkdir -p $(DESTDIR)/etc/qubes-rpc/policy mkdir -p $(DESTDIR)/etc/qubes-rpc
mkdir -p $(DESTDIR)/etc/qubes/policy.d
mkdir -p $(DESTDIR)/usr/libexec/qubes mkdir -p $(DESTDIR)/usr/libexec/qubes
cp qubes-rpc-policy/qubes.FeaturesRequest.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.FeaturesRequest install -m 0644 qubes-rpc-policy/90-default.policy \
cp qubes-rpc-policy/qubes.Filecopy.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.Filecopy $(DESTDIR)/etc/qubes/policy.d/90-default.policy
cp qubes-rpc-policy/qubes.OpenInVM.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.OpenInVM
cp qubes-rpc-policy/qubes.OpenURL.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.OpenURL
cp qubes-rpc-policy/qubes.VMShell.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.VMShell
cp qubes-rpc-policy/qubes.VMRootShell.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.VMRootShell
cp qubes-rpc-policy/qubes.VMExec.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.VMExec
cp qubes-rpc-policy/qubes.VMExecGUI.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.VMExecGUI
cp qubes-rpc-policy/qubes.NotifyUpdates.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.NotifyUpdates
cp qubes-rpc-policy/qubes.NotifyTools.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.NotifyTools
cp qubes-rpc-policy/qubes.GetImageRGBA.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.GetImageRGBA
cp qubes-rpc-policy/qubes.GetRandomizedTime.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.GetRandomizedTime
cp qubes-rpc-policy/qubes.NotifyTools.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.NotifyTools
cp qubes-rpc-policy/qubes.NotifyUpdates.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.NotifyUpdates
cp qubes-rpc-policy/qubes.OpenInVM.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.OpenInVM
cp qubes-rpc-policy/qubes.StartApp.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.StartApp
cp qubes-rpc-policy/qubes.UpdatesProxy.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.UpdatesProxy
cp qubes-rpc-policy/qubes.GetDate.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.GetDate
cp qubes-rpc-policy/qubes.ConnectTCP.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.ConnectTCP
cp qubes-rpc-policy/admin.vm.Console.policy $(DESTDIR)/etc/qubes-rpc/policy/admin.vm.Console
cp qubes-rpc-policy/admin.vm.volume.Import.policy $(DESTDIR)/etc/qubes-rpc/policy/admin.vm.volume.Import
cp qubes-rpc-policy/admin.vm.volume.ImportWithSize.policy $(DESTDIR)/etc/qubes-rpc/policy/admin.vm.volume.ImportWithSize
cp qubes-rpc-policy/policy.RegisterArgument.policy $(DESTDIR)/etc/qubes-rpc/policy/policy.RegisterArgument
cp qubes-rpc/qubes.FeaturesRequest $(DESTDIR)/etc/qubes-rpc/ cp qubes-rpc/qubes.FeaturesRequest $(DESTDIR)/etc/qubes-rpc/
cp qubes-rpc/qubes.GetDate $(DESTDIR)/etc/qubes-rpc/ cp qubes-rpc/qubes.GetDate $(DESTDIR)/etc/qubes-rpc/
cp qubes-rpc/qubes.GetRandomizedTime $(DESTDIR)/etc/qubes-rpc/ cp qubes-rpc/qubes.GetRandomizedTime $(DESTDIR)/etc/qubes-rpc/
@ -214,7 +194,8 @@ endif
ln -s admin.vm.volume.Import $(DESTDIR)/etc/qubes-rpc/admin.vm.volume.ImportWithSize ln -s admin.vm.volume.Import $(DESTDIR)/etc/qubes-rpc/admin.vm.volume.ImportWithSize
install qubes-rpc/admin.vm.Console $(DESTDIR)/etc/qubes-rpc/ install qubes-rpc/admin.vm.Console $(DESTDIR)/etc/qubes-rpc/
PYTHONPATH=.:test-packages qubes-rpc-policy/generate-admin-policy \ PYTHONPATH=.:test-packages qubes-rpc-policy/generate-admin-policy \
--destdir=$(DESTDIR)/etc/qubes-rpc/policy \ --dest=$(DESTDIR)/etc/qubes/policy.d/90-admin-default.policy \
--header=qubes-rpc-policy/90-admin-default.policy.header \
--exclude admin.vm.Create.AdminVM \ --exclude admin.vm.Create.AdminVM \
admin.vm.CreateInPool.AdminVM \ admin.vm.CreateInPool.AdminVM \
admin.vm.device.testclass.Attach \ admin.vm.device.testclass.Attach \
@ -222,16 +203,12 @@ endif
admin.vm.device.testclass.List \ admin.vm.device.testclass.List \
admin.vm.device.testclass.Set.persistent \ admin.vm.device.testclass.Set.persistent \
admin.vm.device.testclass.Available admin.vm.device.testclass.Available
# sanity check install -d $(DESTDIR)/etc/qubes/policy.d/include
for method in $(DESTDIR)/etc/qubes-rpc/policy/admin.*; do \
ls $(DESTDIR)/etc/qubes-rpc/$$(basename $$method) >/dev/null || exit 1; \
done
install -d $(DESTDIR)/etc/qubes-rpc/policy/include
install -m 0644 qubes-rpc-policy/admin-local-ro \ install -m 0644 qubes-rpc-policy/admin-local-ro \
qubes-rpc-policy/admin-local-rwx \ qubes-rpc-policy/admin-local-rwx \
qubes-rpc-policy/admin-global-ro \ qubes-rpc-policy/admin-global-ro \
qubes-rpc-policy/admin-global-rwx \ qubes-rpc-policy/admin-global-rwx \
$(DESTDIR)/etc/qubes-rpc/policy/include/ $(DESTDIR)/etc/qubes/policy.d/include/
mkdir -p "$(DESTDIR)$(FILESDIR)" mkdir -p "$(DESTDIR)$(FILESDIR)"
cp -r templates "$(DESTDIR)$(FILESDIR)/templates" cp -r templates "$(DESTDIR)$(FILESDIR)/templates"

View File

@ -0,0 +1,22 @@
## Do not modify this file, create a new policy file with a lower number in the
## filename instead. For example `30-admin-user.policy`.
###
### Default Admin API qrexec policy
###
## WARNING: most qrexec services here allows a qube to control system
## configuration. It should be allowed only to trusted qubes.
## Remember to add "target=dom0" option to any (allow/ask) entry you create.
## For convenience of maintaining this policy, all services include one of:
## - include/admin-local-rwx (services to modify a specific qube configuration)
## - include/admin-local-ro (services to read a specific qube configuration)
## - include/admin-global-rwx (services to modify global parameters)
## - include/admin-global-ro (services to read global parameters)
!include-service admin.vm.Console * include/admin-local-rwx
!include-service admin.vm.volume.Import * include/admin-local-rwx
!include-service admin.vm.volume.ImportWithSize * include/admin-local-rwx

View File

@ -0,0 +1,127 @@
## Do not modify this file, create a new policy file with a lower number in the
## filename instead. For example `30-user.policy`.
###
### Default qrexec policy
###
## File format:
## service-name|* +argument|* source destination action [options]
## Note that policy parsing stops at the first match.
# policy.RegisterArgument should be allowed only for specific arguments.
policy.RegisterArgument * @anyvm dom0 deny
# WARNING: The qubes.ConnectTCP service is dangerous and allows any
# qube to access any other qube TCP port. It should be restricted
# only to restricted qubes. This is why the default policy is 'deny'
# Example of policy: qubes.ConnectTCP +22 mytcp-client @default allow,target=mytcp-server
qubes.ConnectTCP * @anyvm @anyvm deny
# VM advertise its supported features
qubes.FeaturesRequest * @anyvm dom0 allow
# Windows VM advertise installed Qubes Windows Tools
qubes.NotifyTools * @anyvm dom0 allow
# File copy/move
qubes.Filecopy * @anyvm @anyvm ask
# Get current date/time
qubes.GetDate * @tag:anon-vm @anyvm deny
qubes.GetDate * @anyvm @anyvm allow target=dom0
# Get slightly randomized date/time
qubes.GetRandomizedTime * @anyvm dom0 allow
# Convert image to a safe format, also, allows to get an image (icon) file from a VM
qubes.GetImageRGBA * @anyvm @dispvm allow
qubes.GetImageRGBA * @anyvm @anyvm ask
# Notify about available updates
qubes.NotifyUpdates * @anyvm dom0 allow
# Open a file in a VM
qubes.OpenInVM * @anyvm @dispvm allow
qubes.OpenInVM * @anyvm @anyvm ask
# Open URL in a VM
qubes.OpenURL * @anyvm @dispvm allow
qubes.OpenURL * @anyvm @anyvm ask
# Start application using its menu entry (only applications with menu entries
# are allowed, no arbitrary command). Argument is an application name (in case
# of Linux, basename of .desktop file from /usr/share/applications or similar
# location).
qubes.StartApp * @anyvm @dispvm allow
qubes.StartApp * @anyvm @anyvm ask
# HTTP proxy for downloading updates
# Upgrade all TemplateVMs through sys-whonix.
#qubes.UpdatesProxy * @type:TemplateVM @default allow,target=sys-whonix
# Upgrade Whonix TemplateVMs through sys-whonix.
qubes.UpdatesProxy * @tag:whonix-updatevm @default allow target=sys-whonix
# Deny Whonix TemplateVMs using UpdatesProxy of any other VM.
qubes.UpdatesProxy * @tag:whonix-updatevm @anyvm deny
# Default rule for all TemplateVMs - direct the connection to sys-net
qubes.UpdatesProxy * @type:TemplateVM @default allow target=sys-net
qubes.UpdatesProxy * @anyvm @anyvm deny
# WARNING: The qubes.VMShell service is dangerous and there are really few
# cases when it could be safely used. Especially when policy set to "ask" you
# have no way to know for sure what command(s) will be called. Compromissed
# source VM can substitute the command. Allowing one VM to execute
# qubes.VMShell over the other VM allows the former to TAKE FULL CONTROL over
# the later. In most cases this is not what we want!
#
# Instead we should be using task-specific qrexec services which provide
# assurance as to what program will be responding to the (untrusted) VM
# requests.
#
# It is, however, safe, in most cases, to allow ultimate control of the
# creating AppVM over the DisposableVM it creates as part of the qrexec service
# invocation. That's why by default we have "@anyvm @dispvm allow" rule. Note
# that it does _not_ allow any AppVM to execute qubes.VMShell service over any
# DispVM created in the system -- that would obviously be wrong. It only allows
# qubes.VMShell service access to the AppVM which creates the DispVM as part of
# this very service invocation.
#
# See e.g. this thread for some discussion:
# https://groups.google.com/d/msg/qubes-users/xnAByaL_bjI/3PjYdiTDW-0J
qubes.VMShell * @anyvm @dispvm allow
qubes.VMShell * @anyvm @anyvm deny
# WARNING: qubes.VMRootShell has similar risks as qubes.VMExec
# Add "user=root" option to any ask or allow rules.
qubes.VMRootShell * @anyvm @anyvm deny
# WARNING: The qubes.VMExec service is dangerous and there are really few
# cases when it could be safely used. Contrary to qubes.VMShell, when policy is
# set to "ask", the command to be executed is visible in the confirmation
# prompt. But once allowed, the source VM have full control over the command
# standard input/output. Allowing one VM to execute qubes.VMExec over the
# other VM allows the former to TAKE FULL CONTROL over the later. In most cases
# this is not what we want!
#
# Instead we should be using task-specific qrexec services which provide
# assurance as to what program will be responding to the (untrusted) VM
# requests.
#
# It is, however, safe, in most cases, to allow ultimate control of the
# creating AppVM over the DisposableVM it creates as part of the qrexec service
# invocation. That's why by default we have "@anyvm @dispvm allow" rule. Note
# that it does _not_ allow any AppVM to execute qubes.VMExec service over any
# DispVM created in the system -- that would obviously be wrong. It only allows
# qubes.VMExec service access to the AppVM which creates the DispVM as part of
# this very service invocation.
#
# See e.g. this thread for some discussion:
# https://groups.google.com/d/msg/qubes-users/xnAByaL_bjI/3PjYdiTDW-0J
qubes.VMExec * @anyvm @dispvm allow
qubes.VMExec * @anyvm @anyvm deny
# WARNING: qubes.VMExecGUI has similar risks as qubes.VMExec
qubes.VMExecGUI * @anyvm @dispvm allow
qubes.VMExecGUI * @anyvm @anyvm deny

View File

@ -2,12 +2,12 @@
## _in default configuration_. To allow only specific action, ## _in default configuration_. To allow only specific action,
## edit specific policy file. ## edit specific policy file.
## Note that policy parsing stops at the first match, ## Note that policy parsing stops at the first match.
## Please use a single # to start your custom comments ## Please use a single # to start your custom comments
## Include all already having write access ## Include all already having write access
$include:include/admin-global-rwx !include include/admin-global-rwx
## Add your entries here, make sure to append ",target=dom0" to all allow/ask actions ## Add your entries here, make sure to append "target=dom0" to all allow/ask actions

View File

@ -2,10 +2,9 @@
## _in default configuration_. To allow only specific action, ## _in default configuration_. To allow only specific action,
## edit specific policy file. ## edit specific policy file.
## Note that policy parsing stops at the first match, ## Note that policy parsing stops at the first match.
## so adding anything below "$anyvm $anyvm action" line will have no effect
## Please use a single # to start your custom comments ## Please use a single # to start your custom comments
## Add your entries here, make sure to append ",target=dom0" to all allow/ask actions ## Add your entries here, make sure to append "target=dom0" to all allow/ask actions

View File

@ -2,13 +2,12 @@
## _in default configuration_. To allow only specific action, ## _in default configuration_. To allow only specific action,
## edit specific policy file. ## edit specific policy file.
## Note that policy parsing stops at the first match, ## Note that policy parsing stops at the first match.
## so adding anything below "$anyvm $anyvm action" line will have no effect
## Please use a single # to start your custom comments ## Please use a single # to start your custom comments
## Include all already having write access ## Include all already having write access
$include:include/admin-local-rwx !include include/admin-local-rwx
## Add your entries here, make sure to append ",target=dom0" to all allow/ask actions ## Add your entries here, make sure to append "target=dom0" to all allow/ask actions

View File

@ -2,10 +2,9 @@
## _in default configuration_. To allow only specific action, ## _in default configuration_. To allow only specific action,
## edit specific policy file. ## edit specific policy file.
## Note that policy parsing stops at the first match, ## Note that policy parsing stops at the first match.
## so adding anything below "$anyvm $anyvm action" line will have no effect
## Please use a single # to start your custom comments ## Please use a single # to start your custom comments
## Add your entries here, make sure to append ",target=dom0" to all allow/ask actions ## Add your entries here, make sure to append "target=dom0" to all allow/ask actions

View File

@ -30,9 +30,12 @@ parser = argparse.ArgumentParser(
parser.add_argument('--include-base', action='store', parser.add_argument('--include-base', action='store',
default='include', default='include',
help='Base path for included paths (default: %(default)s)') help='Base path for included paths (default: %(default)s)')
parser.add_argument('--destdir', action='store', parser.add_argument('--dest', action='store',
default='/etc/qubes-rpc/policy', default='/etc/qubes/policy.d/90-admin-default.policy',
help='Directory where write output files to (default: %(default)s)') help='Path where write output file to (default: %(default)s)')
parser.add_argument('--header', action='store',
default='90-admin-default.policy.header',
help='File to prepend to the policy (default: %(default)s)')
parser.add_argument('--verbose', action='store_true', default=False, parser.add_argument('--verbose', action='store_true', default=False,
help='Be verbose') help='Be verbose')
parser.add_argument('--exclude', action='store', nargs='*', parser.add_argument('--exclude', action='store', nargs='*',
@ -40,22 +43,7 @@ parser.add_argument('--exclude', action='store', nargs='*',
parser.add_argument('service', nargs='*', action='store', parser.add_argument('service', nargs='*', action='store',
help='Generate policy for those services (default: all)') help='Generate policy for those services (default: all)')
default_policy_header = '''\ def write_default_policy(args, apiname, clasifiers, f):
## Note that policy parsing stops at the first match.
## Anything not specifically allowed here (or in included file) will be denied.
## Please use a single # to start your custom comments
## Add your entries here, make sure to append ",target=dom0" to all allow/ask actions
## Include a common file for all admin.* methods to ease setting up
## Management VM.
## To allow only specific actions, edit specific policy file, like this one. To
## allow all of them, edit appropriate /etc/qubes-rpc/include/admin-*.
'''
def write_default_policy(args, apiname, clasifiers):
''' Write single default policy for given API call ''' ''' Write single default policy for given API call '''
assert 'scope' in clasifiers, \ assert 'scope' in clasifiers, \
'Method {} lack scope classifier'.format(apiname) 'Method {} lack scope classifier'.format(apiname)
@ -73,9 +61,8 @@ def write_default_policy(args, apiname, clasifiers):
if args.verbose: if args.verbose:
print('Service {}: include {}'.format(apiname, file_to_include), print('Service {}: include {}'.format(apiname, file_to_include),
file=sys.stderr) file=sys.stderr)
with open(os.path.join(args.destdir, apiname), 'w') as f: f.write('!include-service {} * {}\n'.format(
f.write(default_policy_header) apiname,
f.write('$include:{}\n'.format(
os.path.join(args.include_base, file_to_include))) os.path.join(args.include_base, file_to_include)))
@ -83,12 +70,15 @@ def main(args=None):
''' Main function of default-admin-policy tool''' ''' Main function of default-admin-policy tool'''
args = parser.parse_args(args) args = parser.parse_args(args)
with open(os.path.join(args.dest), 'w') as f:
with open(args.header) as header_f:
f.write(header_f.read())
for func, apiname, _ in qubes.api.admin.QubesAdminAPI.list_methods(): for func, apiname, _ in qubes.api.admin.QubesAdminAPI.list_methods():
if args.service and apiname not in args.service: if args.service and apiname not in args.service:
continue continue
if args.exclude and apiname in args.exclude: if args.exclude and apiname in args.exclude:
continue continue
write_default_policy(args, apiname, func.classifiers) write_default_policy(args, apiname, func.classifiers, f)
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -383,29 +383,12 @@ fi
/etc/xen/scripts/block-snapshot /etc/xen/scripts/block-snapshot
/etc/xen/scripts/block-origin /etc/xen/scripts/block-origin
/etc/xen/scripts/vif-route-qubes /etc/xen/scripts/vif-route-qubes
%attr(2775,root,qubes) %dir /etc/qubes-rpc/policy %attr(0664,root,qubes) %config(noreplace) /etc/qubes/policy.d/90-admin-default.policy
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/admin.* %attr(0664,root,qubes) %config(noreplace) /etc/qubes/policy.d/90-default.policy
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/include/admin-local-ro %attr(0664,root,qubes) %config(noreplace) /etc/qubes/policy.d/include/admin-global-ro
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/include/admin-local-rwx %attr(0664,root,qubes) %config(noreplace) /etc/qubes/policy.d/include/admin-global-rwx
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/include/admin-global-ro %attr(0664,root,qubes) %config(noreplace) /etc/qubes/policy.d/include/admin-local-ro
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/include/admin-global-rwx %attr(0664,root,qubes) %config(noreplace) /etc/qubes/policy.d/include/admin-local-rwx
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.ConnectTCP
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.FeaturesRequest
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.Filecopy
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.GetImageRGBA
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.GetRandomizedTime
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.NotifyTools
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.NotifyUpdates
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.OpenInVM
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.OpenURL
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.StartApp
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.VMShell
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.VMRootShell
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.VMExec
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.VMExecGUI
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.UpdatesProxy
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.GetDate
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/policy.RegisterArgument
/etc/qubes-rpc/admin.* /etc/qubes-rpc/admin.*
/etc/qubes-rpc/qubes.FeaturesRequest /etc/qubes-rpc/qubes.FeaturesRequest
/etc/qubes-rpc/qubes.GetDate /etc/qubes-rpc/qubes.GetDate