diff --git a/README.md b/README.md index 03378931..6d18373d 100644 --- a/README.md +++ b/README.md @@ -697,7 +697,7 @@ python manage.py test `TEST_LIBVIRT_GUEST_IMAGE` enables the tests that need a guest OS (disk and NIC hot-unplug, vCPU hotplug, guest agent, ACPI power off). It must be an installed, BIOS-bootable Linux qcow2 image with qemu-guest-agent, in a storage pool of the host other than `wvc-test`; the tests boot copies of it from overlays and only read the image. Shut down any VM using it first. -Two disposable compute nodes for these tests come from the `Vagrantfile`: AlmaLinux 10 with nested KVM, set up by `dev/libvirt-bootstrap.sh` (with this checkout's gstfsd), a SASL user for TCP (`wvc`, password `wvc-test`) and your `~/.ssh/id_ed25519.pub` for root; migration runs between them, and each has an empty second disk (`/dev/vdb`) for the LVM tests and serves a 1 GiB iSCSI LUN on 127.0.0.1 for the iSCSI test. It needs Vagrant with the `vagrant-libvirt` plugin, a KVM host with `qemu-kvm` and `cyrus-sasl-md5`, and a user in the `libvirt` group. On a host that also runs Docker, let the VMs' network (the bridge of `virsh net-info vagrant-libvirt`, `virbr1` here) through Docker's forward rules (`sudo iptables -I DOCKER-USER -i virbr1 -j ACCEPT` and `sudo iptables -I DOCKER-USER -o virbr1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT`). +Two disposable compute nodes for these tests come from the `Vagrantfile`: AlmaLinux 10 with nested KVM, set up by `dev/libvirt-bootstrap.sh` (with this checkout's gstfsd), a SASL user for TCP (`wvc`, password `wvc-test`) and your `~/.ssh/id_ed25519.pub` for root; migration runs between them, and each has an empty second disk (`/dev/vdb`) for the LVM tests and serves a 1 GiB iSCSI LUN on 127.0.0.1 for the iSCSI test. They accept TLS logins (SASL) with certificates from a throwaway CA that `vagrant up` makes in `.vagrant/tls`; the TLS run takes its client certificate from there through `HOME`. It needs Vagrant with the `vagrant-libvirt` plugin, a KVM host with `qemu-kvm` and `cyrus-sasl-md5`, and a user in the `libvirt` group. On a host that also runs Docker, let the VMs' network (the bridge of `virsh net-info vagrant-libvirt`, `virbr1` here) through Docker's forward rules (`sudo iptables -I DOCKER-USER -i virbr1 -j ACCEPT` and `sudo iptables -I DOCKER-USER -o virbr1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT`). ```bash vagrant up --provider=libvirt @@ -706,6 +706,7 @@ for h in $C1 $C2; do ssh-keygen -R $h; ssh -o StrictHostKeyChecking=accept-new r export TEST_LIBVIRT_HOST=$C1 TEST_LIBVIRT_TYPE=1 TEST_LIBVIRT_LOGIN=wvc TEST_LIBVIRT_PASSWORD=wvc-test export TEST_LIBVIRT_SSH_HOST=$C2 TEST_LIBVIRT_SSH_LOGIN=root TEST_LIBVIRT_MIGRATE_ADDRESS=$C2 TEST_LIBVIRT_LVM_DEVICE=/dev/vdb TEST_LIBVIRT_ISCSI_TARGET=iqn.2026-10.test.wvc:lun python manage.py test +HOME=$PWD/.vagrant/tls TEST_LIBVIRT_TYPE=3 TEST_LIBVIRT_SSH_HOST= python manage.py test # compute1 again, over TLS vagrant destroy -f ``` diff --git a/Vagrantfile b/Vagrantfile index beb02ca2..586df600 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -3,7 +3,23 @@ # dev/libvirt-bootstrap.sh, with a SASL user for TCP and the host user's SSH # key for root (SASL user wvc, password wvc-test). The empty second disk # /dev/vdb is for the LVM tests (TEST_LIBVIRT_LVM_DEVICE); each also serves a -# 1 GiB iSCSI LUN on 127.0.0.1 for the iSCSI tests (TEST_LIBVIRT_ISCSI_TARGET). +# 1 GiB iSCSI LUN on 127.0.0.1 for the iSCSI tests (TEST_LIBVIRT_ISCSI_TARGET), +# and accepts TLS logins (SASL) with a certificate from a throwaway CA. + +# The CA is made here once; each compute signs its own certificate with it. +# The client certificate sits where libvirt looks with HOME=.vagrant/tls. +pki = File.join(__dir__, ".vagrant/tls/.pki/libvirt") +unless File.exist?(File.join(pki, "clientcert.pem")) + # the host's openssl, not the one Vagrant puts first on PATH + Vagrant::Util::Env.with_original_env do + system("sh", "-ec", <<-SH, pki, exception: true) + mkdir -p "$0" && cd "$0" + openssl req -x509 -newkey rsa:3072 -nodes -keyout cakey.pem -out cacert.pem -days 365 -subj /CN=wvc-test-ca + openssl req -new -newkey rsa:3072 -nodes -keyout clientkey.pem -subj /CN=wvc-test-client | + openssl x509 -req -CA cacert.pem -CAkey cakey.pem -days 365 -out clientcert.pem + SH + end +end Vagrant.configure(2) do |config| config.vm.box = "almalinux/10" @@ -23,6 +39,8 @@ Vagrant.configure(2) do |config| config.vm.provision "file", source: "dev", destination: "/tmp/wvc/dev" config.vm.provision "file", source: "conf", destination: "/tmp/wvc/conf" config.vm.provision "file", source: "~/.ssh/id_ed25519.pub", destination: "/tmp/wvc/key.pub" + config.vm.provision "file", source: "#{pki}/cacert.pem", destination: "/tmp/wvc/cacert.pem" + config.vm.provision "file", source: "#{pki}/cakey.pem", destination: "/tmp/wvc/cakey.pem" config.vm.provision "shell", inline: <<-SHELL set -e sh /tmp/wvc/dev/libvirt-bootstrap.sh @@ -42,5 +60,14 @@ Vagrant.configure(2) do |config| targetcli /iscsi/$T/tpg1 set attribute generate_node_acls=1 demo_mode_write_protect=0 targetcli saveconfig } + install -D -m 644 /tmp/wvc/cacert.pem /etc/pki/CA/cacert.pem + install -d /etc/pki/libvirt/private + echo "subjectAltName=IP:$(hostname -I | cut -d' ' -f1)" > /tmp/wvc/ext + openssl req -new -newkey rsa:3072 -nodes -keyout /etc/pki/libvirt/private/serverkey.pem -subj /CN=$(hostname) | + openssl x509 -req -CA /tmp/wvc/cacert.pem -CAkey /tmp/wvc/cakey.pem -days 365 -extfile /tmp/wvc/ext -out /etc/pki/libvirt/servercert.pem + sed -i 's/^#auth_tls = "none"/auth_tls = "sasl"/' /etc/libvirt/virtproxyd.conf + # a running service would keep the old settings and refuse a new socket + systemctl stop virtproxyd.service + systemctl enable --now virtproxyd-tls.socket SHELL end