Configure IT Quick: Build a virtual private network with FreeS/WAN

See how to put together the various pieces of the puzzle to build a FreeS/WAN VPN server on Linux.

FreeS/WAN is a Linux implementation of IPSec, the IP security protocol. IPSec implements encryption and authentication at the IP level, which allows encryption of any and all data transferred via IP, rather than just a particular higher-level protocol, as with ssh or ssl.

In this Daily Drill Down, I’ll introduce you to the technology behind FreeS/WAN as well as building the software, configuring FreeS/WAN, generating keys, starting and stopping the connections, and testing the connections.

Components and use of FreeS/WAN
The core components of FreeS/WAN include the following:
  • ·        AH (Authentication Header) provides a packet-level authentication service.
  • ·        ESP (Encapsulating Security Payload) provides encryption plus authentication.
  • ·        IKE (Internet Key Exchange) negotiates connection parameters, including keys, for the other two.
  • ·        KLIPS (kernel IPSec) implements AH, ESP, and packet handling within the kernel.
  • ·        Pluto (an IKE daemon) implements IKE, negotiating connections with other systems.
  • ·        Various scripts provide an administrator's interface to the machinery.

IPSec optional?
IPSec is optional for IPV4, the current protocol version, but it’s required for IPV6. The FreeS/WAN project is working toward implementing IPSec for the Linux IPV6 stack.

Because IPSec is at the IP level, it can secure any type of traffic, but the two most common implementations are establishing a virtual private network (VPN) between two sites across a public network and, on a smaller scale, connecting remote laptop users to the home office across the Internet.

The IPSec protocol is designed to allow different implementations to interoperate, with the VPN Consortium working to encourage cooperation among vendors.

FreeS/WAN is known to be able to interoperate with:
  • ·        BSD IPSec
  • ·        Windows 2000 IPSec
  • ·        PGPNet
  • ·        Safenet SoftPK
  • ·        Cisco routers

An additional concept provided by FreeS/WAN is that of "opportunistic encryption," with which any two IPSec servers can encrypt each other and will do so whenever packets pass between them. The FreeS/WAN team thinks this could encourage using encryption on most Internet traffic, should the idea catch on and network administrators implement it. The technique relies on using DNS to provide the RSA keys needed to encrypt the connection. Although I won't be covering it further here, for more information, see the HowTo document, which covers implementation of opportunistic encryption. Of course, dynamically allocated IPs and firewalls can make IPSec implementation problematic, as it is designed for an end-to-end, fixed IP scheme, but these issues can be worked around.

Where did I leave my keys?
Like all encryption schemes, IPSec relies on the concept of keys. A key is a signature, if you will, that allows the party at the other end of the connection to know you are who you claim to be and that both parties can trust the communication. Of course, keys can be lost or stolen, and in that case, an untrusted party may tune in on the communication.

Keys can be manually transferred between networks either by encrypted mail or some other method, or the systems can be configured to generate and transfer keys automatically, replacing the keys periodically. The FreeS/WAN team recommends automatic key generation; by using this method, you’re assured that the keys will be changed at regular intervals, and any leak will only exist for a fixed period of time before the keys change. For automatic keying, either "shared secrets" or public keys must exist for the two systems to be able negotiate the secure connection.

Getting FreeS/WAN
If you're lucky enough to be using a distribution that includes FreeS/WAN, it may be as easy as installing a package from your CD and doing a little setup work. Apparently, U.S.-based distributions cannot include it due to encryption export regulations, but several Linux distributions that are based outside of the United States include FreeS/WAN, with support built into the stock kernel. Be aware, though, that even though kernel support and the IPSec utilities are built into the distribution, they may not be fully functional. I spent several hours troubleshooting an IPSec setup until I found out in the mail archives that the distribution I was using had shipped a broken implementation.

I’ll outline the steps you would need to take to include FreeS/WAN in an existing server, as a worst-case scenario. If you already have it as a prebuilt package, you can just skip to the appropriate setup steps.

As of this writing, the latest version of FreeS/WAN is 1.92. The downloaded file will be called LATEST.tar.gz and it requires:
  • ·        gcc or egcs (C compiler)
  • ·        An appropriate assembler/linker
  • ·        make and patch (compiler tools)
  • ·        glibc
  • ·        gmp (Gnu MultiPrecision Library)
  • ·        ncurses (for a friendlier, menu-based kernel config)
  • ·        Kernel source (FreeS/WAN with both 2.2 and 2.4 series kernels)

Your kernel source will normally reside in /usr/src/linux. The FreeS/WAN folks recommend untarring the FreeS/WAN tarball in /usr/src, where you will end up with the /usr/src/freeswan-version directory (with version being the version number of the FreeS/WAN source you retrieved). To do so, do the following, as root:
  • ·        Move the LATEST.tar.gz file to /usr/src
  • ·        Untar the .gz file with tar xvzf LATEST.tar.gz

Be sure to build, install, and test your kernel before adding FreeS/WAN. For more information on compiling your kernel, take a look at Jack Wallen, Jr.’s Daily Feature ”Compiling (or recompiling) your Linux kernel.”

As a minimum, you'll want networking support, including support for your network card. You should also probably enable:
  • ·        CONFIG_SYSCTL=y
  • ·        CONFIG_PROC_FS=y

Editor's note
The above options will appear as listed when running the make config command. If you’re running the make menuconfig or the make xconfig commands, you’ll be selecting them from menus.

Boot with your new kernel and make sure the underlying networking works as it should and that you can ping and access the machine at the other end of your proposed VPN without IPSec in place.

Now you can go back and build FreeS/WAN.

Building FreeS/WAN
The first step in building the application is to cd to the /usr/src/freeswan-1.9.2 directory, like so:
cd /usr/src/freeswan-1.9.2

Once you’re in that directory, run this command:
make oldgo

"Make" options
You can also use make ogo, menugo, and xgo, which allow you to redo your kernel config. Oldgo just adds the FreeS/WAN options to your latest config and proceeds with the build.

At this point, you can either do make kinstall in the FreeS/WAN directory or, if you’re more comfortable doing the steps yourself, do the following:
cd ../linux
make install
make modules
make modules_install

Configuring FreeS/WAN
Before you begin to set up IPSec between two gateway machines, be sure to test the underlying network and make sure the machines can communicate with any software you want to wrap in the encryption. This way, you won't waste time troubleshooting the wrong problem. You'll need to enable IP forwarding for IPSec to work, like so:
echo 1 > /proc/sys/net/ipv4/ip_forward

To permanently enable it, typically, a setting in /etc/sysconfig/network (for Red Hat-based systems) must be changed to true, like so:


Before permanently enabling it, be sure you have appropriate firewalling set up so you’re not indiscriminately passing packets.

Generating keys
Both machines will need keys in /etc/ipsec.secrets or possibly /etc/freeswan/ipsec.secrets. If you built from the source as described previously, a set of keys should have been created for you, and if you’re using binaries from your distribution, you may have this file prepopulated also.

If you want to generate a new key pair, use the following command, where nbits equals the number of bits you want to use in the key pair (i.e., 256, 1024, 2048):
ipsec rsasigkey nbits

You’ll end up getting output something like this. You would wrap this in the following:
: RSA          {

Then, cut and paste it into the ipsec.secrets file.

For testing, you could create a trivial ipsec.secrets file and not use RSA encryption, like so: PSK "yourlittlesecret"

Final configurations
The last configurations entail editing /etc/ipsec.conf. This is prepopulated with a sample configuration, which you can copy and edit to suit your situation.

You can specify the interfaces line with an appropriate mapping, such as:
    interfaces="ipsec0=eth0 ipsec1=ppp0"

Or you can leave it as %defaultroute.

By default, the debugging entries are set to none. If you’re having problems, change them to all and you'll get lots of information in /var/log/messages and /var/log/secure. Finally, a set of default values is used for all connections, if not specified in the connection block.

Note the RSA authentication block. If you just have authby=rsasig and no left/right rsasigkey entries, IPSec will expect to receive keys from DNS, and if DNS isn’t set up to send keys to IPSec, the connection will abort immediately.

You should also use something reasonable to name your connections, preferably a name that will assist you in debugging. By naming the connection something like leftmachine-rightmachine, you'll have a reminder of what the connection is supposed to be accomplishing. Also, don't get confused by the "left" and "right" nomenclature. No matter which end of the connection you’re configuring, "left" always refers to the same machine, the "left" gateway. (Or in the simplest case, the left gateway is the only machine at that end of the connection.)

Copy this block and use it as a template to create your own connections, giving them unique names.


Experimenting with ipsec.conf
Don't try to comment out existing lines and add duplicate ones while you experiment with ipsec.conf. IPSec won't tolerate it and will give messages like "Parameter is not within a section—aborting." To make matters worse, if you start IPSec with an init script, you don't even see these messages; you'll need to check /var/log/messages after you get a FAILED message from the init script.

The auto= parameter can be commented out with either add or start. By defining it as add, the plutoload parameter of %search will do essentially this command:
ipsec auto —add connection-name

If you use auto=start, the connection will not only be added but will also be started up. If you want tunneled connections brought up at boot, you should probably enable this setting. If the connection is for a dial-up machine, you may want to leave it as add and let the dial-ins, or Road Warriors, as they are called in the FreeS/WAN docs, bring up the connection.

Webmin also offers a friendlier interface to FreeS/WAN configuration, but not all of the configuration features are fully implemented. Webmin may be included with your distribution.

Starting and stopping
Once you have your configuration information in place, you need to load the kernel modules and start up the pluto daemon, like so:
ipsec setup start

If you need to stop ipsec, run this command:
ipsec setup stop

If you need to restart ipsec, use this command:
ipsec setup restart

Your distribution may also have set up an initscript in /etc/rc.d/init.d to stop and start IPSec services at boot and shutdown, and you can use this script to manually start and stop, like so:
/etc/rc.d/init.d/ipsec start
/etc/rc.d/init.d/ipsec stop

If none of your connections were set to add or start, not too much will be happening at this point, but you should see the kernel module, ipsec, loaded and the pluto daemon running. You should also now see the ipsec0 interface when running ifconfig or route and something like this from the ipsecwhack command:
[root@curly /root]# ipsec whack –status
000 interface ipsec0/eth0

Now if you add the connection, like so:
[root@curly freeswan]# ipsec auto —add curly-larry

you can use the whack command to see the new connection status.

Finally, you can bring the connection up. Both sides need to add the connection, but only one needs to bring it up.

When taking the connection down, both sides need to do so using this command:
[root@curly freeswan]# ipsec auto —down curly-larry

For two machines on the same network with no gateway, the machines are the left and right entries in ipsec.conf, and you can leave the leftsubnet, leftnexthop, rightsubnet, and rightnexthop blank if there are no intermediate machines required to route packets between the two machines. A very trivial configuration file could be something like this (using the trivial secrets example from above):
config setup
   # if eth0 is connected to lan
conn larry-curly

For a Road Warrior setup with a dynamic IP, you don't know the connecting machine’s IP number in advance, so you need to be able to identify the machine and set up the routing on the fly. Such on-the-fly connecting can be achieved with the following ipsec.conf configuration:

Road Warrior's ipsec.conf (excerpt):
conn Road-Central

Host gateway's ipsec.conf (excerpt):
conn Road-Central

Many other variations on these basic schemes exist. The FreeS/WAN documentation covers these and many more in great detail. Several years worth of searchable mailing-list archives are available, too, which cover a lot of specific implementation issues. Should you run into a problem, see the FAQ for many of the common issues and solutions.

Need more information?
Here are links to good user-provided implementation guidelines: IPSec practical configurations and Dynamic IPSec and FreeS/WAN

Testing the connection
If your ipsec whack output looked good, you should now be able to connect to the other machine via telnet or any other protocol, just as you could before setting up the tunnel. The difference is that now, your communications are encrypted at the gateway through the IPSec tunnel. If you can’t ping the machine at the other end of the VPN, most likely something is wrong with your configuration. Don't be misled by the ability to ping between the two gateway machines, as this connection does not use the encrypted tunnel. Refer to the FAQ mentioned earlier for a number of common problems.

If you wanted to test whether or not the packets were truly encrypted, you could put a sniffer machine on the network between the gateways and monitor the traffic using tcpdump.

From the FreeS/WAN documentation
Except for some of the header information, packets should be utterly unintelligible. The output of good encryption looks exactly like random noise. For more documentation on FreeS/WAN, take a look at the Introduction to FreeS/WAN.

You can put recognizable data in the ping packets with something like this:
ping -p feedfacedeadbeef

Feedfacedeadbeef is a legal hexadecimal pattern that is easy to pick out of hex dumps. If your recognizable data looks like garbage, your connection is truly encrypted.

This Daily Drill Down is a brief introduction to FreeS/WAN. Networks and VPNs come in a variety of forms, from the simple to the very complex, and adding VPN tunnels to the mix can make for some interesting troubleshooting sessions.

The sites mentioned previously and the FreeS/WAN mail archives cover a lot of specific examples. Chances are something will be there that is close to what you’re trying to accomplish, so take advantage of the wisdom of those who have walked the trail before you. It's your obligation as an administrator to do everything you can to protect your company’s and users’ data and communications, and FreeS/WAN can be yet another tool to add to your arsenal.

Editor's Picks