Access control
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.
- Server configuration
- UNIX socket permissions/group
- UNIX socket PolicyKit auth
- Username/password auth
- Kerberos auth
Server configuration
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
/etc/libvirt/libvirtd.conf
. Each of the libvirt sockets can
have its authentication mechanism configured independently. There is
currently a choice of none
, polkit
, and sasl
.
The SASL scheme can be further configured to choose between a large
number of different mechanisms.
UNIX socket permissions/group
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 root
user to connect. The read-only socket will
be open access (mode 0777) to allow any user to connect.
To allow non-root users greater access, the libvirtd.conf
file
can be edited to change the permissions via the unix_sock_rw_perms
,
config parameter and to set a user group via the unix_sock_group
parameter. For example, setting the former to mode 0770
and the
latter wheel
would let any user in the wheel group connect to
the libvirt daemon.
UNIX socket PolicyKit auth
If libvirt contains support for PolicyKit, then access control options are
more advanced. The unix_sock_auth
parameter will default to
polkit
, and the file permissions will default to 0777
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 sudo
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.
The default policy can be overridden by the administrator using the PolicyKit
master configuration file in /etc/PolicyKit/PolicyKit.conf
. The
PolicyKit.conf(5)
manual page provides details on the syntax
available. The two libvirt daemon actions available are named org.libvirt.unix.monitor
for the RO socket, and org.libvirt.unix.manage
for the RW socket.
As an example, to allow a user fred
full access to the RW socket,
while requiring joe
to authenticate with the admin password,
would require adding the following snippet to PolicyKit.conf
.
<match action="org.libvirt.unix.manage"> <match user="fred"> <return result="yes"/> </match> </match> <match action="org.libvirt.unix.manage"> <match user="joe"> <return result="auth_admin"/> </match> </match>
Username/password auth
The plain TCP socket of the libvirt daemon defaults to using SASL for authentication.
The SASL mechanism configured by default is DIGEST-MD5, which provides a basic
username+password style authentication. It also provides for encryption of the data
stream, so the security of the plain TCP socket is on a par with that of the TLS
socket. If desired the UNIX socket and TLS socket can also have SASL enabled by
setting the auth_unix_ro
, auth_unix_rw
, auth_tls
config params in libvirt.conf
.
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 saslpasswd2
command. When running this command it is important to tell it that the appname is libvirt
.
As an example, to add a user fred
, run
# saslpasswd2 -a libvirt fred Password: xxxxxx Again (for verification): xxxxxx
To see a list of all accounts the sasldblistusers2
command can be used.
This command expects to be given the path to the libvirt user database, which is kept
in /etc/libvirt/passwd.db
# sasldblistusers2 -f /etc/libvirt/passwd.db fred@t60wlan.home.berrange.com: userPassword
Finally, to disable a user's access, the saslpasswd2
command can be used
again:
# saslpasswd2 -a libvirt -d fred
Kerberos auth
The plain TCP socket of the libvirt daemon defaults to using SASL for authentication.
The SASL mechanism configured by default is DIGEST-MD5, which provides a basic
username+password style authentication. To enable Kerberos single-sign-on instead,
the libvirt SASL configuration file must be changed. This is /etc/sasl2/libvirt.conf
.
The mech_list
parameter must first be changed to gssapi
instead of the default digest-md5
. If SASL is enabled on the UNIX
and/or TLS sockets, Kerberos will also be used for them. Like DIGEST-MD5, the Kerberos
mechanism provides data encryption of the session.
Some operating systems do not install the SASL kerberos plugin by default. It
may be necessary to install a sub-package such as cyrus-sasl-gssapi
.
To check whether the Kerberos plugin is installed run the pluginviewer
program and verify that gssapi
is listed,eg:
# 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
Next is is necessary for the administrator of the Kerberos realm to issue a principle
for the libvirt server. There needs to be one principle per host running the libvirt
daemon. The principle should be named libvirt/full.hostname@KERBEROS.REALM
.
This is typically done by running the kadmin.local
command on the Kerberos
server, though some Kerberos servers have alternate ways of setting up service principles.
Once created, the principle should be exported to a keytab, copied to the host running
the libvirt daemon and placed in /etc/libvirt/krb5.tab
# kadmin.local kadmin.local: add_principal libvirt/foo.example.com Enter password for principal "libvirt/foo.example.com@EXAMPLE.COM": Re-enter password for principal "libvirt/foo.example.com@EXAMPLE.COM": Principal "libvirt/foo.example.com@EXAMPLE.COM" created. kadmin.local: ktadd -k /root/libvirt-foo-example.tab libvirt/foo.example.com@EXAMPLE.COM Entry for principal libvirt/foo.example.com@EXAMPLE.COM 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@EXAMPLE.COM 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@EXAMPLE.COM 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@EXAMPLE.COM 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@foo.example.com:/etc/libvirt/krb5.tab # rm /root/libvirt-foo-example.tab
Any client application wishing to connect to a Kerberos enabled libvirt server
merely needs to run kinit
to gain a user principle. This may well
be done automatically when a user logs into a desktop session, if PAM is setup
to authenticate against Kerberos.