This was made when I was using a Debian host and an Alpine guest, as well as with virt-manager.
This has a heavy assumption that you’re using virt-manager for creating the default network, this may still be valuable, but that might explain things why the default network isn’t configured the way it is and the network for the VM.
This uses NAT forwarding, which does work on wireless cards. I’m running this on a laptop under my bed for a home server.
Inside of virt-manager, after creating the VM and ensuring that networking is working, look at the XML section for the network.
(You can also find this by running sudo virsh edit vm-name
)
The MAC address, 52:54:00:c7:cb:b2
, will be useful for this upcoming step.
Next, we want to edit the default
network, or whichever network you’re using idc but that’s the one that’s created for you by virt-manager.
<network>
<name>default</name>
...
<ip address="192.168.122.1" netmask="255.255.255.0">
<dhcp>
<range start="192.168.122.2" end="192.168.122.254"/>
<host mac="52:54:00:c7:cb:b2" name="vmname" ip="192.168.122.100"/>
</dhcp>
</ip>
</network>
You’re going to want to find the ip
section in the network configuration as is shown above.
Note the host
property.
- You’re going to want to set the
mac
value to the MAC address value from before. - If the VM name is
windows-7
, you’re going to want to change thename
property from"vmname"
to"windows-7"
. - Lastly, you’re going to want to set the
ip
property to be in the range between thestart
and theend
, so since100
is between2
and254
, it’s perfectly valid here.
Next step is to set this static IP at /etc/network/interfaces
in the guest OS.
auto eth0
iface eth0 inet static
address 192.168.122.100
netmask 255.255.255.0
gateway 192.168.122.1
The address
should be set to the ip
property that we set for the host
, and the gateway
and netmask
property align with the values of address
and netmask
in the above configuration.
After rebooting the VM, you should see that the static IP has been configured.
Lastly, you’re going to want create a hook for libvirt to route the ports from that VM through the host to the outside world.
Create this file at /etc/libvirt/hooks/qemu
#!/bin/bash
# IMPORTANT: Change the "VM NAME" string to match your actual VM Name.
# In order to create rules to other VMs, just duplicate the below block and configure
# it accordingly.
if [ "${1}" = "vm-name" ]; then
# Update the following variables to fit your setup
GUEST_IP=192.168.122.100
# You're running an application on port 8080 on the guest
GUEST_PORT=8080
# You want to expose port 80 to the internet and have it route to the guest's application
HOST_PORT=80
if [ "${2}" = "stopped" ] || [ "${2}" = "reconnect" ]; then
/sbin/iptables -D FORWARD -o virbr0 -p tcp -d $GUEST_IP --dport $GUEST_PORT -j ACCEPT
/sbin/iptables -t nat -D PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT
fi
if [ "${2}" = "start" ] || [ "${2}" = "reconnect" ]; then
/sbin/iptables -I FORWARD -o virbr0 -p tcp -d $GUEST_IP --dport $GUEST_PORT -j ACCEPT
/sbin/iptables -t nat -I PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT
fi
fi
You’re going to want to set the GUEST_IP
, GUEST_PORT
, and HOST_PORT
ports accordingly.
You’re also going to want to make this executable using chmod: chmod +x /etc/libvirt/hooks/qemu
You’re then going to have to restart libvirtd: sudo systemctl restart libvirtd
For me, I did it on port 4030
and exposed it to port 4030
on the host.