|
| 1 | +.. _client authorization: |
| 2 | + |
| 3 | +Client authorization |
| 4 | +-------------------- |
| 5 | + |
| 6 | +When configuring a QEMU network backend with either TLS certificates or SASL |
| 7 | +authentication, access will be granted if the client successfully proves |
| 8 | +their identity. If the authorization identity database is scoped to the QEMU |
| 9 | +client this may be sufficient. It is common, however, for the identity database |
| 10 | +to be much broader and thus authentication alone does not enable sufficient |
| 11 | +access control. In this case QEMU provides a flexible system for enforcing |
| 12 | +finer grained authorization on clients post-authentication. |
| 13 | + |
| 14 | +Identity providers |
| 15 | +~~~~~~~~~~~~~~~~~~ |
| 16 | + |
| 17 | +At the time of writing there are two authentication frameworks used by QEMU |
| 18 | +that emit an identity upon completion. |
| 19 | + |
| 20 | + * TLS x509 certificate distinguished name. |
| 21 | + |
| 22 | + When configuring the QEMU backend as a network server with TLS, there |
| 23 | + are a choice of credentials to use. The most common scenario is to utilize |
| 24 | + x509 certificates. The simplest configuration only involves issuing |
| 25 | + certificates to the servers, allowing the client to avoid a MITM attack |
| 26 | + against their intended server. |
| 27 | + |
| 28 | + It is possible, however, to enable mutual verification by requiring that |
| 29 | + the client provide a certificate to the server to prove its own identity. |
| 30 | + This is done by setting the property ``verify-peer=yes`` on the |
| 31 | + ``tls-creds-x509`` object, which is in fact the default. |
| 32 | + |
| 33 | + When peer verification is enabled, client will need to be issued with a |
| 34 | + certificate by the same certificate authority as the server. If this is |
| 35 | + still not sufficiently strong access control the Distinguished Name of |
| 36 | + the certificate can be used as an identity in the QEMU authorization |
| 37 | + framework. |
| 38 | + |
| 39 | + * SASL username. |
| 40 | + |
| 41 | + When configuring the QEMU backend as a network server with SASL, upon |
| 42 | + completion of the SASL authentication mechanism, a username will be |
| 43 | + provided. The format of this username will vary depending on the choice |
| 44 | + of mechanism configured for SASL. It might be a simple UNIX style user |
| 45 | + ``joebloggs``, while if using Kerberos/GSSAPI it can have a realm |
| 46 | + attached `` [email protected]``. Whatever format the username is presented |
| 47 | + in, it can be used with the QEMU authorization framework. |
| 48 | + |
| 49 | +Authorization drivers |
| 50 | +~~~~~~~~~~~~~~~~~~~~~ |
| 51 | + |
| 52 | +The QEMU authorization framework is a general purpose design with choice of |
| 53 | +user customizable drivers. These are provided as objects that can be |
| 54 | +created at startup using the ``-object`` argument, or at runtime using the |
| 55 | +``object_add`` monitor command. |
| 56 | + |
| 57 | +Simple |
| 58 | +^^^^^^ |
| 59 | + |
| 60 | +This authorization driver provides a simple mechanism for granting access |
| 61 | +based on an exact match against a single identity. This is useful when it is |
| 62 | +known that only a single client is to be allowed access. |
| 63 | + |
| 64 | +A possible use case would be when configuring QEMU for an incoming live |
| 65 | +migration. It is known exactly which source QEMU the migration is expected |
| 66 | +to arrive from. The x509 certificate associated with this source QEMU would |
| 67 | +thus be used as the identity to match against. Alternatively if the virtual |
| 68 | +machine is dedicated to a specific tenant, then the VNC server would be |
| 69 | +configured with SASL and the username of only that tenant listed. |
| 70 | + |
| 71 | +To create an instance of this driver via QMP: |
| 72 | + |
| 73 | +:: |
| 74 | + |
| 75 | + { |
| 76 | + "execute": "object-add", |
| 77 | + "arguments": { |
| 78 | + "qom-type": "authz-simple", |
| 79 | + "id": "authz0", |
| 80 | + "props": { |
| 81 | + "identity": "fred" |
| 82 | + } |
| 83 | + } |
| 84 | + } |
| 85 | + |
| 86 | + |
| 87 | +Or via the command line |
| 88 | + |
| 89 | +:: |
| 90 | + |
| 91 | + -object authz-simple,id=authz0,identity=fred |
| 92 | + |
| 93 | + |
| 94 | +List |
| 95 | +^^^^ |
| 96 | + |
| 97 | +In some network backends it will be desirable to grant access to a range of |
| 98 | +clients. This authorization driver provides a list mechanism for granting |
| 99 | +access by matching identities against a list of permitted one. Each match |
| 100 | +rule has an associated policy and a catch all policy applies if no rule |
| 101 | +matches. The match can either be done as an exact string comparison, or can |
| 102 | +use the shell-like glob syntax, which allows for use of wildcards. |
| 103 | + |
| 104 | +To create an instance of this class via QMP: |
| 105 | + |
| 106 | +:: |
| 107 | + |
| 108 | + { |
| 109 | + "execute": "object-add", |
| 110 | + "arguments": { |
| 111 | + "qom-type": "authz-list", |
| 112 | + "id": "authz0", |
| 113 | + "props": { |
| 114 | + "rules": [ |
| 115 | + { "match": "fred", "policy": "allow", "format": "exact" }, |
| 116 | + { "match": "bob", "policy": "allow", "format": "exact" }, |
| 117 | + { "match": "danb", "policy": "deny", "format": "exact" }, |
| 118 | + { "match": "dan*", "policy": "allow", "format": "glob" } |
| 119 | + ], |
| 120 | + "policy": "deny" |
| 121 | + } |
| 122 | + } |
| 123 | + } |
| 124 | + |
| 125 | + |
| 126 | +Due to the way this driver requires setting nested properties, creating |
| 127 | +it on the command line will require use of the JSON syntax for ``-object``. |
| 128 | +In most cases, however, the next driver will be more suitable. |
| 129 | + |
| 130 | +List file |
| 131 | +^^^^^^^^^ |
| 132 | + |
| 133 | +This is a variant on the previous driver that allows for a more dynamic |
| 134 | +access control policy by storing the match rules in a standalone file |
| 135 | +that can be reloaded automatically upon change. |
| 136 | + |
| 137 | +To create an instance of this class via QMP: |
| 138 | + |
| 139 | +:: |
| 140 | + |
| 141 | + { |
| 142 | + "execute": "object-add", |
| 143 | + "arguments": { |
| 144 | + "qom-type": "authz-list-file", |
| 145 | + "id": "authz0", |
| 146 | + "props": { |
| 147 | + "filename": "/etc/qemu/myvm-vnc.acl", |
| 148 | + "refresh": true |
| 149 | + } |
| 150 | + } |
| 151 | + } |
| 152 | + |
| 153 | + |
| 154 | +If ``refresh`` is ``yes``, inotify is used to monitor for changes |
| 155 | +to the file and auto-reload the rules. |
| 156 | + |
| 157 | +The ``myvm-vnc.acl`` file should contain the match rules in a format that |
| 158 | +closely matches the previous driver: |
| 159 | + |
| 160 | +:: |
| 161 | + |
| 162 | + { |
| 163 | + "rules": [ |
| 164 | + { "match": "fred", "policy": "allow", "format": "exact" }, |
| 165 | + { "match": "bob", "policy": "allow", "format": "exact" }, |
| 166 | + { "match": "danb", "policy": "deny", "format": "exact" }, |
| 167 | + { "match": "dan*", "policy": "allow", "format": "glob" } |
| 168 | + ], |
| 169 | + "policy": "deny" |
| 170 | + } |
| 171 | + |
| 172 | + |
| 173 | +The object can be created on the command line using |
| 174 | + |
| 175 | +:: |
| 176 | + |
| 177 | + -object authz-list-file,id=authz0,\ |
| 178 | + filename=/etc/qemu/myvm-vnc.acl,refresh=on |
| 179 | + |
| 180 | + |
| 181 | +PAM |
| 182 | +^^^ |
| 183 | + |
| 184 | +In some scenarios it might be desirable to integrate with authorization |
| 185 | +mechanisms that are implemented outside of QEMU. In order to allow maximum |
| 186 | +flexibility, QEMU provides a driver that uses the ``PAM`` framework. |
| 187 | + |
| 188 | +To create an instance of this class via QMP: |
| 189 | + |
| 190 | +:: |
| 191 | + |
| 192 | + { |
| 193 | + "execute": "object-add", |
| 194 | + "arguments": { |
| 195 | + "qom-type": "authz-pam", |
| 196 | + "id": "authz0", |
| 197 | + "parameters": { |
| 198 | + "service": "qemu-vnc-tls" |
| 199 | + } |
| 200 | + } |
| 201 | + } |
| 202 | + |
| 203 | + |
| 204 | +The driver only uses the PAM "account" verification |
| 205 | +subsystem. The above config would require a config |
| 206 | +file /etc/pam.d/qemu-vnc-tls. For a simple file |
| 207 | +lookup it would contain |
| 208 | + |
| 209 | +:: |
| 210 | + |
| 211 | + account requisite pam_listfile.so item=user sense=allow \ |
| 212 | + file=/etc/qemu/vnc.allow |
| 213 | + |
| 214 | + |
| 215 | +The external file would then contain a list of usernames. |
| 216 | +If x509 cert was being used as the username, a suitable |
| 217 | +entry would match the distinguished name: |
| 218 | + |
| 219 | +:: |
| 220 | + |
| 221 | + CN=laptop.berrange.com,O=Berrange Home,L=London,ST=London,C=GB |
| 222 | + |
| 223 | + |
| 224 | +On the command line it can be created using |
| 225 | + |
| 226 | +:: |
| 227 | + |
| 228 | + -object authz-pam,id=authz0,service=qemu-vnc-tls |
| 229 | + |
| 230 | + |
| 231 | +There are a variety of PAM plugins that can be used which are not illustrated |
| 232 | +here, and it is possible to implement brand new plugins using the PAM API. |
| 233 | + |
| 234 | + |
| 235 | +Connecting backends |
| 236 | +~~~~~~~~~~~~~~~~~~~ |
| 237 | + |
| 238 | +The authorization driver is created using the ``-object`` argument and then |
| 239 | +needs to be associated with a network service. The authorization driver object |
| 240 | +will be given a unique ID that needs to be referenced. |
| 241 | + |
| 242 | +The property to set in the network service will vary depending on the type of |
| 243 | +identity to verify. By convention, any network server backend that uses TLS |
| 244 | +will provide ``tls-authz`` property, while any server using SASL will provide |
| 245 | +a ``sasl-authz`` property. |
| 246 | + |
| 247 | +Thus an example using SASL and authorization for the VNC server would look |
| 248 | +like: |
| 249 | + |
| 250 | +:: |
| 251 | + |
| 252 | + $QEMU --object authz-simple,id=authz0,identity=fred \ |
| 253 | + --vnc 0.0.0.0:1,sasl,sasl-authz=authz0 |
| 254 | + |
| 255 | +While to validate both the x509 certificate and SASL username: |
| 256 | + |
| 257 | +:: |
| 258 | + |
| 259 | + echo "CN=laptop.qemu.org,O=QEMU Project,L=London,ST=London,C=GB" >> tls.acl |
| 260 | + $QEMU --object authz-simple,id=authz0,identity=fred \ |
| 261 | + --object authz-list-file,id=authz1,filename=tls.acl \ |
| 262 | + --object tls-creds-x509,id=tls0,dir=/etc/qemu/tls,verify-peer=yes \ |
| 263 | + --vnc 0.0.0.0:1,sasl,sasl-authz=auth0,tls-creds=tls0,tls-authz=authz1 |
0 commit comments