| .. _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", |
| "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", |
| "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", |
| "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 an example using SASL and authorization for the VNC server would look |
| 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 |