First Draft - Last modified September 2006
TODO: Add hyperlinks, document beautification. Maybe a troubleshooting guide?

Introduction

Overview

This document will attempt to explain the setup and operation of a Virtual Private Network (VPN). Although geared towards a specific software implementation (VTun) and OS (Linux), I hope the information is generic enough to help others.

Most VPN software documentation is (correctly) designed to allow someone who is familiar with VPNs to configure a specific piece of software, not to teach the basics of VPNs. This is not in itself a bad thing, but it creates a stumbling block for those who are new to VPNs. So, rather than give a list of steps to perform, I will attempt to give an understanding of VPNs in general, and provide a background of knowledge for the reader to apply to their own situations, and software of choice.

There is already a VPN-HOWTO that describes using SSH to tunnel services over the Internet, but this isn't really a robust or scalable solution, for a number of reasons (not the least of which is the fact that SSH uses TCP, instead of UDP or GRE. More on this later.)

What is a VPN?

A VPN (Virtual Private Network) is a way to connect multiple Local Area Networks (LANs) together, as if they are one large network. In the past, this was done with WAN (Wide Area Network) technology - by connecting the networks together with dedicated lines.

With high-speed internet connections (such as Cable or DSL) becoming cheaper every day, it's possible to use the internet to connect locations together; encryption is used to protect the data from prying eyes, and compression can be used to maximize bandwidth. The result is much higher bandwidth between nodes, at a fraction of the cost of a leased-line solution.

Terminology

Remote vs. Local Nodes

Basically, a 'node' is a VPN location - it can be a single computer accessing a corporate LAN, the LAN it's accessing, or another network with all or part of the network being routed across the VPN.

Most of this document is geared towards a two-node (client/server) VPN, or a VPN with a central 'hub' that the other nodes communicate through to talk to each other. Local and remote are relative to where you are - if you're at the server end, 'local' would refer to the server, and 'remote' would refer to the client, if I'm talking about the client, 'remote' would refer to the server.

IP Addresses: Routable vs. Non-routable

As you probably know, in order to communicate on the Internet, a host must have an IP address. For the purposes of this document, there are two types of IP addresses: Routable and Non-Routable.

A routable IP address is one that is globally unique, usually assigned to you by your ISP, and can be routed directly on the Internet. Routable IP's are assigned by a global authority. They are frequently called 'real' or 'public' IP addresses (although the term 'real' is incorrect, as non-routable addresses are just as real.)

A non-routable IP address (commonly called 'private' IP), by comparison, is one that cannot be legally routed to the Internet. Non-routables are designed for machines that will never talk to the internet (at least, not without some form of address translation.) You can freely use non-routables on your local network, without ever having to worry that someone will be using the address somewhere else.

Non-routable addresses come from three blocks of addresses (one block from Class A, one from Class B and one from Class C - the Class B and C blocks contain multiple networks of the respective classes.)

  • Class A: 10.0.0.0 (one network with 16777216 addresses)
  • Class B: 172.16.0.0 - 172.31.0.0 (16 networks, each with 65536 addresses)
  • Class C: 192.168.0.0 - 192.168.255.0 (256 networks, each with 256 addresses)

Because it's considered bad form for documentation to contain routable addresses (an inexperienced user could conceivably wreak havok by using a real address presented in an example,) all of the examples presented here will contain non-routable addresses. To differentiate between the routable and non-routable addresses, I will substitute routable addresses with addresses from the 172.{16-31}.0.0 networks.

IP Addresses: External vs. Internal

As the systems running the VPN software will have multiple IP addresses, determining which one you should be looking at can become confusing. In ther document, I will use the term internal IP address to refer to the station's IP address on the VPN, and the term external to refer to the IP address that talks to the internet.

IP Addresses: Static vs. Dynamic

A Static IP address is one that is permanently assigned to a computer. To make a VPN, at least one of the computer must have a static IP address, for the other node(s) to connect to.

A Dynamic IP address is one that can change from time to time - such as one assigned by a DHCP server or your ISP's dial-up pool. computers with dynamic IPs will only be able to act as a VPN client.

Tunnel

A tunnel is the term used to refer to the connection between each end of a VPN. Although physically passing through many routers on the internet, the packets that pass through the tunnel will appear to go directly from one end to the other.

Encapsulation

In a VPN sense, encapsulation is the act of 'wrapping' the source packets inside another packet. A VPN will encapsulate the traffic from one network inside it's own packets, (optionally) compressing and/or encrypting it first. It then sends these packets to the other end of the tunnel.

Egress Filtering

Egress Filtering is the act of routers (usually at your upstream ISP) dropping packets if the source address appears wrong. It's a good thing, and all good ISP's do it, to prevent malicious users from spoofing IP addresses. Most users will be unaffected by it, but if you're using a VPN to assign routable addresses to a remote location, it may affect you.

Policy Routing

For normal day-to-day applications, routers will decide where to send a packet based on its' destination IP address; however for some VPN applications, something more complicated is needed - the router will need to decide where to send the packet based on other criteria (such as where the packet originated from, instead of where it's going.) This is called Policy Routing, and it's useful for overcoming egress filtering.


Basics

Requirements

Requirements for setting up a software VPN will depend on the software you've chosen. In general, one computer will be required for each node (VPN endpoint), but you can re-use existing equipment.

IP Addresses

The biggest problem with setting up a VPN is keeping the IP addresses straight. Each VPN node will typically have two IP addresses - one 'main' one (which could be part of your existing routable addresses, or may be assigned by your ISP), and one that is part of the VPN. If your server has multiple physical interfaces (such as one doing IP Masquerading for your LAN), it will have more than two. (Although this is all technically incorrect - it's the interfaces that have the IP addresses, not the computers.)

Protocol Types

Reliable vs. Unreliable

VPNs can tunnel data over a number of different protocols; GRE, TCP, and UDP are probably the most common, each presents its' own advantages and disadvantages.

Protocols can fall into one of two basic categories: reliable and unreliable. A reliable protocol, such as TCP is one that can handle packet loss over an unreliable medium, resending lost packets, and generally making sure that what goes in one end comes out the other intact, and in the right order.

An unreliable medium, on the other hand, is one that does no error correction or discovery. Any error detection or packet retransmission needs to be handled by the application. Unreliable protocols are used for application such as videoconferencing, where the need for the data to arrive on time is more important than the need for it to be perfect. (As an example, if a live video stream drops a frame, the application should just skip it and keep going, instead of stopping the video until the other end re-sends it.)

A large difference between these two types is that reliable protocols generally take longer to establish than unreliable ones, because the two sides have to negotiate settings to detect lost/corrupted packets.

As IP is an unreliable protocol, it makes sense to use a protocol that mimics it as closely as possible.

Common Protocols used for Tunneling

GRE: (Generic Routing Encapsulation - IP protocol number 47) is a protocol developed by Cisco specifically for tunneling. It's supported natively by the Linux kernel, as well as Cisco routers, and is the closest thing to a 'de-facto' VPN standard. The two most common VPN protocols (IPSec and Microsoft's PPTP) use GRE. Probably the biggest drawbacks are that some firewalls are not GRE-aware, and that it doesn't support multiple tunnels to/from the same IP-addresses. Also, like IP, GRE is designed to be a transport level protocol only (it's job is to move packets from A to B) - another protocol layer is required to do encryption and/or compression of the payload data.

UDP: (User Datagram Protocol - IP protocol number 17) is an unreliable protocol used for such things as DNS queries and video/audio conferencing. Although not explicitly designed for it, UDP is ideal for tunneling, as it mimics the behaviour of IP very closely.

TCP: (Transmission Control Protocol - IP protocol number 6) is the workhorse of the internet. Nearly every stream-oriented protocol (web, mail, FTP, telnet, etc) uses TCP. It is a reliable protocol, designed to work even under conditions of extreme packet loss. TCP is, however, not very well suited to tunneling. While a VPN that's based on TCP will be simpler to implement and easier to get running (especially through a firewall), minor packet loss can result in major connection stalls as the TCP tunnel attempts to compensate by re-sending packets. Basically, if the data that's being tunneled (such as an HTTP stream) is reliable, packet loss is amplified because both layers will be re-transmitting lost packets. If the payload data is unreliable, it has to wait as the tunnel needlessly retransmits the lost data. More information can be found at http://sites.inka.de/sites/bigred/devel/tcp-tcp.html. In general, use of TCP tunnels should be reserved for applications where no other method will work.

Uses for VPNs

There are many different uses for VPNs; this document will focus on the three most common: A single client attaching to a non-routable network (which I call 'client-to-network'), linking two non-routable networks together ('network-to-network'), and configuring a remote branch (either a single computer, or a subnet) with routable addresses, and using a VPN to make the branch appear where it should ('branch-office-to-network'). More detail will be provided in the examples section.


General Configuration Info

VPN Interfaces

Typical VPNs appear to the system as a network device driver, and are configured by the user just like any other interface - the difference is that instead of acting as an interface to a hardware ethernet card, the VPN device encapsulates the data in packets destined for the remote end.

It's important to note that there is no 'magic' in how the data gets to the other end of the tunnel - it's sent through the system's normal routing table. For that reason, it's important that each end has a route to the remote end's external IP that doesn't go through the VPN. This is a common mistake, especially when using routable addresses.

Firewalls

Firewall (packet filter) and NAT/Masquerading rules can wreak havok with your VPN. As VPN's are designed to allow access that a firewall would normally block, it's important to open holes in your firewall if you want your VPN to work properly. If your VPN boxes are also doing NAT/IP Masquerading, you will probably need to disable it for traffic passing through the tunnel.

ARP

ARP is a protocol used to convert virtual (IP) addresses to physical (Ethernet) addresses. In the examples that follow, I will be using addresses from the host networks to create the tunnel; this can create a problem, because the tunnel devices do not ARP. For this reason, it's generally a good idea to manually set the ethernet interface to proxy-ARP for the tunnel address.


Examples

Client to Network

Diagram of Client to Network VPN

Allowing a remote client to connect to your LAN via a VPN is perhaps the simplest VPN configuration; it allows a single remote client (perhaps a telecommuter or roaming user) access to local network resources, as if they were physically connected to that network. The most popular way to do this is with Windows, using the PPTP protocol. If you want the client to use a routable address, you should be looking at the 'branch-office-to-network' section below.

Setup

To start, we assume that your main network is 192.168.1.0/24, and the VPN server is also doing IP Masquerading. The client will be 'borrowing' the IP address 192.168.1.254. As this is a point-to-point link, no routing would be required, but you will need to proxy ARP for the remote client (you should also ARP for the local tunnel endpoint, but we won't in this example.);

The Server's 'internal' IP is on eth1, and it's 'external' IP is eth0.

  # Server Configuration sample No.1
  up {
    ifconfig "%% 192.168.1.200 pointopoint 192.168.1.254 mtu 1450";
    program "/sbin/arp -sD 192.168.1.254 eth1 pub";
    firewall "-I forward -s 192.168.1.0/24 -d 192.168.1.0/24 -j ACCEPT";
  }
  down {
    firewall "-D forward -s 192.168.1.0/24 -d 192.168.1.0/24 -j ACCEPT";
    program "/sbin/arp -d 192.168.1.254 -i eth1";
  }

The ifconfig statement brings the interface up with the correct local and remote addresses; Since the remote end is on the same network as the local end (192.168.1.0/24), we must force the server's ethernet device to ARP for the client, or else the rest of the network won't be able to talk to it. The IPCHAINS statement ensures that the server won't attempt to masquerade the traffic passing through the VPN.

The server would be started with the following command:

  # vtund -s

Client configuration is similar to the server config - we just swap the IP addresses for the tunnel. Also, because the client is a single machine, there is no need to add a proxy ARP entry.

  # Client Configuration sample No.1
  up {
    ifconfig "%% 192.168.1.254 pointopoint 192.168.1.200 mtu 1450";
  }

The client would be started with the following command:

  # vtund -c ourtunnel 172.17.2.5

This tells the client machine to connect to the server at 172.17.2.5, using VPN profile "ourtunnel" (You will need to substitute the server's real IP address, and the name of the tunnel.)

A copy of this config can be downloaded from here. Note that you will need to change the password in the files.

Network to Network

Diagram of Network to Network VPN

Connecting two non-routable networks together is also common - allowing users from branch offices to communicate and share network servers in a secure fashion. Because of the routing (and Network Address Translation) issues involved, it's a little more complex to set up than a client-network VPN.

Setup

Basic setup is similar to the client-network setup described above. The biggest difference is that the client will have its' own network (192.168.2.0/24), instead of taking an address from the server's net.

Again, the server's 'internal' interface is eth1, and its' 'external' is eth0

  # Server Configuration sample No.2
  up {
    ifconfig "%% 192.168.1.254 pointopoint 192.168.2.254 mtu 1450";
    route "add -net 192.168.2.0 netmask 255.255.255.0 gw 192.168.2.254";
    firewall "-I forward -s 192.168.1.0/24 -d 192.168.2.0/24 -j ACCEPT -b";
    program "/sbin/arp -sD 192.168.1.254 eth1 pub";
  }
  down {
    firewall "-D forward -s 192.168.1.0/24 -d 192.168.2.0/24 -j ACCEPT -b";
    program "/sbin/arp -d 192.168.1.254 -i eth1";
  }

As before, the ifconfig simply brings up the tunnel interface, the differences are the route statement, which adds a route to the remote network once the VPN interface has been established. The ipchains rule prevents the server from masquerading traffic between the networks (otherwise the machines on each network won't be able to 'see' past the VPN machines.)

The server would be started with the following command:

  # vtund -s

As the client and server (in this example) are performing identical functions, the configs are the same, with only the network numbers swapped.

  # Client Configuration sample No.2
  up {
    ifconfig "%% 192.168.2.254 pointopoint 192.168.1.254 mtu 1450";
    route "add -net 192.168.1.0 netmask 255.255.255.0 gw 192.168.1.254";
    firewall "-I forward -s 192.168.1.0/24 -d 192.168.2.0/24 -j ACCEPT -b";
    program "/sbin/arp -sD 192.168.2.254 eth1 pub";
  }
  down {
    firewall "-D forward -s 192.168.1.0/24 -d 192.168.2.0/24 -j ACCEPT -b";
    program "/sbin/arp -d 192.168.2.254 -i eth1";
  }

The client would be started with the following command:

  # vtund -c ourtunnel 172.17.2.5

This tells the client machine to connect to the server at 172.17.2.5, using VPN profile "ourtunnel" (You will need to substitute the server's real IP address, and the name of the tunnel.)

A copy of this config can be downloaded from here. Note that you will need to change the password in the files.

Branch-office to Network

Assigning routable addresses to a remote office across a VPN is the trickiest way to run a VPN, especically if your ISP is doing egress filtering. There are some subtle routing issues that need to be addressed at the remote site in order to get this to work properly.

Setup

This setup assumes that you have two blocks of routable addresses, which (to the internet) route through a single router, and you want to assign one of the blocks to a remote site. For the purposes of this example, I will use the non-routable block 172.17.2.0/23 to represent the routable addresses; this block will be broken up into two 256-address blocks, with 172.17.2.0/24 at the server site, and 172.17.3.0/24 at the client site.

We will assume that the VPN server has IP address 172.17.2.5, and the network has a default gateway of 172.17.2.1, which knows to route the address destined for the remote side to the VPN server. The client will be on a dynamic IP address.

Server setup is pretty straightforward. Setup is similar to the network-network configuration presented above, only without the ipchains rules.

  # Server Configuration sample No.3
  up {
    ifconfig "%% 172.17.2.254 pointopoint 172.17.3.254 mtu 1450";
    route "add -net 172.17.3.0 netmask 255.255.255.0 gw 172.17.3.254";
    program "/sbin/arp -sD 172.17.2.254 eth1 pub";
  }
  down {
    program "/sbin/arp -d 172.17.2.254 -i eth1";
  }

Setup is similar to the network-network configuration presented above, only without the ipchains rules (as you are using routable addresses, no masquerading is being done.)

As usual, the server would be started with the following command:

  # vtund -s

For this example, we'll assume that the client's default gateway never changes, even though its' IP address might. (This is a common occurrence.) The client's default gateway will be 172.19.15.1.

  # Client Configuration sample No.3
  up {
    ifconfig "%% 172.17.3.254 pointopoint 172.17.2.254 mtu 1450";
    route "add -host 172.17.3.5 gw 172.19.15.1";
    route "add -net 172.17.2.0 netmask 255.255.255.0 gw 172.17.2.254";
    program "/sbin/arp -sD 172.17.3.254 eth1 pub";
  }
  down {
    route "del -host 172.17.3.5 gw 172.19.15.1";
    program "/sbin/arp -d 172.17.3.254 -i eth1";
  }

Client setup presents a problem - the VPN server is on a routable IP address (172.17.2.5), so if we blindly route all traffic to the remote side through the VPN, the tunnel traffic itself will be routed through the VPN interface, creating a loop. The solution is to add a host route for the VPN server through the (regular) default gateway, before briniging up the VPN's route.

This method is not without its' disadvantages. The biggest problem is that any traffic sent to the VPN server will be unencrypted - necessary for the VPN to work at all. For this reason, your VPN server should not be running any important services that machines on the client network will be accessing.

The client would be started with the following command:

  # vtund -c ourtunnel 172.17.2.5

This tells the client machine to connect to the server at 172.17.2.5, using VPN profile "ourtunnel" (You will need to substitute the server's real IP address, and the name of the tunnel.)

There are no downloadable config files for these types of networks, as there would be too much to change to get it to work.

Egress Filtering

A problem you might encounter with this method is that the machines on the client's network may not be able to access the internet.

When this happens, the most probably cause is egress filtering. What's happening is that the client's ISP is blocking your outbound traffic because it looks like you are spoofing your source IP address.

The easiest way around this is to simply change the default route on the client gateway, to point to the VPN server. However, if the client site is doing NAT/Masquerading in addition to using routable IP addresses, this isn't the most optimal use of the network, as all of your traffic (including the stuff being translated/masqueraded) will be sent through the tunnel.

The solution to this (other than asking your ISP to turn off the filter :o) is to do policy routing, and route traffic from the client's network based on its' source IP address, instead of (or in addition to) the destination IP address.

Under Linux 2.2, the way to do this is with the iproute2 tools, which can be found at ftp://ftp.inr.ac.ru/ip-routing/, if it's not included in your distribution. Detailed info on iproute2 can be found at http://www.compendium.com.ar/policy-routing.txt. You will need to have your kernel compiled with the options IP: Advanced Routing and IP: Policy Routing in order for this to work.

Before changing the vtund.conf, you will have to add a new table to the /etc/iproute2/rt_tables file called vpn. Something like this should do it:

# addition to /etc/iproute2/rt_tables
12	vpn

It's important that the number is unique to the file (ie. there is no other line numbered '12' in your file.)

  # Client Configuration sample No.3.1
  up {
    ifconfig "%% 172.17.3.254 pointopoint 172.17.2.254 mtu 1450";
    route "add -host 172.17.3.5 gw 172.19.15.1";
    route "add -net 172.17.2.0 netmask 255.255.255.0 gw 172.17.2.254";
    program "/sbin/ip rule add from 172.17.3.0/24 table vpn";
    program "/sbin/ip route add default table vpn via 172.17.2.254";
    program "/sbin/arp -sD 172.17.3.254 eth1 pub";
  }
  down {
    ifconfig "%% down";
    route "del -host 172.17.3.5 gw 172.19.15.1";
    program "/sbin/ip rule del from 172.17.3.0/24 table vpn";
    program "/sbin/ip route del default table vpn via 172.17.2.254";
    program "/sbin/arp -d 172.17.3.254 -i eth1";
  }

There are two additions to this config, the ip commands; the ip rule adds a rule to the routing tables which will cause the kernel to use the table 'vpn' if the packet has a source address in the 172.17.3.0/24 network, instead of using the default routing tables. The ip route command tells the kernel that the default route for the 'vpn' table is 172.17.2.254.


About This Document

Errors and Omissions

Although I have put much effort into ensuring that this document is error-free, I realize that there may be errors that proofreading has overlooked. If you enounter an error, please email me at info@northsun.net.

The "Without Whom" department

Thanks to the following people who provided support and/or inspiration and/or feedback:

  • Maksim Krasnyanskiy
  • Lonnie Cumberland
  • Peter Rude
  • Kevin Graff
  • Lionel R Clark (Bishop)
  • Anders Gjerløv

Copyright

This document is Copyright © 2001 by Karl Stevens.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts and no Back-Cover Texts. A copy of the license can be found at http://www.gnu.org/copyleft/fdl.html.