KVM

From CSCWiki
Revision as of 10:03, 7 August 2021 by Merenber (talk | contribs)
Jump to navigation Jump to search

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.