a bit of a warning: the NAT fowarding script is a bit of hardcore kvm “hack” that might not work (kvm is under development), wish to kvm and virsh-manager developers: please please integrate an easy way (like in virtualbox) for
- direct (bridged) and
- NAT connecting VMs = making (for security reasons) only certain ports of the vm publicly available in virsh-manager
- thanks! 🙂
thanks to this excellent script it is now possible to nat-port forward multiple ports from:
[internet]<->port:host<->vm
thanks & great work all invovled 🙂
here is the script: etc_libvirt_hooks_qemu.txt
(and here an older backup of the same)
in NAT mode, the host firewall stands between the wild wild west inet and the guest vm.
in order to allow certain ports through (webserver: 80/443), a bit of config hazzle has to be done.
note: this article is a result of “quick note taking” process and is not of the quality, one would like to see and will have to be refined further, follow the instructions to install the script.
just ignore the rest and study the manual here: https://github.com/doccaz/kvm-scripts
and the admin-user should have no problems getting port-nat-forwarding to work 🙂
- give vm a fixed ip
- this needs to be configured inside the vm, to not use dhcp but stick with a static ip
- plus: via “virsh net-edit default” tell kvm that this vm will use that fixed ip
# how to nat host-port pass-through to kvm guest-vm /etc/libvirt/hooks/qemu
https://github.com/doccaz/kvm-scripts
howto virsh set fixed ip
ssh into server and become root
su - root
download the qemu-hook-script and name it qemu
wget https://raw.githubusercontent.com/doccaz/kvm-scripts/master/qemu-hook-script -O qemu
copy into place
mv -v qemu /etc/libvirt/hooks/qemu
# what port of what vm (webserver3) shall be publicly accessible? (webserver usually: tcp@80, tcp@443) # need to find out mac of webserver3 virsh dumpxml webserver3 | grep -i '<mac' <mac address='52:54:00:4e:51:cf'/> <host mac='52:54:00:4e:51:cf' name='webserver3' ip='192.168.122.204'/> # show what vms have what dhcp asigned ip virsh net-dhcp-leases default Expiry Time MAC address Protocol IP address Hostname Client ID or DUID -------------------------------------------------------------------------------------------------------------------------------------------------- 2021-08-06 11:34:37 52:54:00:4e:51:cf ipv4 192.168.122.204/24 webserver3 ff:00:4e:51:cf:00:01:00:01:28:9a:76:3d:52:54:00:11:c1:e0 # (of course) make sure the webserver is working # for example: generate test page within webserver3 like echo "<h1>hello world</h1>" > /home/user/web/domain.com/index.html
asign fixed ip to webserver3:
which means: the kvm-dhcp server will know, this ip is taken and not re-assign it to other vms
# inside vm: vim /etc/network/interfaces # This file describes the network interfaces available on your system # and how to activate them. For more information, see interfaces(5). source /etc/network/interfaces.d/* # The loopback network interface auto lo iface lo inet loopback # The primary network interface # allow-hotplug enp1s0 # iface enp1s0 inet dhcp auto enp1s0 iface enp1s0 inet static address 192.168.122.204 netmask 255.255.255.0 gateway 192.168.122.1 # on kvm-host-sever: edit the kvm networking config file # to announce that those VMs will use a fixed ip virsh net-edit default <network> <name>default</name> <uuid>82bac856-ef6f-4777-8c29-e296483b4856</uuid> <forward mode='nat'/> <bridge name='virbr0' stp='on' delay='0'/> <mac address='52:54:00:eb:93:ad'/> <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:4e:51:cf' name='vm1' ip='192.168.122.204'/> <host mac='52:54:00:52:3e:f6' name='vm2' ip='192.168.122.166'/> <host mac='52:54:00:b0:7b:b9' name='vm3' ip='192.168.122.203'/> </dhcp> </ip> </network> # to make the changes of net-edit active virsh net-destroy default && virsh net-start default # now add admin-unser-defined rules at the end of config file like vim /etc/libvirt/hooks/qemu ### webserver3: addForward webserver3 enp7s0 public.ip.of.hostsrv 80 virbr0 192.168.122.204 80 tcp addForward webserver3 enp7s0 public.ip.of.hostsrv 443 virbr0 192.168.122.204 443 tcp # every time changes are made to the above qemu networking config file # 1) all vms need to be shut down # 2) networking needs to be restarted with a special script for i in $(virsh list | grep running | awk '{print $2}'); do virsh shutdown $i; done # restart the virtual networking / to make changes active virsh net-destroy default; virsh net-start default; # download and install the networking-restart script wget https://raw.githubusercontent.com/doccaz/kvm-scripts/master/kvm-network-restart # install it mv -v kvm-network-restart /usr/sbin/kvm-network-restart chmod +x /usr/sbin/kvm-network-restart # run it to start network called 'default' /usr/sbin/kvm-network-restart default # now start all vms and test if ports are publicly available :)
liked this article?
- only together we can create a truly free world
- plz support dwaves to keep it up & running!
- (yes the info on the internet is (mostly) free but beer is still not free (still have to work on that))
- really really hate advertisement
- contribute: whenever a solution was found, blog about it for others to find!
- talk about, recommend & link to this blog and articles
- thanks to all who contribute!