Issue 112: VTun

NetworkingLink your home and office securely with a virtual private network.

Back in the halcyon days of the dot-com era, I was the first employee at a P2P software startup. Because we were building an intranet and development environment from the ground up, we were free to use Linux everywhere. As everyone now knows, the world changed, and the dot-coms went the way of the dodo. So too did the independence of my little startup, which was acquired by a larger company with an established Windows developer base. Although the new firm was liberal enough to allow me to continue developing on and for Linux, I largely was left to fend for myself on system administration tasks.

The only area where I encountered significant difficulty was with VPN setup. At my old job, every developer had an inbound SSH port mapped to her development workstation. Not only did the new office lock down external access to SSH ports, the sanctioned VPN solution was not Linux-friendly. Technical inertia guaranteed that a cross-platform solution such as FreeS/WAN would not be available in the foreseeable future. Fortunately, VTun, the VPN solution I used at my old job, is flexible enough to handle even this inhospitable environment.

How Does It Work?

VTun works by seamlessly integrating IP-tunneling technology with existing packet routing programs. True to the UNIX spirit of modularity, VTun is directly responsible only for tunneling packets between two systems, leveraging established network management tools to provide a cohesive VPN solution.

For the sake of analogy, imagine your home and office networks are a set of discrete and isolated railroad networks. Each machine represents a station. The Linux kernel controls the track switches, determining how trains from one station reach the next. These facilities can be manipulated through the route program, allowing the end user to add or remove destinations.

The Linux kernel also provides facilities for rerouting trains. For example, let's add the Internet, a vast railroad system, to our train station analogy. The home and office networks are merely tiny spurs in this system. Typically, only one station, a firewall or gateway router, has direct access to the larger Internet railroad. If another station on the home tracks wants to dispatch trains to the Internet, these trains first are rerouted through the gateway station. This rerouting process, technically known as IP masquerading or network address translation (NAT), is managed through the iptables program. iptables is the user-space half of the Netfilter firewall code in the 2.4 Linux kernel.

So where does VTun fit into this analogy? Recall that the home and office networks are isolated train systems. A train from home generally is not allowed to cross over to the work tracks due to restrictions at the office firewall station. VTun gives us a facility to lay a virtual track between two stations—for example, your home and office desktops—on the separate networks. Once this track has been laid, the stations are configured using iptables and routed such that trains originating from home can access the work system as freely as if they originated from the office desktop.

Conventions and Caveats

Now that we've looked at the components of a VTun VPN, we are ready to examine a complete implementation. The most obvious scenario connects a single remote workstation (your home desktop) to the office LAN by way of your work desktop. To keep this example simple, assume you can establish an SSH connection to your office desktop from home but that the machine is otherwise inaccessible from the Internet. Assume the home network is configured on the 192.168.1.0/24 subnet, and the office network has subnets 192.168.5.0/24 and 192.168.100.0/24.

VTun is a client/server system. The server machine listens for connections from VTun clients on a specified port. The client initiates the creation of the tunnel by connecting to the server port. For this example, the home desktop is the client, and the office desktop is the server.

Before we begin installation, we should take a moment to discuss security. Creation of a VPN can mean the office network now is only as secure as the home network. As such, it is imperative that your home machines are protected by a firewall that is up to date on all security patches and routinely audited for intrusion. Most importantly, never create a VPN without the consent of your office system administrators.

Installation

With the caveats and disclaimers out of the way, we proceed to the fun stuff. VTun needs to be installed on both the client and server, so the procedure outlined below should be completed on each system. This procedure has been tested on recent versions of Red Hat Linux. If you discover this installation path fails for your distribution, please send me an e-mail at ryan@ryanbreen.com. I will use these responses to track a distribution-specific errata file at www.ryanbreen.com/vtun.

Some distributions already have packages for VTun, so you might be able to save a step by using your package manager to install VTun from your distribution's update site.

As with most VPN solutions, VTun requires the support of kernel-level facilities, in this case provided by the TUN point-to-point network driver. The TUN module is included in the stock kernel distribution, so you most likely do not need to recompile your kernel. As a test, attempt to load the driver by running insmod tun as root. If the module is not found, download the latest version (currently tun-1.1) from vtun.sourceforge.net/tun/index.html. Install it with:

tar xzf tun-1.1.tar.gz 
cd tun-1.1 
su -c 'make install'

If you would like the TUN module to be loaded automatically whenever a process attempts to access the virtual tunnel device, add the following line to /etc/modules.conf:

alias char-major-10-200 tun

Next, configure and install the user-space vtund program. You can find the latest VTun package at vtun.sourceforge.net/download.html. For the sake of generality, here we install from source, but if your distribution supports RPMs or debs, feel free to grab one of the precompiled packages. The latest source tarball at press time is vtun-2.5.tar.gz. Compilation follows the standard procedure:

tar xzf vtun-2.5.tar.gz
cd vtun-2.5
./configure
make
su -c 'make install'

Depending on your distribution, configuration might fail with an error that LZO is not installed. LZO is a compression library used by VTun. It can be downloaded from www.oberhumer.com/opensource/lzo/download. Build and install LZO, then retry VTun installation.

Upon installation, VTun places its configuration file at /usr/local/etc/vtund.conf. This can be extremely confusing as the client and server need separate entries in the tunnel specification section. To avoid confusion, I suggest moving vtund.conf to vtund-client.conf and vtund-server.conf as appropriate. Then, manually specify a path to the relevant configuration file on startup. This recommendation is used throughout the following configuration discussion.

VTun Configuration Files

The VTun configuration file format is relatively straightforward (see Listings 1 and 2). The file is organized into three discrete units. First is a set of global options defining basic parameters, such as server port number and paths to helper programs. Second is a set of default session options that define the networking properties of the tunnel. These properties can be overridden as needed in the configuration of a specific tunnel.

Listing 1. Simple vtund-client.conf

options {
   port 5000;
 
   # Path to various programs
   ifconfig   /sbin/ifconfig;
}
 
# Default session options
default {
   compress no;   # Compression is off
   encrypt no;    # ssh does the encryption
   speed 0;       # By default maximum speed
   keepalive yes;
   stat yes;
}
 
 
my_tunnel {
   pass  XXXXXXXX;    # Password
   type  tun;         # IP tunnel
   proto tcp;         # TCP protocol
 
   up {
      # 10.3.0.1 = fake tunnel interface (home-end)
      # 10.3.0.2 = fake tunnel interface (work-end)
      # 192.168.5.0/24 = actual work network 1
      # 192.168.100.0/24 = actual work network 2
      ifconfig
        "%% 10.3.0.1 pointopoint 10.3.0.2 mtu 1450";
   };
   down{
      ifconfig "%% down";
   };
}
 

Listing 2. Simple vtund-server.conf

options {
   port 5000;
 
   # Path to various programs
   ifconfig   /sbin/ifconfig;
}
 
# Default session options
default {
   compress no;   # Compression is off
   encrypt no;    # ssh does the encryption
   speed 0;       # By default maximum speed
   keepalive yes;
   stat yes;
}
 
my_tunnel {
   pass  XXXXXXXX;    # Password
   type  tun;         # IP tunnel
   proto tcp;         # TCP protocol
 
   up {
      # 10.3.0.1 = fake tunnel interface (home-end)
      # 10.3.0.2 = fake tunnel interface (work-end)
      # 192.168.1.0/24 = actual home network
      ifconfig
        "%% 10.3.0.2 pointopoint 10.3.0.1 mtu 1450";
   };
   down{
      ifconfig "%% down";
   };
}
 

One tunnel configuration parameter that deserves special attention is keepalive. Office system administrators often set a low idle time on active connections through their firewalls. If your tunnel is inactive for longer than this deadline, even a few minutes, your connection times out. Enabling keepalive instructs VTun to circumvent this behavior by periodically sending packets from client to server, convincing the firewall the connection is in active use.

The final unit of options defines the configuration for a specific tunnel. The configuration file can contain any number of settings of this type, allowing clients and servers to be involved in multiple VPNs. Each tunnel configuration group begins with a name. I have chosen the name my_tunnel, but the name is an arbitrary designation. Each tunnel can configure a password, though this option generally is ignored when the tunnel is created over SSH. The up and down blocks describe a set of commands run when the tunnel is created and destroyed, respectively.

The simple configuration files in Listings 1 and 2 instruct VTun to create the tunnel interface on each system once the connection is established. The configuration files use the pattern %% to represent the tunnel interface, so multiple tunnels can be created in any order. The actual name of the tunnel interface begins with the prefix tun followed by a digit. The first tunnel created is tun0.

Creating a VTun VPN

Let's put this basic understanding of VTun configuration into practice, using Listings 1 and 2 to create a simple tunnel. You can find the Listings at ftp.ssc.com/pub/lj/listings/issue112/6675.tgz if you would prefer not to enter them by hand. Save vtund-server.conf to /usr/local/etc/ on the office machine, and save vtund-client.conf to /usr/local/etc/ on the home machine. With the config files in place, initiate the VTun processes on each machine. As root, start the server on the office desktop:

vtund -f /usr/local/etc/vtund-server.conf -s

The -s option tells vtund to run as the server, listening for connections on port 5000.

To access the server, you must be able to reach port 5000 on the office machine. Recall that, for the sake of this example, the office is accessible only by SSH, so you must use OpenSSH's port-forwarding mechanism to tunnel port 5000 from the office machine. From home, run:

ssh mydesktop.work.com -L 5000:localhost:5000

The -L option tells OpenSSH to forward port 5000 on the home machine to port 5000 on the office desktop. Connections to port 5000 on the home machine then are tunneled transparently through SSH to port 5000 on the office machine. This configuration has the additional benefit of encrypting all VPN traffic.

With the running server on the office machine now accessible from the home desktop, all that remains is to start the client. As root on the home desktop, run:

vtund -f /usr/local/etc/vtund-client.conf 
↪my_tunnel localhost

The my_tunnel parameter tells the client and server what tunnel is being created. Both systems query their respective configuration files and run the commands within the up block of the my_tunnel stanza. The final parameter, localhost, specifies the hostname of the VTun server. In this case, the VTun server is localhost because you forwarded port 5000 from the home machine to the office desktop.

If the tunnel was created successfully, running ifconfig on each machine should list a tun0 interface. The home machine then has an IP address of 10.3.0.1 on tun0, and the office machine has IP 10.3.0.2. Drawing on the train station analogy, the track between the office desktop and home desktop has been laid, and you can now route trains between the machines over this track. To demonstrate this, create an SSH connection from your home desktop to 10.3.0.2.

Making It Real

You now have a working tunnel from home to the office. Next, you need to configure route and iptables so packets from home are masqueraded through the work desktop to the rest of the office LAN. Fortunately, this is as simple as adding a few lines to the configuration files on the client and server and restarting the vtund processes. VTun executes the appropriate route and iptables commands when the connection is established.

Returning to the train station analogy, you need to instruct the home desktop station that any trains destined for the office network should be routed through the newly created VTun track. You can accomplish this manually by running:

route add -net 192.168.5.0 netmask 
↪255.255.255.0 gw 10.3.0.2
route add -net 192.168.100.0 netmask 
↪255.255.255.0 gw 10.3.0.

Alternatively, you can add the commands as shown in Listing 3 to vtund-client.conf. These commands instruct iptables to forward all packets from the tun interface and to masquerade these packets as coming from the office desktop. Alternatively, we can add the commands shown in Listing 4 to vtund-server.conf and restart the server.

Listing 3. Complete vtund-client.conf

options {
   port 5000;
 
   # Path to various programs
   ifconfig   /sbin/ifconfig;
   firewall   /sbin/iptables;
   route       /sbin/route;
}
 
# Default session options
default {
   compress no;   # Compression is off
   encrypt no;    # ssh does the encryption
   speed 0;       # By default maximum speed
   keepalive yes;
   stat yes;
}
 
my_tunnel {
   pass  XXXXXXXX;    # Password
   type  tun;         # IP tunnel
   proto tcp;         # TCP protocol
 
   up {
      # 10.3.0.1 = fake tunnel interface (home-end)
      # 10.3.0.2 = fake tunnel interface (work-end)
      # 192.168.5.0/24 = actual work network 1
      # 192.168.100.0/24 = actual work network 2
      ifconfig
        "%% 10.3.0.1 pointopoint 10.3.0.2 mtu 1450";
      route "add -net 192.168.5.0 netmask 
      ↪255.255.255.0 gw 10.3.0.2";
      route "add -net 192.168.100.0 netmask 
      ↪255.255.255.0 gw 10.3.0.2";
   };
   down{
      ifconfig "%% down";
      route "del -net 192.168.5.0 netmask 
      ↪255.255.255.0 gw 10.3.0.2";
      route "del -net 192.168.100.0 netmask 
      ↪255.255.255.0 gw 10.3.0.2";
   };
}
 

Listing 4. Complete vtund-server.conf

options {
   port 5000;
 
   # Path to various programs
   ifconfig   /sbin/ifconfig;
   firewall   /sbin/iptables;
   route      /sbin/route;
}
 
# Default session options
default {
   compress no;   # Compression is off
   encrypt no;    # ssh does the encryption
   speed 0;       # By default maximum speed
   keepalive yes;
   stat yes;
}
 
my_tunnel {
   pass  XXXXXXXX;    # Password
   type  tun;         # IP tunnel
   proto tcp;         # TCP protocol
 
   up {
      # 10.3.0.1 = fake tunnel interface (home-end)
      # 10.3.0.2 = fake tunnel interface (work-end)
      # 192.168.1.0/24 = actual home network
      ifconfig
        "%% 10.3.0.2 pointopoint 10.3.0.1 mtu 1450";
      route "add -net 192.168.1.0 netmask 
      ↪255.255.255.0 gw 10.3.0.1";
      firewall "-t nat-A POSTROUTING -o %% 
      ↪-j MASQUERADE";
      firewall "-AFORWARD -i %% -j ACCEPT";
   };
   down{
      ifconfig "%% down";
      route "del -net 192.168.1.0 netmask 
      ↪255.255.255.0 gw 10.3.0.1";
   };
}
 

Once route and iptables are configured, you should have access to your entire corporate intranet from your home desktop. Browse around your internal Web servers, connect to the source code server and try exporting a graphical widget such as an xterm. Performance should be more than adequate for all these tasks, and the SSH tunnel ensures that all traffic is encrypted from prying eyes.

Now that you have a working tunnel, you may want to configure the server to start automatically. This process is distribution-specific. The VTun tarball includes a set of init scripts for different distributions, so you should consult the Readme to determine which will work best for you.

Advanced Configuration

Astute readers may have noticed that only the home desktop has access to the office intranet. Trains originating from other stations within the home network currently are not rerouted through the home desktop station. I feel that this configuration is at least marginally more secure, as it reduces the exposure of the office network to compromises at home. If you desire connectivity from other machines on the home network, simply add the appropriate iptables rules to the up directive in vtund-client.conf. I leave that as an exercise for the interested reader.

The above configuration works perfectly if you can connect by SSH to any machine on your office network. Unfortunately, many offices do not provide any open incoming ports. This was precisely the situation I found upon arrival at my new job, but the flexibility of VTun allowed me to overcome even this obstacle. The solution is to reverse the configuration, using the office desktop as the VTun client and originating the SSH tunnel from within the office.

To make this solution work, we must be able to access our home machine from within the office. However, most broadband connections have dynamic IP addresses. We can sidestep this issue by using a DNS service tailored for dynamic IPs, such as that provided by DynDNS.org.

The greatest downside to this approach is its relative fragility. In a secure setup, the client does not start automatically because the SSH connection requires authentication, leaving you out in the cold if the office machine goes down due to a power outage. If you are less worried about security, you can automate login using SSH public key authentication without a passphrase or expect scripting. I do not encourage either method.

If your office machine is on a UPS, you rarely should encounter this problem. In the six months that I have used this setup, only one power outage lasted long enough to kill the client side of my VPN. This setup also is robust on the home network side. You can take your machine off-line for days, and the VPN re-initializes as soon as you start the vtun server, thanks to the intelligent keepalive and retry facilities in the client.

Conclusion

Hopefully, you now have an appreciation for the versatility and power of a VTun VPN and possess the technical know-how to set one up for yourself. Unfortunately, a comprehensive discussion of VTun's feature set is well beyond the scope of this article. Beyond the basic setups described above, VTun allows Ethernet, PPP or SLIP tunneling of protocols other than IP. VTun also provides native support for encryption, compression and bandwidth shaping, so it is adaptable to every imaginable connection scenario. VTun belongs in the toolkit of every network user and deserves mention alongside breakthrough applications such as OpenSSH, rsync and screen.

Acknowledgements

Many thanks to Jennifer Edwards and James Manning for reviewing this article.

Resources

Ryan's VTun Info Page: www.ryanbreen.com/vtun

Universal TUN/TAP Driver Home: vtun.sourceforge.net/tun

VTun Home: vtun.sourceforge.net

Ryan Breen (ryan@ryanbreen.com) is a 2000 graduate of Duke University with degrees in Computer Science and Economics. He is currently living in Boston with his girlfriend of three years and dog of two and a half years. At work, he builds high-throughput browser simulations, is a devoted KDE user and occasional KDE developer.

© 1994-2003 Specialized Systems Consultants, Inc. (SSC) publishers of Linux Journal.