I have a server with one external IP address (e.g. 1.2.3.4). On that server I use libvirt to run virtual machines. Now I want to access a virtual server on my host via ssh (port 1234) from the outside.

On my host system I got a network interface eth0 which is connected to my outside IP (1.2.3.4).

My virtual machine is connected to the host machine via a nat interface called virbr0 with the ip 192.168.122.235.

As I need to forward a port I did the following with iptable

iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 1234 -j DNAT --to-destination 192.168.122.235:1234

iptables -A FORWARD -p tcp -d 192.168.122.235 --dport 1234 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

For basic networking I also got UFW running on the host allows port 1234:

Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), allow (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
[SOMEOTHERPORTS]
1234/tcp                  ALLOW IN    Anywhere
1234/tcp (v6)             ALLOW IN    Anywhere (v6)

I made sure that forwarding is allowed for all involved network interfaces:

user@someserver ~ # cat /proc/sys/net/ipv4/conf/virbr0/forwarding 
1
user@someserver ~ # cat /proc/sys/net/ipv4/conf/eth0/forwarding 
1

When trying to connect via ssh to the server from the outside network to 1.2.3.4 I get:

ssh: connect to host 1.2.3.4 port 1234: Connection refused

I checked the ssh connection from the host, which is working perfectly.

  • What am I doing wrong here?
  • Does UFW interfere with iptables?
  • How can I get this working?
  • Is there an easier way to do port forwarding with libvirt / virt-manager? (I tried this: http://secomputing.co.uk/2012/02/21/Forwarding-ports-to-KVM-clients/ which did not work either because XML is not valid when changing to / it does validate but not work if I let it on "network")

There are a few things we should consider.

What am I doing wrong here?

Let's see the current iptables config and then we can examine it.

Does UFW interfere with iptables?

UFW is a command line front end for iptables but it lacks many of the features of iptables. Having the iptables configuration will show us what UFW has done based on the commands you entered. You should not however, create rules with both on the same computer. That is asking for complications. If you are going to enter your commands in UFW fine but iptables scripts should be disabled. If you are going to enter your commands in iptables then you should remove UFW.

How can I get this working?

Try this.

iptables -t nat -I PREROUTING -p tcp -i eth0 --dport 1234 -j DNAT --to 192.168.122.235:1234

iptables -A FORWARD -i eth0 -o vibr0 -p tcp --dport 1234 -j ACCEPT

But keep in mind that the guest is connected to the host using NAT with the adapter. So this probably won't work.

What you really should consider is changing the adapter type from NAT to bridged.


I had virtually the same issue. I wanted to forward port 22 from my host machine to my VM, also running KVM, with NAT network.

I found this post: https://ubuntuforums.org/showthread.php?t=2261173&p=13210545#post13210545

Which had the answers for me.

TL;DR

192.168.1.161 is my servers IP on the internal network. 192.168.122.2 is my VMs ip on the host.

iptables -t nat -I PREROUTING -p tcp -d 192.168.1.161 --dport 22 -j DNAT --to-destination 192.168.122.2:22
iptables -I FORWARD -m state -d 192.168.122.2/24 --state NEW,RELATED,ESTABLISHED -j ACCEPT 

Disclaimer. I have no idea what this does exactly. It looks the same as many other answers ive found, just some of the parameter tags being slightly different.