External network requests not seen in KVM guest

Hi all,

I’m having further difficulties with my KVM guest and networking. This is getting rather frustrating! I’ve spent a number of hours on it today with no success, so I’m hoping someone will lend a hand. :slight_smile:

In this case I am trying to set up an Apache web server in the guest, which is working fine. I say this because the host can load the welcome page correctly. However, I cannot get to it from outside the host. I can get to Apache running on the host from outside, but not the guest.

Looking in to it further, I don’t see any traffic coming in to the guest on port 80 with tcpdump. This led me to believe again that the routing is not working correctly. I reviewed the setup in iptables, and it looks fine to me.

I even tried numerous times to set up some more specific routing, in order to do things like redirect the traffic to port 8080 etc. but I cannot see the traffic in the guest, and cannot get a page from the web server.

I’m not really sure what to do at this point, because things appear to be set up correctly to me and I cannot find any errors logged. With that said, I’m not familiar with libvirt at all, and networking is not my strong suit, so I may be missing something simple. I’ve read numerous posts online how to set this up, but they all talk about using iptables to route the traffic, which has already been done.

Here is what libvirt sets up for iptables:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
LIBVIRT_INP  all  --  anywhere             anywhere            

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
LIBVIRT_FWX  all  --  anywhere             anywhere            
LIBVIRT_FWI  all  --  anywhere             anywhere            
LIBVIRT_FWO  all  --  anywhere             anywhere            

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
LIBVIRT_OUT  all  --  anywhere             anywhere            

Chain LIBVIRT_FWI (1 references)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             192.168.122.0/24     ctstate RELATED,ESTABLISHED
REJECT     all  --  anywhere             anywhere             reject-with icmp-port-unreachable

Chain LIBVIRT_FWO (1 references)
target     prot opt source               destination         
ACCEPT     all  --  192.168.122.0/24     anywhere            
REJECT     all  --  anywhere             anywhere             reject-with icmp-port-unreachable

Chain LIBVIRT_FWX (1 references)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere            

Chain LIBVIRT_INP (1 references)
target     prot opt source               destination         
ACCEPT     udp  --  anywhere             anywhere             udp dpt:domain
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:domain
ACCEPT     udp  --  anywhere             anywhere             udp dpt:bootps
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:bootps

Chain LIBVIRT_OUT (1 references)
target     prot opt source               destination         
ACCEPT     udp  --  anywhere             anywhere             udp dpt:domain
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:domain
ACCEPT     udp  --  anywhere             anywhere             udp dpt:bootpc
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:bootpc

Here is the nat table from libvirt:

Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
LIBVIRT_PRT  all  --  anywhere             anywhere            

Chain LIBVIRT_PRT (1 references)
target     prot opt source               destination         
RETURN     all  --  192.168.122.0/24     base-address.mcast.net/24 
RETURN     all  --  192.168.122.0/24     255.255.255.255     
MASQUERADE  tcp  --  192.168.122.0/24    !192.168.122.0/24     masq ports: 0-65535
MASQUERADE  udp  --  192.168.122.0/24    !192.168.122.0/24     masq ports: 0-65535
MASQUERADE  all  --  192.168.122.0/24    !192.168.122.0/24    

The simplest way is setting up the host connection as a bridge shared with the guests:

1 Like

I tried this, but now virsh just “hangs” instead of returning any output. I tried restarting libvirtd and it halts the system. That may be related to the halt I’ve mentioned before being triggered by one of the VMs, but it has never halted at boot before like that.

I’ll have to investigate later, but for now my VMs are all down. :frowning:

Collect the diagnostics and post it to pastebin.com redacting the private parts:

ip address show; ip route show table all; ip rule show; \
brctl show; nmcli connection show; cat /etc/qemu/bridge.conf

Thanks. I have everything running again after a fair bit of reconfiguring.

The bridge seems to be working, but I’m not sure. I think I need another few steps to get network access in the guest now.

I’m not really familiar with how a bridge like this works or is set up, so I need to read up on that. If it works like a switch, then I suppose I need to get some routing set up.

Thanks for your help so far. :slight_smile:

Note that it requires no extra routing or firewall configuration.
The VM should simply fetch an IP address in your LAN subnet.

1 Like

Thank you.

Currently I do not have a LAN subnet set up, because I’ve been having problems with my physical router. Interestingly, it seems to be the exact same problem as in my OP.

I suppose the easiest thing to do would be to buy a new router that actually works correctly. However I’m hesitant to do that because I don’t understand what the problem actually is.

You can try to back up and reset the router configuration to factory defaults.
Also upgrade the firmware to the latest stable release, if possible use OpenWrt.

1 Like

Thanks again.

I’ve tried all that, and it helped a bit, but I’m still unable to get connected properly. At this point I see traffic on the host inside of the router, but I’m still getting connection denied. When I remove the router, the connection works perfectly.

I suspect that the router is responding to requests itself. I’m guessing it is broadcasting instead of forwarding traffic. Unfortunately it is an old router, so I doubt I will be able to find any support or an OpenWRT image for it. However I will be sure to buy a router with an OpenWRT image in the future. Thanks for mentioning that.

1 Like

After some further testing, it seems that the bridge is working correctly and the router is actually routing traffic as opposed to broadcasting it.

When I “forward” port 22 to my host, it says “connection refused”. When I “forward” port 22 to the guest, it says “No route to host”.

I don’t know what this router is really doing, but that’s beyond the scope of this post. I’m a bit sad I haven’t gotten this to work yet. When I worked more with networking 10+ years ago the fundamental concepts were fairly straightforward. I worked mostly with storage networks, but most of the principals are the same.

I’m tempted to try setting up the host as a router. I expect I could get it to work when I have full (CLI) control over it. The only problem is that I read I likely need specific firmware to route using a wireless interface.

So, you need to utilize other methods to access guests if your host has only wireless connection.

Yeah… obviously there’s more to it, given the existence of OpenWRT and such, but it isn’t easy.

I don’t need to bridge wireless to the guests, I only need it for other devices in the building. The underlying issues remains though.

I have no problem accessing my VMs on the host. I set up bridge networking. The host has IP 192.168.122.1 on virbr0. The host also gets IP 192.168.2.111 on the WLAN.
The guests all get an address in the 192.168.122.0/24 subnet (also on virbr0), one of which is 192.168.122.66. From the host I can talk directly to the guest at the above IP.

On my gateway router I set up a route for the 192.168.122.0/24 subnet that is directed to the host at 192.168.2.111. Once that was done then any other device on my WLAN can contact my VMs simply by knowing which IP to use. My laptop can talk to the VM at 192.168.122.66 with ssh flawlessly including using “ssh -X” to get a gui display from the app. I have not gone to the hassle of assigning host names anywhere except in /etc/hosts on my other PCs but everything just works as is.