diff options
| -rw-r--r-- | recipes-extended/libvirt/README | 26 | ||||
| -rwxr-xr-x | recipes-extended/libvirt/libvirt/gnutls-helper.py | 136 | ||||
| -rw-r--r-- | recipes-extended/libvirt/libvirt_5.5.0.bb | 28 |
3 files changed, 189 insertions, 1 deletions
diff --git a/recipes-extended/libvirt/README b/recipes-extended/libvirt/README new file mode 100644 index 00000000..af4fd170 --- /dev/null +++ b/recipes-extended/libvirt/README | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | libvirt default connection mode between client(where for example virsh runs) and | ||
| 2 | server(where libvirtd runs) is tls which requires keys and certificates for | ||
| 3 | certificate authority, client and server to be properly generated and deployed. | ||
| 4 | Otherwise, servers and clients cannot be connected. | ||
| 5 | |||
| 6 | recipes-extended/libvirt/libvirt/gnutls-help.py is provided to help generate | ||
| 7 | required keys and certificates. | ||
| 8 | |||
| 9 | Usage: | ||
| 10 | gnutls-help.py [-a|--ca-info] <ca.info> [-b|--server-info] <server.info> [-c|--client-info] <client.info> | ||
| 11 | If ca.info or server.info or client.info is not provided, a corresponding sample file will be generated. | ||
| 12 | |||
| 13 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
| 14 | !! "ip_address" field of server.info must be IP address of the server. !! | ||
| 15 | !! For more details, please refer to: !! | ||
| 16 | !! https://libvirt.org/remote.html#Remote_certificates !! | ||
| 17 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
| 18 | |||
| 19 | Please deploy cacert.pem to CA and server and client /etc/pki/CA/cacert.pem | ||
| 20 | Please deploy serverkey.pem to server /etc/pki/libvirt/private/serverkey.pem | ||
| 21 | Please deploy servercert.pem to server /etc/pki/libvirt/servercert.pem | ||
| 22 | Please deploy clientkey.pem to client /etc/pki/libvirt/private/clientkey.pem | ||
| 23 | Please deploy clientcert.pem to client /etc/pki/libvirt/clientcert.pem" | ||
| 24 | |||
| 25 | For more details please refer to libvirt official document, | ||
| 26 | https://libvirt.org/remote.html#Remote_certificates | ||
diff --git a/recipes-extended/libvirt/libvirt/gnutls-helper.py b/recipes-extended/libvirt/libvirt/gnutls-helper.py new file mode 100755 index 00000000..b9949469 --- /dev/null +++ b/recipes-extended/libvirt/libvirt/gnutls-helper.py | |||
| @@ -0,0 +1,136 @@ | |||
| 1 | #!/usr/bin/env python3 | ||
| 2 | # | ||
| 3 | # Copyright (C) 2019 Wind River Systems, Inc. | ||
| 4 | # | ||
| 5 | # SPDX-License-Identifier: GPL-2.0-only | ||
| 6 | # | ||
| 7 | |||
| 8 | import os, sys, getopt | ||
| 9 | |||
| 10 | banner = \ | ||
| 11 | '''\ | ||
| 12 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
| 13 | !! "ip_address" field of server.info must be IP address of the server. !! | ||
| 14 | !! For more details, please refer to: !! | ||
| 15 | !! https://libvirt.org/remote.html#Remote_certificates !! | ||
| 16 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
| 17 | |||
| 18 | Please deploy cacert.pem to CA and server and client /etc/pki/CA/cacert.pem | ||
| 19 | Please deploy serverkey.pem to server /etc/pki/libvirt/private/serverkey.pem | ||
| 20 | Please deploy servercert.pem to server /etc/pki/libvirt/servercert.pem | ||
| 21 | Please deploy clientkey.pem to client /etc/pki/libvirt/private/clientkey.pem | ||
| 22 | Please deploy clientcert.pem to client /etc/pki/libvirt/clientcert.pem" | ||
| 23 | ''' | ||
| 24 | |||
| 25 | if os.system('which certtool > /dev/null 2>&1') != 0: | ||
| 26 | print('certtool is not available. It is provided by \n\ | ||
| 27 | gnutls-bin on Yocto like Linux or \n\ | ||
| 28 | gnutls-bin on Debian like distribution or \n\ | ||
| 29 | gnutls-utils on Redhat like distribution.') | ||
| 30 | sys.exit() | ||
| 31 | |||
| 32 | cainfo = "" | ||
| 33 | serverinfo = "" | ||
| 34 | clientinfo = "" | ||
| 35 | yes = 0 | ||
| 36 | |||
| 37 | try: | ||
| 38 | opts, args = getopt.getopt(sys.argv[1:], "ha:b:c:y", ["help", "ca-info=", "server-info=", "client-info=", "yes"]) | ||
| 39 | except getopt.GetoptError: | ||
| 40 | print('Usage:\n{} [-a|--ca-info] <ca.info> [-b|--server-info] <server.info> [-c|--client-info] <client.info> [-y|--yes]'.format(sys.argv[0])) | ||
| 41 | print('If ca.info or server.info or client.info is not provided, a corresponding sample file will be generated.') | ||
| 42 | sys.exit(2) | ||
| 43 | for opt, arg in opts: | ||
| 44 | if opt in ("-h", "--help"): | ||
| 45 | print('Usage:\n{} [-a|--ca-info] <ca.info> [-b|--server-info] <server.info> [-c|--client-info] <client.info> [-y|--yes]'.format(sys.argv[0])) | ||
| 46 | print('If ca.info or server.info or client.info is not provided, a corresponding sample file will be generated.\n') | ||
| 47 | print(banner) | ||
| 48 | sys.exit() | ||
| 49 | elif opt in ("-a", "--ca-info"): | ||
| 50 | cainfo = arg | ||
| 51 | elif opt in ("-b", "--server-info"): | ||
| 52 | serverinfo = arg | ||
| 53 | elif opt in ("-c", "--client-info"): | ||
| 54 | clientinfo = arg | ||
| 55 | elif opt in ("-y", "--yes"): | ||
| 56 | yes = 1 | ||
| 57 | |||
| 58 | cainfodefault = \ | ||
| 59 | '''cn = CA | ||
| 60 | ca | ||
| 61 | cert_signing_key | ||
| 62 | ''' | ||
| 63 | |||
| 64 | serverinfodefault = \ | ||
| 65 | '''organization = Organization | ||
| 66 | cn = Server | ||
| 67 | dns_name = DNS Name | ||
| 68 | ip_address = 127.0.0.1 | ||
| 69 | tls_www_server | ||
| 70 | encryption_key | ||
| 71 | signing_key | ||
| 72 | ''' | ||
| 73 | |||
| 74 | clientinfodefault = \ | ||
| 75 | '''country = Country | ||
| 76 | state = State | ||
| 77 | locality = Locality | ||
| 78 | organization = Organization | ||
| 79 | cn = Client | ||
| 80 | tls_www_client | ||
| 81 | encryption_key | ||
| 82 | signing_key | ||
| 83 | ''' | ||
| 84 | |||
| 85 | if not cainfo: | ||
| 86 | if yes == 0: | ||
| 87 | opt = input('{}\nca.info not provided by -a, the above will be used [y/n]?'.format(cainfodefault)) | ||
| 88 | if opt != 'y': | ||
| 89 | exit() | ||
| 90 | cainfo = "ca.info" | ||
| 91 | with open(cainfo, mode='w') as f: | ||
| 92 | f.write(cainfodefault) | ||
| 93 | |||
| 94 | if not serverinfo: | ||
| 95 | if yes == 0: | ||
| 96 | opt = input('{}\nserver.info not provided by -b, the above will be used [y/n]?'.format(serverinfodefault)) | ||
| 97 | if opt != 'y': | ||
| 98 | exit() | ||
| 99 | serverinfo = "server.info" | ||
| 100 | with open(serverinfo, mode='w') as f: | ||
| 101 | f.write(serverinfodefault) | ||
| 102 | |||
| 103 | if not clientinfo: | ||
| 104 | if yes == 0: | ||
| 105 | opt = input('{}\nclient.info not provided by -c, the above will be used [y/n]?'.format(clientinfodefault)) | ||
| 106 | if opt != 'y': | ||
| 107 | sys.exit() | ||
| 108 | clientinfo = "client.info" | ||
| 109 | with open(clientinfo, mode='w') as f: | ||
| 110 | f.write(clientinfodefault) | ||
| 111 | |||
| 112 | if os.system("certtool --generate-privkey > cakey.pem") != 0: | ||
| 113 | print('ca private key failed.') | ||
| 114 | sys.exit() | ||
| 115 | |||
| 116 | if os.system("certtool --generate-self-signed --load-privkey cakey.pem --template {} --outfile cacert.pem".format(cainfo)) != 0: | ||
| 117 | print('ca cert failed.') | ||
| 118 | sys.exit() | ||
| 119 | |||
| 120 | if os.system("certtool --generate-privkey > serverkey.pem") != 0: | ||
| 121 | print('server private key failed.') | ||
| 122 | sys.exit() | ||
| 123 | |||
| 124 | if os.system("certtool --generate-certificate --load-privkey serverkey.pem --load-ca-certificate cacert.pem --load-ca-privkey cakey.pem --template {} --outfile servercert.pem".format(serverinfo)) != 0: | ||
| 125 | print('server cert failed.') | ||
| 126 | sys.exit() | ||
| 127 | |||
| 128 | if os.system("certtool --generate-privkey > clientkey.pem") != 0: | ||
| 129 | print('client private key failed.') | ||
| 130 | sys.exit() | ||
| 131 | |||
| 132 | if os.system("certtool --generate-certificate --load-privkey clientkey.pem --load-ca-certificate cacert.pem --load-ca-privkey cakey.pem --template {} --outfile clientcert.pem".format(clientinfo)) != 0: | ||
| 133 | print('client cert failed.') | ||
| 134 | sys.exit() | ||
| 135 | |||
| 136 | print(banner) | ||
diff --git a/recipes-extended/libvirt/libvirt_5.5.0.bb b/recipes-extended/libvirt/libvirt_5.5.0.bb index 7ed40a64..8d718628 100644 --- a/recipes-extended/libvirt/libvirt_5.5.0.bb +++ b/recipes-extended/libvirt/libvirt_5.5.0.bb | |||
| @@ -8,7 +8,8 @@ SECTION = "console/tools" | |||
| 8 | 8 | ||
| 9 | DEPENDS = "bridge-utils gnutls libxml2 lvm2 avahi parted curl libpcap util-linux e2fsprogs pm-utils \ | 9 | DEPENDS = "bridge-utils gnutls libxml2 lvm2 avahi parted curl libpcap util-linux e2fsprogs pm-utils \ |
| 10 | iptables dnsmasq readline libtasn1 libxslt-native acl libdevmapper libtirpc \ | 10 | iptables dnsmasq readline libtasn1 libxslt-native acl libdevmapper libtirpc \ |
| 11 | ${@bb.utils.contains('PACKAGECONFIG', 'polkit', 'shadow-native', '', d)}" | 11 | ${@bb.utils.contains('PACKAGECONFIG', 'polkit', 'shadow-native', '', d)} \ |
| 12 | ${@bb.utils.contains('PACKAGECONFIG', 'gnutls', 'gnutls-native', '', d)}" | ||
| 12 | 13 | ||
| 13 | # libvirt-guests.sh needs gettext.sh | 14 | # libvirt-guests.sh needs gettext.sh |
| 14 | # | 15 | # |
| @@ -36,6 +37,7 @@ SRC_URI = "http://libvirt.org/sources/libvirt-${PV}.tar.xz;name=libvirt \ | |||
| 36 | file://0001-ptest-Remove-Windows-1252-check-from-esxutilstest.patch \ | 37 | file://0001-ptest-Remove-Windows-1252-check-from-esxutilstest.patch \ |
| 37 | file://configure.ac-search-for-rpc-rpc.h-in-the-sysroot.patch \ | 38 | file://configure.ac-search-for-rpc-rpc.h-in-the-sysroot.patch \ |
| 38 | file://hook_support.py \ | 39 | file://hook_support.py \ |
| 40 | file://gnutls-helper.py \ | ||
| 39 | " | 41 | " |
| 40 | 42 | ||
| 41 | SRC_URI[libvirt.md5sum] = "27c5fb6c8d2d46eb9e8165aeb3b499b0" | 43 | SRC_URI[libvirt.md5sum] = "27c5fb6c8d2d46eb9e8165aeb3b499b0" |
| @@ -119,6 +121,7 @@ FILES_${PN}-libvirtd = " \ | |||
| 119 | ${sbindir}/libvirtd \ | 121 | ${sbindir}/libvirtd \ |
| 120 | ${systemd_unitdir}/system/* \ | 122 | ${systemd_unitdir}/system/* \ |
| 121 | ${@bb.utils.contains('DISTRO_FEATURES', 'sysvinit', '', '${libexecdir}/libvirt-guests.sh', d)} \ | 123 | ${@bb.utils.contains('DISTRO_FEATURES', 'sysvinit', '', '${libexecdir}/libvirt-guests.sh', d)} \ |
| 124 | ${@bb.utils.contains('PACKAGECONFIG', 'gnutls', '${sysconfdir}/pki/libvirt/* ${sysconfdir}/pki/CA/*', '', d)} \ | ||
| 122 | " | 125 | " |
| 123 | 126 | ||
| 124 | FILES_${PN}-virsh = " \ | 127 | FILES_${PN}-virsh = " \ |
| @@ -198,6 +201,7 @@ PACKAGECONFIG_remove_mipsarchn64 = "qemu" | |||
| 198 | 201 | ||
| 199 | # enable,disable,depends,rdepends | 202 | # enable,disable,depends,rdepends |
| 200 | # | 203 | # |
| 204 | PACKAGECONFIG[gnutls] = ",,,gnutls-bin" | ||
| 201 | PACKAGECONFIG[qemu] = "--with-qemu --with-qemu-user=qemu --with-qemu-group=qemu,--without-qemu,qemu," | 205 | PACKAGECONFIG[qemu] = "--with-qemu --with-qemu-user=qemu --with-qemu-group=qemu,--without-qemu,qemu," |
| 202 | PACKAGECONFIG[yajl] = "--with-yajl,--without-yajl,yajl,yajl" | 206 | PACKAGECONFIG[yajl] = "--with-yajl,--without-yajl,yajl,yajl" |
| 203 | PACKAGECONFIG[xenapi] = "--with-xenapi,--without-xenapi,," | 207 | PACKAGECONFIG[xenapi] = "--with-xenapi,--without-xenapi,," |
| @@ -310,6 +314,28 @@ do_install_append() { | |||
| 310 | chown -R qemu:qemu ${D}/${localstatedir}/lib/libvirt/qemu | 314 | chown -R qemu:qemu ${D}/${localstatedir}/lib/libvirt/qemu |
| 311 | echo "d qemu qemu 0755 ${localstatedir}/cache/libvirt/qemu none" \ | 315 | echo "d qemu qemu 0755 ${localstatedir}/cache/libvirt/qemu none" \ |
| 312 | >> ${D}${sysconfdir}/default/volatiles/99_libvirt | 316 | >> ${D}${sysconfdir}/default/volatiles/99_libvirt |
| 317 | |||
| 318 | if ${@bb.utils.contains('PACKAGECONFIG','gnutls','true','false',d)}; then | ||
| 319 | # Generate sample keys and certificates. | ||
| 320 | cd ${WORKDIR} | ||
| 321 | ${WORKDIR}/gnutls-helper.py -y | ||
| 322 | |||
| 323 | # Deploy all sample keys and certificates of CA, server and client | ||
| 324 | # to target so that libvirtd is able to boot successfully and local | ||
| 325 | # connection via 127.0.0.1 is available out of box. | ||
| 326 | install -d ${D}/etc/pki/CA | ||
| 327 | install -d ${D}/etc/pki/libvirt/private | ||
| 328 | install -m 0755 ${WORKDIR}/gnutls-helper.py ${D}/${bindir} | ||
| 329 | install -m 0644 ${WORKDIR}/cakey.pem ${D}/${sysconfdir}/pki/libvirt/private/cakey.pem | ||
| 330 | install -m 0644 ${WORKDIR}/cacert.pem ${D}/${sysconfdir}/pki/CA/cacert.pem | ||
| 331 | install -m 0644 ${WORKDIR}/serverkey.pem ${D}/${sysconfdir}/pki/libvirt/private/serverkey.pem | ||
| 332 | install -m 0644 ${WORKDIR}/servercert.pem ${D}/${sysconfdir}/pki/libvirt/servercert.pem | ||
| 333 | install -m 0644 ${WORKDIR}/clientkey.pem ${D}/${sysconfdir}/pki/libvirt/private/clientkey.pem | ||
| 334 | install -m 0644 ${WORKDIR}/clientcert.pem ${D}/${sysconfdir}/pki/libvirt/clientcert.pem | ||
| 335 | |||
| 336 | # Force the connection to be tls. | ||
| 337 | sed -i -e 's/^\(listen_tls\ =\ .*\)/#\1/' -e 's/^\(listen_tcp\ =\ .*\)/#\1/' ${D}/etc/libvirt/libvirtd.conf | ||
| 338 | fi | ||
| 313 | } | 339 | } |
| 314 | 340 | ||
| 315 | EXTRA_OECONF += " \ | 341 | EXTRA_OECONF += " \ |
