On Fri, May 14, 2021 at 9:36 PM Daniel P. Berrangé <berra...@redhat.com>
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é <berra...@redhat.com>
> ---
>  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 ``joeblo...@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

Reply via email to