KVM Virtual Manager Network Timeout

Small and simple guest operating systems (i.e. those not running many services) can tend to have network difficulties when using the default KVM and Virtual Machine Manager virtualization. I use a very small Debian etch guest that is a mirror of an identical small machine elsewhere. If the guest OS does not use the network connection for around 10 minutes, the idle network can become disconnected. This is actually a result of the iptables NAT setup by the Virtual Manager.

This can be seen, for example, in tea breaks. If you have an ssh connection into the VM guest and then decide to go and make a cup of tea, after about 15 minutes of inactivity you may come back to find the ssh connection locked up and the entire network connection to the guest down. It is certainly possible to login to the guest console (e.g. using the Virtual Machine Manager) and start and stop the network on the VM again, but this is not ideal.

What is happening is the NAT connection tracking information is timing out. Inactivity for too long can cause the NAT to "forget" what to do with a particular connection and so it drops it. A simple solution is to adjust the system's TCP "keepalive" time. This value determines how often TCP "keepalive" packets are sent in order to keep a connection alive. By decreasing the time interval (i.e. increasing the frequency of such packets) so that the NAT TCP connection tracking does not time out, we can prevent the NAT dropping TCP connections.

The TCP "keepalive" time can be set in the sysctl configuration file /etc/sysctl.conf. In GNU/Linux, the default keepalive time is 7200 seconds (two hours). The lower we reduce it the more network traffic there will be. Adding the following line to the sysctl.conf will change the keepalive time to 2 minutes:

#tcp keepalive reduction for the NAT net.ipv4.tcp_keepalive_time=120

The units are in seconds, and choosing a specific value depends on the NAT and the machine network load. This change will take effect after a reboot. To make an immediate change, we can use the /proc filesystem:

#echo "120" > /proc/sys/net/ipv4/tcp_keepalive_time

Note, changes made only using the /proc filesystem will be lost after a reboot, upon which the system goes back to its defaults. Changes made in the /etc/sysctl.conf persist across reboots.