I’ve been running several game daemons off my primary internal server for a while now. Some of these game daemons are accessible from the Internet. From a security stand-point, this is not a good idea. So I’ll be creating a new KVM virtual private server (VPS) instance for game daemons and placing it in the network’s demilitarized zone (DMZ).

Create the disk image

First we will create a new disk image to hold the instance. The game data currently takes up about a gigabyte of storage. However, it’s a good idea to reserve some extra space for future needs. About 30 gigabytes should be sufficient for the OS, game data, and anything else we decide to add.

Listing 1: Create a KVM disk image.

kvm $ qemu-img create -f qcow2 games.img 30G

Formatting ‘games.img’, fmt=qcow2 size=32212254720 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16

Networking

Next we’ll want to set up the networking. In the current setup, a tap virtual network interface is passing packets from the virtual machine to the rest of the network. This worked well when the DMZ consisted of a single instance. However, we are going to want a more robust solution to accommodate multiple instances.

The internal network is already set up using a virtual bridge. Though I plan on experimenting with other options in the future, setting up a second bridge should work to connect both DMZ instances to the Internet. Packets destined for the DMZ will be routed to the new bridge, which will then distribute them to the correct tap.

Gentoo stores the network configuration in /etc/conf.d/net.

Listing 2: Configure DMZ Bridge in /etc/conf.d/net

#Bridge for DMZ Network
bridge_br1=”tap1 tap2″
rc_net_br1_need=”net.tap1 net.tap2″
brctl_br1=”setfd 0
sethello 10
stp off”
config_br1=”192.168.1.1/24″

The first part of the network configuration defines the bridge. rc_net_br1_need will start the tap network services before trying to attach the taps specified by bridge_br1. brctl_br1 allows us to specify various options that get passed to brctl command that actually creates the bridge.

Forwarding delay determines the amount of time that the bridge spends in each of the Listening and Learning states before entering the Forwarding state. In a busy network, this ensures that the bridge has time to learn what devices it should be forwarding to. In our setup, it is not needed. Thus, “setfd 0”.

Hello packets are used to communicate topology over the Bridged Local Area Network. I’ve seen some conflicting information on this setting. For the setup we are using, I’ve seen recommendations of 0 and 10. The internal network is using 0. However, I’ve used 10 in the DMZ network to see if there is a difference.

Spanning Tree Protocol (IEEE 802.1d) assists multiple bridges in working together. Since our bridges are working independently of each other, we set “stp off”.

Finally, we set a static IP for the bridge. All packets destined for the DMZ will use this IP for routing. The variable “config_br1” takes care of this for us.

Now that we have the bridge configured, we need to define a couple of taps to connect between the bridge and the KVM instances.

Listing 3: Configure DMZ Taps in /etc/conf.d/net

#DMZ virtual server
config_tap1=”null”
tuntap_tap1=”tap”
tunctl_tap1=”-u dmz”
mac_tap1=”52:54:00:12:34:58″

#Games virtual server
config_tap2=”null”
tuntap_tap2=”tap”
tunctl_tap2=”-u dmz”
mac_tap2=”52:54:00:12:34:60″

If you remember from the bridge definition, we used “config_br1″ to set a static IP. This time we do not want an IP assigned to the interface at all. So we use: config_tap1=”null”. The variable “tuntap_tap1″ lets us define this interface as a TAP. We need to assign the user that KVM is running as to the interface. This can be done using: tunctl_tap1=”-u dmz”. Finally, a MAC address needs set with “mac_tap1”. MAC addresses for TAP devices for KVM should fall in the range of “52:54:00;XX;XX;XX”. This MAC address will be referenced in the configuration file below.

KVM/QEMU Configuration

KVM/QEMU takes a lot of options. In this setup, we use an init script that reads a configuration file from /etc/conf.d/vm.games. Be sure to keep an eye out for the followup post for more information on this setup. At some point I plan on exploring pre-built solutions, such as libvirtfs. It should make configuration simpler. In the mean time, here is the configuration we will be using. OTHER_ARGS is the variable used to load a live CD in order to complete the system installation.

Listing 4: Setup QEMU Configuration in /etc/conf.d/vm.games

SHUTDOWNTIME=15
VMN=2
NETWORK=”tap”
NETWORK_MODEL=”virtio”
VMMAC=52:54:00:12:34:61
VMSOFTWARE=qemu-system-x86_64
VMUSER=”kvm”
ENABLE_KVM=Yes
VMCPU=”host”
VMSMP=2
MEMORY=3072
VNC_ADDRESS=192.168.0.1:2
VHOST=Yes
OTHER_ARGS=”-cdrom /var/lib/kvm/systemrescuecd-x86-4.6.0.iso -boot d”

To finish up, there are a few symbolic links needed for starting and stopping the new service and the network devices.

Listing 5: Creating OpenRC symbolic links to control services.

cd /etc/init.d
ln -s vm vm.games
ln -s net.lo net.br1
ln -s net.lo net.tap2

Now that everything is in place, it’s just a matter of starting it all up, logging in, and starting the OS install on the guest. There really isn’t anything special about the install. The basic process can be found in the Gentoo Handbook. After OS installation, don’t forget to remove OTHER_ARGS from /etc/conf.d/vm.games so the instance boots from the disk image.

Listing 6: Staring services.

# service net.br1 start
 * Bringing up interface tap1
 *   Creating Tun/Tap interface tap1 …                                          [ ok ]
 *   Changing MAC address of tap1 …                                             [ ok ]
 *     changed to 52:54:00:12:34:58                                             [ ok ]
 * Bringing up interface tap2
 *   Creating Tun/Tap interface tap2 …                                          [ ok ]
 *   Changing MAC address of tap2 …                                             [ ok ]
 *     changed to 52:54:00:12:34:60                                             [ ok ]
 * Bringing up interface br1
 *   Creating bridge br1 …
 *   Adding ports to br1
 *     tap1 …                                                                   [ ok ]
 *     tap2 …                                                                   [ ok ]
 *   192.168.1.1/24 …                                                           [ ok ]
 *   Waiting for IPv6 addresses …                                               [ ok ]

# service vm.dmz start
 * Starting Virtual Guest dmz …
 * start-stop-daemon: fopen <code>/var/run/vm/dmz.pid': No such file or directory
 * Detaching to start </code>/usr/bin/qemu-system-x86_64′ …                            [ ok ]

 # service vm.games start
 * Starting Virtual Guest games …
 * start-stop-daemon: fopen <code>/var/run/vm/games.pid': No such file or directory
 * Detaching to start </code>/usr/bin/qemu-system-x86_64′ …                            [ ok ]

Leave a Reply

Your email address will not be published. Required fields are marked *