KVM
Here are some recommendations for creating new virtual machines (VMs).
Prerequisites
Working with libvirt is much easier than working with the raw QEMU commands, so make sure to have it installed:
apt install qemu-system libvirt-clients libvirt-daemon-system virtinst
VM Creation
Let's say we want to create a new VM for progcom. First, create a new volume for it:
lvcreate -L 40G vg0 --name progcom
Next, run virt-install:
virt-install \ --connect qemu:///system \ --name progcom \ --virt-type kvm \ --memory 8192 \ --vcpus 4 \ --cpu host \ --disk path=/dev/vg0/progcom,format=raw,bus=virtio \ --network bridge=br0,model=virtio \ --graphics none \ --video virtio \ --serial pty \ --extra-args 'console=ttyS0,115200n8' \ --os-type linux \ --os-variant debian10 \ --location http://mirror.csclub.uwaterloo.ca/debian/dists/stable/main/installer-amd64
This will start the Debian installer on your console. It should be possible to automate the installation using preseeding.
Post-creation
Make sure you run through the steps outlined in New CSC Machine. After you do that, you should be able to ditch the virsh console and SSH in from anywhere.
You probably want the VM to start on boot, so enable that:
virsh autostart progcom
Optional, but recommended: if the VM will be used by potentially untrusted people, it is a good idea to apply libvirt firewall rules to the VM to prevent IP/MAC/ARP spoofing. On Debian 10, some IPv6 filters are missing (they are present in Debian 11), so we will add them now:
cat >no-ipv6-spoofing.xml <<EOF <filter name='no-ipv6-spoofing' chain='ipv6-ip' priority='-610'> <uuid>79872560-4387-472d-8c21-39c2a0db7873</uuid> <rule action='return' direction='out' priority='100'> <ipv6 srcipaddr='fe80::' srcipmask='10' protocol='udp'/> </rule> <rule action='return' direction='out' priority='500'> <ipv6 srcipaddr='$IPV6'/> </rule> <rule action='drop' direction='out' priority='1000'/> </filter> EOF cat >allow-ipv6.xml <<EOF <filter name='allow-ipv6' chain='ipv6' priority='-600'> <uuid>941a84d2-f4de-4692-aebd-3fec521f576a</uuid> <rule action='accept' direction='inout' priority='500'/> </filter> EOF virsh nwfilter-define no-ipv6-spoofing.xml virsh nwfilter-define allow-ipv6.xml rm no-ipv6-spoofing.xml rm allow-ipv6.xml
Now we will add those filters to the clean-traffic filter. Run virsh nwfilter-edit clean-traffic
, and inside the <filter>
tag, add the rules which we just created:
<filter name='clean-traffic' chain='root'> ... <filterref filter='no-ipv6-spoofing'/> <rule action='accept' direction='out' priority='-650'> <mac protocolid='ipv6'/> </rule> <filterref filter='allow-incoming-ipv6'/> </filter>
Now shutdown the VM, run virsh edit progcom
, and insert the following into the <interface>
tag:
<interface type='bridge'> ... <filterref filter='clean-traffic'> <parameter name='IP' value='129.97.134.3'/> <parameter name='IPV6' value='2620:101:f000:4901:c5c::3'/> </filterref> </interface>
Replace the IP and IPV6 values with the desired IPv4 and IPV6 addresses of the VM, respectively. Now, if someone inside the VM tries to change their IP or MAC address, the ebtables and iptables rules on the host will reject their packets.