Port Forwarding from Host to Guest with libvirt 0.8.3 Using KVM on Ubuntu
Solution 1
Here is a better way to set up port forwarding, using a hook script (source).
In /etc/libvirt/hooks/qemu
:
#!/bin/sh
GUEST_NAME=
HOST_PORT=
GUEST_IPADDR=
GUEST_PORT=
if [ "$1" = "$GUEST_NAME" ]; then
if [ "$2" = start ]; then
iptables -t nat -A PREROUTING -p tcp --dport "$HOST_PORT" \
-j DNAT --to "$GUEST_IPADDR:$GUEST_PORT"
iptables -I FORWARD -d "$GUEST_IPADDR/32" -p tcp -m state \
--state NEW -m tcp --dport "$GUEST_PORT" -j ACCEPT
elif [ "$2" = stopped ]; then
iptables -t nat -D PREROUTING -p tcp --dport "$HOST_PORT" \
-j DNAT --to "$GUEST_IPADDR:$GUEST_PORT"
iptables -D FORWARD -d "$GUEST_IPADDR/32" -p tcp -m state \
--state NEW -m tcp --dport "$GUEST_PORT" -j ACCEPT
fi
fi
You should set the four variables at the top to fit your libvirt setup.
You will need to restart libvirt-bin, which on ubuntu is done with:
sudo sh -c 'service libvirt-bin stop; service libvirt-bin start'
then you will need to restart the guest. On Ubuntu, you will need to adjust /etc/apparmor.d/usr.sbin.libvirtd
to allow the hook script to execute:
Next to
/usr/sbin/* PUx,
append
/etc/libvirt/hooks/* PUx,
Then reload apparmor:
sudo service apparmor reload
There's probably a way to autoconfigure $GUEST_IPADDR
using virsh / dumpxml / iface-dumpxml, but I haven't found it. Alternatively, the IP can be set statically in the network xml: documentation.
As far as I can tell, network filters can only be used for restricting what happens on the virtual network, and they aren't useful for port forwarding.
Solution 2
I'm in a similar situation. I have a Windows Server running in KVM in the private NATed network which is connected on the host via the interface virbr0. I want to do access the VM via remote desktop. So I have to forward the traffic to port 3389 (RDP) to the VM port 3389. I have achieved this with some iptable rules.
/sbin/iptables -t nat -A PREROUTING -p tcp -d HOST-IP --dport 3389 -j DNAT --to-destination VM-IP:3389
/sbin/iptables -I FORWARD -m state -d VM-NET/24 --state NEW,RELATED,ESTABLISHED -j ACCEPT
HOST-IP, VM-IP, and VM-NET have to be adopted of course. However messing with iptables and libvirt is tricky. Right now I'm searching for an solution to get internet access on my VM which I have lost due to messing with the iptable rules :-(
Solution 3
I believe that the answer you reference still shows appropriate iptables rules. However, now you could use a script hook to create and destroy rules when virtual machines are started and stopped. Like Isaac said in the previous answer, there are also network filters in current libvirt but I'm not sure how or even if they can be used to open ports for NATed guests.
Related videos on Youtube
cc315
Updated on September 17, 2022Comments
-
cc315 almost 2 years
The host has a single external IP available, so I set my KVM guests up with NAT.
How do I set up a port forwarding to forward some of the requests from the outside to the guests?
I couldn't find any documentation on this. The closest answer is probably this answer,but then it's also mentioned there is easier way to do this in libvirt 0.8.3. Does anyone know of a more current way to do this?
-
Art Shayderov over 13 yearsexternal - you mean internet IP? or just your LAN (external to VMs)? Can you allocate those external addresses to your VMs to set up bridged networking?
-
cc315 over 13 yearsI can only get one Internet IP address, that's why I didn't use bridged networking mode.
-
-
cc315 over 13 yearsI guess I didn't say it ver clearly. The host is not in a NAT, it has an external IP address. Unfortunately, the guest networking is behind the NAT set up by libvirt.
-
David Corsalini over 13 yearsah, then it's another matter. basically libvirt manages it's own NAT solution, which can be edited.
-
cc315 over 13 yearsyeah, that's what I have been told, it can be edited. But I am just can't find any reference about it, the nwfilter xml configuration files just seem like bizarre to me, the documentation on libvirt website isn't very helpful either.
-
Art Shayderov over 13 yearsIf you have bridged networking you can just abandon the default libvirt NAT and setup anything you want. As dyasny said, treat VM as you would a physical machine. I have KVM host and interface with external IP is assigned to a VM which is configured as a gateway. If that suits you needs I can post the configuration (ubuntu-style).
-
mttdbrd over 9 yearsI know it's a few years old but this answer worked for me. Thanks!
-
Amir Ali Akbari over 9 yearsTrusty has a line
/etc/libvirt/hooks/** rmix,
in apparmor config file by default, and it seems to has the same effect. I could run the script without modifying apparmor configuration.