Setting up libvirt with DNS resolution for Vagrant

Over time there have been multiple solutions on how to get hosts to communicate with each other. Back in 2013 Dominic already wrote Automatic DNS updates from libvirt guests and the approach I’m taking here is a more automated way, taking advantage of developments in the Linux ecosystem since then.

For context, I’m using this on Fedora 44 but I expect it to work on any Linux. Make sure you’re using at least libvirt 10.1.

The first part is that your network needs to have a domain set up so libvirt will configure dnsmasq properly. If you already have a network, you can use virsh or virt-manager.

virsh net-edit default

Now make sure a domain entry with the right name exists:

<network>
  <domain name='example.com' localOnly='yes' register='yes'/>
</network>

After you restart the network:

virsh net-stop default
virsh net-start default

This is enough for hosts to be able to resolve each other.

When using systemd-resolved on the host it also works there. You verify it by using resolvectl and looking at the DNS Servers and DNS Domain entries:

$ resolvectl status virbr0
Link 7 (virbr0)
    Current Scopes: none
         Protocols: -DefaultRoute LLMNR=resolve -mDNS -DNSOverTLS DNSSEC=no/unsupported
       DNS Servers: 192.168.122.1
        DNS Domain: example.com
     Default Route: no
3 Likes

On Fedora 44, SELinux broke for me, and I don’t fully grasp it.

The setup seems fine:

root@juuni:~# ls -alhZ /etc/libvirt/hooks/
total 12K
drwxr-xr-x. 2 root root unconfined_u:object_r:virt_hook_t:s0 4.0K Sep  7 11:07 .
drwx------. 7 root root system_u:object_r:virt_etc_t:s0      4.0K Sep  7 11:07 ..
-rwxr-xr-x. 1 root root unconfined_u:object_r:virt_hook_t:s0 2.5K Sep  7 11:07 network
root@juuni:~# semanage boolean -l |grep virt_hooks
virt_hooks_unconfined          (on   ,   on)  Allow virt daemons run unconfined hooks

Yet I am getting a denial:

type=AVC msg=audit(1788849966.333:793): avc:  denied  { execute } for  pid=112435 comm="rpc-virtnetwork" name="env" dev="dm-1" ino=1448486 scontext=system_u:system_r:virtnetworkd_t:s0 tcontext=system_u:object_r:bin_t:s0 tclass=file permissive=0

audit2allow tells me to either do corecmd_exec_bin(virtnetworkd_t) or allow virtnetworkd_t bin_t:file execute; :face_with_spiral_eyes:

Works here on Fedora 44 CSB with enforced. Hmmm.

Edit: Perhaps some libvirt plugin you installed?

[root@yuki ~]# ls -alhZ /etc/libvirt/hooks/
ls: cannot access '/etc/libvirt/hooks/': No such file or directory

Where is the hook installed to, if not to /etc/libvirt/hooks/?

Not sure what hook are you talking about, the DNS resolution works via dnsmasq and that seems to be a core feature of libvirt (I think). What RPM package your hook comes from?

The second part of Ewouds post above? So that my host can also resolve that DNS via systemd-resolved.

Aaaah sorry, I skipped that. Ignore my nonsense :slight_smile:

And to solve the mystery: it works if you use the monolithic libvirtd daemon, but not when using the virtnetworkd.

No idea why (it should transition either way according to Add support for libvirt hooks by zpytela · Pull Request #2195 · fedora-selinux/selinux-policy · GitHub) , but I am happy enough it works now.

I love talking to myself. And people who know libvirt.

If you use register='yes' in that snippet

<domain name='juuni.example.com' localOnly='yes' register='yes'/>

you don’t need a hook at all, and no SELinux shenanigans either.

Available since libvirt 10.1

2 Likes

That’s great! I’ve updated the tutorial to be simplified.

I do wonder if vagrant-libvirt can also pass register="yes" when creating the network. That would simplify GitHub - voxpupuli/setup-vagrant · GitHub

GitHub uses Ubuntu 24.04, which has libvirt 10.0, not 10.1 :confused: