On Fri, May 14, 2021 at 9:36 PM Daniel P. Berrangé wrote: > The authorization framework provides a way to control access to network > services after a client has been authenticated. This documents how to > actually use it. > > Signed-off-by: Daniel P. Berrangé > --- > docs/system/authz.rst | 263 ++++++++++++++++++++++++++++++++++++++++++ > docs/system/index.rst | 1 + > 2 files changed, 264 insertions(+) > create mode 100644 docs/system/authz.rst > > diff --git a/docs/system/authz.rst b/docs/system/authz.rst > new file mode 100644 > index 0000000000..2276546d23 > --- /dev/null > +++ b/docs/system/authz.rst > @@ -0,0 +1,263 @@ > +.. _client authorization: > + > +Client authorization > +-------------------- > + > +When configuring a QEMU network backend with either TLS certificates or > SASL > +authentication, access will be granted if the client successfully proves > +their identity. If the authorization identity database is scoped to the > QEMU > +client this may be sufficient. It is common, however, for the identity > database > +to be much broader and thus authentication alone does not enable > sufficient > +access control. In this case QEMU provides a flexible system for enforcing > +finer grained authorization on clients post-authentication. > + > +Identity providers > +~~~~~~~~~~~~~~~~~~ > + > +At the time of writing there are two authentication frameworks used by > QEMU > +that emit an identity upon completion. > + > + * TLS x509 certificate distinguished name. > + > + When configuring the QEMU backend as a network server with TLS, there > + are a choice of credentials to use. The most common scenario is to > utilize > + x509 certificates. The simplest configuration only involves issuing > + certificates to the servers, allowing the client to avoid a MITM attack > + against their intended server. > + > + It is possible, however, to enable mutual verification by requiring > that > + the client provide a certificate to the server to prove its own > identity. > + This is done by setting the property ``verify-peer=yes`` on the > + ``tls-creds-x509`` object, which is in fact the default. > + > + When peer verification is enabled, client will need to be issued with a > + certificate by the same certificate authority as the server. If this is > + still not sufficiently strong access control the Distinguished Name of > + the certificate can be used as an identity in the QEMU authorization > + framework. > + > + * SASL username. > + > + When configuring the QEMU backend as a network server with SASL, upon > + completion of the SASL authentication mechanism, a username will be > + provided. The format of this username will vary depending on the choice > + of mechanism configured for SASL. It might be a simple UNIX style user > + ``joebloggs``, while if using Kerberos/GSSAPI it can have a realm > + attached ``joebloggs@QEMU.ORG``. Whatever format the username is > presented > + in, it can be used with the QEMU authorization framework. > + > +Authorization drivers > +~~~~~~~~~~~~~~~~~~~~~ > + > +The QEMU authorization framework is a general purpose design with choice > of > +user customizable drivers. These are provided as objects that can be > +created at startup using the ``-object`` argument, or at runtime using the > +``object_add`` monitor command. > + > +Simple > +^^^^^^ > + > +This authorization driver provides a simple mechanism for granting access > +based on an exact match against a single identity. This is useful when it > is > +known that only a single client is to be allowed access. > + > +A possible use case would be when configuring QEMU for an incoming live > +migration. It is known exactly which source QEMU the migration is expected > +to arrive from. The x509 certificate associated with this source QEMU > would > +thus be used as the identity to match against. Alternatively if the > virtual > +machine is dedicated to a specific tenant, then the VNC server would be > +configured with SASL and the username of only that tenant listed. > + > +To create an instance of this driver via QMP: > + > +:: > + > + { > + "execute": "object-add", > + "arguments": { > + "qom-type": "authz-simple", > + "id": "authz0", > + "props": { > + "identity": "fred" > + } > + } > + } > + > + > +Or via the command line > + > +:: > + > + -object authz-simple,id=authz0,identity=fred > + > + > +List > +^^^^ > + > +In some network backends it will be desirable to grant access to a range > of > +clients. This authorization driver provides a list mechanism for granting > +access by matching identities against a list of permitted one. Each match > +rule has an associated policy and a catch all policy applies if no rule > +matches. The match can either be done as an exact string comparison, or > can > +use the shell-like glob syntax, which allows for use of wildcards. > + > +To create an instance of this class via QMP: > + > +:: > + > + { > + "execute": "object-add", > + "arguments": { > + "qom-type": "authz-list", > + "id": "authz0", > + "props": { > + "rules": [ > + { "match": "fred", "policy": "allow", "format": "exact" }, > + { "match": "bob", "policy": "allow", "format": "exact" }, > + { "match": "danb", "policy": "deny", "format": "exact" }, > + { "match": "dan*", "policy": "allow", "format": "glob" } > + ], > + "policy": "deny" > + } > + } > + } > + > + > +Due to the way this driver requires setting nested properties, creating > +it on the command line will require use of the JSON syntax for > ``-object``. > +In most cases, however, the next driver will be more suitable. > + > +List file > +^^^^^^^^^ > + > +This is a variant on the previous driver that allows for a more dynamic > +access control policy by storing the match rules in a standalone file > +that can be reloaded automatically upon change. > + > +To create an instance of this class via QMP: > + > +:: > + > + { > + "execute": "object-add", > + "arguments": { > + "qom-type": "authz-list-file", > + "id": "authz0", > + "props": { > + "filename": "/etc/qemu/myvm-vnc.acl", > + "refresh": true > + } > + } > + } > + > + > +If ``refresh`` is ``yes``, inotify is used to monitor for changes > +to the file and auto-reload the rules. > + > +The ``myvm-vnc.acl`` file should contain the match rules in a format that > +closely matches the previous driver: > + > +:: > + > + { > + "rules": [ > + { "match": "fred", "policy": "allow", "format": "exact" }, > + { "match": "bob", "policy": "allow", "format": "exact" }, > + { "match": "danb", "policy": "deny", "format": "exact" }, > + { "match": "dan*", "policy": "allow", "format": "glob" } > + ], > + "policy": "deny" > + } > + > + > +The object can be created on the command line using > + > +:: > + > + -object authz-list-file,id=authz0,\ > + filename=/etc/qemu/myvm-vnc.acl,refresh=on > + > + > +PAM > +^^^ > + > +In some scenarios it might be desirable to integrate with authorization > +mechanisms that are implemented outside of QEMU. In order to allow maximum > +flexibility, QEMU provides a driver that uses the ``PAM`` framework. > + > +To create an instance of this class via QMP: > + > +:: > + > + { > + "execute": "object-add", > + "arguments": { > + "qom-type": "authz-pam", > + "id": "authz0", > + "parameters": { > + "service": "qemu-vnc-tls" > + } > + } > + } > + > + > +The driver only uses the PAM "account" verification > +subsystem. The above config would require a config > +file /etc/pam.d/qemu-vnc-tls. For a simple file > +lookup it would contain > + > +:: > + > + account requisite pam_listfile.so item=user sense=allow \ > + file=/etc/qemu/vnc.allow > + > + > +The external file would then contain a list of usernames. > +If x509 cert was being used as the username, a suitable > +entry would match the distinguished name: > + > +:: > + > + CN=laptop.berrange.com,O=Berrange Home,L=London,ST=London,C=GB > + > + > +On the command line it can be created using > + > +:: > + > + -object authz-pam,id=authz0,service=qemu-vnc-tls > + > + > +There are a variety of PAM plugins that can be used which are not > illustrated > +here, and it is possible to implement brand new plugins using the PAM API. > + > + > +Connecting backends > +~~~~~~~~~~~~~~~~~~~ > + > +The authorization driver is created using the ``-object`` argument and > then > +needs to be associated with a network service. The authorization driver > object > +will be given a unique ID that needs to be referenced. > + > +The property to set in the network service will vary depending on the > type of > +identity to verify. By convention, any network server backend that uses > TLS > +will provide ``tls-authz`` property, while any server using SASL will > provide > +a ``sasl-authz`` property. > + > +Thus a example using SASL and authorization for the VNC server would look > "an example" +like: > + > +:: > + > + $QEMU --object authz-simple,id=authz0,identity=fred \ > + --vnc 0.0.0.0:1,sasl,sasl-authz=authz0 > + > +While to validate both the x509 certificate and SASL username: > + > +:: > + > + echo "CN=laptop.qemu.org,O=QEMU Project,L=London,ST=London,C=GB" >> > tls.acl > + $QEMU --object authz-simple,id=authz0,identity=fred \ > + --object authz-list-file,id=authz1,filename=tls.acl \ > + --object tls-creds-x509,id=tls0,dir=/etc/qemu/tls,verify-peer=yes > \ > + --vnc 0.0.0.0:1 > ,sasl,sasl-authz=auth0,tls-creds=tls0,tls-authz=authz1 > diff --git a/docs/system/index.rst b/docs/system/index.rst > index 6aa2f8c05c..6092eb2d91 100644 > --- a/docs/system/index.rst > +++ b/docs/system/index.rst > @@ -31,6 +31,7 @@ Contents: > vnc-security > tls > secrets > + authz > gdb > managed-startup > cpu-hotplug > -- > 2.31.1 > > > -- Marc-André Lureau