| Update 08/13/04: Before you do anything, check out the VPN Gaming FAQ |
Introduction
Almost every single Virtual Private Network implementation complies with a widely
accepted standard that prevents any routing device from forwarding broadcast
packets. This is absolutely essential to the proper operation of routers; however,
it is often required to forward broadcast packets across VPN connections to
achieve true LAN functionality. There are many applications that require these
packets to be transmitted to the other hosts on the network.
The ability to send and receive broadcast packets is absolutely crucial in multiplayer
gaming. The majority of modern games feature a LAN gaming option which allows
mutiple players to play together if they are connected over a network. This
does not work over most common VPN setups because nearly all of the games use
UDP broadcasts to initiate games, send chat messages to other players, and announce
other information; and those packets are not transmitted over VPNs.
Although most games also feature an Internet game mode that is usually adequate
for playing another random person or group of people over the Internet, it is
quite cumbersome to use if one wants to play a game with a few friends. The
game servers are often unreliable and impose all sorts of restrictions on the
users. Issues with latency and network speed also arise when a poorly connected
host participates in a multiplayer game. Performance usually degrades for all
other players, as the result. When one plays with a few friends however, all
of the latency and performance issues can usually be brought under control.
Hence, if one is only interested in playing with a small group of friends, a
VPN solution is necessary.
Windows file sharing is another application that can take advantage of this
setup, however I will focus on the uses of VPN technology in gaming. After configuring
your VPN to work with games, modifying the setup to work with Windows printing
and file sharing is trivial.
Our example VPN setup uses a FreeBSD 4.7-RELEASE machine running mpd 3.12 in
order to provide PPTP connections to Windows XP and 2000 clients. In addition
to this software we use a custom perl script and module designed to rewrite
UDP broadcasts into routable packets and send them to appropriate machines.
It's also important to note that to simplify the implementation of this system
we use a machine that already functions as a network gateway to the outside
world.
Preparation
Before configuring any VPN server software we assume that your machine is already
configured to be a functional gateway using natd and ipfw. If for some reason
your machine is not a network gateway, it is still necessary to compile the
FreeBSD kernel with the IPFIREWALL and DIVERT options enabled.
Configuring mpd
First, we install mpd 3.12 from ports. It is found in /usr/ports/net/mpd.
After compiling it, we must edit several files in the /usr/local/etc/mpd/ directory.
First file we edit is mpd.links where we setup the type of link we will use.
pptp1: set link type pptp set pptp self 200.1.1.1 set pptp enable incoming set pptp disable originate
This configures a pptp link that listens on the IP address of 200.1.1.1 and only accepts incoming connections. We expect to have multiple simultaneous users so we also made identical entries while changing the labels to “pptp2”, “pptp3”, etc.
The next step is to setup the mpd.conf file. Here is a sample entry that configures all of the settings of the pptp connection:
default: load pptp1 # Makes mpd load this connection at start
pptp_standard: set ipcp dns 200.1.1.230 # Sets the dns server supplied to clients. This is optional. set iface disable on-demand set iface enable proxy-arp set iface idle 1800 set bundle disable multilink set link yes acfcomp protocomp set link no pap set link enable chap set link keep-alive 10 60 set ipcp yes vjcomp set bundle enable compression set ccp no mppc # Disables Microsoft encryption set ccp no mpp-e40 # Disable 40-bit encryption set ccp no mpp-e128 # Disable 128-bit encryption set ccp no mpp-stateless # Disable the stateless encryption mode set iface up-script /usr/local/etc/mpd/set_routes.pl
pptp1: new -i ng0 pptp1 pptp1 # Creates a new netgraph device set ipcp ranges 192.168.1.1/32 192.168.1.0/24
load pptp_standard # Uses the settings from the above template.
The above config tells mpd to load the connection 'pptp1' as soon as the program
is started. It then configures pptp1 to use the netgraph device ng0 and specifies
the subnet from which to assign IP addresses. Then it loads the remaining settings
from the pptp_standard template. This allows us to make additional connections
(pptp2, pptp3, etc) to allow for simultaneously connected clients. The set_routes.pl
script is needed to set routes for the connecting players. The details are discussed
in the next section. Consult the mpd manual in /usr/local/share/doc/mpd/
for the explanation of other settings used here.
Finally, we have to set the username and password the client has to use, in
mpd.secret:
joe "password" 192.168.1.101The above line assigns 192.168.1.101 to user Joe. In this particular application it is important to allocate a static IP address for each user since we also need to automatically configure routes for some of those users.
Setting up routing
More configuration is necessary in order to allow games running on client machines
to see each other. When players connect to your VPN, several scenarios are possible:
Forwarding Broadcasts
As mentioned earlier, UDP broadcasts are not forwarded across
interfaces. To resolve this problem we can use a PERL script found here.
This script requires NetPacket::IP, NetPacket::UDP and a modified version of
the Net::Divert module which can be found here until
the author integrates these changes into the official distribution. The script
listens for packets on a specified port and upon receiving them, rewrites the
destination field in the packet's header and then sends a copy to all of the
hosts in a list. To figure out what IP to add to the list of recipients, we
have to find out what IP the game uses to announce itself. Since this is what
we did when setting up routing, we can just refer to that data. Note that all
players should be added in this file independent of whether they needed static
routes or not. In addition to executing the script, we also have to add ipfw
rules to forward broadcasts that we receive from the VPN clients to our script.
ipfw add divert 9999 udp from any to 255.255.255.255 via fxp0 ipfw add divert 9999 udp from any to 255.255.255.255 via ng0 ipfw add divert 9999 udp from any to 255.255.255.255 via ng1
The above rules divert all broadcasts received on the internal network interface fxp0 and on the vpn interfaces ng0 and ng1 to the script. If we expect more players we should add corresponding entries for ng2, ng3 and so on. At this point you should be able to play a LAN game with any number of remote players along with LAN players that use the VPN server as their network gateway.
Comments or corrections are welcome at anthonyv@brainlink.com . Special thanks to Nathan J. Yoder for his input. Last Updated 4/8/2003