Augeas is a awesome config file manipulation tool. libvirtd has a config file. libvirtd meet augeas; augeas meet libvirt. Now instead of telling people 'edit /etc/libvirt/libvirtd.conf and change listen_tls to 1, and auth_tls to sasl' we can say run # augtool <<EOF set /files/etc/libvirt/libvirtd.conf/listen_tls 1 set /files/etc/libvirt/libvirtd.conf/auth_tls sasl save EOF THis patch is intended to be committed to libvirt, so the config file rules are distributed alongside libvirt. I'm CC'ing augeas-devel for feedback on the lens itself. libvirt.spec.in | 2 qemud/Makefile.am | 8 qemud/libvirtd.aug | 64 ++++++ qemud/test_libvirtd.aug | 484 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 558 insertions(+) Daniel Index: qemud/Makefile.am =================================================================== RCS file: /data/cvs/libvirt/qemud/Makefile.am,v retrieving revision 1.51 diff -u -p -r1.51 Makefile.am --- qemud/Makefile.am 20 Aug 2008 20:48:35 -0000 1.51 +++ qemud/Makefile.am 26 Aug 2008 20:03:48 -0000 @@ -24,6 +24,8 @@ EXTRA_DIST = \ libvirtd.policy \ libvirtd.sasl \ libvirtd.sysconf \ + libvirtd.aug \ + test_libvirtd.aug \ $(AVAHI_SOURCES) \ $(DAEMON_SOURCES) @@ -56,6 +58,12 @@ sbin_PROGRAMS = libvirtd confdir = $(sysconfdir)/libvirt/ conf_DATA = libvirtd.conf +augeasdir = $(datadir)/augeas/lenses +augeas_DATA = libvirtd.aug + +augeastestsdir = $(datadir)/augeas/lenses/tests +augeastests_DATA = test_libvirtd.aug + libvirtd_SOURCES = $(DAEMON_SOURCES) #-D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_POSIX_C_SOURCE=199506L Index: qemud/libvirtd.aug =================================================================== RCS file: qemud/libvirtd.aug diff -N qemud/libvirtd.aug --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ qemud/libvirtd.aug 26 Aug 2008 20:03:48 -0000 @@ -0,0 +1,64 @@ +(* /etc/libvirt/libvirtd.conf *) + +module Libvirtd = + autoload xfm + + let eol = del /[ \t]*\n/ "\n" + let value_sep = del /[ \t]*=[ \t]*/ " = " + let prespace = del /[ \t]*/ "" + + let array_sep = del /,[ \t\n]*/ ", " + let array_start = del /\[[ \t\n]*/ "[ " + let array_end = del /\]/ " ]" + + let str_val = del /\"/ "\"" . store /[^\"]*/ . del /\"/ "\"" + let bool_val = store /0|1/ + let str_array_element = [ str_val ] . del /[ \t\n]*/ "" + let str_array_val = array_start . ( str_array_element . ( array_sep . str_array_element ) * ) ? . array_end + + let str_entry (kw:string) = [ prespace . key kw . value_sep . str_val . eol ] + let bool_entry (kw:string) = [ prespace . key kw . value_sep . bool_val . eol ] + let str_array_entry (kw:string) = [ prespace . key kw . value_sep . str_array_val . eol ] + + let network_entry = bool_entry "listen_tls" + | bool_entry "listen_tcp" + | str_entry "tls_port" + | str_entry "tcp_port" + | str_entry "listen_addr" + | bool_entry "mdns_adv" + | str_entry "mdns_name" + + let sock_acl_entry = str_entry "unix_sock_group" + | str_entry "unix_sock_ro_perms" + | str_entry "unix_sock_rw_perms" + + let authentication_entry = str_entry "auth_unix_ro" + | str_entry "auth_unix_rw" + | str_entry "auth_tcp" + | str_entry "auth_tls" + + let certificate_entry = str_entry "key_file" + | str_entry "cert_file" + | str_entry "ca_file" + | str_entry "crl_file" + + let authorization_entry = bool_entry "tls_no_verify_certificate" + | str_array_entry "tls_allowed_dn_list" + | str_array_entry "sasl_allowed_username_list" + + let entry = network_entry + | sock_acl_entry + | authentication_entry + | certificate_entry + | authorization_entry + + let comment = [ label "comment" . del /#[ \t]*/ "# " . store /([^ \t\n][^\n]*)?/ . del /\n/ "\n" ] + let empty = [ label "empty" . del /[ \t]*\n/ "" ] + + let lns = ( entry | comment | empty ) + + + let filter = incl "/etc/libvirt/libvirtd.conf" + . Util.stdexcl + + let xfm = transform lns filter + Index: qemud/test_libvirtd.aug =================================================================== RCS file: qemud/test_libvirtd.aug diff -N qemud/test_libvirtd.aug --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ qemud/test_libvirtd.aug 26 Aug 2008 20:03:48 -0000 @@ -0,0 +1,484 @@ +module Test_libvirtd = + let conf1 = "# Master libvirt daemon configuration file +# +# For further information consult http://libvirt.org/format.html + + +################################################################# +# +# Network connectivity controls +# + +# Flag listening for secure TLS connections on the public TCP/IP port. +# NB, must pass the --listen flag to the libvirtd process for this to +# have any effect. +# +# It is necessary to setup a CA and issue server certificates before +# using this capability. +# +# This is enabled by default, uncomment this to disable it +listen_tls = 0 +" + + let conf = "# Master libvirt daemon configuration file +# +# For further information consult http://libvirt.org/format.html + + +################################################################# +# +# Network connectivity controls +# + +# Flag listening for secure TLS connections on the public TCP/IP port. +# NB, must pass the --listen flag to the libvirtd process for this to +# have any effect. +# +# It is necessary to setup a CA and issue server certificates before +# using this capability. +# +# This is enabled by default, uncomment this to disable it +listen_tls = 0 + +# Listen for unencrypted TCP connections on the public TCP/IP port. +# NB, must pass the --listen flag to the libvirtd process for this to +# have any effect. +# +# Using the TCP socket requires SASL authentication by default. Only +# SASL mechanisms which support data encryption are allowed. This is +# DIGEST_MD5 and GSSAPI (Kerberos5) +# +# This is disabled by default, uncomment this to enable it. +listen_tcp = 1 + + + +# Override the port for accepting secure TLS connections +# This can be a port number, or service name +# +tls_port = \"16514\" + +# Override the port for accepting insecure TCP connections +# This can be a port number, or service name +# +tcp_port = \"16509\" + + +# Override the default configuration which binds to all network +# interfaces. This can be a numeric IPv4/6 address, or hostname +# +listen_addr = \"192.168.0.1\" + + +# Flag toggling mDNS advertizement of the libvirt service. +# +# Alternatively can disable for all services on a host by +# stopping the Avahi daemon +# +# This is enabled by default, uncomment this to disable it +mdns_adv = 0 + +# Override the default mDNS advertizement name. This must be +# unique on the immediate broadcast network. +# +# The default is \"Virtualization Host HOSTNAME\", where HOSTNAME +# is subsituted for the short hostname of the machine (without domain) +# +mdns_name = \"Virtualization Host Joe Demo\" + + +################################################################# +# +# UNIX socket access controls +# + +# Set the UNIX domain socket group ownership. This can be used to +# allow a 'trusted' set of users access to management capabilities +# without becoming root. +# +# This is restricted to 'root' by default. +unix_sock_group = \"libvirt\" + +# Set the UNIX socket permissions for the R/O socket. This is used +# for monitoring VM status only +# +# Default allows any user. If setting group ownership may want to +# restrict this to: +unix_sock_ro_perms = \"0777\" + +# Set the UNIX socket permissions for the R/W socket. This is used +# for full management of VMs +# +# Default allows only root. If PolicyKit is enabled on the socket, +# the default will change to allow everyone (eg, 0777) +# +# If not using PolicyKit and setting group ownership for access +# control then you may want to relax this to: +unix_sock_rw_perms = \"0770\" + + + +################################################################# +# +# Authentication. +# +# - none: do not perform auth checks. If you can connect to the +# socket you are allowed. This is suitable if there are +# restrictions on connecting to the socket (eg, UNIX +# socket permissions), or if there is a lower layer in +# the network providing auth (eg, TLS/x509 certificates) +# +# - sasl: use SASL infrastructure. The actual auth scheme is then +# controlled from /etc/sasl2/libvirt.conf. For the TCP +# socket only GSSAPI & DIGEST-MD5 mechanisms will be used. +# For non-TCP or TLS sockets, any scheme is allowed. +# +# - polkit: use PolicyKit to authenticate. This is only suitable +# for use on the UNIX sockets. The default policy will +# require a user to supply their own password to gain +# full read/write access (aka sudo like), while anyone +# is allowed read/only access. +# +# Set an authentication scheme for UNIX read-only sockets +# By default socket permissions allow anyone to connect +# +# To restrict monitoring of domains you may wish to enable +# an authentication mechanism here +auth_unix_ro = \"none\" + +# Set an authentication scheme for UNIX read-write sockets +# By default socket permissions only allow root. If PolicyKit +# support was compiled into libvirt, the default will be to +# use 'polkit' auth. +# +# If the unix_sock_rw_perms are changed you may wish to enable +# an authentication mechanism here +auth_unix_rw = \"none\" + +# Change the authentication scheme for TCP sockets. +# +# If you don't enable SASL, then all TCP traffic is cleartext. +# Don't do this outside of a dev/test scenario. For real world +# use, always enable SASL and use the GSSAPI or DIGEST-MD5 +# mechanism in /etc/sasl2/libvirt.conf +auth_tcp = \"sasl\" + +# Change the authentication scheme for TLS sockets. +# +# TLS sockets already have encryption provided by the TLS +# layer, and limited authentication is done by certificates +# +# It is possible to make use of any SASL authentication +# mechanism as well, by using 'sasl' for this option +auth_tls = \"none\" + + + +################################################################# +# +# TLS x509 certificate configuration +# + + +# Override the default server key file path +# +key_file = \"/etc/pki/libvirt/private/serverkey.pem\" + +# Override the default server certificate file path +# +cert_file = \"/etc/pki/libvirt/servercert.pem\" + +# Override the default CA certificate path +# +ca_file = \"/etc/pki/CA/cacert.pem\" + +# Specify a certificate revocation list. +# +# Defaults to not using a CRL, uncomment to enable it +crl_file = \"/etc/pki/CA/crl.pem\" + + + +################################################################# +# +# Authorization controls +# + + +# Flag to disable verification of client certificates +# +# Client certificate verification is the primary authentication mechanism. +# Any client which does not present a certificate signed by the CA +# will be rejected. +# +# Default is to always verify. Uncommenting this will disable +# verification - make sure an IP whitelist is set +tls_no_verify_certificate = 1 + + +# A whitelist of allowed x509 Distinguished Names +# This list may contain wildcards such as +# +# \"C=GB,ST=London,L=London,O=Red Hat,CN=*\" +# +# See the POSIX fnmatch function for the format of the wildcards. +# +# NB If this is an empty list, no client can connect, so comment out +# entirely rather than using empty list to disable these checks +# +# By default, no DN's are checked + tls_allowed_dn_list = [\"DN1\", \"DN2\"] + + +# A whitelist of allowed SASL usernames. The format for usernames +# depends on the SASL authentication mechanism. Kerberos usernames +# look like username@REALM +# +# This list may contain wildcards such as +# +# \"*@EXAMPLE.COM\" +# +# See the POSIX fnmatch function for the format of the wildcards. +# +# NB If this is an empty list, no client can connect, so comment out +# entirely rather than using empty list to disable these checks +# +# By default, no Username's are checked +sasl_allowed_username_list = [ + \"joe@xxxxxxxxxxx\", + \"fred@xxxxxxxxxxx\" +] +" + + test Libvirtd.lns get conf = + { "comment" = "Master libvirt daemon configuration file" } + { "comment" = "" } + { "comment" = "For further information consult http://libvirt.org/format.html" } + { "empty" } + { "empty" } + { "comment" = "################################################################" } + { "comment" = "" } + { "comment" = "Network connectivity controls" } + { "comment" = "" } + { "empty" } + { "comment" = "Flag listening for secure TLS connections on the public TCP/IP port." } + { "comment" = "NB, must pass the --listen flag to the libvirtd process for this to" } + { "comment" = "have any effect." } + { "comment" = "" } + { "comment" = "It is necessary to setup a CA and issue server certificates before" } + { "comment" = "using this capability." } + { "comment" = "" } + { "comment" = "This is enabled by default, uncomment this to disable it" } + { "listen_tls" = "0" } + { "empty" } + { "comment" = "Listen for unencrypted TCP connections on the public TCP/IP port." } + { "comment" = "NB, must pass the --listen flag to the libvirtd process for this to" } + { "comment" = "have any effect." } + { "comment" = "" } + { "comment" = "Using the TCP socket requires SASL authentication by default. Only" } + { "comment" = "SASL mechanisms which support data encryption are allowed. This is" } + { "comment" = "DIGEST_MD5 and GSSAPI (Kerberos5)" } + { "comment" = "" } + { "comment" = "This is disabled by default, uncomment this to enable it." } + { "listen_tcp" = "1" } + { "empty" } + { "empty" } + { "empty" } + { "comment" = "Override the port for accepting secure TLS connections" } + { "comment" = "This can be a port number, or service name" } + { "comment" = "" } + { "tls_port" = "16514" } + { "empty" } + { "comment" = "Override the port for accepting insecure TCP connections" } + { "comment" = "This can be a port number, or service name" } + { "comment" = "" } + { "tcp_port" = "16509" } + { "empty" } + { "empty" } + { "comment" = "Override the default configuration which binds to all network" } + { "comment" = "interfaces. This can be a numeric IPv4/6 address, or hostname" } + { "comment" = "" } + { "listen_addr" = "192.168.0.1" } + { "empty" } + { "empty" } + { "comment" = "Flag toggling mDNS advertizement of the libvirt service." } + { "comment" = "" } + { "comment" = "Alternatively can disable for all services on a host by" } + { "comment" = "stopping the Avahi daemon" } + { "comment" = "" } + { "comment" = "This is enabled by default, uncomment this to disable it" } + { "mdns_adv" = "0" } + { "empty" } + { "comment" = "Override the default mDNS advertizement name. This must be" } + { "comment" = "unique on the immediate broadcast network." } + { "comment" = "" } + { "comment" = "The default is \"Virtualization Host HOSTNAME\", where HOSTNAME" } + { "comment" = "is subsituted for the short hostname of the machine (without domain)" } + { "comment" = "" } + { "mdns_name" = "Virtualization Host Joe Demo" } + { "empty" } + { "empty" } + { "comment" = "################################################################" } + { "comment" = "" } + { "comment" = "UNIX socket access controls" } + { "comment" = "" } + { "empty" } + { "comment" = "Set the UNIX domain socket group ownership. This can be used to" } + { "comment" = "allow a 'trusted' set of users access to management capabilities" } + { "comment" = "without becoming root." } + { "comment" = "" } + { "comment" = "This is restricted to 'root' by default." } + { "unix_sock_group" = "libvirt" } + { "empty" } + { "comment" = "Set the UNIX socket permissions for the R/O socket. This is used" } + { "comment" = "for monitoring VM status only" } + { "comment" = "" } + { "comment" = "Default allows any user. If setting group ownership may want to" } + { "comment" = "restrict this to:" } + { "unix_sock_ro_perms" = "0777" } + { "empty" } + { "comment" = "Set the UNIX socket permissions for the R/W socket. This is used" } + { "comment" = "for full management of VMs" } + { "comment" = "" } + { "comment" = "Default allows only root. If PolicyKit is enabled on the socket," } + { "comment" = "the default will change to allow everyone (eg, 0777)" } + { "comment" = "" } + { "comment" = "If not using PolicyKit and setting group ownership for access" } + { "comment" = "control then you may want to relax this to:" } + { "unix_sock_rw_perms" = "0770" } + { "empty" } + { "empty" } + { "empty" } + { "comment" = "################################################################" } + { "comment" = "" } + { "comment" = "Authentication." } + { "comment" = "" } + { "comment" = "- none: do not perform auth checks. If you can connect to the" } + { "comment" = "socket you are allowed. This is suitable if there are" } + { "comment" = "restrictions on connecting to the socket (eg, UNIX" } + { "comment" = "socket permissions), or if there is a lower layer in" } + { "comment" = "the network providing auth (eg, TLS/x509 certificates)" } + { "comment" = "" } + { "comment" = "- sasl: use SASL infrastructure. The actual auth scheme is then" } + { "comment" = "controlled from /etc/sasl2/libvirt.conf. For the TCP" } + { "comment" = "socket only GSSAPI & DIGEST-MD5 mechanisms will be used." } + { "comment" = "For non-TCP or TLS sockets, any scheme is allowed." } + { "comment" = "" } + { "comment" = "- polkit: use PolicyKit to authenticate. This is only suitable" } + { "comment" = "for use on the UNIX sockets. The default policy will" } + { "comment" = "require a user to supply their own password to gain" } + { "comment" = "full read/write access (aka sudo like), while anyone" } + { "comment" = "is allowed read/only access." } + { "comment" = "" } + { "comment" = "Set an authentication scheme for UNIX read-only sockets" } + { "comment" = "By default socket permissions allow anyone to connect" } + { "comment" = "" } + { "comment" = "To restrict monitoring of domains you may wish to enable" } + { "comment" = "an authentication mechanism here" } + { "auth_unix_ro" = "none" } + { "empty" } + { "comment" = "Set an authentication scheme for UNIX read-write sockets" } + { "comment" = "By default socket permissions only allow root. If PolicyKit" } + { "comment" = "support was compiled into libvirt, the default will be to" } + { "comment" = "use 'polkit' auth." } + { "comment" = "" } + { "comment" = "If the unix_sock_rw_perms are changed you may wish to enable" } + { "comment" = "an authentication mechanism here" } + { "auth_unix_rw" = "none" } + { "empty" } + { "comment" = "Change the authentication scheme for TCP sockets." } + { "comment" = "" } + { "comment" = "If you don't enable SASL, then all TCP traffic is cleartext." } + { "comment" = "Don't do this outside of a dev/test scenario. For real world" } + { "comment" = "use, always enable SASL and use the GSSAPI or DIGEST-MD5" } + { "comment" = "mechanism in /etc/sasl2/libvirt.conf" } + { "auth_tcp" = "sasl" } + { "empty" } + { "comment" = "Change the authentication scheme for TLS sockets." } + { "comment" = "" } + { "comment" = "TLS sockets already have encryption provided by the TLS" } + { "comment" = "layer, and limited authentication is done by certificates" } + { "comment" = "" } + { "comment" = "It is possible to make use of any SASL authentication" } + { "comment" = "mechanism as well, by using 'sasl' for this option" } + { "auth_tls" = "none" } + { "empty" } + { "empty" } + { "empty" } + { "comment" = "################################################################" } + { "comment" = "" } + { "comment" = "TLS x509 certificate configuration" } + { "comment" = "" } + { "empty" } + { "empty" } + { "comment" = "Override the default server key file path" } + { "comment" = "" } + { "key_file" = "/etc/pki/libvirt/private/serverkey.pem" } + { "empty" } + { "comment" = "Override the default server certificate file path" } + { "comment" = "" } + { "cert_file" = "/etc/pki/libvirt/servercert.pem" } + { "empty" } + { "comment" = "Override the default CA certificate path" } + { "comment" = "" } + { "ca_file" = "/etc/pki/CA/cacert.pem" } + { "empty" } + { "comment" = "Specify a certificate revocation list." } + { "comment" = "" } + { "comment" = "Defaults to not using a CRL, uncomment to enable it" } + { "crl_file" = "/etc/pki/CA/crl.pem" } + { "empty" } + { "empty" } + { "empty" } + { "comment" = "################################################################" } + { "comment" = "" } + { "comment" = "Authorization controls" } + { "comment" = "" } + { "empty" } + { "empty" } + { "comment" = "Flag to disable verification of client certificates" } + { "comment" = "" } + { "comment" = "Client certificate verification is the primary authentication mechanism." } + { "comment" = "Any client which does not present a certificate signed by the CA" } + { "comment" = "will be rejected." } + { "comment" = "" } + { "comment" = "Default is to always verify. Uncommenting this will disable" } + { "comment" = "verification - make sure an IP whitelist is set" } + { "tls_no_verify_certificate" = "1" } + { "empty" } + { "empty" } + { "comment" = "A whitelist of allowed x509 Distinguished Names" } + { "comment" = "This list may contain wildcards such as" } + { "comment" = "" } + { "comment" = "\"C=GB,ST=London,L=London,O=Red Hat,CN=*\"" } + { "comment" = "" } + { "comment" = "See the POSIX fnmatch function for the format of the wildcards." } + { "comment" = "" } + { "comment" = "NB If this is an empty list, no client can connect, so comment out" } + { "comment" = "entirely rather than using empty list to disable these checks" } + { "comment" = "" } + { "comment" = "By default, no DN's are checked" } + { "tls_allowed_dn_list" + { = "DN1"} + { = "DN2"} + } + { "empty" } + { "empty" } + { "comment" = "A whitelist of allowed SASL usernames. The format for usernames" } + { "comment" = "depends on the SASL authentication mechanism. Kerberos usernames" } + { "comment" = "look like username@REALM" } + { "comment" = "" } + { "comment" = "This list may contain wildcards such as" } + { "comment" = "" } + { "comment" = "\"*@EXAMPLE.COM\"" } + { "comment" = "" } + { "comment" = "See the POSIX fnmatch function for the format of the wildcards." } + { "comment" = "" } + { "comment" = "NB If this is an empty list, no client can connect, so comment out" } + { "comment" = "entirely rather than using empty list to disable these checks" } + { "comment" = "" } + { "comment" = "By default, no Username's are checked" } + { "sasl_allowed_username_list" + { = "joe@xxxxxxxxxxx" } + { = "fred@xxxxxxxxxxx" } + } Index: libvirt.spec.in =================================================================== RCS file: /data/cvs/libvirt/libvirt.spec.in,v retrieving revision 1.91 diff -u -p -r1.91 libvirt.spec.in --- libvirt.spec.in 21 Aug 2008 09:28:54 -0000 1.91 +++ libvirt.spec.in 26 Aug 2008 20:04:24 -0000 @@ -252,6 +252,8 @@ fi %dir %{_localstatedir}/lib/libvirt/ %dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/images/ %dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/boot/ +%{_datadir}/augeas/lenses/libvirtd.aug +%{_datadir}/augeas/lenses/tests/test_libvirtd.aug %if %{with_polkit} %{_datadir}/PolicyKit/policy/org.libvirt.unix.policy %endif -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list