Port Forwarding from Host to Guest with libvirt 0.8.3 Using KVM on Ubuntu

15,109

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.

Share:
15,109

Related videos on Youtube

cc315
Author by

cc315

Updated on September 17, 2022

Comments

  • cc315
    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
      Art Shayderov over 13 years
      external - 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
      cc315 over 13 years
      I can only get one Internet IP address, that's why I didn't use bridged networking mode.
  • cc315
    cc315 over 13 years
    I 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
    David Corsalini over 13 years
    ah, then it's another matter. basically libvirt manages it's own NAT solution, which can be edited.
  • cc315
    cc315 over 13 years
    yeah, 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
    Art Shayderov over 13 years
    If 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
    mttdbrd over 9 years
    I know it's a few years old but this answer worked for me. Thanks!
  • Amir Ali Akbari
    Amir Ali Akbari over 9 years
    Trusty 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.