On Thu, Mar 04, 2021 at 06:10:12PM +0000, Daniel P. Berrangé wrote: > Signed-off-by: Daniel P. Berrangé <berrange@xxxxxxxxxx> > --- > docs/auth.html.in | 368 ---------------------------------------------- > docs/auth.rst | 350 +++++++++++++++++++++++++++++++++++++++++++ > docs/meson.build | 2 +- > 3 files changed, 351 insertions(+), 369 deletions(-) > delete mode 100644 docs/auth.html.in > create mode 100644 docs/auth.rst > > diff --git a/docs/auth.html.in b/docs/auth.html.in > deleted file mode 100644 > index 9b940a8598..0000000000 > --- a/docs/auth.html.in > +++ /dev/null > @@ -1,368 +0,0 @@ > -<?xml version="1.0" encoding="UTF-8"?> > -<!DOCTYPE html> > -<html xmlns="http://www.w3.org/1999/xhtml"> > - <body> > - <h1>Connection authentication</h1> > - <p> > - When connecting to libvirt, some connections may require client > - authentication before allowing use of the APIs. The set of possible > - authentication mechanisms is administrator controlled, independent > - of applications using libvirt. Once authenticated, libvirt can apply > - fine grained <a href="acl.html">access control</a> to the operations > - performed by a client. > - </p> > - > - <ul id="toc"></ul> > - > - <h2><a id="Auth_client_config">Client configuration</a></h2> > - > - <p> > - When connecting to a remote hypervisor which requires authentication, > -most libvirt applications will prompt the user for the credentials. It is > -also possible to provide a client configuration file containing all the > -authentication credentials, avoiding any interaction. Libvirt will look > -for the authentication file using the following sequence: > - </p> > - <ol> > - <li>The file path specified by the $LIBVIRT_AUTH_FILE environment > - variable.</li> > - <li>The file path specified by the "authfile=/some/file" URI > - query parameter</li> > - <li>The file $XDG_CONFIG_HOME/libvirt/auth.conf</li> > - <li>The file /etc/libvirt/auth.conf</li> > - </ol> > - > - <p> > - The auth configuration file uses the traditional <code>".ini"</code> > - style syntax. There are two types of groups that can be present in > - the config. First there are one or more <strong>credential</strong> > - sets, which provide the actual authentication credentials. The keys > - within the group may be: > - </p> > - > - <ul> > - <li><code>username</code>: the user login name to act as. This > - is relevant for ESX, Xen, HyperV and SSH, but probably not > - the one you want to libvirtd with SASL.</li> > - <li><code>authname</code>: the name to authorize as. This is > - what is commonly required for libvirtd with SASL.</li> > - <li><code>password</code>: the secret password</li> > - <li><code>realm</code>: the domain realm for SASL, mostly > - unused</li> > - </ul> > - > - <p> > - Each set of credentials has a name, which is part of the group > - entry name. Overall the syntax is > - </p> > - > - <pre> > -[credentials-$NAME] > -credname1=value1 > -credname2=value2</pre> > - > - <p> > - For example, to define two sets of credentials used for production > - and test machines, using libvirtd, and a further ESX server for dev: > - </p> > -<pre> > -[credentials-test] > -authname=fred > -password=123456 > - > -[credentials-prod] > -authname=bar > -password=letmein > - > -[credentials-dev] > -username=joe > -password=hello > - > -[credentials-defgrp] > -username=defuser > -password=defpw</pre> > - > - <p> > - The second set of groups provide mappings of credentials to > - specific machine services. The config file group names compromise > - the service type and host: > - </p> > - > - <pre> > -[auth-$SERVICE-$HOSTNAME] > -credentials=$CREDENTIALS</pre> > - > - <p> > - For example, following the previous example, here is how to > - map some machines. For convenience libvirt supports a default > - mapping of credentials to machines: > - </p> > - > - <pre> > -[auth-libvirt-test1.example.com] > -credentials=test > - > -[auth-libvirt-test2.example.com] > -credentials=test > - > -[auth-libvirt-demo3.example.com] > -credentials=test > - > -[auth-libvirt-prod1.example.com] > -credentials=prod > - > -[auth-libvirt-default] > -credentials=defgrp > - > -[auth-esx-dev1.example.com] > -credentials=dev > - > -[auth-esx-default] > -credentials=defgrp</pre> > - > - > - <p> > - The following service types are known to libvirt: > - </p> > - > - <ul> > - <li><code>esx</code> - used for connections to an ESX or > - VirtualCenter server</li> > - <li><code>hyperv</code> - used for connections to an HyperV > - server</li> > - <li><code>libvirt</code> - used for connections to a libvirtd > - server, which is configured with SASL auth</li> > - <li><code>ssh</code> - used for connections to a remote QEMU driver > - over SSH</li> > - </ul> > - > - <p> > - Applications using libvirt are free to use this same configuration > - file for storing other credentials. For example, it can be used > - to storage VNC or SPICE login credentials > - </p> > - > - <h2><a id="ACL_server_config">Server configuration</a></h2> > - <p> > -The libvirt daemon allows the administrator to choose the authentication > -mechanisms used for client connections on each network socket independently. > -This is primarily controlled via the libvirt daemon master config file in > -<code>/etc/libvirt/libvirtd.conf</code>. Each of the libvirt sockets can > -have its authentication mechanism configured independently. There is > -currently a choice of <code>none</code>, <code>polkit</code>, and <code>sasl</code>. > -The SASL scheme can be further configured to choose between a large > -number of different mechanisms. > -</p> > - <h2><a id="ACL_server_unix_perms">UNIX socket permissions/group</a></h2> > - <p> > -If libvirt does not contain support for PolicyKit, then access control for > -the UNIX domain socket is done using traditional file user/group ownership > -and permissions. There are 2 sockets, one for full read-write access, the > -other for read-only access. The RW socket will be restricted (mode 0700) to > -only allow the <code>root</code> user to connect. The read-only socket will > -be open access (mode 0777) to allow any user to connect. > -</p> > - <p> > -To allow non-root users greater access, the <code>libvirtd.conf</code> file > -can be edited to change the permissions via the <code>unix_sock_rw_perms</code>, > -config parameter and to set a user group via the <code>unix_sock_group</code> > -parameter. For example, setting the former to mode <code>0770</code> and the > -latter <code>wheel</code> would let any user in the wheel group connect to > -the libvirt daemon. > -</p> > - <h2><a id="ACL_server_polkit">UNIX socket PolicyKit auth</a></h2> > - <p> > -If libvirt contains support for PolicyKit, then access control options are > -more advanced. The <code>auth_unix_rw</code> parameter will default to > -<code>polkit</code>, and the file permissions will default to <code>0777</code> > -even on the RW socket. Upon connecting to the socket, the client application > -will be required to identify itself with PolicyKit. The default policy for the > -RW daemon socket will require any application running in the current desktop > -session to authenticate using the user's password. This is akin to <code>sudo</code> > -auth, but does not require that the client application ultimately run as root. > -Default policy will still allow any application to connect to the RO socket. > -</p> > - <p> > -The default policy can be overridden by creating a new policy file in the > -<code>/etc/polkit-1/rules.d</code> directory. Information on the options > -available can be found by reading the <code>polkit(8)</code> man page. The > -two libvirt actions are named <code>org.libvirt.unix.manage</code> for full > -management access, and <code>org.libvirt.unix.monitor</code> for read-only > -access. > -</p> > - <p> > -As an example, creating <code>/etc/polkit-1/rules.d/80-libvirt-manage.rules</code> > -with the following gives the user <code>fred</code> full management access > -when accessing from an active local session: > - </p> > -<pre>polkit.addRule(function(action, subject) { > - if (action.id == "org.libvirt.unix.manage" && > - subject.local && subject.active && subject.user == "fred") { > - return polkit.Result.YES; > - } > -});</pre> > - <p> > -Older versions of PolicyKit used policy files ending with .pkla in the > -local override directory <code>/etc/polkit-1/localauthority/50-local.d/</code>. > -Compatibility with this older format is provided by <a > -href="https://pagure.io/polkit-pkla-compat">polkit-pkla-compat</a>. As an > -example, this gives the user <code>fred</code> full management access: > - </p> > -<pre>[Allow fred libvirt management permissions] > -Identity=unix-user:fred > -Action=org.libvirt.unix.manage > -ResultAny=yes > -ResultInactive=yes > -ResultActive=yes</pre> > - <h2><a id="ACL_server_sasl">SASL pluggable authentication</a></h2> > - > - <p> > -Libvirt integrates with the cyrus-sasl library to provide a pluggable authentication > -system using the SASL protocol. SASL can be used in combination with libvirtd's TLS > -or TCP socket listeners. When used with the TCP listener, the SASL mechanism is > -rqeuired to provide session encryption in addition to authentication. Only a very > -few SASL mechanisms are able to do this, and of those that can do it, only the > -GSSAPI plugin is considered acceptably secure by modern standards: > - </p> > - > - <dl> > - <dt>GSSAPI</dt> > - <dd><strong>This is the current default mechanism to use with libvirtd</strong>. > - It uses the Kerberos v5 authentication protocol underneath, and assuming > - the Kerberos client/server are configured with modern ciphers (AES), > - it provides strong session encryption capabilities.</dd> > - > - <dt>DIGEST-MD5</dt> > - <dd>This was previously set as the default mechanism to use with libvirtd. > - It provides a simple username/password based authentication mechanism > - that includes session encryption. > - <a href="https://tools.ietf.org/html/rfc6331">RFC 6331</a>, however, > - documents a number of serious security flaws with DIGEST-MD5 and as a > - result marks it as <code>OBSOLETE</code>. Specific concerns are that > - it is vulnerable to MITM attacks and the MD5 hash can be brute-forced > - to reveal the password. A replacement is provided via the SCRAM mechanism, > - however, note that this does not provide encryption, so the SCRAM > - mechanism can only be used on the libvirtd TLS listener. > - </dd> > - > - <dt>PASSDSS-3DES-1</dt> > - <dd>This provides a simple username/password based authentication > - mechanism that includes session encryption. The current cyrus-sasl > - implementation does not provide a way to validate the server's > - public key identity, thus it is susceptible to a MITM attacker > - impersonating the server. It is also not enabled in many OS > - distros when building SASL libraries.</dd> > - > - <dt>KERBEROS_V4</dt> > - <dd>This uses the obsolete Kerberos v4 protocol to provide both authentication > - and session encryption. Kerberos v4 protocol has been obsolete since the > - early 1990's and has known security vulnerabilities so this will never be > - used in practice.</dd> > - </dl> > - > - <p> > - Other SASL mechanisms, not listed above, can only be used when the libvirtd > - TLS or UNIX socket listeners. > - </p> > - > - <h3><a id="ACL_server_username">Username/password auth</a></h3> > - <p> > -As noted above, the DIGEST-MD5 mechanism is considered obsolete and should > -not be used anymore. To provide a simple username/password auth scheme on > -the libvirt UNIX socket or TLS listeners, however, it is possible to use > -the SCRAM mechanism. The <code>auth_unix_ro</code>, <code>auth_unix_rw</code>, > -<code>auth_tls</code> config params in <code>libvirt.conf</code> can be used > -to turn on SASL auth in these listeners. > - </p> > - <p> > -Since the libvirt SASL config file defaults to using GSSAPI (Kerberos), a > -config change is required to enable plain password auth. This is done by > -editing <code>/etc/sasl2/libvirt.conf</code> to set the <code>mech_list</code> > -parameter to <code>scram-sha-1</code>. > - </p> > - <p> > -Out of the box, no user accounts are defined, so no clients will be able to authenticate > -on the TCP socket. Adding users and setting their passwords is done with the <code>saslpasswd2</code> > -command. When running this command it is important to tell it that the appname is <code>libvirt</code>. > -As an example, to add a user <code>fred</code>, run > -</p> > - <pre> > -# saslpasswd2 -a libvirt fred > -Password: xxxxxx > -Again (for verification): xxxxxx > -</pre> > - <p> > -To see a list of all accounts the <code>sasldblistusers2</code> command can be used. > -This command expects to be given the path to the libvirt user database, which is kept > -in <code>/etc/libvirt/passwd.db</code> > -</p> > - <pre> > -# sasldblistusers2 -f /etc/libvirt/passwd.db > -fred@xxxxxxxxxxxxxxxxxxxxxxxxx: userPassword > -</pre> > - <p> > -Finally, to disable a user's access, the <code>saslpasswd2</code> command can be used > -again: > -</p> > - <pre> > -# saslpasswd2 -a libvirt -d fred > -</pre> > - <h3><a id="ACL_server_kerberos">GSSAPI/Kerberos auth</a></h3> > - <p> > -The plain TCP listener of the libvirt daemon defaults to using SASL for authentication. > -The libvirt SASL config also defaults to GSSAPI, so there is no need to edit the > -SASL config when using GSSAPI. If the libvirtd TLS or UNIX listeners are used, > -then the Kerberos session encryption will be disabled since it is not required > -in these scenarios - only the plain TCP listener needs encryption > -</p> > - <p> > -Some operating systems do not install the SASL kerberos plugin by default. It > -may be necessary to install a sub-package such as <code>cyrus-sasl-gssapi</code>. > -To check whether the Kerberos plugin is installed run the <code>pluginviewer</code> > -program and verify that <code>gssapi</code> is listed, e.g.: > -</p> > - <pre> > -# pluginviewer > -...snip... > -Plugin "gssapiv2" [loaded], API version: 4 > - SASL mechanism: GSSAPI, best SSF: 56 > - security flags: NO_ANONYMOUS|NO_PLAINTEXT|NO_ACTIVE|PASS_CREDENTIALS|MUTUAL_AUTH > - features: WANT_CLIENT_FIRST|PROXY_AUTHENTICATION|NEED_SERVER_FQDN > -</pre> > - <p> > -Next it is necessary for the administrator of the Kerberos realm to > -issue a principal for the libvirt server. There needs to be one > -principal per host running the libvirt daemon. The principal should be > -named <code>libvirt/full.hostname@KERBEROS.REALM</code>. This is > -typically done by running the <code>kadmin.local</code> command on the > -Kerberos server, though some Kerberos servers have alternate ways of > -setting up service principals. Once created, the principal should be > -exported to a keytab, copied to the host running the libvirt daemon > -and placed in <code>/etc/libvirt/krb5.tab</code> > -</p> > - <pre> > -# kadmin.local > -kadmin.local: add_principal libvirt/foo.example.com > -Enter password for principal "libvirt/foo.example.com@xxxxxxxxxxx": > -Re-enter password for principal "libvirt/foo.example.com@xxxxxxxxxxx": > -Principal "libvirt/foo.example.com@xxxxxxxxxxx" created. > - > -kadmin.local: ktadd -k /root/libvirt-foo-example.tab libvirt/foo.example.com@xxxxxxxxxxx > -Entry for principal libvirt/foo.example.com@xxxxxxxxxxx with kvno 4, encryption type Triple DES cbc mode with HMAC/sha1 added to keytab WRFILE:/root/libvirt-foo-example.tab. > -Entry for principal libvirt/foo.example.com@xxxxxxxxxxx with kvno 4, encryption type ArcFour with HMAC/md5 added to keytab WRFILE:/root/libvirt-foo-example.tab. > -Entry for principal libvirt/foo.example.com@xxxxxxxxxxx with kvno 4, encryption type DES with HMAC/sha1 added to keytab WRFILE:/root/libvirt-foo-example.tab. > -Entry for principal libvirt/foo.example.com@xxxxxxxxxxx with kvno 4, encryption type DES cbc mode with RSA-MD5 added to keytab WRFILE:/root/libvirt-foo-example.tab. > - > -kadmin.local: quit > - > -# scp /root/libvirt-foo-example.tab root@xxxxxxxxxxxxxxx:/etc/libvirt/krb5.tab > -# rm /root/libvirt-foo-example.tab > -</pre> > - <p> > -Any client application wishing to connect to a Kerberos enabled libvirt server > -merely needs to run <code>kinit</code> to gain a user principal. This may well > -be done automatically when a user logs into a desktop session, if PAM is set up > -to authenticate against Kerberos. > -</p> > - </body> > -</html> > diff --git a/docs/auth.rst b/docs/auth.rst > new file mode 100644 > index 0000000000..506e6b5c13 > --- /dev/null > +++ b/docs/auth.rst > @@ -0,0 +1,350 @@ > +========================= > +Connection authentication > +========================= > + > +.. contents:: > + > +When connecting to libvirt, some connections may require client > +authentication before allowing use of the APIs. The set of possible > +authentication mechanisms is administrator controlled, independent > +of applications using libvirt. Once authenticated, libvirt can apply > +fine grained `access control <acl.html>`_ to the operations > +performed by a client. > + > +Client configuration > +==================== > + > +When connecting to a remote hypervisor which requires authentication, > +most libvirt applications will prompt the user for the credentials. It is > +also possible to provide a client configuration file containing all the > +authentication credentials, avoiding any interaction. Libvirt will look > +for the authentication file using the following sequence: > + > +* The file path specified by the ``$LIBVIRT_AUTH_FILE`` environment > + variable. > +* The file path specified by the ``authfile=/some/file`` URI > + query parameter > +* The file ``$XDG_CONFIG_HOME/libvirt/auth.conf`` > +* The file ``/etc/libvirt/auth.conf`` > + > +The auth configuration file uses the traditional ``.ini`` > +style syntax. There are two types of groups that can be present in > +the config. First there are one or more ``credential`` > +sets, which provide the actual authentication credentials. The keys > +within the group may be: > + > +* ``username``: the user login name to act as. This > + is relevant for ESX, Xen, HyperV and SSH, but probably not > + the one you want to libvirtd with SASL. s/want to/want for ... > +For example, to define two sets of credentials used for production > +and test machines, using libvirtd, and a further ESX server for dev: s/dev/development/ ... > + polkit.addRule(function(action, subject) { > + if (action.id == "org.libvirt.unix.manage" && > + subject.local && subject.active &&; subject.user == "fred") { s/amp;//g s/; subject/ subject/ ... > + > +As noted above, the DIGEST-MD5 mechanism is considered obsolete and should > +not be used anymore. To provide a simple username/password auth scheme on > +the libvirt UNIX socket or TLS listeners, however, it is possible to use > +the SCRAM mechanism. The ``auth_unix_ro``, ``auth_unix_rw``, > +``auth_tls`` config params in ``libvirt.conf`` can be used s/libvirt.conf/libvirtd.conf/ All of the nits are pre-existing...please fix them in a trivial patch before pushing. Reviewed-by: Erik Skultety <eskultet@xxxxxxxxxx>